shithub: jbig2

Download patch

ref: a6820e140bc4b306fb7852ae4994bf6d38f2a906
parent: 55a01f747fb2b992f7b777f1a2d7ee8cac1e13af
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Wed Jul 3 15:43:21 EDT 2002

As per raph's suggestion, switch to byte-wise addressing for the image data.
It solves some endianness problems, and saves a significant amount of memory
since page and pattern dictionaries contain many small (< 32 pixels wide)
images.


git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@101 ded80894-8fb9-0310-811b-c03f3676ab4d

--- a/jbig2.h
+++ b/jbig2.h
@@ -8,7 +8,7 @@
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
         
-    $Id: jbig2.h,v 1.10 2002/07/03 00:10:07 giles Exp $
+    $Id: jbig2.h,v 1.11 2002/07/03 19:43:21 giles Exp $
 */
 
 #ifdef __cplusplus
@@ -42,7 +42,7 @@
 
 /*
    this is the general image structure used by the jbig2dec library
-   images are 1 bpp, packed into word-aligned rows. stride gives
+   images are 1 bpp, packed into rows a byte at a time. stride gives
    the byte offset to the next row, while width and height define
    the size of the image area in pixels.
 */
@@ -49,7 +49,7 @@
 
 struct _Jbig2Image {
         int             width, height, stride;
-        uint32_t        *data;
+        uint8_t        *data;
 };
 
 Jbig2Image*     jbig2_image_new(Jbig2Ctx *ctx, int width, int height);
--- a/jbig2_image.c
+++ b/jbig2_image.c
@@ -8,7 +8,7 @@
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
 
-    $Id: jbig2_image.c,v 1.11 2002/07/03 14:56:15 giles Exp $
+    $Id: jbig2_image.c,v 1.12 2002/07/03 19:43:21 giles Exp $
 */
 
 #include <stdio.h>
@@ -33,8 +33,8 @@
 		return NULL;
 	}
 	
-	stride = (((width - 1) >> 5) + 1) << 2;	/* generate a word-aligned stride */
-	image->data = (uint32_t *)jbig2_alloc(ctx->allocator, stride*height);
+	stride = ((width - 1) >> 3) + 1; /* generate a byte-aligned stride */
+	image->data = (uint8_t *)jbig2_alloc(ctx->allocator, stride*height);
 	if (image->data == NULL) {
                 jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
                     "could not allocate image data buffer! [%d bytes]\n", stride*height);
@@ -62,12 +62,12 @@
 			int x, int y, Jbig2ComposeOp op)
 {
     int w, h;
-    int src_stride, dst_stride;
-    int leftword, rightword;
+    int leftbyte, rightbyte;
     int leftbits, rightbits;
-    int row, word, shift, i;
-    uint32_t *s, *d;
-    uint32_t mask, highmask;
+    int i, j;
+    uint8_t *s, *ss;
+    uint8_t *d, *dd;
+    uint8_t mask, highmask;
     
     if (op != JBIG2_COMPOSE_OR) {
         jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
@@ -75,6 +75,7 @@
     }
 
     /* clip */
+    // FIXME: this isn't sufficient
     w = src->width;
     h = src->height;
     if (x < 0) { w += x; x = 0; }
@@ -81,9 +82,10 @@
     if (y < 0) { h += y; y = 0; } 
     w = (x + w < dst->width) ? w : dst->width - x;
     h = (y + h < dst->height) ? h : dst->height - y;
-    
+#ifdef DEBUG    
     fprintf(stderr, "composting %dx%d at (%d, %d) afer clipping\n",
         w, h, x, y);
+#endif
     
     /* special case complete/strip replacement */
     if ((x == 0) && (w == src->width)) {
@@ -91,46 +93,34 @@
         return 0;
     }
 
-    /* general case */
-    leftword = x >> 5;
-    leftbits = x & 31;
-    rightword = (x + w) >> 5;
-    rightbits = (x + w) & 31;
-    shift = 0;
-    while (leftbits >= 1 << shift) shift++;
-    mask = 0;
-    if (leftbits) for (i = 0; i < leftbits; i++)
-        mask = mask << 1 | 1;
-    highmask = 1;    
-    if (rightbits) for (i = 0; i < rightbits; i++)
-        highmask = highmask << 1 | 1;
-    
-    /* word strides */
-    src_stride = src->stride >> 2;
-    dst_stride = dst->stride >> 2;
-    fprintf(stderr, "leftword = %d leftbits = %d rightword = %d rightbits=%d shift=%d\n",
-        leftword, leftbits, rightword, rightbits, shift);
-    fprintf(stderr, "mask = 0x%08x highmask = 0x%08x\n", mask, highmask); 
-    
-    if (leftword == rightword) {
-        for (row = 0; row < h; row++) {
-            s = src->data + row*src_stride;
-            d = dst->data + (y + row)*dst_stride + leftword;
+    /* general OR case */
+    leftbyte = x >> 3;
+    leftbits = x & 7;
+    rightbyte = (x + w) >> 3;
+    rightbits = (x + w) & 7;
+    fprintf(stderr, "left byte:bits %d:%d right byte:bits %d:%d\n",
+        leftbyte, leftbits, rightbyte, rightbits);
+
+    s = ss = src->data;
+    d = dd = dst->data + y*dst->stride + leftbyte;    
+    if (leftbyte == rightbyte) {
+        mask = (1 << (w & 7)) - 1;
+        for (j = 0; j < h; j++) {
             *d |= (*s & mask) << leftbits;
+            d += dst->stride;
+            s += src->stride;
         }
     } else {
-        mask = 0;
-        for (i = 0; i < 32 - leftbits; i++)
-            mask = mask << 1 | 1;
-        for (row = 0; row < h; row++) {
-            s = src->data + row*src_stride;
-            d = dst->data + (y + row)*dst_stride + leftword;
+        mask = 1 << (8 - leftbits) - 1;
+        for (j = 0; j < h; j++) {
             *d++ |= (*s & mask) << leftbits;
-            for(word = leftword; word < rightword; word++) {
-                *d |= (*s++ & ~mask) >> (32 - leftbits);
+            for(i = leftbyte; i < rightbyte; i++) {
+                *d |= (*s++ & ~mask) >> leftbits;
                 *d++ |= (*s & mask) << leftbits;
             }
-            *d |= (*++s & highmask) << (32 - rightbits);
+            *d |= (*++s & highmask) << (8 - rightbits);
+            d = (dd += dst->stride);
+            s = (ss += src->stride);
         }
     }
             
--- a/jbig2_image_pbm.c
+++ b/jbig2_image_pbm.c
@@ -8,7 +8,7 @@
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
 
-    $Id: jbig2_image_pbm.c,v 1.5 2002/06/21 19:10:02 giles Exp $
+    $Id: jbig2_image_pbm.c,v 1.6 2002/07/03 19:43:21 giles Exp $
 */
 
 #include <stdio.h>
@@ -38,24 +38,16 @@
 
 int jbig2_image_write_pbm(Jbig2Image *image, FILE *out)
 {
-        int i, short_stride, extra_bits;
+        int i;
         char *p = (char *)image->data;
         
         // pbm header
         fprintf(out, "P4\n%d %d\n", image->width, image->height);
         
-        // pbm format pads only to the next byte boundary
-        // so we figure our output byte stride and fixup
-        short_stride = image->width >> 3;
-        extra_bits = image->width - (short_stride << 3);
-        fprintf(stderr, "creating %dx%d pbm image, short_stride %d, extra_bits %d\n",
-            image->width, image->height, short_stride, extra_bits);
-        // write out each row
-        for(i = 0; i < image->height; i++) {
-            fwrite(p, sizeof(*p), short_stride, out);
-            if (extra_bits) fwrite(p + short_stride, sizeof(*p), 1, out);
-            p += image->stride;
-        }
+        // pbm format pads to a byte boundary, so we can
+        // just write out the whole data buffer
+        // NB: this assumes minimal stride for the width
+        fwrite(image->data, 1, image->height*image->stride, out);
         
         /* success */
 	return 0;
@@ -127,23 +119,17 @@
     // allocate image structure
     image = jbig2_image_new(ctx, dim[0], dim[1]);
     if (image == NULL) {
-        fprintf(stderr, "could not allocate %dx%d image structure\n", dim[0], dim[1]);
+        fprintf(stderr, "could not allocate %dx%d image for pbm file\n", dim[0], dim[1]);
         return NULL;
     }
-    // the pbm data is byte-aligned, and our image struct is word-aligned,
-    // so we have to index each line separately
-    pbm_stride = (dim[0] + 1) >> 3;
-    data = (char *)image->data;
-    for (i = 0; i < dim[1]; i++) {
-        fread(data, sizeof(*data), pbm_stride, in);
-        if (feof(in)) {
-            fprintf(stderr, "unexpected end of pbm file.\n");
-            jbig2_image_free(ctx, image);
-            return NULL;
-        }
-        data += image->stride;
-    }
-    
+    // the pbm data is byte-aligned, so we can
+    // do a simple block read
+    fread(image->data, 1, image->height*image->stride, in);
+    if (feof(in)) {
+        fprintf(stderr, "unexpected end of pbm file.\n");
+        jbig2_image_free(ctx, image);
+        return NULL;
+    }    
     // success
     return image;
 }