shithub: jbig2

Download patch

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