📄 jbig.c
字号:
} /* for (i = ...) */ } arith_encode_flush(se); jbg_buf_remove_zeros(s->sde[stripe][layer][plane]); jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]); jbg_buf_write(MARKER_SDNORM, s->sde[stripe][layer][plane]); /* add ATMOVE */ if (new_tx != -1) { if (s->options & JBG_DELAY_AT) { /* ATMOVE will become active at the first line of the next stripe */ s->tx[plane] = new_tx; jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]); jbg_buf_write(MARKER_ATMOVE, s->sde[stripe][layer][plane]); jbg_buf_write(0, s->sde[stripe][layer][plane]); jbg_buf_write(0, s->sde[stripe][layer][plane]); jbg_buf_write(0, s->sde[stripe][layer][plane]); jbg_buf_write(0, s->sde[stripe][layer][plane]); jbg_buf_write(s->tx[plane], s->sde[stripe][layer][plane]); jbg_buf_write(0, s->sde[stripe][layer][plane]); } else { /* ATMOVE has already become active during this stripe * => we have to prefix the SDE data with an ATMOVE marker */ new_jbg_buf = jbg_buf_init(&s->free_list); jbg_buf_write(MARKER_ESC, new_jbg_buf); jbg_buf_write(MARKER_ATMOVE, new_jbg_buf); jbg_buf_write((new_tx_line >> 24) & 0xff, new_jbg_buf); jbg_buf_write((new_tx_line >> 16) & 0xff, new_jbg_buf); jbg_buf_write((new_tx_line >> 8) & 0xff, new_jbg_buf); jbg_buf_write(new_tx_line & 0xff, new_jbg_buf); jbg_buf_write(new_tx, new_jbg_buf); jbg_buf_write(0, new_jbg_buf); jbg_buf_prefix(new_jbg_buf, &s->sde[stripe][layer][plane]); } }#if 0 if (stripe == s->stripes - 1) fprintf(stderr, "tp_lines = %ld, tp_exceptions = %ld, tp_pixels = %ld, " "dp_pixels = %ld, encoded_pixels = %ld\n", tp_lines, tp_exceptions, tp_pixels, dp_pixels, encoded_pixels);#endif return;}/* * Create the next lower resolution version of an image */static void resolution_reduction(struct jbg_enc_state *s, int plane, int higher_layer){ unsigned long hx, hy, lx, ly, hbpl, lbpl; unsigned char *hp1, *hp2, *hp3, *lp; unsigned long line_h1, line_h2, line_h3, line_l2; unsigned long i, j; int pix, k, l; /* number of pixels in highres image */ hx = jbg_ceil_half(s->xd, s->d - higher_layer); hy = jbg_ceil_half(s->yd, s->d - higher_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; /* pointers to first image bytes */ hp2 = s->lhp[s->highres[plane]][plane]; hp1 = hp2 + hbpl; hp3 = hp2 - hbpl; lp = s->lhp[1 - s->highres[plane]][plane]; #ifdef DEBUG fprintf(stderr, "resolution_reduction: plane = %d, higher_layer = %d\n", plane, higher_layer);#endif /* * Layout of the variables line_h1, line_h2, line_h3, which contain * as bits the high resolution neighbour pixels of the currently coded * lowres pixel /\: * \/ * * 76543210 76543210 76543210 76543210 line_h3 * 76543210 76543210 765432/\ 76543210 line_h2 * 76543210 76543210 765432\/ 76543210 line_h1 * * Layout of the variable line_l2, which contains the low resolution * pixels near the currently coded pixel as bits. The lowres pixel * which is currently coded is marked as X: * * 76543210 76543210 76543210 76543210 line_l2 * X */ for (i = 0; i < ly; i++) { if (2*i + 1 >= hy) hp1 = hp2; pix = 0; line_h1 = line_h2 = line_h3 = line_l2 = 0; for (j = 0; j < lbpl * 8; j += 8) { *lp = 0; line_l2 |= i ? lp[-lbpl] : 0; for (k = 0; k < 8 && j + k < lx; k += 4) { if (((j + k) >> 2) < hbpl) { line_h3 |= i ? *hp3 : 0; ++hp3; line_h2 |= *(hp2++); line_h1 |= *(hp1++); } for (l = 0; l < 4 && j + k + l < lx; l++) { line_h3 <<= 2; line_h2 <<= 2; line_h1 <<= 2; line_l2 <<= 1; pix = s->res_tab[((line_h1 >> 8) & 0x007) | ((line_h2 >> 5) & 0x038) | ((line_h3 >> 2) & 0x1c0) | (pix << 9) | ((line_l2 << 2) & 0xc00)]; *lp = (*lp << 1) | pix; } } ++lp; } *(lp - 1) <<= lbpl * 8 - lx; hp1 += hbpl; hp2 += hbpl; hp3 += hbpl; }#ifdef DEBUG { FILE *f; char fn[50]; sprintf(fn, "dbg_d=%02d.pbm", higher_layer - 1); f = fopen(fn, "wb"); fprintf(f, "P4\n%lu %lu\n", lx, ly); fwrite(s->lhp[1 - s->highres[plane]][plane], 1, lbpl * ly, f); fclose(f); }#endif return;}/* * This function is called inside the three loops of jbg_enc_out() in * order to write the next SDE. It has first to generate the required * SDE and all SDEs which have to be encoded before this SDE can be * created. The problem here is that if we want to output a lower * resolution layer, we have to allpy the resolution reduction * algorithm in order to get it. As we try to safe as much memory as * possible, the resolution reduction will overwrite previous higher * resolution bitmaps. Consequently, we have to encode and buffer SDEs * which depend on higher resolution layers before we can start the * resolution reduction. All this logic about which SDE has to be * encoded before resolution reduction is allowed is handled here. * This approach might be a little bit more complex than alternative * ways to do it, but it allows us to do the encoding with the minimal * possible amount of temporary memory. */static void output_sde(struct jbg_enc_state *s, unsigned long stripe, int layer, int plane){ int lfcl; /* lowest fully coded layer */ long i; unsigned long u; assert(s->sde[stripe][layer][plane] != SDE_DONE); if (s->sde[stripe][layer][plane] != SDE_TODO) {#ifdef DEBUG fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", stripe, layer, plane);#endif jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file); s->sde[stripe][layer][plane] = SDE_DONE; return; } /* Determine the smallest resolution layer in this plane for which * not yet all stripes have been encoded into SDEs. This layer will * have to be completely coded, before we can apply the next * resolution reduction step. */ lfcl = 0; for (i = s->d; i >= 0; i--) if (s->sde[s->stripes - 1][i][plane] == SDE_TODO) { lfcl = i + 1; break; } if (lfcl > s->d && s->d > 0 && stripe == 0) { /* perform the first resolution reduction */ resolution_reduction(s, plane, s->d); } /* In case HITOLO is not used, we have to encode and store the higher * resolution layers first, although we do not need them right now. */ while (lfcl - 1 > layer) { for (u = 0; u < s->stripes; u++) encode_sde(s, u, lfcl - 1, plane); --lfcl; s->highres[plane] ^= 1; if (lfcl > 1) resolution_reduction(s, plane, lfcl - 1); } encode_sde(s, stripe, layer, plane);#ifdef DEBUG fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", stripe, layer, plane);#endif jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file); s->sde[stripe][layer][plane] = SDE_DONE; if (stripe == s->stripes - 1 && layer > 0 && s->sde[0][layer-1][plane] == SDE_TODO) { s->highres[plane] ^= 1; if (layer > 1) resolution_reduction(s, plane, layer - 1); } return;}/* * Convert the table which controls the deterministic prediction * process from the internal format into the representation required * for the 1728 byte long DPTABLE element of a BIH. * * The bit order of the DPTABLE format (see also ITU-T T.82 figure 13) is * * high res: 4 5 6 low res: 0 1 * 7 8 9 2 3 * 10 11 12 * * were 4 table entries are packed into one byte, while we here use * internally an unpacked 6912 byte long table indexed by the following * bit order: * * high res: 7 6 5 high res: 8 7 6 low res: 1 0 * (phase 0) 4 . . (phase 1) 5 4 . 3 2 * . . . . . . * * high res: 10 9 8 high res: 11 10 9 * (phase 2) 7 6 5 (phase 3) 8 7 6 * 4 . . 5 4 . */void jbg_int2dppriv(unsigned char *dptable, const char *internal){ int i, j, k; int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 }; int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 }; int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 }; int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 }; for (i = 0; i < 1728; dptable[i++] = 0);#define FILL_TABLE1(offset, len, trans) \ for (i = 0; i < len; i++) { \ k = 0; \ for (j = 0; j < 8; j++) \ k |= ((i >> j) & 1) << trans[j]; \ dptable[(i + offset) >> 2] |= \ (internal[k + offset] & 3) << ((3 - (i&3)) << 1); \ } FILL_TABLE1( 0, 256, trans0); FILL_TABLE1( 256, 512, trans1); FILL_TABLE1( 768, 2048, trans2); FILL_TABLE1(2816, 4096, trans3); return;}/* * Convert the table which controls the deterministic prediction * process from the 1728 byte long DPTABLE format into the 6912 byte long * internal format. */void jbg_dppriv2int(char *internal, const unsigned char *dptable){ int i, j, k; int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 }; int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 }; int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 }; int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 }; #define FILL_TABLE2(offset, len, trans) \ for (i = 0; i < len; i++) { \ k = 0; \ for (j = 0; j < 8; j++) \ k |= ((i >> j) & 1) << trans[j]; \ internal[k + offset] = \ (dptable[(i + offset) >> 2] >> ((3 - (i & 3)) << 1)) & 3; \ } FILL_TABLE2( 0, 256, trans0); FILL_TABLE2( 256, 512, trans1); FILL_TABLE2( 768, 2048, trans2); FILL_TABLE2(2816, 4096, trans3); return;}/* * Encode one full BIE and pass the generated data to the specified * call-back function */void jbg_enc_out(struct jbg_enc_state *s){ long bpl; unsigned char bih[20]; unsigned long xd, yd, y; long ii[3], is[3], ie[3]; /* generic variables for the 3 nested loops */ unsigned long stripe; int layer, plane; int order; unsigned char dpbuf[1728]; extern char jbg_dptable[]; /* some sanity checks */ s->order &= JBG_HITOLO | JBG_SEQ | JBG_ILEAVE | JBG_SMID; order = s->order & (JBG_SEQ | JBG_ILEAVE | JBG_SMID); if (index[order][0] < 0) s->order = order = JBG_SMID | JBG_ILEAVE; if (s->options & JBG_DPON && s->dppriv != jbg_dptable) s->options |= JBG_DPPRIV; if (s->mx > MX_MAX) s->mx = MX_MAX; s->my = 0; if (s->mx && s->mx < ((s->options & JBG_LRLTWO) ? 5U : 3U)) s->mx = 0; if (s->d > 255 || s->d < 0 || s->dh > s->d || s->dh < 0 || s->dl < 0 || s->dl > s->dh || s->planes < 0 || s->planes > 255) return; /* ensure correct zero padding of bitmap at the final byte of each line */ if (s->xd & 7) { bpl = (s->xd + 7) / 8; /* bytes per line */ for (plane = 0; plane < s->planes; plane++) for (y = 0; y < s->yd; y++) s->lhp[0][plane][y * bpl + bpl - 1] &= ~((1 << (8 - (s->xd & 7))) - 1); } /* calculate number of stripes that will be required */ s->stripes = ((s->yd >> s->d) + ((((1UL << s->d) - 1) & s->xd) != 0) + s->l0 - 1) / s->l0; /* allocate buffers for SDE pointers */ if (s->sde == NULL) { s->sde = (struct jbg_buf ****) checked_malloc(s->stripes * sizeof(struct jbg_buf ***)); for (stripe = 0; stripe < s->stripes; stripe++) { s->sde[stripe] = (struct jbg_buf ***) checked_malloc((s->d + 1) * sizeof(struct jbg_buf **)); for (layer = 0; layer < s->d + 1; layer++) { s->sde[stripe][layer] = (struct jbg_buf **) checked_malloc(s->planes * sizeof(struct jbg_buf *)); for (plane = 0; plane < s->planes; plane++) s->sde[stripe][layer][plane] = SDE_TODO; } } } /* output BIH */ bih[0] = s->dl; bih[1] = s->dh; bih[2] = s->planes; bih[3] = 0; xd = jbg_ceil_half(s->xd, s->d - s->dh); yd = jbg_ceil_half(s->yd, s->d - s->dh); bih[4] = xd >> 24; bih[5] = (xd >> 16) & 0xff; bih[6] = (xd >> 8) & 0xff; bih[7] = xd & 0xff; bih[8] = yd >> 24; bih[9] = (yd >> 16) & 0xff; bih[10] = (yd >> 8) & 0xff; bih[11] = yd & 0xff; bih[12] = s->l0 >> 24; bih[13] = (s->l0 >> 16) & 0xff; bih[14] = (s->l0 >> 8) & 0xff; bih[15] = s->l0 & 0xff; bih[16] = s->mx; bih[17] = s->my; bih[18] = s->order; bih[19] = s->options & 0x7f; s->data_out(bih, 20, s->file); if ((s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) == (JBG_DPON | JBG_DPPRIV)) { /* write private table */ jbg_int2dppriv(dpbuf, s->dppriv); s->data_out(dpbuf, 1728, s->file); }#if 0 /* * Encode everything first. This is a simple-minded alternative to * all the tricky on-demand encoding logic in output_sde() for * debugging purposes. */ for (layer = s->dh; layer >= s->dl; layer--) { for (plane = 0; plane < s->planes; plane++) { if (layer > 0) resolution_reduction(s, plane, layer); for (stripe = 0; stripe < s->stripes; stripe++) encode_sde(s, stripe, layer, plane); s->highres[plane] ^= 1; } }#endif /* * Generic loops over all SDEs. Which loop represents layer, plane and * stripe depends on the option flags. */ /* start and end value vor each loop */ is[index[order][STRIPE]] = 0; ie[index[order][STRIPE]] = s->stripes - 1; is[index[order][LAYER]] = s->dl; ie[index[order][LAYER]] = s->dh; is[index[order][PLANE]] = 0; ie[index[order][PLANE]] = s->planes - 1; for (ii[0] = is[0]; ii[0] <= ie[0]; ii[0]++) for (ii[1] = is[1]; ii[1] <= ie[1]; ii[1]++) for (ii[2] = is[2]; ii[2] <= ie[2]; ii[2]++) { stripe = ii[index[order][STRIPE]]; if (s->order & JBG_HITOLO) layer = s->dh - (ii[index[order][LAYER]] - s->dl); else layer = ii[index[order][LAYER]]; plane = ii[index[order][PLANE]];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -