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

📄 configured_jbig.c

📁 基于ADI BLACKFIN的jbig压缩和解压缩程序
💻 C
📖 第 1 页 / 共 3 页
字号:
  if (s->x == 0 && s->i == 0 && s->pseudo)    fprintf(stderr, "decode_pscd(%p, %p, %ld): s/d/p = %2lu/%2u/%2u\n",	    (void *) s, (void *) data, (long) len, stripe, layer, plane);#endif    /*     *  Decode lowest resolution layer     */    for (; s->i < hl && y < hy; s->i++, y++) {      /* adaptive template changes */      if (x == 0)	for (n = 0; n < s->at_moves; n++)	  if (s->at_line[n] == s->i) {	    s->tx = s->at_tx[n];	    s->ty = s->at_ty[n];#ifdef DEBUG	    fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,		    s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);#endif	  }      tx = s->tx;      assert(tx >= 0); /* i.e., tx can safely be cast to unsigned */      /* typical prediction */      if (s->options & JBG_TPBON && s->pseudo) {	slntp = arith_decode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX);	if (se->result == JBG_MORE || se->result == JBG_MARKER)	  goto leave;	s->lntp =	  !(slntp ^ s->lntp);	if (s->lntp) {	  /* this line is 'not typical' and has to be coded completely */	  s->pseudo = 0;	} else {	  /* this line is 'typical' (i.e. identical to the previous one) */	  p1 = hp;	  if (s->i == 0 && (stripe == 0 || s->reset))	    while (p1 < hp + hbpl) *p1++ = 0;	  else {	    q1 = hp - hbpl;	    while (q1 < hp) *p1++ = *q1++;	  }	  hp += hbpl;	  continue;	}      }            /*       * Layout of the variables line_h1, line_h2, line_h3, which contain       * as bits the neighbour pixels of the currently decoded pixel X:       *       *                     76543210 76543210 76543210 76543210     line_h3       *                     76543210 76543210 76543210 76543210     line_h2       *   76543210 76543210 76543210 76543210 X                     line_h1       */            if (x == 0) {	line_h1 = line_h2 = line_h3 = 0;	if (s->i > 0 || (y > 0 && !s->reset))	  line_h2 = (long)*(hp - hbpl) << 8;	if (s->i > 1 || (y > 1 && !s->reset))	  line_h3 = (long)*(hp - hbpl - hbpl) << 8;      }            /*       * Another tiny JBIG standard bug:       *       * While implementing the line_h3 handling here, I discovered       * another problem with the ITU-T T.82(1993 E) specification.       * This might be a somewhat pathological case, however. The       * standard is unclear about how a decoder should behave in the       * following situation:       *       * Assume we are in layer 0 and all stripes are single lines       * (L0=1 allowed by table 9). We are now decoding the first (and       * only) line of the third stripe. Assume, the first stripe was       * terminated by SDRST and the second stripe was terminated by       * SDNORM. While decoding the only line of the third stripe with       * the three-line template, we need access to pixels from the       * previous two stripes. We know that the previous stripe       * terminated with SDNROM, so we access the pixel from the       * second stripe. But do we have to replace the pixels from the       * first stripe by background pixels, because this stripe ended       * with SDRST? The standard, especially clause 6.2.5 does never       * mention this case, so the behaviour is undefined here. My       * current implementation remembers only the marker used to       * terminate the previous stripe. In the above example, the       * pixels of the first stripe are accessed despite the fact that       * this stripe ended with SDRST. An alternative (only slightly       * more complicated) implementation would be to remember the end       * marker (SDNORM or SDRST) of the previous two stripes in a       * plane/layer and to act accordingly when accessing the two       * previous lines. What am I supposed to do here?       *       * As the standard is unclear about the correct behaviour in the       * situation of the above example, I strongly suggest to avoid       * the following situation while encoding data with JBIG:       *       *   LRLTWO = 0, L0=1 and both SDNORM and SDRST appear in layer 0.       *       * I guess that only a very few if any encoders will switch       * between SDNORM and SDRST, so let us hope that this ambiguity       * in the standard will never cause any interoperability       * problems.       *       * Markus Kuhn -- 1995-04-30       */      /* decode line */      while (x < hx) {	if ((x & 7) == 0) {	  if (x < hbpl * 8 - 8 &&	      (s->i > 0 || (y > 0 && !s->reset))) {	    line_h2 |= *(hp - hbpl + 1);	    if (s->i > 1 || (y > 1 && !s->reset))	      line_h3 |= *(hp - hbpl - hbpl + 1);	  }	}	  /* three line template */	  do {	    if (tx) {	      if ((unsigned) tx > x)		a = 0;	      else if (tx < 8)		a = ((line_h1 >> (tx - 3)) & 0x004);	      else {		o = (x - tx) - (x & ~7L);		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;		a <<= 2;	      }	      assert(tx > 31 ||		     a == ((line_h1 >> (tx - 3)) & 0x004));	      pix = arith_decode(se, (((line_h3 >>  7) & 0x380) |				      ((line_h2 >> 11) & 0x078) | a |				      (line_h1 & 0x003)));	    } else	      pix = arith_decode(se, (((line_h3 >>  7) & 0x380) |				      ((line_h2 >> 11) & 0x07c) |				      (line_h1 & 0x003)));	    if (se->result == JBG_MORE || se->result == JBG_MARKER)	      goto leave;	    	    line_h1 = (line_h1 << 1) | pix;	    line_h2 <<= 1;	    line_h3 <<= 1;	  } while ((++x & 7) && x < hx);	 /* if (s->options & JBG_LRLTWO) */	*hp++ = (unsigned char)line_h1;      } /* while */      *(hp - 1) <<= hbpl * 8 - hx;      x = 0;      s->pseudo = 1;    } /* for (i = ...) */ leave:  /* save a few local variables */  s->line_h1 = line_h1;  s->line_h2 = line_h2;  s->line_h3 = line_h3;  s->x = x;  return se->pscd_ptr - data;}/* * Provide a new BIE fragment to the decoder. * * If cnt is not NULL, then *cnt will contain after the call the * number of actually read bytes. If the data was not complete, then * the return value will be JBG_EAGAIN and *cnt == len. In case this * function has returned with JBG_EOK, then it has reached the end of * a BIE but it can be called again with data from the next BIE if * there exists one in order to get to a higher resolution layer. In * case the return value was JBG_EOK_INTR then this function can be * called again with the rest of the BIE, because parsing the BIE has * been interrupted by a jbg_dec_maxsize() specification. In both * cases the remaining len - *cnt bytes of the previous block will * have to passed to this function again (if len > *cnt). In case of * any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN, a * serious problem has occured and the only function you should call * is jbg_dec_free() in order to remove the mess (and probably * jbg_strerror() in order to find out what to tell the user). */int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,	       size_t *cnt){  int  j, required_length;  unsigned long x, y;  size_t dummy_cnt;  if (!cnt) cnt = &dummy_cnt;  *cnt = 0;  if (len < 1) return JBG_EAGAIN;  /* read in 20-byte BIH */  if (s->bie_len < 20) {    while (s->bie_len < 20 && *cnt < len)      s->buffer[s->bie_len++] = data[(*cnt)++];    if (s->bie_len < 20)       return JBG_EAGAIN;    if (s->buffer[1] < s->buffer[0])      return JBG_EINVAL;    /* test whether this looks like a valid JBIG header at all */    if (s->buffer[3] != 0 || (s->buffer[18] & 0xf0) != 0 ||	(s->buffer[19] & 0x80) != 0)      return JBG_EINVAL;    if (s->buffer[0] != s->d + 1)      return JBG_ENOCONT;    s->dl = s->buffer[0];    s->d = s->buffer[1];    if (s->dl == 0)      s->planes = s->buffer[2];    else      if (s->planes != s->buffer[2])	return JBG_ENOCONT;    x = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) |	 ((long) s->buffer[ 6] <<  8) | (long) s->buffer[ 7]);    y = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) |	 ((long) s->buffer[10] <<  8) | (long) s->buffer[11]);    if (s->dl != 0 && ((s->xd << (s->d - s->dl + 1)) != x &&		       (s->yd << (s->d - s->dl + 1)) != y))      return JBG_ENOCONT;    s->xd = x;    s->yd = y;    s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) |	     ((long) s->buffer[14] <<  8) | (long) s->buffer[15]);    /* ITU-T T.85 trick not directly supported by decoder; for full     * T.85 compatibility with respect to all NEWLEN marker scenarios,     * preprocess BIE with jbg_newlen() before passing it to the decoder. */    if (s->yd == 0xffffffff)      return JBG_EIMPL;    if (!s->planes || !s->xd || !s->yd || !s->l0)      return JBG_EINVAL;    /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */    if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d))))      return JBG_EIMPL;    s->mx = s->buffer[16];    if (s->mx > 127)      return JBG_EINVAL;    s->my = s->buffer[17];    s->order = s->buffer[18];      s->options = s->buffer[19];    /* calculate number of stripes that will be required */    s->stripes = jbg_stripes(s->l0, s->yd);        /* some initialization */    s->ii = 0;	s->s = (struct jbg_ardec_state *)checked_malloc(1, sizeof(struct jbg_ardec_state));	s->lhp[0] = (unsigned char *)checked_malloc(s->yd, jbg_ceil_half(s->xd, 3));    	arith_decode_init(s->s, 0);    s->comment_skip = 0;    s->buf_len = 0;    s->x = 0;    s->i = 0;    s->pseudo = 1;    s->at_moves = 0;  }  /*   * BID processing loop   */    while (*cnt < len) {    /* process floating marker segments */    /* skip COMMENT contents */    if (s->comment_skip) {      if (s->comment_skip <= len - *cnt) {	*cnt += s->comment_skip;	s->comment_skip = 0;      } else {	s->comment_skip -= len - *cnt;	*cnt = len;      }      continue;    }    /* load complete marker segments into s->buffer for processing */    if (s->buf_len > 0) {      assert(s->buffer[0] == MARKER_ESC);      while (s->buf_len < 2 && *cnt < len)	s->buffer[s->buf_len++] = data[(*cnt)++];      if (s->buf_len < 2) continue;      switch (s->buffer[1]) {      case MARKER_COMMENT: required_length = 6; break;      case MARKER_ATMOVE:  required_length = 8; break;      case MARKER_NEWLEN:  required_length = 6; break;      case MARKER_ABORT:      case MARKER_SDNORM:      case MARKER_SDRST:   required_length = 2; break;      case MARKER_STUFF:	/* forward stuffed 0xff to arithmetic decoder */	s->buf_len = 0;	decode_pscd(s, s->buffer, 2);	continue;      default:	return JBG_EMARKER;      }      while (s->buf_len < required_length && *cnt < len)	s->buffer[s->buf_len++] = data[(*cnt)++];      if (s->buf_len < required_length) continue;      /* now the buffer is filled with exactly one marker segment */      switch (s->buffer[1])       {      case MARKER_ATMOVE:	if (s->at_moves < JBG_ATMOVES_MAX) {	  s->at_line[s->at_moves] =	    (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |	     ((long) s->buffer[4] <<  8) | (long) s->buffer[5]);	  s->at_tx[s->at_moves] = (signed char) s->buffer[6];	  s->at_ty[s->at_moves] = s->buffer[7];	  if (s->at_tx[s->at_moves] < - (int) s->mx ||	      s->at_tx[s->at_moves] >   (int) s->mx ||	      s->at_ty[s->at_moves] >   (int) s->my ||	      (s->at_ty[s->at_moves] == 0 && s->at_tx[s->at_moves] < 0))	    return JBG_EINVAL;	  if (s->at_ty[s->at_moves] != 0)	    return JBG_EIMPL;	  s->at_moves++;	} else	  return JBG_EIMPL;	break;      case MARKER_ABORT:		return JBG_EABORT;	      case MARKER_SDNORM:      case MARKER_SDRST:	/* decode final pixels based on trailing zero bytes */	decode_pscd(s, s->buffer, 2);	arith_decode_init(s->s, s->ii != s->stripes - 1 && s->buffer[1] != MARKER_SDRST);		s->reset = (s->buffer[1] == MARKER_SDRST);		/* prepare for next SDE */	s->x = 0;	s->i = 0;	s->pseudo = 1;	s->at_moves = 0;		/* increment layer/stripe/plane loop variables */	/* start and end value for each loop: */	if (++s->ii >= s->stripes)		j = 1;	else		j = 0;	    	s->buf_len = 0;		/* check whether this have been all SDEs */	if (j) {#ifdef DEBUG	  fprintf(stderr, "This was the final SDE in this BIE, "		  "%d bytes left.\n", len - *cnt);#endif	  s->bie_len = 0;	  return JBG_EOK;	}	break;	  }      s->buf_len = 0;    } else if (data[*cnt] == MARKER_ESC)      s->buffer[s->buf_len++] = data[(*cnt)++];    else {      /* we have found PSCD bytes */      *cnt += decode_pscd(s, data + *cnt, len - *cnt);      if (*cnt < len && data[*cnt] != 0xff) {#ifdef DEBUG	fprintf(stderr, "PSCD was longer than expected, unread bytes "		"%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1],		data[*cnt+2], data[*cnt+3]);#endif	return JBG_EINVAL;      }          }  }  /* of BID processing loop 'while (*cnt < len) ...' */  return JBG_EAGAIN;}/* * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this * function in order to find out the width of the image. */long jbg_dec_getwidth(const struct jbg_dec_state *s){  if (s->d < 0)    return -1;  if (s->ii < 1)      return -1;  else      return jbg_ceil_half(s->xd, s->d - (s->ii - 1));}/* * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this * function in order to find out the height of the image. */long jbg_dec_getheight(const struct jbg_dec_state *s){  if (s->d < 0)    return -1;  if (s->ii < 1)     return -1;  else     return jbg_ceil_half(s->yd, s->d - (s->ii - 1));}/* * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this * function in order to get a pointer to the image. */unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s){  if (s->d < 0)    return NULL;  if (s->ii < 1)    return NULL;  else    return s->lhp[0];}/* * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call * this function in order to find out the size in bytes of one * bitplane of the image. */long jbg_dec_getsize(const struct jbg_dec_state *s){  if (s->d < 0)    return -1;  if (s->ii < 1)      return -1;  else      return 	jbg_ceil_half(s->xd, s->d - (s->ii - 1) + 3) *	jbg_ceil_half(s->yd, s->d - (s->ii - 1));}/*  * The destructor function which releases any resources obtained by the * other decoder functions. */void jbg_dec_free(struct jbg_dec_state *s){  if (s->d < 0 || s->s == NULL)    return;  s->d = -2;    checked_free(s->lhp[0]);    checked_free(s->s);  s->s = NULL;  return;}/* * Given a pointer p to the first byte of either a marker segment or a * PSCD, as well as the length len of the remaining data, return * either the pointer to the first byte of the next marker segment or * PSCD, or p+len if this was the last one, or NULL if some error was * encountered. */unsigned char *jbg_next_pscdms(unsigned char *p, size_t len){  unsigned char *pp;  unsigned long l;  if (len < 2)    return NULL;  if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) {    do {      while (p[0] == MARKER_ESC && p[1] == MARKER_STUFF) {	p += 2;	len -= 2;	if (len < 2) return NULL;      }      pp = (unsigned char *) memchr(p, MARKER_ESC, len - 1);      if (!pp) return NULL;      l = pp - p;      assert(l < len);      p += l;      len -= l;    } while (p[1] == MARKER_STUFF);  } else {    switch (p[1]) {    case MARKER_SDNORM:    case MARKER_SDRST:    case MARKER_ABORT:      return p + 2;    case MARKER_NEWLEN:      if (len < 6) return NULL;      return p + 6;    case MARKER_ATMOVE:      if (len < 8) return NULL;      return p + 8;    case MARKER_COMMENT:      if (len < 6) return NULL;      l = (((long) p[2] << 24) | ((long) p[3] << 16) |	   ((long) p[4] <<  8) |  (long) p[5]);      if (len - 6 < l) return NULL;      return p + 6 + l;    default:      return NULL;    }  }  return p;}

⌨️ 快捷键说明

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