many bug fixes including bit ordering of output, search positions and polarities. added G4_DEBUG conditional.

Tue, 11 Mar 2003 11:14:39 +0000

author
eric
date
Tue, 11 Mar 2003 11:14:39 +0000
changeset 95
851a04fa5324
parent 94
7664a3f112ba
child 96
25c6b1a63f93

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