Tue, 11 Mar 2003 11:14:39 +0000
many bug fixes including bit ordering of output, search positions and polarities. added G4_DEBUG conditional.
bitblt_g4.c | file | annotate | diff | revisions |
1.1 diff -r 7664a3f112ba -r 851a04fa5324 bitblt_g4.c 1.2 --- a/bitblt_g4.c Mon Mar 10 13:08:25 2003 +0000 1.3 +++ b/bitblt_g4.c Tue Mar 11 11:14:39 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.10 2003/03/10 05:08:25 eric Exp $ 1.9 + * $Id: bitblt_g4.c,v 1.11 2003/03/11 03:14:39 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 @@ -24,6 +24,9 @@ 1.14 */ 1.15 1.16 1.17 +#define G4_DEBUG 0 1.18 + 1.19 + 1.20 #include <stdbool.h> 1.21 #include <stdint.h> 1.22 #include <stdio.h> 1.23 @@ -38,38 +41,53 @@ 1.24 #include "g4_tables.h" 1.25 1.26 1.27 -#define BIT_BUF_SIZE 4096 1.28 +#define BIT_BUF_SIZE 1 /* 4096 */ 1.29 1.30 struct bit_buffer 1.31 { 1.32 FILE *f; 1.33 uint32_t byte_idx; /* index to next byte position in data buffer */ 1.34 - uint32_t bit_idx; /* index to next bit position in data buffer, 1.35 - 0 = MSB, 7 = LSB */ 1.36 + uint32_t bit_idx; /* one greater than the next bit position in data buffer, 1.37 + 8 = MSB, 1 = LSB */ 1.38 uint8_t data [BIT_BUF_SIZE]; 1.39 }; 1.40 1.41 1.42 +static void init_bit_buffer (struct bit_buffer *buf) 1.43 +{ 1.44 + buf->byte_idx = 0; 1.45 + buf->bit_idx = 8; 1.46 + memset (& buf->data [0], 0, BIT_BUF_SIZE); 1.47 +} 1.48 + 1.49 + 1.50 static void flush_bits (struct bit_buffer *buf) 1.51 { 1.52 size_t s; 1.53 - if (buf->bit_idx) 1.54 + if (buf->bit_idx != 8) 1.55 { 1.56 - /* zero remaining bits in last byte */ 1.57 - buf->data [buf->byte_idx] &= ~ ((1 << (8 - buf->bit_idx)) - 1); 1.58 buf->byte_idx++; 1.59 - buf->bit_idx = 0; 1.60 + buf->bit_idx = 8; 1.61 } 1.62 +#if (G4_DEBUG >= 3) 1.63 + { 1.64 + int i; 1.65 + fprintf (stderr, "::: "); 1.66 + for (i = 0; i < buf->byte_idx; i++) 1.67 + fprintf (stderr, "%02x ", buf->data [i]); 1.68 + fprintf (stderr, "\n"); 1.69 + } 1.70 +#endif 1.71 s = fwrite (& buf->data [0], 1, buf->byte_idx, buf->f); 1.72 /* $$$ should check result */ 1.73 - buf->byte_idx = 0; 1.74 + init_bit_buffer (buf); 1.75 } 1.76 1.77 1.78 static void advance_byte (struct bit_buffer *buf) 1.79 { 1.80 buf->byte_idx++; 1.81 - buf->bit_idx = 0; 1.82 + buf->bit_idx = 8; 1.83 if (buf->byte_idx == BIT_BUF_SIZE) 1.84 flush_bits (buf); 1.85 } 1.86 @@ -79,24 +97,28 @@ 1.87 uint32_t count, 1.88 uint32_t bits) 1.89 { 1.90 - uint32_t b2; /* how many bits will fit in byte in data buffer */ 1.91 - uint32_t c2; /* how many bits to transfer on this iteration */ 1.92 - uint32_t d2; /* bits to transfer on this iteration */ 1.93 +#if (G4_DEBUG >= 2) 1.94 + { 1.95 + int i; 1.96 + fprintf (stderr, "%d %04x: ", count, bits); 1.97 + for (i = count - 1; i >= 0; i--) 1.98 + fprintf (stderr, "%d", (bits >> i) & 1); 1.99 + fprintf (stderr, "\n"); 1.100 + } 1.101 +#endif 1.102 1.103 - while (count) 1.104 + while (count > buf->bit_idx) 1.105 { 1.106 - b2 = 8 - buf->bit_idx; 1.107 - if (b2 >= count) 1.108 - c2 = count; 1.109 - else 1.110 - c2 = b2; 1.111 - d2 = bits >> (count - c2); 1.112 - buf->data [buf->byte_idx] |= (d2 << (b2 + c2)); 1.113 - buf->bit_idx += c2; 1.114 - if (buf->bit_idx > 7) 1.115 - advance_byte (buf); 1.116 - count -= c2; 1.117 + buf->data [buf->byte_idx] |= bits >> (count - buf->bit_idx); 1.118 + count -= buf->bit_idx; 1.119 + advance_byte (buf); 1.120 } 1.121 + 1.122 + bits &= ((1 << count) - 1); 1.123 + buf->data [buf->byte_idx] |= bits << (buf->bit_idx - count); 1.124 + buf->bit_idx -= count; 1.125 + if (buf->bit_idx == 0) 1.126 + advance_byte (buf); 1.127 } 1.128 1.129 1.130 @@ -169,17 +191,29 @@ 1.131 a0_c = 0; 1.132 1.133 a1 = g4_find_pixel (row, 0, width, 1); 1.134 + 1.135 b1 = g4_find_pixel (ref, 0, width, 1); 1.136 + 1.137 +#if G4_DEBUG 1.138 + fprintf (stderr, "start of row\n"); 1.139 + if ((a1 != width) || (b1 != width)) 1.140 + { 1.141 + fprintf (stderr, "a1 = %u, b1 = %u\n", a1, b1); 1.142 + } 1.143 +#endif 1.144 1.145 while (a0 < width) 1.146 { 1.147 - b2 = g4_find_pixel (ref, b1 + 1, width, g4_get_pixel (ref, b1)); 1.148 + b2 = g4_find_pixel (ref, b1 + 1, width, ! g4_get_pixel (ref, b1)); 1.149 1.150 if (b2 < a1) 1.151 { 1.152 /* pass mode - 0001 */ 1.153 write_bits (buf, 4, 0x1); 1.154 a0 = b2; 1.155 +#if G4_DEBUG 1.156 + fprintf (stderr, "pass\n"); 1.157 +#endif 1.158 } 1.159 else if (abs (a1 - b1) <= 3) 1.160 { 1.161 @@ -188,14 +222,22 @@ 1.162 g4_vert_code [3 + a1 - b1].count, 1.163 g4_vert_code [3 + a1 - b1].bits); 1.164 a0 = a1; 1.165 +#if G4_DEBUG 1.166 + fprintf (stderr, "vertical %d\n", a1 - b1); 1.167 +#endif 1.168 } 1.169 else 1.170 { 1.171 /* horizontal mode - 001 */ 1.172 - a2 = g4_find_pixel (row, a1, width, a0_c); 1.173 + a2 = g4_find_pixel (row, a1 + 1, width, a0_c); 1.174 write_bits (buf, 3, 0x1); 1.175 g4_encode_horizontal_run (buf, a0_c, a1 - a0); 1.176 g4_encode_horizontal_run (buf, ! a0_c, a2 - a1); 1.177 +#if G4_DEBUG 1.178 + fprintf (stderr, "horizontal %d %s, %d %s\n", 1.179 + a1 - a0, a0_c ? "black" : "white", 1.180 + a2 - a1, a0_c ? "white" : "black"); 1.181 +#endif 1.182 a0 = a2; 1.183 } 1.184 1.185 @@ -205,15 +247,19 @@ 1.186 a0_c = g4_get_pixel (row, a0); 1.187 1.188 a1 = g4_find_pixel (row, a0 + 1, width, ! a0_c); 1.189 - b1 = g4_find_pixel (ref, a0 + 1, width, a0_c); 1.190 - b1 = g4_find_pixel (ref, b1 + 1, width, ! a0_c); 1.191 + b1 = g4_find_pixel (ref, a0 + 1, width, ! g4_get_pixel (ref, a0)); 1.192 + if (g4_get_pixel (ref, b1) == a0_c) 1.193 + b1 = g4_find_pixel (ref, b1 + 1, width, ! a0_c); 1.194 +#if G4_DEBUG 1.195 + fprintf (stderr, "a1 = %u, b1 = %u\n", a1, b1); 1.196 +#endif 1.197 } 1.198 } 1.199 1.200 1.201 void bitblt_write_g4 (Bitmap *bitmap, FILE *f) 1.202 { 1.203 - uint32_t width = (bitmap->rect.max.x - bitmap->rect.min.x) + 1; 1.204 + uint32_t width = bitmap->rect.max.x - bitmap->rect.min.x; 1.205 uint32_t row; 1.206 struct bit_buffer bb; 1.207 1.208 @@ -222,13 +268,17 @@ 1.209 word_type *cur_line; 1.210 word_type *ref_line; /* reference (previous) row */ 1.211 1.212 +#if G4_DEBUG 1.213 + fprintf (stderr, "width %u\n", width); 1.214 +#endif 1.215 + 1.216 temp_buffer = pdf_calloc ((width + BITS_PER_WORD - 1) / BITS_PER_WORD, 1.217 sizeof (word_type)); 1.218 1.219 cur_line = bitmap->bits; 1.220 ref_line = temp_buffer; 1.221 1.222 - memset (& bb, 0, sizeof (bb)); 1.223 + init_bit_buffer (& bb); 1.224 1.225 bb.f = f; 1.226