📄 configured_jbig.c
字号:
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 + -