bitblt_g4.c

changeset 94
7664a3f112ba
parent 91
e63762afae80
child 95
851a04fa5324
     1.1 diff -r 98a8a2c763fd -r 7664a3f112ba bitblt_g4.c
     1.2 --- a/bitblt_g4.c	Mon Mar 10 09:58:34 2003 +0000
     1.3 +++ b/bitblt_g4.c	Mon Mar 10 13:08:25 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.9 2003/03/10 01:49:50 eric Exp $
     1.9 + * $Id: bitblt_g4.c,v 1.10 2003/03/10 05:08:25 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 @@ -32,6 +32,7 @@
    1.14  
    1.15  
    1.16  #include "bitblt.h"
    1.17 +#include "pdf_util.h"
    1.18  
    1.19  
    1.20  #include "g4_tables.h"
    1.21 @@ -134,13 +135,24 @@
    1.22  }
    1.23  
    1.24  
    1.25 -static uint32_t find_transition (uint8_t *data,
    1.26 -				 uint32_t pos,
    1.27 -				 uint32_t width)
    1.28 +static inline int g4_get_pixel (uint8_t *buf, uint32_t x)
    1.29  {
    1.30 -  if (! data)
    1.31 -    return (width);
    1.32 -  return (0);  /* $$$ */
    1.33 +  return ((buf [x >> 3] >> (x & 7)) & 1);
    1.34 +}
    1.35 +
    1.36 +
    1.37 +static uint32_t g4_find_pixel (uint8_t *buf,
    1.38 +			       uint32_t pos,
    1.39 +			       uint32_t width,
    1.40 +			       bool color)
    1.41 +{
    1.42 +  while (pos < width)
    1.43 +    {
    1.44 +      if (g4_get_pixel (buf, pos) == color)
    1.45 +	return (pos);
    1.46 +      pos++;
    1.47 +    }
    1.48 +  return (width);
    1.49  }
    1.50  
    1.51  
    1.52 @@ -149,22 +161,19 @@
    1.53  			   uint8_t *ref,
    1.54  			   uint8_t *row)
    1.55  {
    1.56 -  int a0, a1, a2;
    1.57 -  int b1, b2;
    1.58 +  uint32_t a0, a1, a2;
    1.59 +  uint32_t b1, b2;
    1.60 +  bool a0_c;
    1.61  
    1.62 -  a0 = -1;
    1.63 +  a0 = 0;
    1.64 +  a0_c = 0;
    1.65 +
    1.66 +  a1 = g4_find_pixel (row, 0, width, 1);
    1.67 +  b1 = g4_find_pixel (ref, 0, width, 1);
    1.68    
    1.69    while (a0 < width)
    1.70      {
    1.71 -      /* find a1, a2 */
    1.72 -      a1 = find_transition (row, a0, width);
    1.73 -      a2 = find_transition (row, a1, width);
    1.74 -
    1.75 -      /* find b1, b2 */
    1.76 -      b1 = find_transition (ref, a0, width);
    1.77 -      if (0) /* $$$ b1 color = a0 color */
    1.78 -	b1 = find_transition (ref, b1, width);
    1.79 -      b2 = find_transition (ref, b2, width);
    1.80 +      b2 = g4_find_pixel (ref, b1 + 1, width, g4_get_pixel (ref, b1));
    1.81  
    1.82        if (b2 < a1)
    1.83  	{
    1.84 @@ -183,22 +192,41 @@
    1.85        else
    1.86  	{
    1.87  	  /* horizontal mode - 001 */
    1.88 +	  a2 = g4_find_pixel (row, a1, width, a0_c);
    1.89  	  write_bits (buf, 3, 0x1);
    1.90 -	  g4_encode_horizontal_run (buf, 0 /* $$$ color (a0) */, a1 - a0);
    1.91 -	  g4_encode_horizontal_run (buf, 1 /* $$$ color (a1) */, a2 - a1);
    1.92 +	  g4_encode_horizontal_run (buf,   a0_c, a1 - a0);
    1.93 +	  g4_encode_horizontal_run (buf, ! a0_c, a2 - a1);
    1.94  	  a0 = a2;
    1.95  	}
    1.96 +
    1.97 +      if (a0 >= width)
    1.98 +	break;;
    1.99 +
   1.100 +      a0_c = g4_get_pixel (row, a0);
   1.101 +
   1.102 +      a1 = g4_find_pixel (row, a0 + 1, width, ! a0_c);
   1.103 +      b1 = g4_find_pixel (ref, a0 + 1, width, a0_c);
   1.104 +      b1 = g4_find_pixel (ref, b1 + 1, width, ! a0_c);
   1.105      }
   1.106  }
   1.107  
   1.108  
   1.109  void bitblt_write_g4 (Bitmap *bitmap, FILE *f)
   1.110  {
   1.111 +  uint32_t width = (bitmap->rect.max.x - bitmap->rect.min.x) + 1;
   1.112    uint32_t row;
   1.113    struct bit_buffer bb;
   1.114  
   1.115 -  word_type *ref_line = NULL;  /* reference (previous) row */
   1.116 -  word_type *line = bitmap->bits;
   1.117 +  word_type *temp_buffer;
   1.118 +
   1.119 +  word_type *cur_line;
   1.120 +  word_type *ref_line;  /* reference (previous) row */
   1.121 +
   1.122 +  temp_buffer = pdf_calloc ((width + BITS_PER_WORD - 1) / BITS_PER_WORD,
   1.123 +			    sizeof (word_type));
   1.124 +
   1.125 +  cur_line = bitmap->bits;
   1.126 +  ref_line = temp_buffer;
   1.127  
   1.128    memset (& bb, 0, sizeof (bb));
   1.129  
   1.130 @@ -209,11 +237,11 @@
   1.131         row++)
   1.132      {
   1.133        g4_encode_row (& bb,
   1.134 -		     (bitmap->rect.max.x - bitmap->rect.min.x) + 1,
   1.135 +		     width,
   1.136  		     (uint8_t *) ref_line,
   1.137 -		     (uint8_t *) line);
   1.138 -      ref_line = line;
   1.139 -      line += bitmap->row_words;
   1.140 +		     (uint8_t *) cur_line);
   1.141 +      ref_line = cur_line;
   1.142 +      cur_line += bitmap->row_words;
   1.143      }
   1.144  
   1.145    
   1.146 @@ -221,6 +249,8 @@
   1.147    write_bits (& bb, 24, 0x001001);
   1.148  
   1.149    flush_bits (& bb);
   1.150 +
   1.151 +  free (temp_buffer);
   1.152  }
   1.153  
   1.154