ref: 5613e3f978e406268fe5c42b7da322c0e4bfa7a9
parent: a6752fd2a6859efeabbb29954d5b5d34ec0eb96b
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Mon Jun 24 15:09:47 EDT 2002
checkpoint in-progress text region decoding procedures git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@91 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -8,7 +8,7 @@
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
- $Id: jbig2_symbol_dict.c,v 1.12 2002/06/24 15:51:57 giles Exp $
+ $Id: jbig2_symbol_dict.c,v 1.13 2002/06/24 19:09:47 giles Exp $
symbol dictionary segment decode and support
*/
@@ -16,7 +16,10 @@
#include <stddef.h>
#include <stdint.h>
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
@@ -64,7 +67,7 @@
#endif /* HAVE_LIBPNG */
/* 6.5 */
-Jbig2SymbolDict *
+static Jbig2SymbolDict *
jbig2_decode_symbol_dict(Jbig2Ctx *ctx,
Jbig2Segment *segment,
const Jbig2SymbolDictParams *params,
@@ -123,10 +126,10 @@
"Invalid HCHEIGHT value");
return NULL;
}
-
+#ifdef DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"HCHEIGHT = %d", HCHEIGHT);
-
+#endif
for (;;)
{
/* 6.5.7 */
@@ -149,9 +152,10 @@
"Invalid SYMWIDTH value");
return NULL;
}
+#ifdef DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"SYMWIDTH = %d", SYMWIDTH);
-
+#endif
/* 6.5.5 (4c.ii) */
if (!params->SDHUFF || params->SDREFAGG)
{
@@ -186,8 +190,10 @@
/* 6.5.5 (4c.iv) */
NSYMSDECODED = NSYMSDECODED + 1;
+#ifdef DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"%d of %d decoded", NSYMSDECODED, params->SDNUMNEWSYMS);
+#endif
}
}
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -8,12 +8,17 @@
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
- $Id: jbig2_text.c,v 1.3 2002/06/24 15:51:57 giles Exp $
+ $Id: jbig2_text.c,v 1.4 2002/06/24 19:09:47 giles Exp $
*/
#include <stddef.h>
#include <stdint.h>
+#include <string.h> /* memset() */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
@@ -35,7 +40,7 @@
Jbig2ComposeOp SBCOMBOP;
bool TRANSPOSED;
Jbig2RefCorner REFCORNER;
- int SBDOFFSET;
+ int SBDSOFFSET;
/* SBW */
/* SBH */
uint32_t SBNUMINSTANCES;
@@ -56,12 +61,159 @@
int8_t sbrat[4];
} Jbig2TextRegionParams;
+/**
+ * jbig2_decode_text_region: decode a text region segment
+ *
+ * @ctx: jbig2 decoder context
+ * @segment: jbig2 segment (header) structure
+ * @params: parameters from the text region header
+ * @dicts: an array of referenced symbol dictionaries
+ * @n_dicts: the number of referenced symbol dictionaries
+ * @image: image structure in which to store the decoded region bitmap
+ * @data: pointer to text region data to be decoded
+ * @size: length of text region data
+ *
+ * Implements the text region decoding proceedure
+ * described in section 6.4 of the JBIG2 spec.
+ *
+ * returns: 0 on success
+ **/
int jbig2_decode_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
const Jbig2TextRegionParams *params,
- const Jbig2RegionSegmentInfo *info,
+ const Jbig2SymbolDict **dicts, const int n_dicts,
Jbig2Image *image,
const byte *data, size_t size)
{
+ /* relevent bits of 6.4.4 */
+ uint32_t NINSTANCES;
+ uint32_t ID;
+ int32_t STRIPT;
+ int32_t FIRSTS;
+ int32_t DT;
+ int32_t DFS;
+ int32_t IDS;
+ int32_t CURS;
+ int32_t CURT;
+ int S,T;
+ int x,y;
+ bool first_symbol = TRUE;
+ Jbig2Image *IB;
+ Jbig2ArithState *as;
+ Jbig2ArithIntCtx *IADT = NULL;
+ Jbig2ArithIntCtx *IAFS = NULL;
+ Jbig2ArithIntCtx *IADS = NULL;
+ Jbig2ArithIntCtx *IAIT = NULL;
+ Jbig2ArithIntCtx *IAID = NULL;
+ int code;
+
+ if (!params->SBHUFF) {
+ Jbig2WordStream *ws = jbig2_word_stream_buf_new(ctx, data, size);
+ as = jbig2_arith_new(ctx, ws);
+ IADT = jbig2_arith_int_ctx_new(ctx);
+ IAFS = jbig2_arith_int_ctx_new(ctx);
+ IADS = jbig2_arith_int_ctx_new(ctx);
+ IAIT = jbig2_arith_int_ctx_new(ctx);
+ IAID = jbig2_arith_int_ctx_new(ctx);
+ }
+
+ /* 6.4.5 (1) */
+ memset(image->data, image->stride*image->height, params->SBDEFPIXEL ? 0xFF: 0x00);
+
+ /* 6.4.6 */
+ if (params->SBHUFF) {
+ /* todo */
+ } else {
+ code = jbig2_arith_int_decode(IADT, as, &STRIPT);
+ }
+ /* 6.4.5 (2) */
+ STRIPT *= -params->SBSTRIPS;
+ FIRSTS = 0;
+ NINSTANCES = 0;
+
+ /* 6.4.5 (3) */
+ while (NINSTANCES < params->SBNUMINSTANCES) {
+ /* (3b) */
+ if (params->SBHUFF) {
+ /* todo */
+ } else {
+ code = jbig2_arith_int_decode(IADT, as, &DT);
+ }
+ DT *= params->SBSTRIPS;
+ STRIPT += DT;
+
+ /* (3c) */
+ if (first_symbol) {
+ /* 6.4.7 */
+ if (params->SBHUFF) {
+ /* todo */
+ } else {
+ code = jbig2_arith_int_decode(IAFS, as, &DFS);
+ }
+ FIRSTS += DFS;
+ CURS = FIRSTS;
+ } else {
+ /* 6.4.8 */
+ if (params->SBHUFF) {
+ /* todo */
+ } else {
+ code = jbig2_arith_int_decode(IADS, as, &IDS);
+ }
+ CURS += IDS + params->SBDSOFFSET;
+ }
+ /* 6.4.9 */
+ code = jbig2_arith_int_decode(IAIT, as, &CURT);
+ T = STRIPT + CURT;
+
+ /* (3b.iv) / 6.4.10 */
+ code = jbig2_arith_int_decode(IAID, as, &ID);
+
+ /* (3b.v) */
+ if (!params->TRANSPOSED) {
+ switch (params->REFCORNER) { // FIXME: double check offsets
+ case JBIG2_CORNER_TOPLEFT: x = S; y = T; break;
+ case JBIG2_CORNER_TOPRIGHT: x = S - IB->width; y = T; break;
+ case JBIG2_CORNER_BOTTOMLEFT: x = S; y = T - IB->height; break;
+ case JBIG2_CORNER_BOTTOMRIGHT: x = S - IB->width; y = T - IB->height; break;
+ }
+ } else { /* TRANSPOSED */
+ switch (params->REFCORNER) {
+ case JBIG2_CORNER_TOPLEFT: x = S; y = T; break;
+ case JBIG2_CORNER_TOPRIGHT: x = S - IB->width; y = T; break;
+ case JBIG2_CORNER_BOTTOMLEFT: x = S; y = T - IB->height; break;
+ case JBIG2_CORNER_BOTTOMRIGHT: x = S - IB->width; y = T - IB->height; break;
+ }
+ }
+
+ /* (3b.vi) */
+ if ((!params->TRANSPOSED) && (params->REFCORNER > 1)) {
+ CURS += IB->width - 1;
+ } else if ((params->TRANSPOSED) && (params->REFCORNER < 2)) {
+ CURS += IB->height - 1;
+ }
+
+ /* (3b.vii) */
+ S = CURS;
+
+ /* (3b.viii) */
+ // todo: choose glyph bitmap
+
+ /* (3b.ix) */
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "composing glyph id %d at (%d, %d)", ID, x, y);
+ jbig2_image_compose(ctx, image, IB, x, y, params->SBCOMBOP);
+
+ /* (3b.x) */
+ if ((!params->TRANSPOSED) && (params->REFCORNER < 2)) {
+ CURS += IB->width -1 ;
+ } else if ((params->TRANSPOSED) && (params->REFCORNER > 1)) {
+ CURS += IB->height - 1;
+ }
+
+ /* (3b.xi) */
+ NINSTANCES++;
+ }
+
+ return 0;
}
/**
@@ -74,11 +226,14 @@
Jbig2RegionSegmentInfo region_info;
Jbig2TextRegionParams params;
Jbig2Image *image, *page_image;
- int code;
+ Jbig2SymbolDict **dicts;
+ int n_dicts;
uint32_t num_instances;
uint16_t segment_flags;
uint16_t huffman_flags;
int8_t sbrat[4];
+ int index;
+ int code;
/* 7.4.1 */
if (segment->data_length < 17)
@@ -124,11 +279,24 @@
region_info.x, region_info.y, num_instances);
}
+ /* compose the list of symbol dictionaries */
+ n_dicts = 0;
+ for (index = 0; index < segment->referred_to_segment_count; index++) {
+ if (ctx->segments[segment->referred_to_segments[index]]->flags & 63 == 0)
+ n_dicts++;
+ }
+ dicts = jbig2_alloc(ctx->allocator, sizeof(Jbig2SymbolDict *) * n_dicts);
+ for (index = 0; index < segment->referred_to_segment_count; index++) {
+ int dindex = 0;
+ if (ctx->segments[segment->referred_to_segments[index]]->flags & 63 == 0)
+ dicts[dindex++] = (Jbig2SymbolDict *)ctx->segments[segment->referred_to_segments[index]]->result;
+ }
+
page_image = ctx->pages[ctx->current_page].image;
image = jbig2_image_new(ctx, region_info.width, region_info.height);
code = jbig2_decode_text_region(ctx, segment, ¶ms,
- ®ion_info, image,
+ dicts, n_dicts, image,
segment_data + offset, segment->data_length - offset);
/* todo: check errors */