📄 jbig.c
字号:
output_sde(s, stripe, layer, plane); } return;}void jbg_enc_free(struct jbg_enc_state *s){ unsigned long stripe; int layer, plane;#ifdef DEBUG fprintf(stderr, "jbg_enc_free(%p)\n", s);#endif /* clear buffers for SDEs */ if (s->sde) { for (stripe = 0; stripe < s->stripes; stripe++) { for (layer = 0; layer < s->d + 1; layer++) { for (plane = 0; plane < s->planes; plane++) if (s->sde[stripe][layer][plane] != SDE_DONE && s->sde[stripe][layer][plane] != SDE_TODO) jbg_buf_free(&s->sde[stripe][layer][plane]); checked_free(s->sde[stripe][layer]); } checked_free(s->sde[stripe]); } checked_free(s->sde); } /* clear free_list */ jbg_buf_free(&s->free_list); /* clear memory for arithmetic encoder states */ checked_free(s->s); /* clear memory for differential-layer typical prediction buffer */ checked_free(s->tp); /* clear memory for adaptive template pixel offsets */ checked_free(s->tx); /* clear lowres image buffers */ if (s->lhp[1]) { for (plane = 0; plane < s->planes; plane++) checked_free(s->lhp[1][plane]); checked_free(s->lhp[1]); } return;}/* * Convert the error codes used by jbg_dec_in() into a string * written in the selected language and character set. */const char *jbg_strerror(int errnum, int language){ if (errnum < 0 || errnum >= NEMSG) return "Unknown error code passed to jbg_strerror()"; if (language < 0 || language >= NEMSG_LANG) return "Unknown language code passed to jbg_strerror()"; return errmsg[language][errnum];}/* * The constructor for a decoder */void jbg_dec_init(struct jbg_dec_state *s){ s->order = 0; s->d = -1; s->bie_len = 0; s->buf_len = 0; s->dppriv = NULL; s->xmax = 4294967295UL; s->ymax = 4294967295UL; s->dmax = 256; s->s = NULL; return;}/* * Specify a maximum image size for the decoder. If the JBIG file has * the order bit ILEAVE, but not the bit SEQ set, then the decoder * will abort to decode after the image has reached the maximal * resolution layer which is still not wider than xmax or higher than * ymax. */void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax, unsigned long ymax){ if (xmax > 0) s->xmax = xmax; if (ymax > 0) s->ymax = ymax; return;}/* * Decode the new len PSDC bytes to which data points and add them to * the current stripe. Return the number of bytes which have actually * been read (this will be less than len if a marker segment was * part of the data or if the final byte was 0xff were this code * can not determine, whether we have a marker segment. */static size_t decode_pscd(struct jbg_dec_state *s, unsigned char *data, size_t len){ unsigned long stripe; unsigned int layer, plane; unsigned long hl, ll, y, hx, hy, lx, ly, hbpl, lbpl; unsigned char *hp, *lp1, *lp2, *p1, *q1; register unsigned long line_h1, line_h2, line_h3; register unsigned long line_l1, line_l2, line_l3; struct jbg_ardec_state *se; unsigned long x; int n; int pix, cx = 0, slntp, shift, tx; /* SDE loop variables */ stripe = s->ii[index[s->order & 7][STRIPE]]; layer = s->ii[index[s->order & 7][LAYER]]; plane = s->ii[index[s->order & 7][PLANE]]; /* forward data to arithmetic decoder */ se = s->s[plane] + layer - s->dl; se->pscd_ptr = data; se->pscd_end = data + len; /* number of lines per stripe in highres image */ hl = s->l0 << layer; /* number of lines per stripe in lowres image */ ll = hl >> 1; /* current line number in highres image */ y = stripe * hl + s->i; /* number of pixels in highres image */ hx = jbg_ceil_half(s->xd, s->d - layer); hy = jbg_ceil_half(s->yd, s->d - layer); /* number of pixels in lowres image */ lx = jbg_ceil_half(hx, 1); ly = jbg_ceil_half(hy, 1); /* bytes per line in highres and lowres image */ hbpl = (hx + 7) / 8; lbpl = (lx + 7) / 8; /* pointer to highres and lowres image bytes */ hp = s->lhp[ layer & 1][plane] + (stripe * hl + s->i) * hbpl + (s->x >> 3); lp2 = s->lhp[(layer-1) & 1][plane] + (stripe * ll + (s->i >> 1)) * lbpl + (s->x >> 4); lp1 = lp2 + lbpl; /* restore a few local variables */ line_h1 = s->line_h1; line_h2 = s->line_h2; line_h3 = s->line_h3; line_l1 = s->line_l1; line_l2 = s->line_l2; line_l3 = s->line_l3; x = s->x; if (s->x == 0 && s->i == 0 && (stripe == 0 || s->reset[plane][layer - s->dl])) { s->tx[plane][layer - s->dl] = s->ty[plane][layer - s->dl] = 0; if (s->pseudo) s->lntp[plane][layer - s->dl] = 1; }#ifdef DEBUG if (s->x == 0 && s->i == 0 && s->pseudo) fprintf(stderr, "decode_pscd(%p, %p, %ld): s/d/p = %2lu/%2u/%2u\n", s, data, (long) len, stripe, layer, plane);#endif if (layer == 0) { /* * 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[plane][layer - s->dl] = s->at_tx[n]; s->ty[plane][layer - s->dl] = 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[plane][layer - s->dl]; shift = tx - ((s->options & JBG_LRLTWO) ? 5 : 3); /* 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[plane][layer - s->dl] = !(slntp ^ s->lntp[plane][layer - s->dl]); if (s->lntp[plane][layer - s->dl]) { /* 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[plane][layer - s->dl])) 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[plane][layer - s->dl])) line_h2 = (long)*(hp - hbpl) << 8; if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) 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[plane][layer - s->dl]))) { line_h2 |= *(hp - hbpl + 1); if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) line_h3 |= *(hp - hbpl - hbpl + 1); } } if (s->options & JBG_LRLTWO) { /* two line template */ do { if (tx) pix = arith_decode(se, (((line_h2 >> 9) & 0x3e0) | ((line_h1 >> shift) & 0x010) | (line_h1 & 0x00f))); else pix = arith_decode(se, (((line_h2 >> 9) & 0x3f0) | (line_h1 & 0x00f))); if (se->result == JBG_MORE || se->result == JBG_MARKER) goto leave; line_h1 = (line_h1 << 1) | pix; line_h2 <<= 1; } while ((++x & 7) && x < hx); } else { /* three line template */ do { if (tx) pix = arith_decode(se, (((line_h3 >> 7) & 0x380) | ((line_h2 >> 11) & 0x078) | ((line_h1 >> shift) & 0x004) | (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++ = line_h1; } /* while */ *(hp - 1) <<= hbpl * 8 - hx; x = 0; s->pseudo = 1; } /* for (i = ...) */ } else { /* * Decode differential 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[plane][layer - s->dl] = s->at_tx[n]; s->ty[plane][layer - s->dl] = 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[plane][layer - s->dl]; shift = tx - 3; /* handle lower border of low-resolution image */ if ((s->i >> 1) >= ll - 1 || (y >> 1) >= ly - 1) lp1 = lp2; /* typical prediction */ if (s->options & JBG_TPDON && s->pseudo) { s->lntp[plane][layer - s->dl] = arith_decode(se, TPDCX); if (se->result == JBG_MORE || se->result == JBG_MARKER) goto leave; s->pseudo = 0; } /* * Layout of the variables line_h1, line_h2, line_h3, which contain * as bits the high resolution neighbour pixels of the currently * decoded highres pixel X: * * 76543210 76543210 76543210 76543210 line_h3 * 76543210 76543210 76543210 76543210 line_h2 * 76543210 76543210 76543210 76543210 X line_h1 * * Layout of the variables line_l1, line_l2, line_l3, which contain * the low resolution pixels near the currently decoded pixel as bits. * The lowres pixel in which the currently coded highres pixel is * located is marked as Y: * * 76543210 76543210 76543210 76543210 line_l3 * 76543210 76543210 Y6543210 76543210 line_l2 * 76543210 76543210 76543210 76543210 line_l1 */ if (x == 0) { line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0; if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) { line_h2 = (long)*(hp - hbpl) << 8; if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) line_h3 = (long)*(hp - hbpl - hbpl) << 8; } if (s->i > 1 || (y > 1 && !s->reset[plane][layer-s->dl])) line_l3 = (long)*(lp2 - lbpl) << 8; line_l2 = (long)*lp2 << 8; line_l1 = (long)*lp1 << 8; } /* decode line */ while (x < hx) { if ((x & 15) == 0) if ((x >> 1) < lbpl * 8 - 8) { line_l1 |= *(lp1 + 1); line_l2 |= *(lp2 + 1); if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) line_l3 |= *(lp2 - lbpl + 1); } do { assert(hp - (s->lhp[ layer &1][plane] + (stripe * hl + s->i) * hbpl) == (ptrdiff_t) x >> 3); assert(lp2 - (s->lhp[(layer-1) &1][plane] + (stripe * ll + (s->i>>1)) * lbpl) == (ptrdiff_t) x >> 4); if ((x & 7) == 0) if (x < hbpl * 8 - 8) { if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) { line_h2 |= *(hp + 1 - hbpl); if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) line_h3 |= *(hp + 1 - hbpl - hbpl); } } do { if (!s->lntp[plane][layer - s->dl]) cx = (((line_l3 >> 14) & 0x007) | ((line_l2 >> 11) & 0x038) | ((line_l1 >> 8) & 0x1c0)); if (!s->lntp[plane][layer - s->dl] && (cx == 0x000 || cx == 0x1ff)) { /* pixels are typical and have not to be decoded */ do { line_h1 = (line_h1 << 1) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -