optimized g4_find_pixel().

Wed, 12 Mar 2003 10:59:29 +0000

author
eric
date
Wed, 12 Mar 2003 10:59:29 +0000
changeset 110
cb75ec9430b4
parent 109
663da96ad2bc
child 111
966310797665

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;