Wed, 12 Mar 2003 10:59:29 +0000
optimized g4_find_pixel().
bitblt_g4.c | file | annotate | diff | revisions |
1.1 diff -r 663da96ad2bc -r cb75ec9430b4 bitblt_g4.c 1.2 --- a/bitblt_g4.c Wed Mar 12 10:59:09 2003 +0000 1.3 +++ b/bitblt_g4.c Wed Mar 12 10:59:29 2003 +0000 1.4 @@ -4,7 +4,7 @@ 1.5 * will be compressed using ITU-T T.6 (G4) fax encoding. 1.6 * 1.7 * G4 compression 1.8 - * $Id: bitblt_g4.c,v 1.11 2003/03/11 03:14:39 eric Exp $ 1.9 + * $Id: bitblt_g4.c,v 1.12 2003/03/12 02:59:29 eric Exp $ 1.10 * Copyright 2003 Eric Smith <eric@brouhaha.com> 1.11 * 1.12 * This program is free software; you can redistribute it and/or modify 1.13 @@ -35,6 +35,7 @@ 1.14 1.15 1.16 #include "bitblt.h" 1.17 +#include "bitblt_tables.h" 1.18 #include "pdf_util.h" 1.19 1.20 1.21 @@ -69,15 +70,6 @@ 1.22 buf->byte_idx++; 1.23 buf->bit_idx = 8; 1.24 } 1.25 -#if (G4_DEBUG >= 3) 1.26 - { 1.27 - int i; 1.28 - fprintf (stderr, "::: "); 1.29 - for (i = 0; i < buf->byte_idx; i++) 1.30 - fprintf (stderr, "%02x ", buf->data [i]); 1.31 - fprintf (stderr, "\n"); 1.32 - } 1.33 -#endif 1.34 s = fwrite (& buf->data [0], 1, buf->byte_idx, buf->f); 1.35 /* $$$ should check result */ 1.36 init_bit_buffer (buf); 1.37 @@ -97,16 +89,6 @@ 1.38 uint32_t count, 1.39 uint32_t bits) 1.40 { 1.41 -#if (G4_DEBUG >= 2) 1.42 - { 1.43 - int i; 1.44 - fprintf (stderr, "%d %04x: ", count, bits); 1.45 - for (i = count - 1; i >= 0; i--) 1.46 - fprintf (stderr, "%d", (bits >> i) & 1); 1.47 - fprintf (stderr, "\n"); 1.48 - } 1.49 -#endif 1.50 - 1.51 while (count > buf->bit_idx) 1.52 { 1.53 buf->data [buf->byte_idx] |= bits >> (count - buf->bit_idx); 1.54 @@ -163,17 +145,72 @@ 1.55 } 1.56 1.57 1.58 +#define not_aligned(p) (((word_t) p) & (sizeof (word_t) - 1)) 1.59 + 1.60 + 1.61 static uint32_t g4_find_pixel (uint8_t *buf, 1.62 uint32_t pos, 1.63 uint32_t width, 1.64 bool color) 1.65 { 1.66 - while (pos < width) 1.67 + uint8_t *p = buf + pos / 8; 1.68 + int bit = pos & 7; 1.69 + uint8_t *max_p = buf + (width - 1) / 8; 1.70 + uint8_t d; 1.71 + 1.72 + /* check first byte (may be partial) */ 1.73 + d = *p; 1.74 + if (! color) 1.75 + d = ~d; 1.76 + bit += rle_tab [bit][d]; 1.77 + if (bit < 8) 1.78 + goto done; 1.79 + p++; 1.80 + 1.81 + /* check individual bytes until we hit word alignment */ 1.82 + while ((p <= max_p) && not_aligned (p)) 1.83 + { 1.84 + d = *p; 1.85 + if (! color) 1.86 + d = ~d; 1.87 + if (d != 0) 1.88 + goto found; 1.89 + p++; 1.90 + } 1.91 + 1.92 + /* check aligned words in middle */ 1.93 + while ((p <= (max_p - sizeof (word_t)))) 1.94 { 1.95 - if (g4_get_pixel (buf, pos) == color) 1.96 - return (pos); 1.97 - pos++; 1.98 + word_t w = *((word_t *) p); 1.99 + if (! color) 1.100 + w = ~w; 1.101 + if (w != 0) 1.102 + break; 1.103 + p += sizeof (word_t); 1.104 } 1.105 + 1.106 + /* check trailing bytes */ 1.107 + while (p <= max_p) 1.108 + { 1.109 + d = *p; 1.110 + if (! color) 1.111 + d = ~d; 1.112 + if (d) 1.113 + goto found; 1.114 + p++; 1.115 + } 1.116 + 1.117 + goto not_found; 1.118 + 1.119 + found: 1.120 + bit = rle_tab [0][d]; 1.121 + 1.122 + done: 1.123 + pos = ((p - buf) << 3) + bit; 1.124 + if (pos < width) 1.125 + return (pos); 1.126 + 1.127 + not_found: 1.128 return (width); 1.129 } 1.130 1.131 @@ -194,7 +231,7 @@ 1.132 1.133 b1 = g4_find_pixel (ref, 0, width, 1); 1.134 1.135 -#if G4_DEBUG 1.136 +#if (G4_DEBUG & 1) 1.137 fprintf (stderr, "start of row\n"); 1.138 if ((a1 != width) || (b1 != width)) 1.139 { 1.140 @@ -211,7 +248,7 @@ 1.141 /* pass mode - 0001 */ 1.142 write_bits (buf, 4, 0x1); 1.143 a0 = b2; 1.144 -#if G4_DEBUG 1.145 +#if (G4_DEBUG & 1) 1.146 fprintf (stderr, "pass\n"); 1.147 #endif 1.148 } 1.149 @@ -222,7 +259,7 @@ 1.150 g4_vert_code [3 + a1 - b1].count, 1.151 g4_vert_code [3 + a1 - b1].bits); 1.152 a0 = a1; 1.153 -#if G4_DEBUG 1.154 +#if (G4_DEBUG & 1) 1.155 fprintf (stderr, "vertical %d\n", a1 - b1); 1.156 #endif 1.157 } 1.158 @@ -233,7 +270,7 @@ 1.159 write_bits (buf, 3, 0x1); 1.160 g4_encode_horizontal_run (buf, a0_c, a1 - a0); 1.161 g4_encode_horizontal_run (buf, ! a0_c, a2 - a1); 1.162 -#if G4_DEBUG 1.163 +#if (G4_DEBUG & 1) 1.164 fprintf (stderr, "horizontal %d %s, %d %s\n", 1.165 a1 - a0, a0_c ? "black" : "white", 1.166 a2 - a1, a0_c ? "white" : "black"); 1.167 @@ -250,7 +287,7 @@ 1.168 b1 = g4_find_pixel (ref, a0 + 1, width, ! g4_get_pixel (ref, a0)); 1.169 if (g4_get_pixel (ref, b1) == a0_c) 1.170 b1 = g4_find_pixel (ref, b1 + 1, width, ! a0_c); 1.171 -#if G4_DEBUG 1.172 +#if (G4_DEBUG & 1) 1.173 fprintf (stderr, "a1 = %u, b1 = %u\n", a1, b1); 1.174 #endif 1.175 } 1.176 @@ -263,17 +300,13 @@ 1.177 uint32_t row; 1.178 struct bit_buffer bb; 1.179 1.180 - word_type *temp_buffer; 1.181 + word_t *temp_buffer; 1.182 1.183 - word_type *cur_line; 1.184 - word_type *ref_line; /* reference (previous) row */ 1.185 - 1.186 -#if G4_DEBUG 1.187 - fprintf (stderr, "width %u\n", width); 1.188 -#endif 1.189 + word_t *cur_line; 1.190 + word_t *ref_line; /* reference (previous) row */ 1.191 1.192 temp_buffer = pdf_calloc ((width + BITS_PER_WORD - 1) / BITS_PER_WORD, 1.193 - sizeof (word_type)); 1.194 + sizeof (word_t)); 1.195 1.196 cur_line = bitmap->bits; 1.197 ref_line = temp_buffer;