📄 jbig.c
字号:
se = s->s + plane; arith_encode_init(se, stripe != 0); s->sde[stripe][layer][plane] = jbg_buf_init(&s->free_list); se->byte_out = jbg_buf_write; se->file = s->sde[stripe][layer][plane]; /* initialize adaptive template movement algorithm */ c_all = 0; for (t = 0; t <= s->mx; t++) c[t] = 0; if (stripe == 0) s->tx[plane] = 0; new_tx = -1; at_determined = 0; /* we haven't yet decided the template move */ if (s->mx == 0) at_determined = 1; /* initialize typical prediction */ ltp = 0; if (stripe == 0) ltp_old = 0; else { ltp_old = 1; p1 = hp - hbpl; if (y > 1) { q1 = p1 - hbpl; while (p1 < hp && (ltp_old = (*p1++ == *q1++)) != 0); } else while (p1 < hp && (ltp_old = (*p1++ == 0)) != 0); } if (layer == 0) { /* * Encode lowest resolution layer */ for (i = 0; i < hl && y < hy; i++, y++) { /* check whether it is worth to perform an ATMOVE */ if (!at_determined && c_all > 2048) { cmin = clmin = 0xffffffffL; cmax = clmax = 0; tmax = 0; for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) { if (c[t] > cmax) cmax = c[t]; if (c[t] < cmin) cmin = c[t]; if (c[t] > c[tmax]) tmax = t; } clmin = (c[0] < cmin) ? c[0] : cmin; clmax = (c[0] > cmax) ? c[0] : cmax; if (c_all - cmax < (c_all >> 3) && cmax - c[s->tx[plane]] > c_all - cmax && cmax - c[s->tx[plane]] > (c_all >> 4) && /* ^ T.82 says here < !!! Typo ? */ cmax - (c_all - c[s->tx[plane]]) > c_all - cmax && cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) && cmax - cmin > (c_all >> 2) && (s->tx[plane] || clmax - clmin > (c_all >> 3))) { /* we have decided to perform an ATMOVE */ new_tx = tmax; if (!(s->options & JBG_DELAY_AT)) { new_tx_line = i; s->tx[plane] = new_tx; } } at_determined = 1; } /* typical prediction */ if (s->options & JBG_TPBON) { ltp = 1; p1 = hp; if (y > 0) { q1 = hp - hbpl; while (q1 < hp && (ltp = (*p1++ == *q1++)) != 0); } else while (p1 < hp + hbpl && (ltp = (*p1++ == 0)) != 0); arith_encode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX, ltp == ltp_old);#ifdef DEBUG tp_lines += ltp;#endif ltp_old = ltp; if (ltp) { /* skip next line */ hp += hbpl; continue; } } /* * Layout of the variables line_h1, line_h2, line_h3, which contain * as bits the neighbour pixels of the currently coded pixel X: * * 76543210765432107654321076543210 line_h3 * 76543210765432107654321076543210 line_h2 * 76543210765432107654321X76543210 line_h1 */ line_h1 = line_h2 = line_h3 = 0; if (y > 0) line_h2 = (long)*(hp - hbpl) << 8; if (y > 1) line_h3 = (long)*(hp - hbpl - hbpl) << 8; /* encode line */ for (j = 0; j < hx; hp++) { line_h1 |= *hp; if (j < hbpl * 8 - 8 && y > 0) { line_h2 |= *(hp - hbpl + 1); if (y > 1) line_h3 |= *(hp - hbpl - hbpl + 1); } if (s->options & JBG_LRLTWO) { /* two line template */ do { line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; if (s->tx[plane]) arith_encode(se, (((line_h2 >> 10) & 0x3e0) | ((line_h1 >> (4 + s->tx[plane])) & 0x010) | ((line_h1 >> 9) & 0x00f)), (line_h1 >> 8) & 1); else arith_encode(se, (((line_h2 >> 10) & 0x3f0) | ((line_h1 >> 9) & 0x00f)), (line_h1 >> 8) & 1);#ifdef DEBUG encoded_pixels++;#endif /* statistics for adaptive template changes */ if (!at_determined && j >= s->mx && j < hx-2) { c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100); for (t = 5; t <= s->mx; t++) c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100); ++c_all; } } while (++j & 7 && j < hx); } else { /* three line template */ do { line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; if (s->tx[plane]) arith_encode(se, (((line_h3 >> 8) & 0x380) | ((line_h2 >> 12) & 0x078) | ((line_h1 >> (6 + s->tx[plane])) & 0x004) | ((line_h1 >> 9) & 0x003)), (line_h1 >> 8) & 1); else arith_encode(se, (((line_h3 >> 8) & 0x380) | ((line_h2 >> 12) & 0x07c) | ((line_h1 >> 9) & 0x003)), (line_h1 >> 8) & 1);#ifdef DEBUG encoded_pixels++;#endif /* statistics for adaptive template changes */ if (!at_determined && j >= s->mx && j < hx-2) { c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100); for (t = 3; t <= s->mx; t++) c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100); ++c_all; } } while (++j & 7 && j < hx); } /* if (s->options & JBG_LRLTWO) */ } /* for (j = ...) */ } /* for (i = ...) */ } else { /* * Encode differential layer */ for (i = 0; i < hl && y < hy; i++, y++) { /* check whether it is worth to perform an ATMOVE */ if (!at_determined && c_all > 2048) { cmin = clmin = 0xffffffffL; cmax = clmax = 0; tmax = 0; for (t = 3; t <= s->mx; t++) { if (c[t] > cmax) cmax = c[t]; if (c[t] < cmin) cmin = c[t]; if (c[t] > c[tmax]) tmax = t; } clmin = (c[0] < cmin) ? c[0] : cmin; clmax = (c[0] > cmax) ? c[0] : cmax; if (c_all - cmax < (c_all >> 3) && cmax - c[s->tx[plane]] > c_all - cmax && cmax - c[s->tx[plane]] > (c_all >> 4) && /* ^ T.82 says here < !!! Typo ? */ cmax - (c_all - c[s->tx[plane]]) > c_all - cmax && cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) && cmax - cmin > (c_all >> 2) && (s->tx[plane] || clmax - clmin > (c_all >> 3))) { /* we have decided to perform an ATMOVE */ new_tx = tmax; if (!(s->options & JBG_DELAY_AT)) { new_tx_line = i; s->tx[plane] = new_tx; }#ifdef DEBUG fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n", i, new_tx, c_all);#endif } at_determined = 1; } if ((i >> 1) >= ll - 1 || (y >> 1) >= ly - 1) lp1 = lp2; /* typical prediction */ if (s->options & JBG_TPDON && (i & 1) == 0) { q1 = lp1; q2 = lp2; p0 = p1 = hp; if (i < hl - 1 && y < hy - 1) p0 = hp + hbpl; if (y > 1) line_l3 = (long)*(q2 - lbpl) << 8; else line_l3 = 0; line_l2 = (long)*q2 << 8; line_l1 = (long)*q1 << 8; ltp = 1; for (j = 0; j < lx && ltp; q1++, q2++) { if (j < lbpl * 8 - 8) { if (y > 1) line_l3 |= *(q2 - lbpl + 1); line_l2 |= *(q2 + 1); line_l1 |= *(q1 + 1); } do { if ((j >> 2) < hbpl) { line_h1 = *(p1++); line_h0 = *(p0++); } do { line_l3 <<= 1; line_l2 <<= 1; line_l1 <<= 1; line_h1 <<= 2; line_h0 <<= 2; cx = (((line_l3 >> 15) & 0x007) | ((line_l2 >> 12) & 0x038) | ((line_l1 >> 9) & 0x1c0)); if (cx == 0x000) if ((line_h1 & 0x300) == 0 && (line_h0 & 0x300) == 0) s->tp[j] = 0; else { ltp = 0;#ifdef DEBUG tp_exceptions++;#endif } else if (cx == 0x1ff) if ((line_h1 & 0x300) == 0x300 && (line_h0 & 0x300) == 0x300) s->tp[j] = 1; else { ltp = 0;#ifdef DEBUG tp_exceptions++;#endif } else s->tp[j] = 2; } while (++j & 3 && j < lx); } while (j & 7 && j < lx); } /* for (j = ...) */ arith_encode(se, TPDCX, !ltp);#ifdef DEBUG tp_lines += ltp;#endif } /* * Layout of the variables line_h1, line_h2, line_h3, which contain * as bits the high resolution neighbour pixels of the currently coded * highres pixel X: * * 76543210 76543210 76543210 76543210 line_h3 * 76543210 76543210 76543210 76543210 line_h2 * 76543210 76543210 7654321X 76543210 line_h1 * * Layout of the variables line_l1, line_l2, line_l3, which contain * the low resolution pixels near the currently coded 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 7654321Y 76543210 76543210 line_l2 * 76543210 76543210 76543210 76543210 line_l1 */ line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0; if (y > 0) line_h2 = (long)*(hp - hbpl) << 8; if (y > 1) { line_h3 = (long)*(hp - hbpl - hbpl) << 8; line_l3 = (long)*(lp2 - lbpl) << 8; } line_l2 = (long)*lp2 << 8; line_l1 = (long)*lp1 << 8; /* encode line */ for (j = 0; j < hx; lp1++, lp2++) { if ((j >> 1) < lbpl * 8 - 8) { if (y > 1) line_l3 |= *(lp2 - lbpl + 1); line_l2 |= *(lp2 + 1); line_l1 |= *(lp1 + 1); } do { assert(hp - (s->lhp[s->highres[plane]][plane] + (stripe * hl + i) * hbpl) == (ptrdiff_t) j >> 3); assert(lp2 - (s->lhp[1-s->highres[plane]][plane] + (stripe * ll + (i>>1)) * lbpl) == (ptrdiff_t) j >> 4); line_h1 |= *(hp++); if (j < hbpl * 8 - 8) { if (y > 0) { line_h2 |= *(hp - hbpl); if (y > 1) line_h3 |= *(hp - hbpl - hbpl); } } do { line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1; if (ltp && s->tp[j >> 1] < 2) { /* pixel are typical and have not to be encoded */ line_h1 <<= 2; line_h2 <<= 2; line_h3 <<= 2;#ifdef DEBUG do { ++tp_pixels; } while (++j & 1 && j < hx);#else j += 2;#endif } else do { line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; /* deterministic prediction */ if (s->options & JBG_DPON) { if ((y & 1) == 0) { if ((j & 1) == 0) { /* phase 0 */ if (s->dppriv[((line_l3 >> 16) & 0x003) | ((line_l2 >> 14) & 0x00c) | ((line_h1 >> 5) & 0x010) | ((line_h2 >> 10) & 0x0e0)] < 2) {#ifdef DEBUG ++dp_pixels;#endif continue; } } else { /* phase 1 */ if (s->dppriv[(((line_l3 >> 16) & 0x003) | ((line_l2 >> 14) & 0x00c) | ((line_h1 >> 5) & 0x030) | ((line_h2 >> 10) & 0x1c0)) + 256] < 2) {#ifdef DEBUG ++dp_pixels;#endif continue; } } } else { if ((j & 1) == 0) { /* phase 2 */ if (s->dppriv[(((line_l3 >> 16) & 0x003) | ((line_l2 >> 14) & 0x00c) | ((line_h1 >> 5) & 0x010) | ((line_h2 >> 10) & 0x0e0) | ((line_h3 >> 7) & 0x700)) + 768] < 2) {#ifdef DEBUG ++dp_pixels;#endif continue; } } else { /* phase 3 */ if (s->dppriv[(((line_l3 >> 16) & 0x003) | ((line_l2 >> 14) & 0x00c) | ((line_h1 >> 5) & 0x030) | ((line_h2 >> 10) & 0x1c0) | ((line_h3 >> 7) & 0xe00)) + 2816] < 2) {#ifdef DEBUG ++dp_pixels;#endif continue; } } } } /* determine context */ if (s->tx[plane]) cx = (((line_h1 >> 9) & 0x003) | ((line_h1 >> (4 + s->tx[plane])) & 0x010) | ((line_h2 >> 13) & 0x00c) | ((line_h3 >> 11) & 0x020)); else cx = (((line_h1 >> 9) & 0x003) | ((line_h2 >> 13) & 0x01c) | ((line_h3 >> 11) & 0x020)); if (j & 1) cx |= (((line_l2 >> 9) & 0x0c0) | ((line_l1 >> 7) & 0x300)) | (1UL << 10); else cx |= (((line_l2 >> 10) & 0x0c0) | ((line_l1 >> 8) & 0x300)); cx |= (y & 1) << 11; arith_encode(se, cx, (line_h1 >> 8) & 1);#ifdef DEBUG encoded_pixels++;#endif /* statistics for adaptive template changes */ if (!at_determined && j >= s->mx) { c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100); for (t = 3; t <= s->mx; t++) c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100); ++c_all; } } while (++j & 1 && j < hx); } while (j & 7 && j < hx); } while (j & 15 && j < hx); } /* for (j = ...) */ /* low resolution pixels are used twice */ if ((i & 1) == 0) { lp1 -= lbpl; lp2 -= lbpl; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -