ref: 508693c17eb8f052fbcc0ea4976cb326e746c2f0
parent: 19918285ec07521885d12a624507435a3da9f473
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Thu Aug 12 20:00:17 EDT 2004
Work in progress to implement generic refinement regions and aggregate symbol coding. Commit to avoid losing work. git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@318 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -1,7 +1,7 @@
/*
jbig2dec
- Copyright (c) 2002 artofcode LLC.
+ Copyright (c) 2002-2004 artofcode LLC.
This software is provided AS-IS with no warranty,
either express or implied.
@@ -317,14 +317,14 @@
/**
* jbig2_decode_generic_region: Decode a generic region.
* @ctx: The context for allocation and error reporting.
- * @params: Parameters, as specified in Table 2.
+ * @segment: A segment reference for error reporting.
+ * @params: Decoding parameter set.
* @as: Arithmetic decoder state.
- * @gbreg: Where to store the decoded data.
+ * @image: Where to store the decoded data.
* @GB_stats: Arithmetic stats.
*
* Decodes a generic region, according to section 6.2. The caller should
- * have allocated the memory for @gbreg, which is packed 8 pixels to a
- * byte, scanlines aligned to one byte boundaries.
+ * pass an already allocated Jbig2Image object for @image
*
* Because this API is based on an arithmetic decoding state, it is
* not suitable for MMR decoding.
@@ -457,3 +457,33 @@
return code;
}
+
+
+/**
+ * jbig2_decode_refinement_region: Decode a generic refinement region.
+ * @ctx: The context for allocation and error reporting.
+ * @segment: A segment reference for error reporting.
+ * @params: Decoding parameter set.
+ * @as: Arithmetic decoder state.
+ * @image: Where to store the decoded data.
+ * @GB_stats: Arithmetic stats.
+ *
+ * Decodes a generic region, according to section 6.2. The caller should
+ * pass an already allocated Jbig2Image object for @image
+ *
+ * Because this API is based on an arithmetic decoding state, it is
+ * not suitable for MMR decoding.
+ *
+ * Return code: 0 on success.
+ **/
+int
+jbig2_decode_refinement_region(Jbig2Ctx *ctx,
+ Jbig2Segment *segment,
+ const Jbig2RefinementRegionParams *params,
+ Jbig2ArithState *as,
+ Jbig2Image *image,
+ Jbig2ArithCx *GB_stats)
+{
+
+}
+
--- a/jbig2_generic.h
+++ b/jbig2_generic.h
@@ -1,7 +1,7 @@
/*
jbig2dec
- Copyright (c) 2002 artofcode LLC.
+ Copyright (c) 2002-2004 artofcode LLC.
This software is distributed under license and may not
be copied, modified or distributed except as expressly
@@ -13,10 +13,10 @@
Artifex Software, Inc., 101 Lucas Valley Road #110,
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
- $Id: jbig2_generic.h,v 1.7 2002/07/04 13:34:29 giles Exp $
+ $Id$
*/
-/* Table 2 */
+/* 6.4 Table 2 */
typedef struct {
bool MMR;
/* GBW */
@@ -28,7 +28,6 @@
byte gbat[8];
} Jbig2GenericRegionParams;
-/* 6.2 */
int
jbig2_decode_generic_region(Jbig2Ctx *ctx,
Jbig2Segment *segment,
@@ -38,3 +37,21 @@
Jbig2ArithCx *GB_stats);
+/* 6.3 Table 6 */
+typedef struct {
+ /* GRW */
+ /* GRH */
+ bool GRTEMPLATE;
+ Jbig2Image *reference;
+ int32_t DX, DY;
+ bool TPGDON;
+ byte grat[4];
+} Jbig2RefinementRegionParams;
+
+int
+jbig2_decode_refinement_region(Jbig2Ctx *ctx,
+ Jbig2Segment *segment,
+ const Jbig2RefinementRegionParams *params,
+ Jbig2ArithState *as,
+ Jbig2Image *image,
+ Jbig2ArithCx *GB_stats);
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -93,12 +93,15 @@
new->glyphs = (Jbig2Image **)jbig2_alloc(ctx->allocator,
n_symbols*sizeof(Jbig2Image*));
new->n_symbols = n_symbols;
+ } else {
+ return NULL;
}
+
if (new->glyphs != NULL) {
memset(new->glyphs, 0, n_symbols*sizeof(Jbig2Image*));
} else {
jbig2_free(ctx->allocator, new);
- new = NULL;
+ return NULL;
}
return new;
@@ -215,6 +218,10 @@
Jbig2ArithIntCtx *IADH = NULL;
Jbig2ArithIntCtx *IADW = NULL;
Jbig2ArithIntCtx *IAEX = NULL;
+ Jbig2ArithIntCtx *IAAI = NULL;
+ Jbig2ArithIntCtx *IAID = NULL;
+ Jbig2ArithIntCtx *IARDX = NULL;
+ Jbig2ArithIntCtx *IARDY = NULL;
int code = 0;
/* 6.5.5 (3) */
@@ -221,30 +228,40 @@
HCHEIGHT = 0;
NSYMSDECODED = 0;
- if (!params->SDHUFF)
- {
+ if (!params->SDHUFF) {
Jbig2WordStream *ws = jbig2_word_stream_buf_new(ctx, data, size);
as = jbig2_arith_new(ctx, ws);
IADH = jbig2_arith_int_ctx_new(ctx);
IADW = jbig2_arith_int_ctx_new(ctx);
IAEX = jbig2_arith_int_ctx_new(ctx);
- }
+ IAAI = jbig2_arith_int_ctx_new(ctx);
+ IAID = jbig2_arith_int_ctx_new(ctx);
+ IARDX = jbig2_arith_int_ctx_new(ctx);
+ IARDY = jbig2_arith_int_ctx_new(ctx);
+ } else {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "NYI: huffman coded symbol dictionary");
+ return NULL;
+ }
SDNEWSYMS = jbig2_sd_new(ctx, params->SDNUMNEWSYMS);
-
+
/* 6.5.5 (4a) */
- while (NSYMSDECODED < params->SDNUMNEWSYMS)
- {
+ while (NSYMSDECODED < params->SDNUMNEWSYMS) {
int32_t HCDH, DW;
/* 6.5.6 */
- if (params->SDHUFF)
+ if (params->SDHUFF) {
; /* todo */
- else
- {
+ } else {
code = jbig2_arith_int_decode(IADH, as, &HCDH);
- }
+ }
+ if (code != 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "error or OOB decoding height class delta (%d)\n", code);
+ }
+
/* 6.5.5 (4b) */
HCHEIGHT = HCHEIGHT + HCDH;
SYMWIDTH = 0;
@@ -251,49 +268,61 @@
TOTWIDTH = 0;
HCFIRSTSYM = NSYMSDECODED;
- if (HCHEIGHT < 0)
- {
+ if (HCHEIGHT < 0) {
/* todo: mem cleanup */
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Invalid HCHEIGHT value");
return NULL;
- }
+ }
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"HCHEIGHT = %d", HCHEIGHT);
#endif
- for (;;)
- {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "decoding height class %d with %d syms decoded", HCHEIGHT, NSYMSDECODED);
+
+ for (;;) {
+ /* check for broken symbol table */
+ if (NSYMSDECODED > params->SDNUMNEWSYMS)
+ {
+ /* todo: mem cleanup? */
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "No OOB signalling end of height class %d", HCHEIGHT);
+ break;
+ }
/* 6.5.7 */
- if (params->SDHUFF)
+ if (params->SDHUFF) {
; /* todo */
- else
- {
+ } else {
code = jbig2_arith_int_decode(IADW, as, &DW);
- }
+ }
/* 6.5.5 (4c.i) */
- if (code == 1)
+ if (code == 1) {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ " OOB signals end of height class %d", HCHEIGHT);
break;
+ }
SYMWIDTH = SYMWIDTH + DW;
TOTWIDTH = TOTWIDTH + SYMWIDTH;
- if (SYMWIDTH < 0)
- {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ " decoded symbol %d width %d (total width now %d)", NSYMSDECODED, SYMWIDTH, TOTWIDTH);
+ if (SYMWIDTH < 0) {
/* todo: mem cleanup */
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"Invalid SYMWIDTH value (%d) at symbol %d", SYMWIDTH, NSYMSDECODED+1);
return NULL;
- }
+ }
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"SYMWIDTH = %d", SYMWIDTH);
#endif
/* 6.5.5 (4c.ii) */
- if (!params->SDHUFF || params->SDREFAGG)
- {
+ if (!params->SDHUFF || params->SDREFAGG) {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "SDHUFF = %d; SDREFAGG = %d", params->SDHUFF, params->SDREFAGG);
/* 6.5.8 */
- if (!params->SDREFAGG)
- {
+ if (!params->SDREFAGG) {
Jbig2GenericRegionParams region_params;
int sdat_bytes;
Jbig2Image *image;
@@ -314,20 +343,80 @@
SDNEWSYMS->glyphs[NSYMSDECODED] = image;
+ } else {
+ /* 6.5.8.2 refinement/aggregate symbol */
+ uint32_t REFAGGNINST;
+
+ if (params->SDHUFF) {
+ /* todo */
+ } else {
+ code = jbig2_arith_int_decode(IAAI, as, &REFAGGNINST);
+ }
+ if (code || REFAGGNINST <= 0)
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "invalid number of symbols or OOB in aggregate glyph");
+
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "aggregate symbol coding (%d instances)", REFAGGNINST);
+
+ if (REFAGGNINST > 1) {
+ /* multiple symbols are like a text region */
+ } else {
+ /* 6.5.8.2.2 */
+ bool SBHUFF = params->SDHUFF;
+ uint32_t ID;
+ int32_t RDX, RDY;
+
+ if (params->SDHUFF) {
+ /* todo */
+ } else {
+ code = jbig2_arith_int_decode(IAID, as, &ID);
+ code = jbig2_arith_int_decode(IARDY, as, &RDX);
+ code = jbig2_arith_int_decode(IARDY, as, &RDY);
+ }
+
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "symbol is a refinement of id %d with the refinement applied at (%d,%d)",
+ ID, RDX, RDY);
+
+ }
+ }
+
#ifdef OUTPUT_PBM
- jbig2_image_write_pbm(image, stdout);
+ {
+ char name[64];
+ FILE *out;
+ snprintf(name, 64, "sd.%04d.%04d.pbm",
+ segment->number, NSYMSDECODED);
+ out = fopen(name, "wb");
+ jbig2_image_write_pbm(SDNEWSYMS->glyphs[NSYMSDECODED], out);
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "writing out glyph as '%s' ...", name);
+ fclose(out);
+ }
#endif
- }
- }
+ } else {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "unhandled bitmap case!!!");
+ }
+
+ /* 6.5.5 (4c.iii) */
+ if (params->SDHUFF && !params->SDREFAGG) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "NYI: parsing collective bitmaps!!!");
+ }
+
/* 6.5.5 (4c.iv) */
NSYMSDECODED = NSYMSDECODED + 1;
+
#ifdef JBIG2_DEBUG
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"%d of %d decoded", NSYMSDECODED, params->SDNUMNEWSYMS);
#endif
+
}
- }
+ }
jbig2_free(ctx->allocator, GB_stats);
@@ -393,22 +482,19 @@
/* FIXME: there are quite a few of these conditions to check */
/* maybe #ifdef CONFORMANCE and a separate routine */
- if(!params.SDHUFF && (flags & 0x000c))
- {
+ if(!params.SDHUFF && (flags & 0x000c)) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"SDHUFF is zero, but contrary to spec SDHUFFDH is not.");
- }
- if(!params.SDHUFF && (flags & 0x0030))
- {
+ }
+ if(!params.SDHUFF && (flags & 0x0030)) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"SDHUFF is zero, but contrary to spec SDHUFFDW is not.");
- }
+ }
- if (flags & 0x0080)
- {
+ if (flags & 0x0080) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"bitmap coding context is used (NYI) symbol data likely to be garbage!");
- }
+ }
/* 7.4.2.1.2 */
sdat_bytes = params.SDHUFF ? 0 : params.SDTEMPLATE == 0 ? 8 : 2;
@@ -416,13 +502,12 @@
offset = 2 + sdat_bytes;
/* 7.4.2.1.3 */
- if (params.SDREFAGG && !params.SDRTEMPLATE)
- {
+ if (params.SDREFAGG && !params.SDRTEMPLATE) {
if (offset + 4 > segment->data_length)
goto too_short;
memcpy(params.sdrat, segment_data + offset, 4);
offset += 4;
- }
+ }
if (offset + 8 > segment->data_length)
goto too_short;
@@ -455,19 +540,17 @@
}
/* 7.4.2.2 (4) */
- if (!params.SDHUFF)
- {
+ if (!params.SDHUFF) {
int stats_size = params.SDTEMPLATE == 0 ? 65536 :
params.SDTEMPLATE == 1 ? 8192 : 1024;
GB_stats = jbig2_alloc(ctx->allocator, stats_size);
memset(GB_stats, 0, stats_size);
- }
+ }
- if (flags & 0x0100)
- {
+ if (flags & 0x0100) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
"segment marks bitmap coding context as retained (NYI)");
- }
+ }
segment->result = (void *)jbig2_decode_symbol_dict(ctx, segment,
¶ms,