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