ref: 9cd558cd34c857cb3fc15167a754d1619ecc57d3
parent: fa37e9a7b8c933da66c2850a22c10559f38c68bb
author: raph <raph@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Thu May 31 02:23:32 EDT 2001
Fixed API so that context is now an argument to the arithmetic decode procedure. Context is also now packed into a byte, and context changes are done with a single xor. git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@18 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/jbig2_arith.c
+++ b/jbig2_arith.c
@@ -4,11 +4,13 @@
#include "jbig2.h"
#include "jbig2_arith.h"
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
struct _Jbig2ArithState {
uint32 C;
int A;
- int I_CX;
- int MPS_CX;
int CT;
@@ -46,7 +48,9 @@
B1 = (as->next_word >> 24) & 0xFF;
if (B1 > 0x8F)
{
+#ifdef DEBUG
printf ("read %02x (aa)\n", B);
+#endif
#ifndef SOFTWARE_CONVENTION
as->C += 0xFF00;
#endif
@@ -56,7 +60,12 @@
}
else
{
+#ifdef DEBUG
printf ("read %02x (a)\n", B);
+#endif
+ /* Note: the spec calls for adding (or subtracting) B <<
+ 9 here. However, to be consistent with the sample run
+ in Annex H.2, we use the B << 8 instead. */
#ifdef SOFTWARE_CONVENTION
as->C += 0xFE00 - (B << 8);
#else
@@ -71,7 +80,9 @@
B1 = (as->next_word >> 16) & 0xFF;
if (B1 > 0x8F)
{
+#ifdef DEBUG
printf ("read %02x (ba)\n", B);
+#endif
#ifndef SOFTWARE_CONVENTION
as->C += 0xFF00;
#endif
@@ -81,7 +92,12 @@
{
as->next_word_bytes--;
as->next_word <<= 8;
+#ifdef DEBUG
printf ("read %02x (b)\n", B);
+#endif
+ /* Note: the spec calls for adding (or subtracting) B <<
+ 9 here. However, to be consistent with the sample run
+ in Annex H.2, we use the B << 8 instead. */
#ifdef SOFTWARE_CONVENTION
as->C += 0xFE00 - (B << 8);
#else
@@ -93,7 +109,9 @@
}
else
{
+#ifdef DEBUG
printf ("read %02x\n", B);
+#endif
#ifdef SOFTWARE_CONVENTION
as->C += 0xFF00 - (B << 8);
#else
@@ -109,10 +127,10 @@
#include <stdio.h>
static void
-jbig2_arith_trace (Jbig2ArithState *as)
+jbig2_arith_trace (Jbig2ArithState *as, Jbig2ArithCx cx)
{
- printf ("I = %2d, A = %04x, CT = %2d, C = %08x\n",
- as->I_CX, as->A, as->CT, as->C);
+ printf ("I = %2d, MPS = %d, A = %04x, CT = %2d, C = %08x\n",
+ cx & 0x7f, cx >> 7, as->A, as->CT, as->C);
}
#endif
@@ -141,70 +159,64 @@
result->CT -= 7;
result->A = 0x8000;
- /* note: these are merely defaults; it may be necessary to provide
- additional arguments to initialize these to non-default values. */
- result->I_CX = 0;
- result->MPS_CX = 0;
-
return result;
};
/* could put bit fields in to minimize memory usage */
typedef struct {
- int Qe;
- int NMPS;
- int NLPS;
- bool SWITCH;
+ unsigned short Qe;
+ byte mps_xor; /* mps_xor = index ^ NMPS */
+ byte lps_xor; /* lps_xor = index ^ NLPS ^ (SWITCH << 7) */
} Jbig2ArithQe;
const Jbig2ArithQe jbig2_arith_Qe[] = {
- { 0x5601, 1, 1, 1 },
- { 0x3401, 2, 6, 0 },
- { 0x1801, 3, 9, 0 },
- { 0x0AC1, 4, 12, 0 },
- { 0x0521, 5, 29, 0 },
- { 0x0221, 38, 33, 0 },
- { 0x5601, 7, 6, 1 },
- { 0x5401, 8, 14, 0 },
- { 0x4801, 9, 14, 0 },
- { 0x3801, 10, 14, 0 },
- { 0x3001, 11, 17, 0 },
- { 0x2401, 12, 18, 0 },
- { 0x1C01, 13, 20, 0 },
- { 0x1601, 29, 21, 0 },
- { 0x5601, 15, 14, 1 },
- { 0x5401, 16, 14, 0 },
- { 0x5101, 17, 15, 0 },
- { 0x4801, 18, 16, 0 },
- { 0x3801, 19, 17, 0 },
- { 0x3401, 20, 18, 0 },
- { 0x3001, 21, 19, 0 },
- { 0x2801, 22, 19, 0 },
- { 0x2401, 23, 20, 0 },
- { 0x2201, 24, 21, 0 },
- { 0x1C01, 25, 22, 0 },
- { 0x1801, 26, 23, 0 },
- { 0x1601, 27, 24, 0 },
- { 0x1401, 28, 25, 0 },
- { 0x1201, 29, 26, 0 },
- { 0x1101, 30, 27, 0 },
- { 0x0AC1, 31, 28, 0 },
- { 0x09C1, 32, 29, 0 },
- { 0x08A1, 33, 30, 0 },
- { 0x0521, 34, 31, 0 },
- { 0x0441, 35, 32, 0 },
- { 0x02A1, 36, 33, 0 },
- { 0x0221, 37, 34, 0 },
- { 0x0141, 38, 35, 0 },
- { 0x0111, 39, 36, 0 },
- { 0x0085, 40, 37, 0 },
- { 0x0049, 41, 38, 0 },
- { 0x0025, 42, 39, 0 },
- { 0x0015, 43, 40, 0 },
- { 0x0009, 44, 41, 0 },
- { 0x0005, 45, 42, 0 },
- { 0x0001, 45, 43, 0 },
- { 0x5601, 46, 46, 0 }
+ { 0x5601, 1 ^ 0, 1 ^ 0 ^ 0x80 },
+ { 0x3401, 2 ^ 1, 6 ^ 1 },
+ { 0x1801, 3 ^ 2, 9 ^ 2 },
+ { 0x0AC1, 4 ^ 3, 12 ^ 3 },
+ { 0x0521, 5 ^ 4, 29 ^ 4 },
+ { 0x0221, 38 ^ 5, 33 ^ 5 },
+ { 0x5601, 7 ^ 6, 6 ^ 6 ^ 0x80 },
+ { 0x5401, 8 ^ 7, 14 ^ 7 },
+ { 0x4801, 9 ^ 8, 14 ^ 8 },
+ { 0x3801, 10 ^ 9, 14 ^ 9 },
+ { 0x3001, 11 ^ 10, 17 ^ 10 },
+ { 0x2401, 12 ^ 11, 18 ^ 11 },
+ { 0x1C01, 13 ^ 12, 20 ^ 12 },
+ { 0x1601, 29 ^ 13, 21 ^ 13 },
+ { 0x5601, 15 ^ 14, 14 ^ 14 ^ 0x80 },
+ { 0x5401, 16 ^ 15, 14 ^ 15 },
+ { 0x5101, 17 ^ 16, 15 ^ 16 },
+ { 0x4801, 18 ^ 17, 16 ^ 17 },
+ { 0x3801, 19 ^ 18, 17 ^ 18 },
+ { 0x3401, 20 ^ 19, 18 ^ 19 },
+ { 0x3001, 21 ^ 20, 19 ^ 20 },
+ { 0x2801, 22 ^ 21, 19 ^ 21 },
+ { 0x2401, 23 ^ 22, 20 ^ 22 },
+ { 0x2201, 24 ^ 23, 21 ^ 23 },
+ { 0x1C01, 25 ^ 24, 22 ^ 24 },
+ { 0x1801, 26 ^ 25, 23 ^ 25 },
+ { 0x1601, 27 ^ 26, 24 ^ 26 },
+ { 0x1401, 28 ^ 27, 25 ^ 27 },
+ { 0x1201, 29 ^ 28, 26 ^ 28 },
+ { 0x1101, 30 ^ 29, 27 ^ 29 },
+ { 0x0AC1, 31 ^ 30, 28 ^ 30 },
+ { 0x09C1, 32 ^ 31, 29 ^ 31 },
+ { 0x08A1, 33 ^ 32, 30 ^ 32 },
+ { 0x0521, 34 ^ 33, 31 ^ 33 },
+ { 0x0441, 35 ^ 34, 32 ^ 34 },
+ { 0x02A1, 36 ^ 35, 33 ^ 35 },
+ { 0x0221, 37 ^ 36, 34 ^ 36 },
+ { 0x0141, 38 ^ 37, 35 ^ 37 },
+ { 0x0111, 39 ^ 38, 36 ^ 38 },
+ { 0x0085, 40 ^ 39, 37 ^ 39 },
+ { 0x0049, 41 ^ 40, 38 ^ 40 },
+ { 0x0025, 42 ^ 41, 39 ^ 41 },
+ { 0x0015, 43 ^ 42, 40 ^ 42 },
+ { 0x0009, 44 ^ 43, 41 ^ 43 },
+ { 0x0005, 45 ^ 44, 42 ^ 44 },
+ { 0x0001, 45 ^ 45, 43 ^ 45 },
+ { 0x5601, 46 ^ 46, 46 ^ 46 }
};
static void
@@ -223,9 +235,10 @@
}
bool
-jbig2_arith_decode (Jbig2ArithState *as)
+jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx)
{
- const Jbig2ArithQe *pqe = &jbig2_arith_Qe[as->I_CX];
+ Jbig2ArithCx cx = *pcx;
+ const Jbig2ArithQe *pqe = &jbig2_arith_Qe[cx & 0x7f];
bool D;
/* Figure F.2 */
@@ -246,20 +259,19 @@
/* MPS_EXCHANGE, Figure E.16 */
if (as->A < pqe->Qe)
{
- D = 1 - as->MPS_CX;
- as->MPS_CX ^= pqe->SWITCH;
- as->I_CX = pqe->NLPS;
+ D = 1 - (cx >> 7);
+ *pcx ^= pqe->lps_xor;
}
else
{
- D = as->MPS_CX;
- as->I_CX = pqe->NMPS;
+ D = cx >> 7;
+ *pcx ^= pqe->mps_xor;
}
jbig2_arith_renormd (as);
return D;
}
else
- return as->MPS_CX;
+ return cx >> 7;
}
else
{
@@ -270,15 +282,14 @@
if (as->A < pqe->Qe)
{
as->A = pqe->Qe;
- D = as->MPS_CX;
- as->I_CX = pqe->NMPS;
+ D = cx >> 7;
+ *pcx ^= pqe->mps_xor;
}
else
{
as->A = pqe->Qe;
- D = 1 - as->MPS_CX;
- as->MPS_CX ^= pqe->SWITCH;
- as->I_CX = pqe->NLPS;
+ D = 1 - (cx >> 7);
+ *pcx ^= pqe->lps_xor;
}
jbig2_arith_renormd (as);
return D;
@@ -309,18 +320,19 @@
Jbig2WordStream ws;
Jbig2ArithState *as;
int i;
+ Jbig2ArithCx cx = 0;
ws.get_next_word = test_get_word;
as = jbig2_arith_new (&ws);
- jbig2_arith_trace (as);
+ jbig2_arith_trace (as, cx);
for (i = 0; i < 256; i++)
{
bool D;
- D = jbig2_arith_decode (as);
+ D = jbig2_arith_decode (as, &cx);
printf ("%3d: D = %d, ", i, D);
- jbig2_arith_trace (as);
+ jbig2_arith_trace (as, cx);
}
return 0;
--- a/jbig2_arith.h
+++ b/jbig2_arith.h
@@ -1,4 +1,12 @@
typedef struct _Jbig2ArithState Jbig2ArithState;
+/* An arithmetic coding context is stored as a single byte, with the
+ index in the low order 7 bits (actually only 6 are used), and the
+ MPS in the top bit. */
+typedef unsigned char Jbig2ArithCx;
+
Jbig2ArithState *
jbig2_arith_new (Jbig2WordStream *ws);
+
+bool
+jbig2_arith_decode (Jbig2ArithState *as, Jbig2ArithCx *pcx);
--- a/makefile
+++ b/makefile
@@ -1,6 +1,6 @@
CFLAGS=-Wall -g
-all: jbig2
+all: jbig2 test_arith test_huffman
jbig2: jbig2.o jbig2_huffman.o jbig2_arith.o