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