📄 jbig.c
字号:
s->ct += 8; s->result = JBG_OK; } } s->c <<= 1; s->a <<= 1; --s->ct; if (s->a == 0x10000L) s->startup = 0; } st = s->st + cx; ss = *st & 0x7f; assert(ss < 113); lsz = jbg_lsz[ss];#if 0 fprintf(stderr, "cx = %d, mps = %d, st = %3d, lsz = 0x%04x, a = 0x%05lx, " "c = 0x%08lx, ct = %2d\n", cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct);#endif if ((s->c >> 16) < (s->a -= lsz)) if (s->a & 0xffff8000L) return *st >> 7; else { /* MPS_EXCHANGE */ if (s->a < lsz) { pix = 1 - (*st >> 7); /* Check whether MPS/LPS exchange is necessary * and chose next probability estimator status */ *st &= 0x80; *st ^= jbg_nlps[ss]; } else { pix = *st >> 7; *st &= 0x80; *st |= jbg_nmps[ss]; } } else { /* LPS_EXCHANGE */ if (s->a < lsz) { s->c -= s->a << 16; s->a = lsz; pix = *st >> 7; *st &= 0x80; *st |= jbg_nmps[ss]; } else { s->c -= s->a << 16; s->a = lsz; pix = 1 - (*st >> 7); /* Check whether MPS/LPS exchange is necessary * and chose next probability estimator status */ *st &= 0x80; *st ^= jbg_nlps[ss]; } } return pix;}/* * Memory management for buffers which are used for temporarily * storing SDEs by the encoder. * * The following functions manage a set of struct jbg_buf storage * containers were each can keep JBG_BUFSIZE bytes. The jbg_buf * containers can be linked to form linear double-chained lists for * which a number of operations are provided. Blocks which are * tempoarily not used any more are returned to a freelist which each * encoder keeps. Only the destructor of the encoder actually returns * the block via checked_free() to the stdlib memory management. *//* * Allocate a new buffer block and initialize it. Try to get it from * the free_list, and if it is empty, call checked_malloc(). */static struct jbg_buf *jbg_buf_init(struct jbg_buf **free_list){ struct jbg_buf *new_block; /* Test whether a block from the free list is available */ if (*free_list) { new_block = *free_list; *free_list = new_block->next; } else { /* request a new memory block */ new_block = (struct jbg_buf *) checked_malloc(sizeof(struct jbg_buf)); } new_block->len = 0; new_block->next = NULL; new_block->previous = NULL; new_block->last = new_block; new_block->free_list = free_list; return new_block;}/* * Return an entire free_list to the memory management of stdlib. * This is only done by jbg_enc_free(). */static void jbg_buf_free(struct jbg_buf **free_list){ struct jbg_buf *tmp; while (*free_list) { tmp = (*free_list)->next; checked_free(*free_list); *free_list = tmp; } return;}/* * Append a single byte to a single list that starts with the block * *(struct jbg_buf *) head. The type of *head is void here in order to * keep the interface of the arithmetic encoder gereric, which uses this * function as a call-back function in order to deliver single bytes * for a PSCD. */static void jbg_buf_write(int b, void *head){ struct jbg_buf *now; now = ((struct jbg_buf *) head)->last; if (now->len < JBG_BUFSIZE - 1) { now->d[now->len++] = b; return; } now->next = jbg_buf_init(((struct jbg_buf *) head)->free_list); now->next->previous = now; now->next->d[now->next->len++] = b; ((struct jbg_buf *) head)->last = now->next; return;}/* * Remove any trailing zero bytes from the end of a linked jbg_buf list, * however make sure that no zero byte is removed which directly * follows a 0xff byte (i.e., keep MARKER_ESC MARKER_STUFF sequences * intact). This function is used to remove any redundant final zero * bytes from a PSCD. */static void jbg_buf_remove_zeros(struct jbg_buf *head){ struct jbg_buf *last; while (1) { /* remove trailing 0x00 in last block of list until this block is empty */ last = head->last; while (last->len && last->d[last->len - 1] == 0) last->len--; /* if block became really empty, remove it in case it is not the * only remaining block and then loop to next block */ if (last->previous && !last->len) { head->last->next = *head->free_list; *head->free_list = head->last; head->last = last->previous; head->last->next = NULL; } else break; } /* * If the final non-zero byte is 0xff (MARKER_ESC), then we just have * removed a MARKER_STUFF and we will append it again now in order * to preserve PSCD status of byte stream. */ if (head->last->len && head->last->d[head->last->len - 1] == MARKER_ESC) jbg_buf_write(MARKER_STUFF, head); return;}/* * The jbg_buf list which starts with block *new_prefix is concatenated * with the list which starts with block **start and *start will then point * to the first block of the new list. */static void jbg_buf_prefix(struct jbg_buf *new_prefix, struct jbg_buf **start){ new_prefix->last->next = *start; new_prefix->last->next->previous = new_prefix->last; new_prefix->last = new_prefix->last->next->last; *start = new_prefix; return;}/* * Send the contents of a jbg_buf list that starts with block **head to * the call back function data_out and return the blocks of the jbg_buf * list to the freelist from which these jbg_buf blocks have been taken. * After the call, *head == NULL. */static void jbg_buf_output(struct jbg_buf **head, void (*data_out)(unsigned char *start, size_t len, void *file), void *file){ struct jbg_buf *tmp; while (*head) { data_out((*head)->d, (*head)->len, file); tmp = (*head)->next; (*head)->next = *(*head)->free_list; *(*head)->free_list = *head; *head = tmp; } return;}/* * Calculate y = ceil(x/2) applied n times. This function is used to * determine the number of pixels per row or column after n resolution * reductions. E.g. X[d-1] = jbg_ceil_half(X[d], 1) and X[0] = * jbg_ceil_half(X[d], d) as defined in clause 6.2.3 of T.82. */unsigned long jbg_ceil_half(unsigned long x, int n){ unsigned long mask; mask = (1UL << n) - 1; /* the lowest n bits are 1 here */ return (x >> n) + ((mask & x) != 0);}/* * Initialize the status struct for the encoder. */void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y, int planes, unsigned char **p, void (*data_out)(unsigned char *start, size_t len, void *file), void *file){ unsigned long l, lx; int i; size_t bufsize; extern char jbg_resred[], jbg_dptable[]; s->xd = x; s->yd = y; s->planes = planes; s->data_out = data_out; s->file = file; s->d = 0; s->dl = 0; s->dh = s->d; s->l0 = jbg_ceil_half(s->yd, s->d) / 35; /* 35 stripes/image */ while ((s->l0 << s->d) > 128) /* but <= 128 lines/stripe */ --s->l0; if (s->l0 < 2) s->l0 = 2; s->mx = 8; s->my = 0; s->order = JBG_ILEAVE | JBG_SMID; s->options = JBG_TPBON | JBG_TPDON | JBG_DPON; s->dppriv = jbg_dptable; s->res_tab = jbg_resred; s->highres = checked_malloc(planes * sizeof(int)); s->lhp[0] = p; s->lhp[1] = checked_malloc(planes * sizeof(unsigned char *)); bufsize = ((jbg_ceil_half(x, 1) + 7) / 8) * jbg_ceil_half(y, 1); for (i = 0; i < planes; i++) { s->highres[i] = 0; s->lhp[1][i] = checked_malloc(sizeof(unsigned char) * bufsize); } s->free_list = NULL; s->s = (struct jbg_arenc_state *) checked_malloc(s->planes * sizeof(struct jbg_arenc_state)); s->tx = (int *) checked_malloc(s->planes * sizeof(int)); lx = jbg_ceil_half(x, 1); s->tp = (char *) checked_malloc(lx * sizeof(char)); for (l = 0; l < lx; s->tp[l++] = 2); s->sde = NULL; return;}/* * This function selects the number of differential layers based on * the maximum size requested for the lowest resolution layer. If * possible, a number of differential layers is selected, which will * keep the size of the lowest resolution layer below or equal to the * given width x and height y. However not more than 6 differential * resolution layers will be used. In addition, a reasonable value for * l0 (height of one stripe in the lowest resolution layer) is * selected, which obeys the recommended limitations for l0 in annex A * and C of the JBIG standard. The selected number of resolution layers * is returned. */int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long x, unsigned long y){ for (s->d = 0; s->d < 6; s->d++) if (jbg_ceil_half(s->xd, s->d) <= x && jbg_ceil_half(s->yd, s->d) <= y) break; s->dl = 0; s->dh = s->d; s->l0 = jbg_ceil_half(s->yd, s->d) / 35; /* 35 stripes/image */ while ((s->l0 << s->d) > 128) /* but <= 128 lines/stripe */ --s->l0; if (s->l0 < 2) s->l0 = 2; return s->d;}/* * As an alternative to jbg_enc_lrlmax(), the following function allows * to specify the number of layers directly. The stripe height and layer * range is also adjusted automatically here. */void jbg_enc_layers(struct jbg_enc_state *s, int d){ if (d < 0 || d > 255) return; s->d = d; s->dl = 0; s->dh = s->d; s->l0 = jbg_ceil_half(s->yd, s->d) / 35; /* 35 stripes/image */ while ((s->l0 << s->d) > 128) /* but <= 128 lines/stripe */ --s->l0; if (s->l0 < 2) s->l0 = 2; return;}/* * Specify the highest and lowest resolution layers which will be * written to the output file. Call this function not before * jbg_enc_layers() or jbg_enc_lrlmax(), because these two functions * reset the lowest and highest resolution layer to default values. * Negative values are ignored. The total number of layers is returned. */int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh){ if (dl >= 0 && dl <= s->d) s->dl = dl; if (dh >= s->dl && dh <= s->d) s->dh = dh; return s->d;}/* * The following function allows to specify the bits describing the * options of the format as well as the maximum AT movement window and * the number of layer 0 lines per stripes. */void jbg_enc_options(struct jbg_enc_state *s, int order, int options, long l0, int mx, int my){ if (order >= 0 && order <= 0x0f) s->order = order; if (options >= 0) s->options = options; if (l0 >= 0) s->l0 = l0; if (mx >= 0 && my < 128) s->mx = mx; if (my >= 0 && my < 256) s->my = my; return;}/* * This function actually does all the tricky work involved in producing * a SDE, which is stored in the appropriate s->sde[][][] element * for later output in the correct order. */static void encode_sde(struct jbg_enc_state *s, long stripe, int layer, int plane){ unsigned char *hp, *lp1, *lp2, *p0, *p1, *q1, *q2; unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl; unsigned long line_h0 = 0, line_h1 = 0; unsigned long line_h2, line_h3, line_l1, line_l2, line_l3; struct jbg_arenc_state *se; unsigned long i, j, y; unsigned t; int ltp, ltp_old, cx; unsigned long c_all, c[MX_MAX + 1], cmin, cmax, clmin, clmax; int tmax, at_determined; int new_tx; long new_tx_line = -1; struct jbg_buf *new_jbg_buf;#ifdef DEBUG static long tp_lines, tp_exceptions, tp_pixels, dp_pixels; static long encoded_pixels;#endif /* return immediately if this stripe has already been encoded */ if (s->sde[stripe][layer][plane] != SDE_TODO) return;#ifdef DEBUG if (stripe == 0) tp_lines = tp_exceptions = tp_pixels = dp_pixels = encoded_pixels = 0; fprintf(stderr, "encode_sde: s/d/p = %2ld/%2d/%2d\n", stripe, layer, plane);#endif /* 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; /* 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 first image byte of highres stripe */ hp = s->lhp[s->highres[plane]][plane] + stripe * hl * hbpl; lp2 = s->lhp[1 - s->highres[plane]][plane] + stripe * ll * lbpl; lp1 = lp2 + lbpl; /* initialize arithmetic encoder */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -