about summary refs log tree commit diff
path: root/converter/other/bmepsoe.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
commit1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch)
tree64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/other/bmepsoe.c
downloadnetpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/bmepsoe.c')
-rw-r--r--converter/other/bmepsoe.c539
1 files changed, 539 insertions, 0 deletions
diff --git a/converter/other/bmepsoe.c b/converter/other/bmepsoe.c
new file mode 100644
index 00000000..cdb52779
--- /dev/null
+++ b/converter/other/bmepsoe.c
@@ -0,0 +1,539 @@
+/* 
+ * This was adapted for Netpbm from bmpesoe.c in Dirk Krause's Bmeps package
+ * by Bryan Henderson on 2005.01.05.
+ *
+ * Differences:
+ *   - doesn't require Bmeps configuration stuff (bmepsco.h)
+ *   - doesn't include pngeps.h
+ *   - doesn't have test scaffold code
+ *   - a few compiler warnings fixed
+ *
+ * Copyright (C) 2000 - Dirk Krause
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * In this package the copy of the GNU Library General Public License
+ * is placed in file COPYING.
+ */
+
+#include "bmepsoe.h"
+
+#define RL_RUNLENGTH(i) (257 - (i))
+#define RL_STRINGLENGTH(i) ((i) - 1)
+#define RL_MAXLENGTH (127)
+
+#define FINALOUTPUT(c) fputc((c),o->out)
+
+void oe_init(Output_Encoder *o, FILE *out, int mode, int rate, int *buf,
+  Bytef *flib, size_t flis, Bytef *flob, size_t flos
+)
+{
+  
+  o->out = out;
+  o->mode = mode;
+  o->textpos = 0;
+  o->a85_value = 0UL; o->a85_consumed = 0;
+  o->a85_0 = 1UL;
+  o->a85_1 = 85UL;
+  o->a85_2 = 85UL * 85UL;
+  o->a85_3 = 85UL * o->a85_2;
+  o->a85_4 = 85UL * o->a85_3;
+  o->rl_lastbyte = 0;
+  o->rl_buffer = buf;
+  o->rl_bufused = 0;
+  o->rl_state = 0;
+  o->bit_value = 0;
+  o->bit_consumed = 0;
+  o->flate_rate = rate;
+  if(o->flate_rate < 0) {
+    o->mode &= (~OE_FLATE);
+  }
+  if(o->flate_rate > 9) {
+    o->flate_rate = 9;
+  }
+  if((o->mode & OE_FLATE) && flib && flis && flob && flos) {
+    (o->flate_stream).zfree = (free_func)0;
+    (o->flate_stream).zalloc = (alloc_func)0;
+    (o->flate_stream).opaque = (voidpf)0;
+    if(deflateInit((&(o->flate_stream)),o->flate_rate) != Z_OK) {
+      o->mode &= (~OE_FLATE);
+    }
+  }
+  o->fl_i_buffer = flib;
+  o->fl_o_buffer = flob;
+  o->fl_i_size   = flis;
+  o->fl_o_size   = flos;
+  o->fl_i_used   = 0;
+  
+}
+
+static char hexdigits[] = {
+  "0123456789ABCDEF"
+};
+
+static void asciihex_add(Output_Encoder *o, int b)
+{
+  
+  FINALOUTPUT(hexdigits[(b/16)]) ;
+  FINALOUTPUT(hexdigits[(b%16)]) ;
+  o->textpos = o->textpos + 2;
+  if(o->textpos >= 64) {
+    FINALOUTPUT('\n') ;
+    o->textpos = 0;
+  }
+  
+}
+
+static void asciihex_flush(Output_Encoder *o)
+{
+  
+  if(o->textpos > 0) {
+    FINALOUTPUT('\n') ;
+    o->textpos = 0;
+  }
+  
+}
+
+static char   ascii85_char(unsigned long x)
+{
+  unsigned u;
+  int      i;
+  char back;
+  back = (char)0;
+  u = (unsigned)x;
+  i = (int)u;
+  i += 33;
+  back = (char)i;
+  return back;
+}
+
+
+
+static void
+ascii85_output(Output_Encoder * const o) {
+    unsigned long value;
+
+    value = o->a85_value;  /* initial value */
+
+    if (value == 0 && o->a85_consumed == 4) {
+        FINALOUTPUT('z');
+        ++o->textpos;
+    } else {
+        unsigned int i;
+        unsigned int j;
+        char buffer[6];
+
+        buffer[0] = ascii85_char(value / (o->a85_4));
+        value = value % (o->a85_4);
+        buffer[1] = ascii85_char(value / (o->a85_3));
+        value = value % (o->a85_3);
+        buffer[2] = ascii85_char(value / (o->a85_2));
+        value = value % (o->a85_2);
+        buffer[3] = ascii85_char(value / (o->a85_1));
+        value = value % (o->a85_1);
+        buffer[4] = ascii85_char(value);
+        buffer[5] = '\0';
+
+        i = o->a85_consumed + 1;
+        o->textpos += i;
+
+        for (j = 0; j < i; ++j)
+            FINALOUTPUT(buffer[j]);
+    }
+    if (o->textpos >= 64) {
+        FINALOUTPUT('\n');
+        o->textpos = 0;
+    }
+}
+
+
+
+static void ascii85_add(Output_Encoder *o, int b)
+{
+  unsigned u;
+  unsigned long ul;
+  
+  u = (unsigned)b;
+  ul = (unsigned long)u;
+  o->a85_value = 256UL * (o->a85_value) + ul;
+  o->a85_consumed = o->a85_consumed + 1;
+  if(o->a85_consumed >= 4) {
+    ascii85_output(o);
+    o->a85_value = 0UL;
+    o->a85_consumed = 0;
+  }
+  
+}
+
+static void ascii85_flush(Output_Encoder *o)
+{
+  int i;
+  
+  if(o->a85_consumed > 0) {
+    i = o->a85_consumed;
+    while(i < 4) {
+      o->a85_value = 256UL * o->a85_value;
+      i++;
+    }
+    ascii85_output(o);
+    o->a85_value = 0UL;
+    o->a85_consumed = 0;
+  }
+  if(o->textpos > 0) {
+    FINALOUTPUT('\n') ;
+    o->textpos = 0;
+  }
+  
+}
+
+static void after_flate_add(Output_Encoder *o, int b)
+{
+  
+  if(o->mode & OE_ASC85) {
+    ascii85_add(o,b);
+  } else {
+    asciihex_add(o,b);
+  }
+  
+}
+
+static void do_flate_flush(Output_Encoder *o, int final)
+{
+  Bytef *iptr, *optr, *xptr;
+  uLong  is, os, xs;
+  int err, must_continue;
+  
+  iptr = o->fl_i_buffer; optr = o->fl_o_buffer;
+  is = o->fl_i_size; os = o->fl_o_size;
+  
+  if(iptr && optr && is && os) {
+    is = o->fl_i_used;
+    if(is) {
+      (o->flate_stream).next_in = iptr;
+      (o->flate_stream).avail_in = is;
+      if(final) { 
+    must_continue = 1;
+    while(must_continue) {
+      (o->flate_stream).next_out = optr;
+      (o->flate_stream).avail_out = os;
+      must_continue = 0;
+      err = deflate(&(o->flate_stream), Z_FINISH);
+      switch(err) {
+        case Z_STREAM_END: { 
+              xptr = optr;
+          
+          xs = os - ((o->flate_stream).avail_out);
+          while(xs--) {
+        after_flate_add(o, (*(xptr++)));
+          }
+        } break;
+        case Z_OK : {
+          must_continue = 1;
+              xptr = optr;
+          
+          xs = os - ((o->flate_stream).avail_out);
+          while(xs--) {
+        after_flate_add(o, (*(xptr++)));
+          }
+        } break;
+        default : { 
+        } break;
+      }
+    }
+      } else { 
+    must_continue = 1;
+    while(must_continue) {
+      must_continue = 0;
+      (o->flate_stream).avail_out = os; (o->flate_stream).next_out = optr;
+      err = deflate(&(o->flate_stream), 0);
+      switch(err) {
+        case Z_OK: {
+          if((o->flate_stream).avail_in) {
+        must_continue = 1;
+          }
+          
+          xptr = optr; xs = os - ((o->flate_stream).avail_out);
+          while(xs--) {
+        after_flate_add(o, (*(xptr++)));
+          }
+        } break;
+        default : { 
+        } break;
+      }
+    }
+      }
+    }
+  }
+  
+}
+
+static void flate_add(Output_Encoder *o, int b)
+{
+  Byte bt;
+  Bytef *btptr;
+  
+  btptr = o->fl_i_buffer;
+  if(btptr) { 
+    bt = (Byte)b; 
+    btptr[(o->fl_i_used)] = bt;
+    o->fl_i_used += 1UL;
+    if(o->fl_i_used >= o->fl_i_size) {
+      do_flate_flush(o, 0);
+      o->fl_i_used = 0UL;
+    }
+  }
+  
+}
+
+static void after_flate_flush(Output_Encoder *o)
+{
+  
+  if(o->mode & OE_ASC85) {
+    ascii85_flush(o);
+  } else {
+    asciihex_flush(o);
+  }
+  
+}
+
+static void flate_flush(Output_Encoder *o)
+{
+  do_flate_flush(o,1);
+  deflateEnd(&(o->flate_stream));
+  after_flate_flush(o);
+}
+
+
+static void after_rl_add(Output_Encoder *o, int b)
+{
+  
+  if(o->mode & OE_FLATE) {
+    flate_add(o,b);
+  } else {
+    after_flate_add(o,b);
+  }
+  
+}
+
+static void rl_add(Output_Encoder *o, int b)
+{
+  int lgt, i;
+  int *buffer;
+  /* ##### */
+  
+  buffer = o->rl_buffer;
+  lgt = o->rl_bufused;
+  if(buffer) {
+    
+    if(lgt > 0) {
+      if(o->rl_lastbyte == b) {
+    switch(o->rl_state) {
+      case 2: {
+        buffer[lgt++] = b;
+        o->rl_bufused = lgt;
+        o->rl_state = 2;
+        o->rl_lastbyte = b;
+        if(lgt >= RL_MAXLENGTH) {
+          after_rl_add(o, RL_RUNLENGTH(lgt));
+          after_rl_add(o, b);
+          o->rl_bufused = 0;
+          o->rl_state = 0;
+          o->rl_lastbyte = b;
+        }
+      } break;
+      case 1: {
+        buffer[lgt++] = b;
+        o->rl_bufused = lgt;
+        o->rl_state = 2;
+        o->rl_lastbyte = b;
+        lgt = lgt - 3;
+        if(lgt > 0) {
+          after_rl_add(o, RL_STRINGLENGTH(lgt));
+          for(i = 0; i < lgt; i++) {
+        after_rl_add(o, buffer[i]);
+          }
+          buffer[0] = buffer[1] = buffer[2] = b;
+          o->rl_bufused = 3;
+          o->rl_state = 2;
+          o->rl_lastbyte = b;
+        }
+      } break;
+      default: {
+        buffer[lgt++] = b;
+        o->rl_bufused = lgt;
+        o->rl_state = 1;
+        o->rl_lastbyte = b;
+        if(lgt >= RL_MAXLENGTH) {
+          lgt = lgt - 2;
+          after_rl_add(o, RL_STRINGLENGTH(lgt));
+          for(i = 0; i < lgt; i++) {
+        after_rl_add(o, buffer[i]);
+          }
+          buffer[0] = buffer[1] = b;
+          o->rl_bufused = 2;
+          o->rl_state = 1;
+          o->rl_lastbyte = b;
+        }
+      } break;
+    }
+      } else {
+    if(o->rl_state == 2) {
+      after_rl_add(o, RL_RUNLENGTH(lgt));
+      after_rl_add(o, (o->rl_lastbyte));
+      buffer[0] = b; o->rl_bufused = 1; o->rl_lastbyte = b;
+      o->rl_state = 0;
+    } else {
+      buffer[lgt++] = b;
+      o->rl_bufused = lgt;
+      o->rl_lastbyte = b;
+      if(lgt >= RL_MAXLENGTH) {
+        after_rl_add(o, RL_STRINGLENGTH(lgt));
+        for(i = 0; i < lgt; i++) {
+          after_rl_add(o, buffer[i]);
+        }
+        o->rl_bufused = 0;
+      }
+      o->rl_state = 0;
+    }
+      }
+    } else {
+      buffer[0] = b;
+      o->rl_bufused = 1;
+      o->rl_lastbyte = b;
+    }
+    o->rl_lastbyte = b;
+    
+  } else { 
+    after_rl_add(o,0);
+    after_rl_add(o,b);
+  }
+  
+}
+
+static void after_rl_flush(Output_Encoder *o)
+{
+  
+  if(o->mode & OE_FLATE) {
+    flate_flush(o);
+  } else {
+    after_flate_flush(o);
+  }
+  
+}
+
+static void rl_flush(Output_Encoder *o)
+{
+  int lgt;
+  int *buffer;
+  int i;
+  
+  buffer = o->rl_buffer;
+  lgt = o->rl_bufused;
+  if(lgt > 0) {
+    if(o->rl_state == 2) {
+      i = o->rl_lastbyte;
+      after_rl_add(o,RL_RUNLENGTH(lgt));
+      after_rl_add(o,i);
+    } else {
+      after_rl_add(o,RL_STRINGLENGTH(lgt));
+      for(i = 0; i < lgt; i++) {
+    after_rl_add(o,buffer[i]);
+      }
+    }
+  }
+  after_rl_flush(o);
+  
+}
+
+static void internal_byte_add(Output_Encoder *o, int b)
+{
+  
+  if((o->mode) & OE_RL) {
+    rl_add(o,b);
+  } else {
+    after_rl_add(o,b);
+  }
+  
+}
+
+static void internal_byte_flush(Output_Encoder *o)
+{
+  
+  if((o->mode) & OE_RL) {
+    rl_flush(o);
+  } else {
+    after_rl_flush(o);
+  }
+  
+}
+
+void oe_bit_add(Output_Encoder *o, int b)
+{
+  
+  o->bit_value = 2 * o->bit_value + (b ? 1 : 0);
+  o->bit_consumed = o->bit_consumed + 1;
+  if(o->bit_consumed >= 8) {
+    o->bit_consumed = 0;
+    internal_byte_add(o, (o->bit_value));
+    o->bit_value = 0;
+  }
+  
+}
+
+void oe_bit_flush(Output_Encoder *o)
+{
+  
+  if(o->bit_consumed) {
+    int v, i;
+    v = o->bit_value;
+    i = o->bit_consumed;
+    while(i < 8) {
+      i++;
+      v = v * 2;
+    }
+    internal_byte_add(o,v);
+    o->bit_value = 0;
+    o->bit_consumed = 0;
+  }
+  internal_byte_flush(o);
+  
+}
+
+void oe_byte_add(Output_Encoder *o, int b)
+{
+  
+  if(o->bit_consumed) {
+    int testval,i;
+    testval = 128;
+    for(i = 0; i < 8; i++) {
+      if(b & testval) {
+    oe_bit_add(o,1);
+      } else {
+    oe_bit_add(o,0);
+      }
+      testval = testval / 2;
+    }
+  } else {
+    internal_byte_add(o,b);
+  }
+  
+}
+
+void oe_byte_flush(Output_Encoder *o)
+{
+  
+  oe_bit_flush(o);
+  
+}