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 --- 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;