jbig2dec

Raph Levien <[email protected]> Mon, 01 Jul 2002 12:34:33 -0700
Newsgroups gmane.comp.printing.ghostscript.jbig2dec.cvs
Message-ID <[email protected]>
Update of /cvsroot/jbig2dec/jbig2dec
In directory usw-pr-cvs1:/tmp/cvs-serv3651

Modified Files:
	Makefile.am jbig2_text.c 
Added Files:
	jbig2_arith_iaid.c jbig2_arith_iaid.h 
Log Message:
Text region decoding now seems to decode 042_10.jb2 correctly. Added
IAID decoding procedure. Changed jbig2_decode_text_region to use IAID
procedure. Fixed off-by-one errors in corner alignment calculations.
Added for (;;) loop for 3c, corresponding to looping over all symbol
instances in a strip (outer while loop corresponds to looping over all
strips in the region). Fixed predicates in CURS updating logic.


--- NEW FILE: jbig2_arith_iaid.c ---
/* Annex A.3 */

#ifdef VERBOSE
#include <stdio.h> /* for debug printing only */
#endif

#include <stddef.h>
#include <stdint.h>
#include "jbig2.h"
#include "jbig2_priv.h"
#include "jbig2_arith.h"
#include "jbig2_arith_iaid.h"

struct _Jbig2ArithIaidCtx {
  int SBSYMCODELEN;
  Jbig2ArithCx *IAIDx;
};

Jbig2ArithIaidCtx *
jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, int SBSYMCODELEN)
{
  Jbig2ArithIaidCtx *result = jbig2_new(ctx, Jbig2ArithIaidCtx, 1);
  int ctx_size = 1 << SBSYMCODELEN;

  result->SBSYMCODELEN = SBSYMCODELEN;
  result->IAIDx = jbig2_alloc(ctx->allocator, ctx_size);
  memset(result->IAIDx, 0, ctx_size);

  return result;
}

/* A.3 */
/* Return value: -1 on error, 0 on normal value */
int
jbig2_arith_iaid_decode(Jbig2ArithIaidCtx *ctx, Jbig2ArithState *as,
		       int32_t *p_result)
{
  Jbig2ArithCx *IAIDx = ctx->IAIDx;
  int SBSYMCODELEN = ctx->SBSYMCODELEN;
  int PREV = 1;
  int D;
  int i;

  /* A.3 (2) */
  for (i = 0; i < SBSYMCODELEN; i++)
    {
      D = jbig2_arith_decode(as, &IAIDx[PREV]);
#ifdef VERBOSE
      fprintf(stderr, "IAID%x: D = %d\n", PREV, D);
#endif
      PREV = (PREV << 1) | D;
    }
  /* A.3 (3) */
  PREV -= 1 << SBSYMCODELEN;
#ifdef VERBOSE
  fprintf(stderr, "IAID result: %d\n", PREV);
#endif
  *p_result = PREV;
  return 0;
}

void
jbig2_arith_iaid_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *iax)
{
  jbig2_free(ctx->allocator, iax->IAIDx);
  jbig2_free(ctx->allocator, iax);
}

--- NEW FILE: jbig2_arith_iaid.h ---
typedef struct _Jbig2ArithIaidCtx Jbig2ArithIaidCtx;

Jbig2ArithIaidCtx *
jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, int SBSYMCODELEN);

int
jbig2_arith_iaid_decode(Jbig2ArithIaidCtx *ctx, Jbig2ArithState *as,
		       int32_t *p_result);

void
jbig2_arith_iaid_ctx_free(Jbig2Ctx *ctx, Jbig2ArithIaidCtx *iax);

Index: Makefile.am
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Makefile.am	20 Jun 2002 15:42:47 -0000	1.4
+++ Makefile.am	1 Jul 2002 19:34:30 -0000	1.5
@@ -4,7 +4,7 @@
 lib_LIBRARIES = libjbig2dec.a
 
 libjbig2dec_a_SOURCES = jbig2.c \
-	jbig2_arith.c jbig2_arith_int.c jbig2_huffman.c \
+	jbig2_arith.c jbig2_arith_int.c jbig2_arith_iaid.c jbig2_huffman.c \
 	jbig2_segment.c jbig2_page.c \
 	jbig2_symbol_dict.c jbig2_text.c \
 	jbig2_generic.c jbig2_mmr.c \

Index: jbig2_text.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_text.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- jbig2_text.c	27 Jun 2002 14:02:08 -0000	1.6
+++ jbig2_text.c	1 Jul 2002 19:34:31 -0000	1.7
@@ -24,6 +24,7 @@
 #include "jbig2_priv.h"
 #include "jbig2_arith.h"
 #include "jbig2_arith_int.h"
+#include "jbig2_arith_iaid.h"
 #include "jbig2_generic.h"
 #include "jbig2_symbol_dict.h"
 
@@ -97,7 +98,7 @@
     int32_t CURT;
     int S,T;
     int x,y;
-    bool first_symbol = TRUE;
+    bool first_symbol;
     uint32_t index, max_id;
     Jbig2Image *IB;
     Jbig2ArithState *as;
@@ -105,7 +106,7 @@
     Jbig2ArithIntCtx *IAFS = NULL;
     Jbig2ArithIntCtx *IADS = NULL;
     Jbig2ArithIntCtx *IAIT = NULL;
-    Jbig2ArithIntCtx *IAID = NULL;
+    Jbig2ArithIaidCtx *IAID = NULL;
     int code;
     
     max_id = 0;
@@ -121,13 +122,17 @@
     }
     
     if (!params->SBHUFF) {
+	int SBSYMCODELEN;
+
         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);
+	/* Table 31 */
+	for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < max_id; SBSYMCODELEN++);
+        IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
     }
     
     /* 6.4.5 (1) */
@@ -157,109 +162,113 @@
         STRIPT += DT;
         fprintf(stderr, "decoded DT = %d, STRIPT = %d\n", DT, STRIPT);
         
-        /* (3c) */
-        if (first_symbol) {
-            /* 6.4.7 */
-            if (params->SBHUFF) {
-                /* todo */
-            } else {
-                code = jbig2_arith_int_decode(IAFS, as, &DFS);
-            }
-            FIRSTS += DFS;
-            CURS = FIRSTS;
-            first_symbol = FALSE;
+	first_symbol = TRUE;
+	/* (3c) */
+	for (;;) {
+	    /* (3c.i) */
+	    if (first_symbol) {
+		/* 6.4.7 */
+		if (params->SBHUFF) {
+		    /* todo */
+		} else {
+		    code = jbig2_arith_int_decode(IAFS, as, &DFS);
+		}
+		FIRSTS += DFS;
+		CURS = FIRSTS;
+		first_symbol = FALSE;
             fprintf(stderr, "decoded DFS = %d (first symbol) CURS = %d\n", DFS, CURS);
-        } else {
-            /* 6.4.8 */
-            if (params->SBHUFF) {
-                /* todo */
-            } else {
-                code = jbig2_arith_int_decode(IADS, as, &IDS);
-            }
-            if (code) {
-                fprintf(stderr, "Symbol instance S coordinate OOB: End of Strip\n");
-                continue;
-            }
-            CURS += IDS + params->SBDSOFFSET;
-            fprintf(stderr, "decoded IDS = %d, CURS = %d\n", IDS, CURS);
-        }
+	    } else {
+		/* (3c.ii), 6.4.8 */
+		if (params->SBHUFF) {
+		    /* todo */
+		} else {
+		    code = jbig2_arith_int_decode(IADS, as, &IDS);
+		}
+		if (code) {
+		    fprintf(stderr, "Symbol instance S coordinate OOB: End of Strip\n");
+		    break;
+		}
+		CURS += IDS + params->SBDSOFFSET;
+		fprintf(stderr, "decoded IDS = %d, CURS = %d\n", IDS, CURS);
+	    }
 
-        /* 6.4.9 */
-        if (params->SBSTRIPS == 1) {
-            CURT = 0;
-        } else if (params->SBHUFF) {
-            /* todo */
-        } else {
-            code = jbig2_arith_int_decode(IAIT, as, &CURT);
-        }
-        T = STRIPT + CURT;
-        fprintf(stderr, "decoded CURT = %d, STRIPT = %d, T = %d\n", CURT, STRIPT, T);
-        
-        /* (3b.iv) / 6.4.10 decode the symbol id */
-        if (params->SBHUFF) {
-            /* todo */
-        } else {
-            code = jbig2_arith_int_decode(IAID, as, &ID);
-        }
-        if (ID < 0 || ID >= max_id) {
-            return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
-                "symbol id out of range! (%d/%d)", ID, max_id);
-        }
-        fprintf(stderr, "decoded symbol id = %d (code = %d)\n", ID, code);
+	    /* (3c.iii), 6.4.9 */
+	    if (params->SBSTRIPS == 1) {
+		CURT = 0;
+	    } else if (params->SBHUFF) {
+		/* todo */
+	    } else {
+		code = jbig2_arith_int_decode(IAIT, as, &CURT);
+	    }
+	    T = STRIPT + CURT;
+	    fprintf(stderr, "decoded CURT = %d, STRIPT = %d, T = %d\n", CURT, STRIPT, T);
 
-        /* (3b.v) look up the symbol bitmap IB */
-        {
-            int id = ID;
-            
-            index = 0;
-            while (id >= dicts[index]->n_symbols)
-                id -= dicts[index++]->n_symbols;
-            IB = dicts[index]->glyphs[id];
-        }
-        
-        /* (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.vii) */
-        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.ix) */
-        jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
-            "composing glyph id %d: %dx%d @ (%d,%d) symbol %d/%d", 
-            ID, IB->width, IB->height, x, y, NINSTANCES + 1,
-            params->SBNUMINSTANCES);
-        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++;
+	    /* (3b.iv) / 6.4.10 decode the symbol id */
+	    if (params->SBHUFF) {
+		/* todo */
+	    } else {
+		code = jbig2_arith_iaid_decode(IAID, as, &ID);
+	    }
+	    if (ID < 0 || ID >= max_id) {
+		return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+                    "symbol id out of range! (%d/%d)", ID, max_id);
+	    }
+	    fprintf(stderr, "decoded symbol id = %d (code = %d)\n", ID, code);
+
+	    /* (3c.v) look up the symbol bitmap IB */
+	    {
+		int id = ID;
+
+		index = 0;
+		while (id >= dicts[index]->n_symbols)
+		    id -= dicts[index++]->n_symbols;
+		IB = dicts[index]->glyphs[id];
+	    }
+        
+	    /* (3c.vi) */
+	    if ((!params->TRANSPOSED) && (params->REFCORNER > 1)) {
+		CURS += IB->width - 1;
+	    } else if ((params->TRANSPOSED) && !(params->REFCORNER & 1)) {
+		CURS += IB->height - 1;
+	    }
+        
+	    /* (3c.vii) */
+	    S = CURS;
+        
+	    /* (3c.viii) */
+	    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 + 1; y = T; break;
+		case JBIG2_CORNER_BOTTOMLEFT: x = S; y = T - IB->height + 1; break;
+		case JBIG2_CORNER_BOTTOMRIGHT: x = S - IB->width + 1; y = T - IB->height + 1; break;
+		}
+	    } else { /* TRANSPOSED */
+		switch (params->REFCORNER) {
+		case JBIG2_CORNER_TOPLEFT: x = S; y = T; break;
+		case JBIG2_CORNER_TOPRIGHT: x = S - IB->width + 1; y = T; break;
+		case JBIG2_CORNER_BOTTOMLEFT: x = S; y = T - IB->height + 1; break;
+		case JBIG2_CORNER_BOTTOMRIGHT: x = S - IB->width + 1; y = T - IB->height + 1; break;
+		}
+	    }
+        
+	    /* (3c.ix) */
+	    jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+			"composing glyph id %d: %dx%d @ (%d,%d) symbol %d/%d", 
+			ID, IB->width, IB->height, x, y, NINSTANCES + 1,
+			params->SBNUMINSTANCES);
+	    jbig2_image_compose(ctx, image, IB, x, y, params->SBCOMBOP);
+        
+	    /* (3c.x) */
+	    if ((!params->TRANSPOSED) && (params->REFCORNER < 2)) {
+		CURS += IB->width -1 ;
+	    } else if ((params->TRANSPOSED) && (params->REFCORNER & 1)) {
+		CURS += IB->height - 1;
+	    }
+        
+	    /* (3c.xi) */
+	    NINSTANCES++;
+	}
     }
     
     return 0;
@@ -393,4 +402,4 @@
     too_short:
         return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
                     "Segment too short");
-}
\ No newline at end of file
+}