jbig2dec
Ralph Giles <[email protected]> Fri, 21 Jun 2002 12:10:04 -0700
| Newsgroups | gmane.comp.printing.ghostscript.jbig2dec.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/jbig2dec/jbig2dec
In directory usw-pr-cvs1:/tmp/cvs-serv17436
Modified Files:
jbig2.h jbig2_generic.c jbig2_generic.h jbig2_image.c
jbig2_image_pbm.c jbig2_mmr.c jbig2_mmr.h jbig2_page.c
jbig2_priv.h jbig2dec.c
Log Message:
Generic regions decode into Jbig2Image structures, which are then (trivially)
composited with the page buffer as the final step in handling the segment.
We now write the page data out at out.png or out.pbm. Compile with -DOUTPUT_PBM
for the old behavior.
Index: jbig2.h
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- jbig2.h 18 Jun 2002 13:40:29 -0000 1.7
+++ jbig2.h 21 Jun 2002 19:10:02 -0000 1.8
@@ -85,6 +85,8 @@
/* get the next available decoded page image */
Jbig2Image *jbig2_get_page(Jbig2Ctx *ctx);
+/* mark a returned page image as read */
+int jbig2_release_page(Jbig2Ctx *ctx, Jbig2Image *image);
/* segment header routines */
Index: jbig2_generic.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_generic.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- jbig2_generic.c 20 Jun 2002 15:42:47 -0000 1.5
+++ jbig2_generic.c 21 Jun 2002 19:10:02 -0000 1.6
@@ -15,8 +15,6 @@
* Generic region handlers.
**/
-#define OUTPUT_PBM
-
#include <stdint.h>
#include <stddef.h>
#ifdef OUTPUT_PBM
@@ -33,22 +31,23 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
- byte *gbreg,
+ Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
- int GBW = params->GBW;
- int rowstride = (GBW + 7) >> 3;
+ const int GBW = image->width;
+ const int GBH = image->height;
+ const int rowstride = image->stride;
int x, y;
- byte *gbreg_line = gbreg;
+ byte *gbreg_line = (byte *)image->data;
bool LTP = 0;
/* todo: currently we only handle the nominal gbat location */
#ifdef OUTPUT_PBM
- printf("P4\n%d %d\n", GBW, params->GBH);
+ printf("P4\n%d %d\n", GBW, GBH);
#endif
- for (y = 0; y < params->GBH; y++)
+ for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
@@ -101,22 +100,23 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
- byte *gbreg,
+ Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
- int GBW = params->GBW;
- int rowstride = (GBW + 7) >> 3;
+ const int GBW = image->width;
+ const int GBH = image->height;
+ const int rowstride = image->stride;
int x, y;
- byte *gbreg_line = gbreg;
+ byte *gbreg_line = (byte *)image->data;
bool LTP = 0;
/* todo: currently we only handle the nominal gbat location */
#ifdef OUTPUT_PBM
- printf("P4\n%d %d\n", GBW, params->GBH);
+ printf("P4\n%d %d\n", GBW, GBH);
#endif
- for (y = 0; y < params->GBH; y++)
+ for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
@@ -169,22 +169,23 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
- byte *gbreg,
+ Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
- int GBW = params->GBW;
- int rowstride = (GBW + 7) >> 3;
+ const int GBW = image->width;
+ const int GBH = image->height;
+ const int rowstride = image->stride;
int x, y;
- byte *gbreg_line = gbreg;
+ byte *gbreg_line = (byte *)image->data;
bool LTP = 0;
/* todo: currently we only handle the nominal gbat location */
#ifdef OUTPUT_PBM
- printf("P4\n%d %d\n", GBW, params->GBH);
+ printf("P4\n%d %d\n", GBW, GBH);
#endif
- for (y = 0; y < params->GBH; y++)
+ for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
@@ -237,22 +238,23 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
- byte *gbreg,
+ Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
- int GBW = params->GBW;
- int rowstride = (GBW + 7) >> 3;
+ const int GBW = image->width;
+ const int GBH = image->height;
+ const int rowstride = image->stride;
int x, y;
- byte *gbreg_line = gbreg;
+ byte *gbreg_line = (byte *)image->data;
bool LTP = 0;
/* This is a special case for GBATX1 = 3, GBATY1 = -1 */
#ifdef OUTPUT_PBM
- printf("P4\n%d %d\n", GBW, params->GBH);
+ printf("P4\n%d %d\n", GBW, GBH);
#endif
- for (y = 0; y < params->GBH; y++)
+ for (y = 0; y < GBH; y++)
{
uint32_t CONTEXT;
uint32_t line_m1;
@@ -323,23 +325,23 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
- byte *gbreg,
+ Jbig2Image *image,
Jbig2ArithCx *GB_stats)
{
if (!params->MMR && params->GBTEMPLATE == 0)
return jbig2_decode_generic_template0(ctx, seg_number,
- params, as, gbreg, GB_stats);
+ params, as, image, GB_stats);
else if (!params->MMR && params->GBTEMPLATE == 1)
return jbig2_decode_generic_template1(ctx, seg_number,
- params, as, gbreg, GB_stats);
+ params, as, image, GB_stats);
else if (!params->MMR && params->GBTEMPLATE == 2)
{
if (params->gbat[0] == 3 && params->gbat[1] == 255)
return jbig2_decode_generic_template2a(ctx, seg_number,
- params, as, gbreg, GB_stats);
+ params, as, image, GB_stats);
else
return jbig2_decode_generic_template2(ctx, seg_number,
- params, as, gbreg, GB_stats);
+ params, as, image, GB_stats);
}
{
int i;
@@ -363,7 +365,7 @@
int gbat_bytes = 0;
Jbig2GenericRegionParams params;
int code;
- byte *gbreg;
+ Jbig2Image *image;
Jbig2WordStream *ws;
Jbig2ArithState *as;
Jbig2ArithCx *GB_stats = NULL;
@@ -410,14 +412,16 @@
params.GBH = rsi.height;
memcpy (params.gbat, gbat, gbat_bytes);
- gbreg = jbig2_alloc(ctx->allocator, ((rsi.width + 7) >> 3) * rsi.height);
-
-
+ image = jbig2_image_new(ctx, rsi.width, rsi.height);
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, sh->segment_number,
+ "allocated %d x %d image buffer for region decode results",
+ rsi.width, rsi.height);
+
if (params.MMR)
{
code = jbig2_decode_generic_mmr(ctx, sh->segment_number, ¶ms,
segment_data + offset, sh->data_length - offset,
- gbreg);
+ image);
}
else
{
@@ -431,12 +435,14 @@
sh->data_length - offset);
as = jbig2_arith_new(ctx, ws);
code = jbig2_decode_generic_region(ctx, sh->segment_number, ¶ms,
- as, gbreg, GB_stats);
+ as, image, GB_stats);
}
- /* todo: stash gbreg as segment result */
/* todo: free ws, as */
-
+
+ jbig2_image_compose(ctx, ctx->pages[ctx->current_page].image, image, rsi.x, rsi.y);
+ jbig2_image_free(ctx, image);
+
jbig2_free(ctx->allocator, GB_stats);
return code;
Index: jbig2_generic.h
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_generic.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- jbig2_generic.h 19 Feb 2002 07:09:16 -0000 1.3
+++ jbig2_generic.h 21 Jun 2002 19:10:02 -0000 1.4
@@ -29,7 +29,7 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
Jbig2ArithState *as,
- byte *gbreg,
+ Jbig2Image *image,
Jbig2ArithCx *GB_stats);
/* 7.4 */
Index: jbig2_image.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_image.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- jbig2_image.c 17 Jun 2002 16:30:20 -0000 1.5
+++ jbig2_image.c 21 Jun 2002 19:10:02 -0000 1.6
@@ -56,3 +56,18 @@
jbig2_free(ctx->allocator, image->data);
jbig2_free(ctx->allocator, image);
}
+
+/* composite one jbig2_image onto another */
+// FIXME: need to add a drawing mode argument
+int jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, int x, int y)
+{
+ /* special case complete replacement */
+ if ((x == 0) && (y == 0) && (src->width == dst->width) && (src->height == dst->height)) {
+ memcpy(dst->data, src->data, src->height*src->stride);
+ return 0;
+ }
+
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
+ "non-aligned image composition NYI");
+ return 1;
+}
Index: jbig2_image_pbm.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_image_pbm.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- jbig2_image_pbm.c 17 Jun 2002 16:30:20 -0000 1.4
+++ jbig2_image_pbm.c 21 Jun 2002 19:10:02 -0000 1.5
@@ -14,7 +14,6 @@
#include <stdio.h>
#include "jbig2.h"
-#include "jbig2_priv.h"
#include "jbig2_image.h"
/* take an image structure and write it to a file in pbm format */
@@ -25,8 +24,8 @@
int error;
if ((out = fopen(filename, "wb")) == NULL) {
- fprintf(stderr, "unable to open '%s' for writing\n", filename);
- return 1;
+ fprintf(stderr, "unable to open '%s' for writing", filename);
+ return 1;
}
error = jbig2_image_write_pbm(image, out);
@@ -40,7 +39,7 @@
int jbig2_image_write_pbm(Jbig2Image *image, FILE *out)
{
int i, short_stride, extra_bits;
- byte *p = (byte *)image->data;
+ char *p = (char *)image->data;
// pbm header
fprintf(out, "P4\n%d %d\n", image->width, image->height);
@@ -53,8 +52,8 @@
image->width, image->height, short_stride, extra_bits);
// write out each row
for(i = 0; i < image->height; i++) {
- fwrite(p, sizeof(byte), short_stride, out);
- if (extra_bits) fwrite(p + short_stride, sizeof(byte), 1, out);
+ fwrite(p, sizeof(*p), short_stride, out);
+ if (extra_bits) fwrite(p + short_stride, sizeof(*p), 1, out);
p += image->stride;
}
@@ -86,7 +85,7 @@
int done;
Jbig2Image *image;
char c,buf[32];
- byte *data;
+ char *data;
// look for 'P4' magic
while ((c = fgetc(in)) != 'P') {
@@ -134,9 +133,9 @@
// 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 = (byte *)image->data;
+ data = (char *)image->data;
for (i = 0; i < dim[1]; i++) {
- fread(data, sizeof(byte), pbm_stride, in);
+ fread(data, sizeof(*data), pbm_stride, in);
if (feof(in)) {
fprintf(stderr, "unexpected end of pbm file.\n");
jbig2_image_free(ctx, image);
Index: jbig2_mmr.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_mmr.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- jbig2_mmr.c 8 May 2002 03:03:17 -0000 1.2
+++ jbig2_mmr.c 21 Jun 2002 19:10:02 -0000 1.3
@@ -795,16 +795,16 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
const byte *data, size_t size,
- byte *gbreg)
+ Jbig2Image *image)
{
Jbig2MmrCtx mmr;
- int rowstride = (params->GBW + 7) >> 3;
- const byte *gbreg_line = gbreg;
+ const int rowstride = image->stride;
+ const byte *gbreg_line = (const byte *)image->data;
int y;
- jbig2_decode_mmr_init(&mmr, params->GBW, params->GBH, data, size);
+ jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
- for (y = 0; y < params->GBH; y++)
+ for (y = 0; y < image->height; y++)
{
jbig2_decode_mmr_line(&mmr, gbreg_line, NULL);
gbreg_line += rowstride;
Index: jbig2_mmr.h
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_mmr.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- jbig2_mmr.h 25 Apr 2002 23:24:08 -0000 1.1
+++ jbig2_mmr.h 21 Jun 2002 19:10:02 -0000 1.2
@@ -3,5 +3,5 @@
int32_t seg_number,
const Jbig2GenericRegionParams *params,
const byte *data, size_t size,
- byte *gbreg);
+ Jbig2Image *image);
Index: jbig2_page.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_page.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- jbig2_page.c 20 Jun 2002 15:40:36 -0000 1.4
+++ jbig2_page.c 21 Jun 2002 19:10:02 -0000 1.5
@@ -17,6 +17,10 @@
#include "jbig2.h"
#include "jbig2_priv.h"
+#ifdef OUTPUT_PBM
+#include "jbig2_image.h"
+#endif
+
/* dump the page struct info */
static void
dump_page_info(Jbig2Ctx *ctx, Jbig2SegmentHeader *sh, Jbig2Page *page)
@@ -170,7 +174,63 @@
jbig2_error(ctx, JBIG2_SEVERITY_INFO, sh->segment_number,
"end of page %d", page_number);
- // FIXME: write out the page image
-
+#ifdef OUTPUT_PBM
+ jbig2_image_write_pbm(ctx->pages[ctx->current_page].image, stdout);
+#endif
+
return 0;
+}
+
+/**
+ * jbig2_get_page: return the next available page image buffer
+ *
+ * the client can call this at any time to check if any pages
+ * have been decoded. If so, it returns the first available
+ * one. The client should then call jbig2_release_page() when
+ * it no longer needs to refer to the image buffer.
+ *
+ * since this is a public routine for the library clients, we
+ * return an image structure pointer, even though the function
+ * name refers to a page; the page structure is private.
+ **/
+Jbig2Image *jbig2_get_page(Jbig2Ctx *ctx)
+{
+ int index;
+ Jbig2Image *image;
+
+ /* search for a completed page */
+ for (index=0; index < ctx->max_page_index; index++) {
+ if (ctx->pages[index].state == JBIG2_PAGE_COMPLETE) {
+ ctx->pages[index].state = JBIG2_PAGE_RETURNED;
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
+ "page %d returned to the client", ctx->pages[index].number);
+ return ctx->pages[index].image;
+ }
+ }
+
+ /* no pages available */
+ return NULL;
+}
+
+/**
+ * jbig2_release_page: tell the library a page can be freed
+ **/
+int jbig2_release_page(Jbig2Ctx *ctx, Jbig2Image *image)
+{
+ int index;
+
+ /* find the matching page struct and mark it released */
+ for (index = 0; index < ctx->max_page_index; index++) {
+ if (ctx->pages[index].image == image) {
+ ctx->pages[index].state = JBIG2_PAGE_RELEASED;
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
+ "page %d released by the client", ctx->pages[index].number);
+ return 0;
+ }
+ }
+
+ /* no matching pages */
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1,
+ "jbig2_release_page called on unknown page");
+ return 1;
}
Index: jbig2_priv.h
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2_priv.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- jbig2_priv.h 20 Jun 2002 15:42:47 -0000 1.6
+++ jbig2_priv.h 21 Jun 2002 19:10:02 -0000 1.7
@@ -90,7 +90,8 @@
JBIG2_PAGE_FREE,
JBIG2_PAGE_NEW,
JBIG2_PAGE_COMPLETE,
- JBIG2_PAGE_RETURNED
+ JBIG2_PAGE_RETURNED,
+ JBIG2_PAGE_RELEASED
} Jbig2PageState;
struct _Jbig2Page {
@@ -107,6 +108,8 @@
int jbig2_read_page_info (Jbig2Ctx *ctx, Jbig2SegmentHeader *sh, const byte *segment_data);
int jbig2_complete_page (Jbig2Ctx *ctx, Jbig2SegmentHeader *sh, const byte *segment_data);
+
+int jbig2_image_compose(Jbig2Ctx *ctx, Jbig2Image *dst, Jbig2Image *src, int x, int y);
/* region segment info */
Index: jbig2dec.c
===================================================================
RCS file: /cvsroot/jbig2dec/jbig2dec/jbig2dec.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- jbig2dec.c 18 Jun 2002 13:40:29 -0000 1.21
+++ jbig2dec.c 21 Jun 2002 19:10:02 -0000 1.22
@@ -27,6 +27,7 @@
#endif
#include "jbig2.h"
+#include "jbig2_image.h"
typedef enum {
usage,dump,render
@@ -257,6 +258,15 @@
filearg = parse_options(argc, argv, ¶ms);
+ if (params.output_file == NULL)
+ {
+#ifdef HAVE_LIBPNG
+ params.output_file = "out.png";
+#else
+ params.output_file = "out.pbm";
+#endif
+ }
+
if ((argc - filearg) == 1)
// only one argument--open as a jbig2 file
{
@@ -324,6 +334,21 @@
jbig2_global_ctx_free(global_ctx);
}
+ // retrieve and output the returned pages
+ {
+ Jbig2Image *image;
+
+ while ((image = jbig2_get_page(ctx)) != NULL) {
+ fprintf(stderr, "saving decoded page as '%s'\n", params.output_file);
+#ifdef HAVE_LIBPNG
+ jbig2_image_write_png_file(image, params.output_file);
+#else
+ jbig2_image_write_pbm_file(image, params.output_file);
+#endif
+ jbig2_release_page(ctx, image);
+ }
+ }
+
jbig2_ctx_free(ctx);
// fin