bmepsoe.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 433 行

C
433
字号
/*
 * libbmeps - Bitmap to EPS conversion library
 * 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.
 */

/*      Usage short:
        ============
        oetest [ -{ar}+ ]

        -a      ASCII85
        -r      Run length
        -ar     algorithms combined
*/

#include "bmepsco.h"
#include "bmeps.h"
#include "pngeps.h"
#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)
{

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

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 *o)
{
  int i;
  char buffer[6], c, *ptr;
  unsigned long value;
  value = o->a85_value;
  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;
  ptr = buffer;
  o->textpos = o->textpos + i;
  while(i--) {
    c = *(ptr++);
    FINALOUTPUT(c) ;
  }
  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 after_flate_flush(Output_Encoder *o)
{
    if(o->mode & OE_ASC85) {
        ascii85_flush(o);
    } else {
        asciihex_flush(o);
    }
}

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_flate_add(o, RL_RUNLENGTH(lgt));
              after_flate_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_flate_add(o, RL_STRINGLENGTH(lgt));
              for(i = 0; i < lgt; i++) {
                after_flate_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_flate_add(o, RL_STRINGLENGTH(lgt));
              for(i = 0; i < lgt; i++) {
                after_flate_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_flate_add(o, RL_RUNLENGTH(lgt));
          after_flate_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_flate_add(o, RL_STRINGLENGTH(lgt));
            for(i = 0; i < lgt; i++) {
              after_flate_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_flate_add(o,0);
    after_flate_add(o,b);
  }

}

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_flate_add(o,RL_RUNLENGTH(lgt));
      after_flate_add(o,i);
    } else {
      after_flate_add(o,RL_STRINGLENGTH(lgt));
      for(i = 0; i < lgt; i++) {
        after_flate_add(o,buffer[i]);
      }
    }
  }
  after_flate_flush(o);
}

static void internal_byte_add(Output_Encoder *o, int b)
{

  if((o->mode) & OE_RL) {
    rl_add(o,b);
  } else {
    after_flate_add(o,b);
  }

}

static void internal_byte_flush(Output_Encoder *o)
{

  if((o->mode) & OE_RL) {
    rl_flush(o);
  } else {
    after_flate_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);
}


#ifdef OE_TEST_MAIN

int main(int argc, char *argv[])
{
  Output_Encoder o;
  int methods; int number;
  int rlbuffer[129];
  char buffer[512];

  methods = 0;
  if(argc > 1) {
    char *ptr;
    ptr = argv[1];
    while(*ptr) {
      switch(*ptr) {
        case 'a' : {
          methods |= OE_ASC85;
        } break;
        case 'r' : {
          methods |= OE_RL;
        } break;
      }
      ptr++;
    }
  }
  oe_init(&o, stdout, methods, 9, rlbuffer);
  methods = 1;
  while(methods) {
    number = read(0, buffer, sizeof(buffer));
    if(number > 0) {
      char c, *ptr;
      int  i;
      ptr = buffer;
      for(i = 0; i < number; i++) {
        c = *ptr;
        oe_byte_add(&o, c);
        ptr++;
      }
    } else { methods = 0; }
  }
  oe_byte_flush(&o);
  return 0;
}
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?