jbig2dec

Ralph Giles <[email protected]> Tue, 09 Jul 2002 02:38:39 -0700
Newsgroups gmane.comp.printing.ghostscript.jbig2dec.cvs
Message-ID <[email protected]>
Update of /cvsroot/jbig2dec/jbig2dec
In directory usw-pr-cvs1:/tmp/cvs-serv31764

Modified Files:
	jbig2_text.c 
Log Message:
Correct the dictionary-referral logic in the text segment decoder. Previously
we were using the decode order index to lookup the referenced segments(s) but
this breaks if the segment numbers don't begin and 0 and increase one-by-one.
We now search backward looking for a matching segment number. Should replace
this with a binary search once we start seeing bigger files.


Index: jbig2_text.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_text.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- jbig2_text.c	8 Jul 2002 14:54:02 -0000	1.13
+++ jbig2_text.c	9 Jul 2002 09:38:37 -0000	1.14
@@ -67,6 +67,7 @@
     int8_t sbrat[4];
 } Jbig2TextRegionParams;
 
+
 /**
  * jbig2_decode_text_region: decode a text region segment
  *
@@ -277,6 +278,58 @@
     return 0;
 }
 
+/* find a segment by number */
+static Jbig2Segment *
+find_segment(Jbig2Ctx *ctx, uint32_t number)
+{
+    int index, index_max = ctx->segment_index;
+    
+    // FIXME: binary search would be better?
+    for (index = index_max; index >= 0; index--)
+        if (ctx->segments[index]->number == number)
+            return (ctx->segments[index]);
+        
+    /* didn't find a match */
+    return NULL;
+}
+
+/* count the number of dictionary segments referred to by the given segment */
+static int
+count_referred_dicts(Jbig2Ctx *ctx, Jbig2Segment *segment)
+{
+    int index;
+    Jbig2Segment *rsegment;
+    int n_dicts = 0;
+
+    for (index = 0; index < segment->referred_to_segment_count; index++) {
+        rsegment = find_segment(ctx, segment->referred_to_segments[index]);
+        if (rsegment && ((rsegment->flags & 63) == 0))
+            n_dicts++;
+    }
+    
+    return (n_dicts);
+}
+
+/* return an array of pointers to symbol dictionaries referred to by the given segment */
+static Jbig2SymbolDict **
+list_referred_dicts(Jbig2Ctx *ctx, Jbig2Segment *segment)
+{
+    int index;
+    Jbig2Segment *rsegment;
+    Jbig2SymbolDict **dicts;
+    int n_dicts = count_referred_dicts(ctx, segment);
+    int dindex = 0;
+    
+    dicts = jbig2_alloc(ctx->allocator, sizeof(Jbig2SymbolDict *) * n_dicts);
+    for (index = 0; index < segment->referred_to_segment_count; index++) {
+        rsegment = find_segment(ctx, segment->referred_to_segments[index]);
+        if (rsegment && ((rsegment->flags & 63) == 0))
+            dicts[dindex++] = (Jbig2SymbolDict *)rsegment->result;
+    }
+    
+    return (dicts);
+}
+
 /**
  * jbig2_read_text_info: read a text region segment header
  **/
@@ -370,21 +423,13 @@
     }
     
     /* compose the list of symbol dictionaries */
-    n_dicts = 0;
-    for (index = 0; index < segment->referred_to_segment_count; index++) {
-        int sindex = segment->referred_to_segments[index];
-        if ((ctx->segments[sindex]->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 sindex = segment->referred_to_segments[index];
-        int dindex = 0;
-        if ((ctx->segments[sindex]->flags & 63) == 0)
-            dicts[dindex++] = (Jbig2SymbolDict *)ctx->segments[sindex]->result;
+    n_dicts = count_referred_dicts(ctx, segment);
+    if (n_dicts != 0) {
+        dicts = list_referred_dicts(ctx, segment);
+    } else {
+        return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+                "text region refers to no symbol dictionaries!");
     }
-    jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
-        "refers to %d symbol dictionaries", n_dicts);
     
     page_image = ctx->pages[ctx->current_page].image;
     image = jbig2_image_new(ctx, region_info.width, region_info.height);