⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jbig.c

📁 linux下将各类格式图片转换工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  Portable Free JBIG image compression library * *  Markus Kuhn -- mkuhn@acm.org * *  $Id: jbig.c,v 1.12 2000-04-08 11:42:18+01 mgk25 Rel $ * *  This module implements a portable standard C encoder and decoder *  using the JBIG lossless bi-level image compression algorithm as *  specified in International Standard ISO 11544:1993 or equivalently *  as specified in ITU-T Recommendation T.82. See the file jbig.doc *  for usage instructions and application examples. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program 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 General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *  *  If you want to use this program under different license conditions, *  then contact the author for an arrangement. * *  It is possible that certain products which can be built using this *  software module might form inventions protected by patent rights in *  some countries (e.g., by patents about arithmetic coding algorithms *  owned by IBM and AT&T in the USA). Provision of this software by the *  author does NOT include any licences for any patents. In those *  countries where a patent licence is required for certain applications *  of this software module, you will have to obtain such a licence *  yourself. */#ifdef DEBUG#include <stdio.h>#endif#include <stdlib.h>#include <assert.h>#include "jbig.h"/* optional export of arithmetic coder functions for test purposes */#ifdef TEST_CODEC#define ARITH#define ARITH_INL#else#define ARITH      static#ifdef __GNUC__#define ARITH_INL  static __inline__#else#define ARITH_INL  static#endif#endif#define MX_MAX  23     /* maximal supported mx offset for			* adaptive template in the encoder */#define TPB2CX  0x195  /* contexts for TP special pixels */#define TPB3CX  0x0e5#define TPDCX   0xc3f/* marker codes */#define MARKER_STUFF    0x00#define MARKER_RESERVE  0x01#define MARKER_SDNORM   0x02#define MARKER_SDRST    0x03#define MARKER_ABORT    0x04#define MARKER_NEWLEN   0x05#define MARKER_ATMOVE   0x06#define MARKER_COMMENT  0x07#define MARKER_ESC      0xff/* loop array indices */#define STRIPE  0#define LAYER   1#define PLANE   2/* special jbg_buf pointers (instead of NULL) */#define SDE_DONE ((struct jbg_buf *) -1)#define SDE_TODO ((struct jbg_buf *) 0)/* object code version id */const char jbg_version[] = " JBIG-KIT " JBG_VERSION " -- Markus Kuhn -- ""$Id: jbig.c,v 1.12 2000-04-08 11:42:18+01 mgk25 Rel $ ";/* * the following array specifies for each combination of the 3 * ordering bits, which ii[] variable represents which dimension * of s->sde. */static const int index[8][3] = {  { 2, 1, 0 },    /* no ordering bit set */  { -1, -1, -1},  /* SMID -> illegal combination */  { 2, 0, 1 },    /* ILEAVE */  { 1, 0, 2 },    /* SMID + ILEAVE */  { 0, 2, 1 },    /* SEQ */  { 1, 2, 0 },    /* SEQ + SMID */  { 0, 1, 2 },    /* SEQ + ILEAVE */  { -1, -1, -1 }  /* SEQ + SMID + ILEAVE -> illegal combination */};/* * Array [language][message] with text string error messages that correspond * to return values from public functions in this library. */#define NEMSG         9  /* number of error codes */#define NEMSG_LANG    3  /* number of supported languages */static const char *errmsg[NEMSG_LANG][NEMSG] = {  /* English (JBG_EN) */  {    "Everything is ok",                                     /* JBG_EOK */    "Reached specified maximum size",                       /* JBG_EOK_INTR */    "Unexpected end of data",                               /* JBG_EAGAIN */    "Not enough memory available",                          /* JBG_ENOMEM */    "ABORT marker found",                                   /* JBG_EABORT */    "Unknown marker segment encountered",                   /* JBG_EMARKER */    "Incremental BIE does not fit to previous one",         /* JBG_ENOCONT */    "Invalid data encountered",                             /* JBG_EINVAL */    "Unimplemented features used"                           /* JBG_EIMPL */  },  /* German (JBG_DE_8859_1) */  {    "Kein Problem aufgetreten",                             /* JBG_EOK */    "Angegebene maximale Bildgr\366\337e erreicht",         /* JBG_EOK_INTR */    "Unerwartetes Ende der Daten",                          /* JBG_EAGAIN */    "Nicht gen\374gend Speicher vorhanden",                 /* JBG_ENOMEM */    "Es wurde eine Abbruch-Sequenz gefunden",               /* JBG_EABORT */    "Eine unbekannte Markierungssequenz wurde gefunden",    /* JBG_EMARKER */    "Neue Daten passen nicht zu vorangegangenen Daten",     /* JBG_ENOCONT */    "Es wurden ung\374ltige Daten gefunden",                /* JBG_EINVAL */    "Noch nicht implementierte Optionen wurden benutzt"     /* JBG_EIMPL */  },  /* German (JBG_DE_UTF_8) */  {    "Kein Problem aufgetreten",                             /* JBG_EOK */    "Angegebene maximale Bildgr\303\266\303\237e erreicht", /* JBG_EOK_INTR */    "Unerwartetes Ende der Daten",                          /* JBG_EAGAIN */    "Nicht gen\303\274gend Speicher vorhanden",             /* JBG_ENOMEM */    "Es wurde eine Abbruch-Sequenz gefunden",               /* JBG_EABORT */    "Eine unbekannte Markierungssequenz wurde gefunden",    /* JBG_EMARKER */    "Neue Daten passen nicht zu vorangegangenen Daten",     /* JBG_ENOCONT */    "Es wurden ung\303\274ltige Daten gefunden",            /* JBG_EINVAL */    "Noch nicht implementierte Optionen wurden benutzt"     /* JBG_EIMPL */  }};/* * The following three functions are the only places in this code, were * C library memory management functions are called. The whole JBIG * library has been designed in order to allow multi-threaded * execution. no static or global variables are used, so all fuctions * are fully reentrant. However if you want to use this multi-thread * capability and your malloc, realloc and free are not reentrant, * then simply add the necessary semaphores or mutex primitives below. */static void *checked_malloc(size_t size){  void *p;    p = malloc(size);  /* Full manual exception handling is ugly here for performance   * reasons. If an adequate handling of lack of memory is required,   * then use C++ and throw a C++ exception here. */  if (!p)    abort();#if 0  fprintf(stderr, "%p = malloc(%ld)\n", p, (long) size);#endif  return p;}static void *checked_realloc(void *ptr, size_t size){  void *p;  p = realloc(ptr, size);  /* Full manual exception handling is ugly here for performance   * reasons. If an adequate handling of lack of memory is required,   * then use C++ and throw a C++ exception here. */  if (!p)    abort();#if 0  fprintf(stderr, "%p = realloc(%p, %ld)\n", p, ptr, (long) size);#endif  return p;}static void checked_free(void *ptr){  free(ptr);#if 0  fprintf(stderr, "free(%p)\n", ptr);#endif}/* * The next functions implement the arithmedic encoder and decoder * required for JBIG. The same algorithm is also used in the arithmetic * variant of JPEG. */#ifdef DEBUGstatic long encoded_pixels = 0;#endifARITH void arith_encode_init(struct jbg_arenc_state *s, int reuse_st){  int i;    if (!reuse_st)    for (i = 0; i < 4096; s->st[i++] = 0);  s->c = 0;  s->a = 0x10000L;  s->sc = 0;  s->ct = 11;  s->buffer = -1;    /* empty */    return;}ARITH void arith_encode_flush(struct jbg_arenc_state *s){  unsigned long temp;#ifdef DEBUG  fprintf(stderr, "  encoded pixels = %ld, a = %05lx, c = %08lx\n",	  encoded_pixels, s->a, s->c);#endif  /* find the s->c in the coding interval with the largest   * number of trailing zero bits */  if ((temp = (s->a - 1 + s->c) & 0xffff0000L) < s->c)    s->c = temp + 0x8000;  else    s->c = temp;  /* send remaining bytes to output */  s->c <<= s->ct;  if (s->c & 0xf8000000L) {    /* one final overflow has to be handled */    if (s->buffer >= 0) {      s->byte_out(s->buffer + 1, s->file);      if (s->buffer + 1 == MARKER_ESC)	s->byte_out(MARKER_STUFF, s->file);    }    /* output 0x00 bytes only when more non-0x00 will follow */    if (s->c & 0x7fff800L)      for (; s->sc; --s->sc)	s->byte_out(0x00, s->file);  } else {    if (s->buffer >= 0)      s->byte_out(s->buffer, s->file);     /* T.82 figure 30 says buffer+1 for the above line! Typo? */    for (; s->sc; --s->sc) {      s->byte_out(0xff, s->file);      s->byte_out(MARKER_STUFF, s->file);    }  }  /* output final bytes only if they are not 0x00 */  if (s->c & 0x7fff800L) {    s->byte_out((s->c >> 19) & 0xff, s->file);    if (((s->c >> 19) & 0xff) == MARKER_ESC)      s->byte_out(MARKER_STUFF, s->file);    if (s->c & 0x7f800L) {      s->byte_out((s->c >> 11) & 0xff, s->file);      if (((s->c >> 11) & 0xff) == MARKER_ESC)	s->byte_out(MARKER_STUFF, s->file);    }  }  return;}ARITH_INL void arith_encode(struct jbg_arenc_state *s, int cx, int pix) {  extern short jbg_lsz[];  extern unsigned char jbg_nmps[], jbg_nlps[];  register unsigned lsz, ss;  register unsigned char *st;  long temp;#ifdef DEBUG  ++encoded_pixels;#endif  assert(cx >= 0 && cx < 4096);  st = s->st + cx;  ss = *st & 0x7f;  assert(ss < 113);  lsz = jbg_lsz[ss];#if 0  fprintf(stderr, "pix = %d, cx = %d, mps = %d, st = %3d, lsz = 0x%04x, "	  "a = 0x%05lx, c = 0x%08lx, ct = %2d, buf = 0x%02x\n",	  pix, cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct,	  s->buffer);#endif  if (((pix << 7) ^ s->st[cx]) & 0x80) {    /* encode the less probable symbol */    if ((s->a -= lsz) >= lsz) {      /* If the interval size (lsz) for the less probable symbol (LPS)       * is larger than the interval size for the MPS, then exchange       * the two symbols for coding efficiency, otherwise code the LPS       * as usual: */      s->c += s->a;      s->a = lsz;    }    /* Check whether MPS/LPS exchange is necessary     * and chose next probability estimator status */    *st &= 0x80;    *st ^= jbg_nlps[ss];  } else {    /* encode the more probable symbol */    if ((s->a -= lsz) & 0xffff8000L)      return;   /* A >= 0x8000 -> ready, no renormalization required */    if (s->a < lsz) {      /* If the interval size (lsz) for the less probable symbol (LPS)       * is larger than the interval size for the MPS, then exchange       * the two symbols for coding efficiency: */      s->c += s->a;      s->a = lsz;    }    /* chose next probability estimator status */    *st &= 0x80;    *st |= jbg_nmps[ss];  }  /* renormalization of coding interval */  do {    s->a <<= 1;    s->c <<= 1;    --s->ct;    if (s->ct == 0) {      /* another byte is ready for output */      temp = s->c >> 19;      if (temp & 0xffffff00L) {	/* handle overflow over all buffered 0xff bytes */	if (s->buffer >= 0) {	  ++s->buffer;	  s->byte_out(s->buffer, s->file);	  if (s->buffer == MARKER_ESC)	    s->byte_out(MARKER_STUFF, s->file);	}	for (; s->sc; --s->sc)	  s->byte_out(0x00, s->file);	s->buffer = temp & 0xff;  /* new output byte, might overflow later */	assert(s->buffer != 0xff);	/* can s->buffer really never become 0xff here? */      } else if (temp == 0xff) {	/* buffer 0xff byte (which might overflow later) */	++s->sc;      } else {	/* output all buffered 0xff bytes, they will not overflow any more */	if (s->buffer >= 0)	  s->byte_out(s->buffer, s->file);	for (; s->sc; --s->sc) {	  s->byte_out(0xff, s->file);	  s->byte_out(MARKER_STUFF, s->file);	}	s->buffer = temp;   /* buffer new output byte (can still overflow) */      }      s->c &= 0x7ffffL;      s->ct = 8;    }  } while (s->a < 0x8000);   return;}ARITH void arith_decode_init(struct jbg_ardec_state *s, int reuse_st){  int i;    if (!reuse_st)    for (i = 0; i < 4096; s->st[i++] = 0);  s->c = 0;  s->a = 1;  s->ct = 0;  s->result = JBG_OK;  s->startup = 1;  return;}ARITH_INL int arith_decode(struct jbg_ardec_state *s, int cx){  extern short jbg_lsz[];  extern unsigned char jbg_nmps[], jbg_nlps[];  register unsigned lsz, ss;  register unsigned char *st;  int pix;  /* renormalization */  while (s->a < 0x8000 || s->startup) {    if (s->ct < 1 && s->result != JBG_READY) {      /* first we have to move a new byte into s->c */      if (s->pscd_ptr >= s->pscd_end) {	s->result = JBG_MORE;	return -1;      }      if (*s->pscd_ptr == 0xff) 	if (s->pscd_ptr + 1 >= s->pscd_end) {	  s->result = JBG_MARKER;	  return -1;	} else {	  if (*(s->pscd_ptr + 1) == MARKER_STUFF) {	    s->c |= 0xffL << (8 - s->ct);	    s->ct += 8;	    s->pscd_ptr += 2;	    s->result = JBG_OK;	  } else	    s->result = JBG_READY;	}      else {	s->c |= (long)*(s->pscd_ptr++) << (8 - s->ct);

⌨️ 快捷键说明

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