summaryrefslogtreecommitdiff
path: root/jbig2dec
diff options
context:
space:
mode:
Diffstat (limited to 'jbig2dec')
-rw-r--r--jbig2dec/jbig2_generic.c605
1 files changed, 362 insertions, 243 deletions
diff --git a/jbig2dec/jbig2_generic.c b/jbig2dec/jbig2_generic.c
index fc00f62b0..3f1b41b57 100644
--- a/jbig2dec/jbig2_generic.c
+++ b/jbig2dec/jbig2_generic.c
@@ -356,36 +356,6 @@ jbig2_image_get_pixel_fast(Jbig2Image *image, int x, int y)
return ((image->data[byte] >> bit) & 1);
}
-/* Get a run of up to 9 bits. This reads into the next byte, so the caller
- * must ensure that we are always safe to read at least 9 pixels, even if
- * it only wants less than that. */
-static inline int
-jbig2_image_get_pixels_fast(Jbig2Image *image, int x, int y, int bits)
-{
- const int byte = (x >> 3) + y * image->stride;
- const int bit = 7 - (x & 7);
- int v = ((image->data[byte]<<8) | (image->data[byte+1]))>>(bit+9-bits);
-
- return v & ((1<<bits)-1);
-}
-
-/* set an individual pixel value in an image - no bounds checking */
-static inline void
-jbig2_image_set_pixel_fast(Jbig2Image *image, int x, int y, bool value)
-{
- int scratch, mask;
- int bit, byte;
-
- byte = (x >> 3) + y * image->stride;
- bit = 7 - (x & 7);
- mask = (1 << bit) ^ 0xff;
-
- scratch = image->data[byte] & mask;
- image->data[byte] = scratch | (value << bit);
-}
-
-
-
/* return the appropriate context size for the given template */
int
jbig2_generic_stats_size(Jbig2Ctx *ctx, int template)
@@ -484,36 +454,56 @@ jbig2_decode_generic_template0_unopt(Jbig2Ctx *ctx,
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"adaptive template pixel is out of field");
- /* this version is generic and easy to understand, but very slow */
-
for (y = 0; y < GBH; y++) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x000F; /* First 4 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
+ CONTEXT |= (pd>>8) & 0x03E0; /* Next 5 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[2], y + params->gbat[3]) << 10;
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[4], y + params->gbat[5]) << 11;
+ CONTEXT |= (ppd>>2) & 0x7000; /* Next 3 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6], y + params->gbat[7]) << 15;
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 unoptimized");
+ }
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
+ }
}
- CONTEXT = 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 9;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[2], y + params->gbat[3]) << 10;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[4], y + params->gbat[5]) << 11;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 12;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 2) << 13;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6], y + params->gbat[7]) << 15;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 unoptimized");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
}
return 0;
}
@@ -534,33 +524,53 @@ jbig2_decode_generic_template1_unopt(Jbig2Ctx *ctx,
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"adaptive template pixel is out of field");
- /* this version is generic and easy to understand, but very slow */
-
for (y = 0; y < GBH; y++) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x0007; /* First 3 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 3;
+ CONTEXT |= (pd>>9) & 0x01F0; /* Next 5 pixels */
+ CONTEXT |= (ppd>>4) & 0x1E00; /* Next 4 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template1 unoptimized");
+ }
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
+ }
}
- CONTEXT = 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 2) << 9;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 10;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 2) << 11;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 12;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template1 unoptimized");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
}
return 0;
}
@@ -647,30 +657,53 @@ jbig2_decode_generic_template2_unopt(Jbig2Ctx *ctx,
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"adaptive template pixel is out of field");
- /* this version is generic and easy to understand, but very slow */
-
for (y = 0; y < GBH; y++) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x003; /* First 2 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 2;
+ CONTEXT |= (pd>>11) & 0x078; /* Next 4 pixels */
+ CONTEXT |= (ppd>>7) & 0x380; /* Next 3 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template2 unoptimized");
+ }
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
+ }
}
- CONTEXT = 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 2) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 9;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template2 unoptimized");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
}
return 0;
@@ -817,30 +850,41 @@ jbig2_decode_generic_template3_unopt(Jbig2Ctx *ctx,
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"adaptive template pixel is out of field");
- /* this version is generic and easy to understand, but very slow */
-
for (y = 0; y < GBH; y++) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint32_t pd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x00F; /* First 4 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
+ CONTEXT |= (pd>>9) & 0x3E0; /* Next 5 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template3 unoptimized");
+ }
+ pd = pd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0)
+ pd |= *pline++;
}
- CONTEXT = 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template3 unoptimized");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
}
return 0;
}
@@ -890,53 +934,55 @@ jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx,
params->gbat[4] == 2 && params->gbat[5] == -2 &&
params->gbat[6] == -2 && params->gbat[7] == -2)
{
- right = GBW-9; /* To allow us to use get_pixels */
for (y = 0; y < GBH; y++) {
LTP ^= jbig2_arith_decode(as, &GB_stats[0x9B25], &code);
if (code)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON1");
if (!LTP) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel_fast(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x00F; /* First 4 pixels */
+ CONTEXT |= (pd>>8) & 0x7F0; /* Next 7 pixels */
+ CONTEXT |= (ppd>>2) & 0xF800; /* Final 5 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON2");
}
- if (y >= 2 && x >= 4 && x < right)
- {
- CONTEXT = jbig2_image_get_pixels_fast(image, x - 4, y, 4);
- CONTEXT |= jbig2_image_get_pixels_fast(image, x - 3, y - 1, 7) << 4;
- CONTEXT |= jbig2_image_get_pixels_fast(image, x - 2, y - 2, 5) << 11;
- }
- else
- {
- CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
- if (y >= 1)
- {
- CONTEXT |= jbig2_image_get_pixel(image, x + 3, y - 1) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 9;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 10;
- }
- if (y >= 2)
- {
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 2) << 11;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 12;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 13;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 2) << 15;
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ *d++ = (uint8_t)out_byte;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
}
}
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON2");
- jbig2_image_set_pixel_fast(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
} else {
copy_prev_row(image, y);
}
@@ -966,10 +1012,6 @@ jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx,
left = -gmin;
if ((int)right < gmax)
right = gmax;
- /* We need to guarantee 9 pixels in the right margin to be able
- * to use jbig2_image_get_pixels_fast. */
- if (right < 9)
- right = 9;
right = GBW - right;
/* So 0 <= x < left or right <= x < GBW needs bounds checking. */
@@ -992,51 +1034,65 @@ jbig2_decode_generic_template0_TPGDON(Jbig2Ctx *ctx,
if (code)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON1");
if (!LTP) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel_fast(image, x, y, 0);
- continue;
- }
- if (y >= top && x >= left && x < right)
- {
- CONTEXT = jbig2_image_get_pixels_fast(image, x - 4, y, 4);
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[0], y + params->gbat[1]) << 4;
- CONTEXT |= jbig2_image_get_pixels_fast(image, x - 2, y - 1, 5) << 5;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[2], y + params->gbat[3]) << 10;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[4], y + params->gbat[5]) << 11;
- CONTEXT |= jbig2_image_get_pixels_fast(image, x - 1, y - 2, 3) << 12;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[6], y + params->gbat[7]) << 15;
- }
- else
- {
- CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
- if (y >= 1)
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x000F; /* First 4 pixels */
+ CONTEXT |= (pd>>8) & 0x03E0; /* Skip one, next 5 pixels */
+ CONTEXT |= (ppd>>2) & 0x7000; /* Skip 2, next 3 pixels, skip one */
+ if (y >= top && x >= left && x < right)
{
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 9;
+ CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[0], y + params->gbat[1]) << 4;
+ CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[2], y + params->gbat[3]) << 10;
+ CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[4], y + params->gbat[5]) << 11;
+ CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[6], y + params->gbat[7]) << 15;
}
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[2], y + params->gbat[3]) << 10;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[4], y + params->gbat[5]) << 11;
- if (y >= 2)
+ else
{
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 12;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 13;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14;
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[2], y + params->gbat[3]) << 10;
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[4], y + params->gbat[5]) << 11;
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6], y + params->gbat[7]) << 15;
+ }
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON2");
+ }
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
}
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[6], y + params->gbat[7]) << 15;
}
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON2");
- jbig2_image_set_pixel_fast(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
} else {
copy_prev_row(image, y);
}
@@ -1067,29 +1123,52 @@ jbig2_decode_generic_template1_TPGDON(Jbig2Ctx *ctx,
if (code)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template1 TPGDON1");
if (!LTP) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x0007; /* First 3 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 3;
+ CONTEXT |= (pd>>9) & 0x01F0; /* next 5 pixels */
+ CONTEXT |= (ppd>>4) & 0x1E00; /* next 4 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template1 TPGDON2");
+ }
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
+ }
}
- CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 2) << 9;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 10;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 11;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 12;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template1 TPGDON2");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
} else {
copy_prev_row(image, y);
}
@@ -1120,26 +1199,52 @@ jbig2_decode_generic_template2_TPGDON(Jbig2Ctx *ctx,
if (code)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template2 TPGDON1");
if (!LTP) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint8_t *ppline = &image->data[image->stride * (y-2)];
+ uint32_t pd = 0;
+ uint32_t ppd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ if (y > 1) {
+ ppd = (*ppline++ << 8);
+ if (GBW > 8)
+ ppd |= *ppline++;
+ }
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x003; /* First 2 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 2;
+ CONTEXT |= (pd>>11) & 0x078; /* next 4 pixels */
+ CONTEXT |= (ppd>>7) & 0x380; /* next 3 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template2 TPGDON2");
+ }
+ pd = pd<<1;
+ ppd = ppd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0) {
+ pd |= *pline++;
+ if (y > 1)
+ ppd |= *ppline++;
+ }
}
- CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 1) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 2) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 9;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template2 TPGDON2");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
} else {
copy_prev_row(image, y);
}
@@ -1170,26 +1275,40 @@ jbig2_decode_generic_template3_TPGDON(Jbig2Ctx *ctx,
if (code)
return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template3 TPGDON1");
if (!LTP) {
+ uint32_t out_byte = 0;
+ int out_bits_to_go_in_byte = 8;
+ uint8_t *d = &image->data[image->stride * y];
+ uint8_t *pline = &image->data[image->stride * (y-1)];
+ uint32_t pd = 0;
+ if (y > 0) {
+ pd = (*pline++ << 8);
+ if (GBW > 8)
+ pd |= *pline++;
+ }
for (x = 0; x < GBW; x++) {
if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
- jbig2_image_set_pixel(image, x, y, 0);
- continue;
+ bit = 0;
+ } else {
+ CONTEXT = out_byte & 0x0F; /* First 4 pixels */
+ CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
+ CONTEXT |= (pd>>9) & 0x3E0; /* next 5 pixels */
+ bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+ if (code)
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template3 TPGDON2");
+ }
+ pd = pd<<1;
+ out_byte = (out_byte<<1) | bit;
+ out_bits_to_go_in_byte--;
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
+ if (out_bits_to_go_in_byte == 0) {
+ out_bits_to_go_in_byte = 8;
+ d++;
+ if (x+9 < GBW && y > 0)
+ pd |= *pline++;
}
- CONTEXT = jbig2_image_get_pixel(image, x - 1, y);
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
- CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0], y + params->gbat[1]) << 4;
- CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel(image, x, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
- bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
- if (code)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template3 TPGDON2");
- jbig2_image_set_pixel(image, x, y, bit);
}
+ if (out_bits_to_go_in_byte != 8)
+ *d = (uint8_t)out_byte<<out_bits_to_go_in_byte;
} else {
copy_prev_row(image, y);
}