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);