shithub: jbig2

Download patch

ref: 0a396e48949d90a8cd1a91c685af09a165a1f5d9
parent: d8294b25104e9033408c18b68567281ae8e9d5e0
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Mon Nov 23 18:07:35 EST 2020

plan 9 port

diff: cannot open b/plan9//null: file does not exist: 'b/plan9//null'
--- a/README
+++ /dev/null
@@ -1,32 +1,0 @@
-jbig2dec is a decoder library and example utility implementing the JBIG2
-bi-level image compression spec. Also known as ITU T.88 and ISO IEC
-14492, and included by reference in Adobe's PDF version 1.4 and later.
-
-The basic invocation is:
-
-    jbig2dec [-o <output file>] file.jbig2
-
-It also supports separate 'global' and 'page' streams, generally
-extracted from some embedded format:
-
-    jbig2dec [-o <output file>] <global_stream> <page_stream>
-
-The program is only partially functional at this time, but should be
-useful in some limited contexts. We welcome files that the decoder can't
-handle, or renders incorrectly.
-
-More information about jbig2dec and updated versions are available from:
-https://jbig2dec.com/
-
-A set of example files is available from
-https://jbig2dec.com/tests/
-
-Development source code is kept in a git repository at:
-http://git.ghostscript.com/?p=jbig2dec.git
-
-Report bugs at https://bugs.ghostscript.com
-For security issues please use the "Security - Other" product,
-and for normal bugs the "jbig2dec" product.
-
-Contact the developers at the IRC channel #ghostscript at freenode.net
-or via the mailing list <gs-devel@ghostscript.com>.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,3 @@
+# jbig2
+
+JBIG2 decoder for Plan 9.
--- /dev/null
+++ b/jb2.c
@@ -1,0 +1,106 @@
+#include "config.h"
+#include "jbig2.h"
+#include "jbig2_priv.h"
+#include "jbig2_image.h"
+#include "jbig2_image_rw.h"
+#include <draw.h>
+#include <memdraw.h>
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-p PAGE]\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+	/* this header is inserted in case the input stream doesn't have one (when extracted from a PDF) */
+	uchar header[] = { 0x97, 0x4a, 0x42, 0x32, 0x0d, 0x0a, 0x1a, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x01 };
+    int n, w, h, x, y, page;
+	uchar *rgb, d[8192];
+	Jbig2Image *j;
+	Jbig2Ctx *ctx;
+	Memimage *m;
+
+	page = 0;
+	ARGBEGIN{
+	case 'p':
+		page = atoi(EARGF(usage()));
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if(argc != 0)
+		usage();
+
+	memimageinit();
+
+	if((ctx = jbig2_ctx_new(nil, 0, nil, nil, nil)) == nil){
+		werrstr("ctx_new");
+		goto error;
+	}
+	for(x = 0;; x += n){
+		if((n = read(0, d, sizeof(d))) == 0)
+			break;
+		if(n < 0)
+			goto error;
+		if(x == 0 && n >= 8 && memcmp(d, header, 8) != 0)
+			jbig2_data_in(ctx, header, sizeof(header));
+		if(jbig2_data_in(ctx, d, n) < 0){
+			werrstr("data_in");
+			goto error;
+		}
+	}
+	if(jbig2_complete_page(ctx) < 0){
+		werrstr("unable to complete page");
+		goto error;
+	}
+
+	n = page;
+	while((j = jbig2_page_out(ctx)) != nil){
+		if(n > 1){
+			n--;
+			jbig2_release_page(ctx, j);
+			continue;
+		}
+
+		w = j->width;
+		h = j->height;
+		if((rgb = malloc(j->stride*h)) == nil){
+			werrstr("memory");
+			goto error;
+		}
+		for(y = 0; y < h; y++){
+			memmove(rgb+y*j->stride, j->data+y*j->stride, j->stride);
+			for(x = 0; x < j->stride; x++)
+				rgb[y*j->stride+x] = ~rgb[y*j->stride+x];
+		}
+		jbig2_release_page(ctx, j);
+
+		if((m = allocmemimage(Rect(0,0,w,h), GREY1)) == nil){
+			werrstr("memory");
+			goto error;
+		}
+		loadmemimage(m, m->r, rgb, w*h);
+		free(rgb);
+		writememimage(1, m);
+		freememimage(m);
+
+		if(n == 1){
+			n--;
+			break;
+		}
+	}
+	if(n > 0){
+		werrstr("no page %d", page);
+		goto error;
+	}
+
+	exits(nil);
+error:
+	fprint(2, "%r\n");
+	exits("error");
+}
--- a/jbig2.c
+++ b/jbig2.c
@@ -37,6 +37,7 @@
 static void *
 jbig2_default_alloc(Jbig2Allocator *allocator, size_t size)
 {
+    USED(allocator);
     return malloc(size);
 }
 
@@ -43,6 +44,7 @@
 static void
 jbig2_default_free(Jbig2Allocator *allocator, void *p)
 {
+    USED(allocator);
     free(p);
 }
 
@@ -49,6 +51,7 @@
 static void *
 jbig2_default_realloc(Jbig2Allocator *allocator, void *p, size_t size)
 {
+    USED(allocator);
     return realloc(p, size);
 }
 
@@ -73,6 +76,7 @@
 static void
 jbig2_default_error(void *data, const char *msg, Jbig2Severity severity, uint32_t seg_idx)
 {
+    USED(data);
     /* report only fatal errors by default */
     if (severity == JBIG2_SEVERITY_FATAL) {
         fprintf(stderr, "jbig2 decoder FATAL ERROR: %s", msg);
@@ -116,7 +120,7 @@
     if (allocator == NULL)
         allocator = &jbig2_default_allocator;
     if (error_callback == NULL)
-        error_callback = &jbig2_default_error;
+        error_callback = jbig2_default_error;
 
     result = (Jbig2Ctx *) jbig2_alloc(allocator, sizeof(Jbig2Ctx), 1);
     if (result == NULL) {
--- a/jbig2.h
+++ b/jbig2.h
@@ -43,6 +43,7 @@
 /* forward public structure declarations */
 typedef struct _Jbig2Allocator Jbig2Allocator;
 typedef struct _Jbig2Ctx Jbig2Ctx;
+#pragma incomplete Jbig2Ctx
 typedef struct _Jbig2GlobalCtx Jbig2GlobalCtx;
 
 /*
--- a/jbig2_arith.h
+++ b/jbig2_arith.h
@@ -21,6 +21,7 @@
 #define _JBIG2_ARITH_H
 
 typedef struct _Jbig2ArithState Jbig2ArithState;
+#pragma incomplete 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
--- a/jbig2_arith_iaid.h
+++ b/jbig2_arith_iaid.h
@@ -21,6 +21,7 @@
 #define _JBIG2_ARITH_IAID_H
 
 typedef struct _Jbig2ArithIaidCtx Jbig2ArithIaidCtx;
+#pragma incomplete Jbig2ArithIaidCtx
 
 Jbig2ArithIaidCtx *jbig2_arith_iaid_ctx_new(Jbig2Ctx *ctx, uint8_t SBSYMCODELEN);
 
--- a/jbig2_arith_int.h
+++ b/jbig2_arith_int.h
@@ -21,6 +21,7 @@
 #define _JBIG2_ARITH_INT_H
 
 typedef struct _Jbig2ArithIntCtx Jbig2ArithIntCtx;
+#pragma incomplete Jbig2ArithIntCtx
 
 Jbig2ArithIntCtx *jbig2_arith_int_ctx_new(Jbig2Ctx *ctx);
 
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -358,6 +358,7 @@
 {
     int stats_size = template == 0 ? 1 << 16 : template == 1 ? 1 << 13 : 1 << 10;
 
+    USED(ctx);
     return stats_size;
 }
 
@@ -375,6 +376,7 @@
     byte *line1 = NULL;
     byte *gbreg_line = (byte *) image->data;
 
+    USED(params);
 #ifdef OUTPUT_PBM
     printf("P4\n%d %d\n", GBW, GBH);
 #endif
@@ -428,7 +430,7 @@
 }
 
 #define pixel_outside_field(x, y) \
-    ((y) < -128 || (y) > 0 || (x) < -128 || ((y) < 0 && (x) > 127) || ((y) == 0 && (x) >= 0))
+    ((y) > 0 || ((y) == 0 && (x) >= 0))
 
 static int
 jbig2_decode_generic_template0_unopt(Jbig2Ctx *ctx,
@@ -581,6 +583,7 @@
     byte *line1 = NULL;
     byte *gbreg_line = (byte *) image->data;
 
+    USED(params);
 #ifdef OUTPUT_PBM
     printf("P4\n%d %d\n", GBW, GBH);
 #endif
@@ -713,6 +716,7 @@
     byte *line1 = NULL;
     byte *gbreg_line = (byte *) image->data;
 
+    USED(params);
 #ifdef OUTPUT_PBM
     printf("P4\n%d %d\n", GBW, GBH);
 #endif
@@ -777,6 +781,7 @@
     byte *gbreg_line = (byte *) image->data;
     uint32_t x, y;
 
+    USED(params);
 #ifdef OUTPUT_PBM
     printf("P4\n%d %d\n", GBW, GBH);
 #endif
@@ -1394,8 +1399,8 @@
     int offset;
     uint32_t gbat_bytes = 0;
     Jbig2GenericRegionParams params;
-    int code = 0;
-    Jbig2Image *image = NULL;
+    int code;
+    Jbig2Image *image;
     Jbig2WordStream *ws = NULL;
     Jbig2ArithState *as = NULL;
     Jbig2ArithCx *GB_stats = NULL;
--- a/jbig2_halftone.c
+++ b/jbig2_halftone.c
@@ -135,9 +135,9 @@
                           const Jbig2PatternDictParams *params, const byte *data, const size_t size, Jbig2ArithCx *GB_stats)
 {
     Jbig2PatternDict *hd = NULL;
-    Jbig2Image *image = NULL;
+    Jbig2Image *image;
     Jbig2GenericRegionParams rparams;
-    int code = 0;
+    int code;
 
     /* allocate the collective image */
     image = jbig2_image_new(ctx, params->HDPW * (params->GRAYMAX + 1), params->HDPH);
@@ -420,7 +420,7 @@
 {
     int index = 0;
     Jbig2PatternDict *pattern_dict = NULL;
-    Jbig2Segment *rsegment = NULL;
+    Jbig2Segment *rsegment;
 
     /* loop through all referred segments */
     while (!pattern_dict && segment->referred_to_segment_count > index) {
@@ -556,9 +556,9 @@
     int offset = 0;
     Jbig2RegionSegmentInfo region_info;
     Jbig2HalftoneRegionParams params;
-    Jbig2Image *image = NULL;
+    Jbig2Image *image;
     Jbig2ArithCx *GB_stats = NULL;
-    int code = 0;
+    int code;
 
     /* 7.4.5.1 */
     if (segment->data_length < 17)
--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -67,7 +67,7 @@
 Jbig2HuffmanState *
 jbig2_huffman_new(Jbig2Ctx *ctx, Jbig2WordStream *ws)
 {
-    Jbig2HuffmanState *result = NULL;
+    Jbig2HuffmanState *result;
     int code;
 
     result = jbig2_new(ctx, Jbig2HuffmanState, 1);
--- a/jbig2_huffman.h
+++ b/jbig2_huffman.h
@@ -26,6 +26,7 @@
 typedef struct _Jbig2HuffmanState Jbig2HuffmanState;
 typedef struct _Jbig2HuffmanTable Jbig2HuffmanTable;
 typedef struct _Jbig2HuffmanParams Jbig2HuffmanParams;
+#pragma incomplete Jbig2HuffmanState
 
 struct _Jbig2HuffmanEntry {
     union {
--- a/jbig2_image.c
+++ b/jbig2_image.c
@@ -75,6 +75,7 @@
 Jbig2Image *
 jbig2_image_reference(Jbig2Ctx *ctx, Jbig2Image *image)
 {
+    USED(ctx);
     if (image)
         image->refcount++;
     return image;
@@ -344,6 +345,7 @@
     uint32_t bytewidth;
     uint32_t syoffset = 0;
 
+    USED(ctx);
     if (src == NULL)
         return 0;
 
@@ -460,6 +462,7 @@
 {
     const uint8_t fill = value ? 0xFF : 0x00;
 
+    USED(ctx);
     memset(image->data, fill, image->stride * image->height);
 }
 
--- a/jbig2_mmr.c
+++ b/jbig2_mmr.c
@@ -1200,6 +1200,7 @@
     int code = 0;
     int eofb = 0;
 
+    USED(params);
     jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
 
     for (y = 0; !eofb && y < image->height; y++) {
@@ -1244,6 +1245,7 @@
     const uint32_t EOFB = 0x001001;
     int eofb = 0;
 
+    USED(params);
     jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
 
     for (y = 0; !eofb && y < image->height; y++) {
--- a/jbig2_page.c
+++ b/jbig2_page.c
@@ -239,6 +239,7 @@
     uint32_t page_number = ctx->pages[ctx->current_page].number;
     int code;
 
+    USED(segment_data);
     if (segment->page_association != page_number) {
         jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
                     "end of page marker for page %d doesn't match current page number %d", segment->page_association, page_number);
@@ -286,7 +287,7 @@
         new_height = y + image->height;
 
         if (page->image->height < new_height) {
-            Jbig2Image *resized_image = NULL;
+            Jbig2Image *resized_image;
 
             jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, JBIG2_UNKNOWN_SEGMENT_NUMBER, "growing page buffer to %u rows to accommodate new stripe", new_height);
             resized_image = jbig2_image_resize(ctx, page->image, page->image->width, new_height, page->flags & 4);
--- a/jbig2_priv.h
+++ b/jbig2_priv.h
@@ -67,6 +67,7 @@
 
 typedef struct _Jbig2Page Jbig2Page;
 typedef struct _Jbig2Segment Jbig2Segment;
+#pragma incomplete Jbig2Segment
 
 typedef enum {
     JBIG2_FILE_HEADER,
@@ -137,6 +138,7 @@
    32 bit word. The offset argument is provided as a convenience. It
    begins at 0 and increments by 4 for each successive invocation. */
 typedef struct _Jbig2WordStream Jbig2WordStream;
+#pragma incomplete Jbig2WordStream
 
 struct _Jbig2WordStream {
     int (*get_next_word)(Jbig2Ctx *ctx, Jbig2WordStream *self, size_t offset, uint32_t *word);
--- a/jbig2_refinement.c
+++ b/jbig2_refinement.c
@@ -41,9 +41,9 @@
 #include "jbig2_segment.h"
 
 #define pixel_outside_field(x, y) \
-    ((y) < -128 || (y) > 0 || (x) < -128 || ((y) < 0 && (x) > 127) || ((y) == 0 && (x) >= 0))
+    ((y) > 0 || ((y) == 0 && (x) >= 0))
 #define refpixel_outside_field(x, y) \
-    ((y) < -128 || (y) > 127 || (x) < -128 || (x) > 127)
+    (0)
 
 static int
 jbig2_decode_refinement_template0_unopt(Jbig2Ctx *ctx,
@@ -244,6 +244,7 @@
     int j = y - params->GRREFERENCEDY;
     int m = jbig2_image_get_pixel(ref, i, j);
 
+    USED(image);
     return ((jbig2_image_get_pixel(ref, i - 1, j - 1) == m) &&
             (jbig2_image_get_pixel(ref, i, j - 1) == m) &&
             (jbig2_image_get_pixel(ref, i + 1, j - 1) == m) &&
@@ -422,7 +423,7 @@
     Jbig2RegionSegmentInfo rsi;
     int offset = 0;
     byte seg_flags;
-    int code = 0;
+    int code;
 
     /* 7.4.7 */
     if (segment->data_length < 18)
@@ -488,7 +489,7 @@
         Jbig2ArithState *as = NULL;
         Jbig2ArithCx *GR_stats = NULL;
         int stats_size;
-        Jbig2Image *image = NULL;
+        Jbig2Image *image;
 
         image = jbig2_image_new(ctx, rsi.width, rsi.height);
         if (image == NULL) {
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -95,7 +95,7 @@
 Jbig2SymbolDict *
 jbig2_sd_new(Jbig2Ctx *ctx, uint32_t n_symbols)
 {
-    Jbig2SymbolDict *new_dict = NULL;
+    Jbig2SymbolDict *new_dict;
 
     new_dict = jbig2_new(ctx, Jbig2SymbolDict, 1);
     if (new_dict != NULL) {
@@ -200,7 +200,7 @@
 jbig2_sd_cat(Jbig2Ctx *ctx, uint32_t n_dicts, Jbig2SymbolDict **dicts)
 {
     uint32_t i, j, k, symbols;
-    Jbig2SymbolDict *new_dict = NULL;
+    Jbig2SymbolDict *new_dict;
 
     /* count the imported symbols and allocate a new array */
     symbols = 0;
@@ -236,10 +236,10 @@
     uint32_t SYMWIDTH, TOTWIDTH;
     uint32_t HCFIRSTSYM;
     uint32_t *SDNEWSYMWIDTHS = NULL;
-    uint8_t SBSYMCODELEN = 0;
-    Jbig2WordStream *ws = NULL;
+    uint8_t SBSYMCODELEN;
+    Jbig2WordStream *ws;
     Jbig2HuffmanState *hs = NULL;
-    Jbig2ArithState *as = NULL;
+    Jbig2ArithState *as;
     Jbig2ArithIntCtx *IADH = NULL;
     Jbig2ArithIntCtx *IADW = NULL;
     Jbig2ArithIntCtx *IAEX = NULL;
@@ -863,8 +863,8 @@
     uint16_t flags;
     uint32_t sdat_bytes;
     uint32_t offset;
-    Jbig2ArithCx *GB_stats = NULL;
-    Jbig2ArithCx *GR_stats = NULL;
+    Jbig2ArithCx *GB_stats;
+    Jbig2ArithCx *GR_stats;
     int table_index = 0;
     const Jbig2HuffmanParams *huffman_params;
 
@@ -963,6 +963,7 @@
             }
             params.SDHUFFAGGINST = jbig2_build_huffman_table(ctx, huffman_params);
             ++table_index;
+            USED(table_index);
         } else {
             /* Table B.1 */
             params.SDHUFFAGGINST = jbig2_build_huffman_table(ctx, &jbig2_huffman_params_A);
@@ -1014,7 +1015,7 @@
     /* 7.4.2.2 (2) */
     {
         uint32_t n_dicts = jbig2_sd_count_referred(ctx, segment);
-        Jbig2SymbolDict **dicts = NULL;
+        Jbig2SymbolDict **dicts;
 
         if (n_dicts > 0) {
             dicts = jbig2_sd_list_referred(ctx, segment);
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -70,7 +70,7 @@
     int32_t DT;
     int32_t DFS;
     int32_t IDS;
-    int32_t CURS;
+    int32_t CURS = 0;
     int32_t CURT;
     int S, T;
     int x, y;
@@ -84,6 +84,7 @@
     int code = 0;
     int RI;
 
+    USED(size, data);
     SBNUMSYMS = 0;
     for (index = 0; index < n_dicts; index++) {
         SBNUMSYMS += dicts[index]->n_symbols;
@@ -96,7 +97,7 @@
         Jbig2HuffmanLine runcodelengths[35];
         Jbig2HuffmanLine *symcodelengths = NULL;
         Jbig2HuffmanParams symcodeparams;
-        int err, len, range, r;
+        int err, len, range = 0, r;
 
         jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number, "huffman coded text region");
         hs = jbig2_huffman_new(ctx, ws);
@@ -583,15 +584,15 @@
     Jbig2TextRegionParams params;
     Jbig2Image *image = NULL;
     Jbig2SymbolDict **dicts = NULL;
-    uint32_t n_dicts = 0;
-    uint16_t flags = 0;
+    uint32_t n_dicts;
+    uint16_t flags;
     uint16_t huffman_flags = 0;
     Jbig2ArithCx *GR_stats = NULL;
-    int code = 0;
-    Jbig2WordStream *ws = NULL;
-    Jbig2ArithState *as = NULL;
+    int code;
+    Jbig2WordStream *ws;
+    Jbig2ArithState *as;
     uint32_t table_index = 0;
-    const Jbig2HuffmanParams *huffman_params = NULL;
+    const Jbig2HuffmanParams *huffman_params;
 
     /* zero params to ease cleanup later */
     memset(&params, 0, sizeof(Jbig2TextRegionParams));
@@ -872,6 +873,7 @@
             }
             params.SBHUFFRSIZE = jbig2_build_huffman_table(ctx, huffman_params);
             ++table_index;
+            USED(table_index);
             break;
         }
         if (params.SBHUFFRSIZE == NULL) {
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,18 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin
+TARG=jbig2
+CFLAGS=$CFLAGS -p -Iplan9
+CLEANFILES=libjbig2.a
+
+OFILES=\
+	jb2.$O\
+
+default:V: all
+
+</sys/src/cmd/mkone
+
+jb2.$O: libjbig2.a
+
+libjbig2.a:
+	mk -f mklib
--- /dev/null
+++ b/mklib
@@ -1,0 +1,43 @@
+</$objtype/mkfile
+LIB=libjbig2.a
+CFLAGS=$CFLAGS -p -Iplan9 -DHAVE_CONFIG_H
+
+OFILES=\
+	jbig2.$O\
+	jbig2_arith.$O\
+	jbig2_arith_iaid.$O\
+	jbig2_arith_int.$O\
+	jbig2_generic.$O\
+	jbig2_halftone.$O\
+	jbig2_huffman.$O\
+	jbig2_hufftab.$O\
+	jbig2_image.$O\
+	jbig2_mmr.$O\
+	jbig2_page.$O\
+	jbig2_refinement.$O\
+	jbig2_segment.$O\
+	jbig2_symbol_dict.$O\
+	jbig2_text.$O\
+
+HFILES=\
+	plan9/config.h\
+	jbig2.h\
+	jbig2_arith.h\
+	jbig2_arith_iaid.h\
+	jbig2_arith_int.h\
+	jbig2_generic.h\
+	jbig2_halftone.h\
+	jbig2_huffman.h\
+	jbig2_hufftab.h\
+	jbig2_image.h\
+	jbig2_image_rw.h\
+	jbig2_mmr.h\
+	jbig2_page.h\
+	jbig2_priv.h\
+	jbig2_refinement.h\
+	jbig2_segment.h\
+	jbig2_symbol_dict.h\
+	jbig2_text.h\
+	os_types.h\
+
+</sys/src/cmd/mklib
--- /dev/null
+++ b/plan9/config.h
@@ -1,0 +1,26 @@
+/* configuration header file for compiling under Plan 9 */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#include <u.h>
+#include <libc.h>
+#include </sys/include/stdio.h>
+
+#pragma lib "./libjbig2.a"
+
+typedef s8int int8_t;
+typedef s16int int16_t;
+typedef s32int int32_t;
+typedef s64int int64_t;
+
+typedef u8int uint8_t;
+typedef u16int uint16_t;
+typedef u32int uint32_t;
+typedef u64int uint64_t;
+
+typedef ulong size_t;
+
+#define SIZE_MAX (~((size_t)0))
+
+#endif