shithub: jbig2

Download patch

ref: 9607332ea3d0d609324d5e6c02fd00700456ca06
parent: d50d2bbd939654edb7275c19843de02ae0d37e4d
author: Sebastian Rasmussen <sebras@gmail.com>
date: Fri Jul 13 08:41:14 EDT 2018

jbig2dec: Handle EOFB whether it is required or not.

Chapter 6.2.6 in the JBIG2 specification states that MMR-encoded
data _may_ skip the EOFB code when the data length is known in
advance. If the data length is _not_ known in advance EOFB is
required. Since an encoder may choose to use or skip EOFB when
the data length is known, decoders must always be prepared to
handle EOFB regardless of whether the data length is known or
unknown.

After encountering EOFB jbig2dec now stops consuming MMR-coded
data regardless of whether the data lenght is known in advance
or not. The remainder of the decoded image region is filled with
white.

--- a/jbig2_mmr.c
+++ b/jbig2_mmr.c
@@ -833,7 +833,7 @@
 }
 
 static int
-jbig2_decode_mmr_line(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const byte *ref, byte *dst)
+jbig2_decode_mmr_line(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const byte *ref, byte *dst, int *eofb)
 {
     uint32_t a0 = MINUS1;
     uint32_t a1, a2, b1, b2;
@@ -1012,6 +1012,13 @@
             c = !c;
         }
 
+        else if ((word >> (32 - 24)) == 0x1001) {
+            /* printf ("EOFB\n"); */
+            jbig2_decode_mmr_consume(mmr, 24);
+            *eofb = 1;
+            break;
+        }
+
         else
             break;
     }
@@ -1028,12 +1035,13 @@
     byte *ref = NULL;
     uint32_t y;
     int code = 0;
+    int eofb = 0;
 
     jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
 
-    for (y = 0; y < image->height; y++) {
+    for (y = 0; !eofb && y < image->height; y++) {
         memset(dst, 0, rowstride);
-        code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst);
+        code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst, &eofb);
         if (code < 0)
             return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode mmr line");
         ref = dst;
@@ -1040,6 +1048,10 @@
         dst += rowstride;
     }
 
+    if (eofb && y < image->height) {
+        memset(dst, 0, rowstride * (image->height - y));
+    }
+
     return code;
 }
 
@@ -1067,12 +1079,13 @@
     uint32_t y;
     int code = 0;
     const uint32_t EOFB = 0x001001;
+    int eofb = 0;
 
     jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
 
-    for (y = 0; y < image->height; y++) {
+    for (y = 0; !eofb && y < image->height; y++) {
         memset(dst, 0, rowstride);
-        code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst);
+        code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst, &eofb);
         if (code < 0)
             return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "failed to decode halftone mmr line");
         ref = dst;
@@ -1079,9 +1092,13 @@
         dst += rowstride;
     }
 
+    if (eofb && y < image->height) {
+        memset(dst, 0, rowstride * (image->height - y));
+    }
+
     /* test for EOFB (see section 6.2.6) */
     if (mmr.word >> 8 == EOFB) {
-        mmr.data_index += 3;
+        jbig2_decode_mmr_consume(&mmr, 24);
     }
 
     *consumed_bytes += mmr.data_index + (mmr.bit_index >> 3) + (mmr.bit_index > 0 ? 1 : 0);