ref: e5bdc75cc8afaf2630953f1784381cc6c9305e36
parent: d954b0f143afbf16da24b2ea0a54d88b39af4129
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Wed Jun 8 10:23:43 EDT 2005
Add support for striped page decode. We still return a full page buffer, so there is no savings in memory footprint. We now decode 042_9.jb2 from the UBC test streams. git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@411 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
Version 0.9 (unreleased)
- * no notable changes
+ * striped page support
+ * successfully decodes ubc test stream 042_9
Version 0.8 (2005 April 6)
--- a/jbig2.h
+++ b/jbig2.h
@@ -1,7 +1,7 @@
/*
jbig2dec
- Copyright (c) 2002-2003 artofcode LLC.
+ Copyright (c) 2002-2005 artofcode LLC.
This software is distributed under license and may not
be copied, modified or distributed except as expressly
@@ -64,6 +64,8 @@
void jbig2_image_release(Jbig2Ctx *ctx, Jbig2Image *image);
void jbig2_image_free(Jbig2Ctx *ctx, Jbig2Image *image);
void jbig2_image_clear(Jbig2Ctx *ctx, Jbig2Image *image, int value);
+Jbig2Image *jbig2_image_resize(Jbig2Ctx *ctx, Jbig2Image *image,
+ int width, int height);
/* errors are returned from the library via a callback. If no callback
is provided (a NULL argument is passed ot jbig2_ctx_new) a default
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -1,7 +1,7 @@
/*
jbig2dec
- Copyright (c) 2002-2004 artofcode LLC.
+ Copyright (c) 2002-2005 artofcode LLC.
This software is provided AS-IS with no warranty,
either express or implied.
@@ -617,9 +617,8 @@
jbig2_free(ctx->allocator, GB_stats);
}
-
- jbig2_image_compose(ctx, ctx->pages[ctx->current_page].image, image,
- rsi.x, rsi.y, JBIG2_COMPOSE_OR);
+ jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page],
+ image, rsi.x, rsi.y, JBIG2_COMPOSE_OR);
jbig2_image_release(ctx, image);
return code;
--- a/jbig2_image.c
+++ b/jbig2_image.c
@@ -81,6 +81,33 @@
jbig2_free(ctx->allocator, image);
}
+/* resize a Jbig2Image */
+Jbig2Image *jbig2_image_resize(Jbig2Ctx *ctx, Jbig2Image *image,
+ int width, int height)
+{
+ if (width == image->width) {
+ /* use the same stride, just change the length */
+ image->data = jbig2_realloc(ctx->allocator,
+ image->data, image->stride*height);
+ if (image->data == NULL) {
+ return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+ "could not resize image buffer!");
+ }
+ if (height > image->height) {
+ memset(image->data + image->height*image->stride,
+ 0, (height - image->height)*image->stride);
+ }
+ image->height = height;
+
+ } else {
+ /* we must allocate a new image buffer and copy */
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
+ "jbig2_image_resize called with a different width (NYI)");
+ }
+
+ return 0;
+}
+
/* composite one jbig2_image onto another
slow but general version */
int jbig2_image_compose_unopt(Jbig2Ctx *ctx,
--- a/jbig2_page.c
+++ b/jbig2_page.c
@@ -1,7 +1,7 @@
/*
jbig2dec
- Copyright (c) 2001-2002 artofcode LLC.
+ Copyright (c) 2001-2005 artofcode LLC.
This software is distributed under license and may not
be copied, modified or distributed except as expressly
@@ -132,6 +132,7 @@
"height is unspecified but page is not markes as striped");
page->striped = TRUE;
}
+ page->end_row = 0;
if (segment->data_length > 19) {
jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
@@ -164,11 +165,37 @@
}
/**
+ * jbig2_parse_end_of_stripe: parse an end of stripe segment
+ **/
+int
+jbig2_parse_end_of_stripe(Jbig2Ctx *ctx, Jbig2Segment *segment, const uint8_t *segment_data)
+{
+ Jbig2Page page = ctx->pages[ctx->current_page];
+ int end_row;
+
+ end_row = jbig2_get_int32(segment_data);
+ if (end_row < page.end_row) {
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+ "end of stripe segment with non-positive end row advance"
+ "(new end row %d vs current end row %d)",
+ end_row, page.end_row);
+ } else {
+ jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,
+ "end of stripe: advancing end row to %d", end_row);
+ }
+
+ page.end_row = end_row;
+
+ return 0;
+}
+
+/**
* jbig2_complete_page: complete a page image
*
* called upon seeing an 'end of page' segment, this routine
- * marks a page as completed. final compositing and output
- * of the page image will also happen from here (NYI)
+ * marks a page as completed so it can be returned.
+ * compositing will have already happened in the previous
+ * segment handlers.
**/
int
jbig2_complete_page (Jbig2Ctx *ctx)
@@ -200,6 +227,35 @@
#ifdef OUTPUT_PBM
jbig2_image_write_pbm(ctx->pages[ctx->current_page].image, stdout);
#endif
+
+ return 0;
+}
+
+/**
+ * jbig2_add_page_result: composite a decoding result onto a page
+ *
+ * this is called to add the results of segment decode (when it
+ * is an image) to a page image buffer
+ **/
+int
+jbig2_page_add_result(Jbig2Ctx *ctx, Jbig2Page *page, Jbig2Image *image,
+ int x, int y, Jbig2ComposeOp op)
+{
+ /* grow the page to accomodate a new stripe if necessary */
+ if (page->striped) {
+ int old_height = page->image->height;
+ int new_height = y + image->height + page->end_row;
+ if (page->image->height < new_height) {
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
+ "growing page buffer to %d rows "
+ "to accomodate new stripe", new_height);
+ jbig2_image_resize(ctx, page->image,
+ page->image->width, new_height);
+ }
+ }
+
+ jbig2_image_compose(ctx, page->image, image,
+ x, y + page->end_row, JBIG2_COMPOSE_OR);
return 0;
}
--- a/jbig2_priv.h
+++ b/jbig2_priv.h
@@ -115,6 +115,7 @@
y_resolution; /* in pixels per meter */
uint16_t stripe_size;
bool striped;
+ int end_row;
uint8_t flags;
Jbig2Image *image;
};
@@ -131,6 +132,7 @@
} Jbig2ComposeOp;
int jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, int x, int y, Jbig2ComposeOp op);
+int jbig2_page_add_result(Jbig2Ctx *ctx, Jbig2Page *page, Jbig2Image *src, int x, int y, Jbig2ComposeOp op);
/* region segment info */
--- a/jbig2_refinement.c
+++ b/jbig2_refinement.c
@@ -435,7 +435,7 @@
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"composing %dx%d decoded refinement region onto page at (%d, %d)",
rsi.width, rsi.height, rsi.x, rsi.y);
- jbig2_image_compose(ctx, ctx->pages[ctx->current_page].image,
+ jbig2_page_add_result(ctx, &ctx->pages[ctx->current_page],
image, rsi.x, rsi.y, JBIG2_COMPOSE_OR);
jbig2_image_release(ctx, image);
}
--- a/jbig2_segment.c
+++ b/jbig2_segment.c
@@ -264,8 +264,7 @@
case 49:
return jbig2_parse_end_of_page(ctx, segment, segment_data);
case 50:
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
- "unhandled segment type 'end of stripe'");
+ return jbig2_parse_end_of_stripe(ctx, segment, segment_data);
case 51:
ctx->state = JBIG2_FILE_EOF;
return jbig2_error(ctx, JBIG2_SEVERITY_INFO, segment->number,