about summary refs log tree commit diff
path: root/converter/other/jbig/jbigtopnm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/jbig/jbigtopnm.c')
-rw-r--r--converter/other/jbig/jbigtopnm.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/converter/other/jbig/jbigtopnm.c b/converter/other/jbig/jbigtopnm.c
new file mode 100644
index 00000000..7a6e95c1
--- /dev/null
+++ b/converter/other/jbig/jbigtopnm.c
@@ -0,0 +1,286 @@
+/*
+    jbigtopnm - JBIG to PNM converter
+  
+    This program was derived from jbgtopbm.c in Markus Kuhn's
+    JBIG-KIT package by Bryan Henderson on 2000.05.11
+
+    The main difference is that this version uses the Netpbm libraries.
+  
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <jbig.h>
+#include "pnm.h"
+
+#define BUFSIZE 8192
+
+
+static void
+collect_image (unsigned char *data, size_t len, void *image) {
+    static int cursor = 0;
+    int i;
+
+    for (i = 0; i < len; i++) {
+        ((unsigned char *)image)[cursor++] = data[i];
+    }
+}
+
+
+
+static void 
+write_pnm (FILE *fout, const unsigned char * const image, const int bpp,
+           const int rows, const int cols, const int maxval,
+           const int format) {
+
+    int row;
+    xel *pnm_row;
+
+    pnm_writepnminit(fout, cols, rows, maxval, format, 0);
+
+    pnm_row = pnm_allocrow(cols);
+
+    for (row = 0; row < rows; row++) {
+        int col;
+        for (col = 0; col < cols; col++) {
+            int j;
+            for (j = 0; j < bpp; j++)
+                PNM_ASSIGN1(pnm_row[col], 
+                            image[(((row*cols)+col) * bpp) + j]);
+        }
+        pnm_writepnmrow(fout, pnm_row, cols, maxval, format, 0);
+    }
+    
+    pnm_freerow(pnm_row);
+}
+
+
+
+static void
+write_raw_pbm(FILE * const fout, 
+              const unsigned char * const binary_image,
+              int                   const cols,
+              int                   const rows) { 
+
+    unsigned int const bytes_per_row = pbm_packed_bytes(cols);
+
+    int row;
+
+    pbm_writepbminit(fout, cols, rows, 0);
+
+    for (row = 0; row < rows; ++row)
+        pbm_writepbmrow_packed(fout, &binary_image[row*bytes_per_row], cols, 
+                               0);
+}
+
+
+
+/*
+ *
+ */
+static void 
+diagnose_bie(FILE *f)
+{
+  unsigned char bih[20];
+  int len;
+  unsigned long xd, yd, l0;
+
+  len = fread(bih, 1, 20, f);
+  if (len < 20) {
+    printf("Input file is %d < 20 bytes long and does therefore not "
+	   "contain an intact BIE header!\n", len);
+    return;
+  }
+
+  printf("Decomposition of BIH:\n\n  DL = %d\n  D  = %d\n  P  = %d\n"
+	 "  -  = %d\n  XD = %lu\n  YD = %lu\n  L0 = %lu\n  MX = %d\n"
+	 "  MY = %d\n",
+	 bih[0], bih[1], bih[2], bih[3],
+	 xd = ((unsigned long) bih[ 4] << 24) | ((unsigned long)bih[ 5] << 16)|
+	 ((unsigned long) bih[ 6] <<  8) | ((unsigned long) bih[ 7]),
+	 yd = ((unsigned long) bih[ 8] << 24) | ((unsigned long)bih[ 9] << 16)|
+	 ((unsigned long) bih[10] <<  8) | ((unsigned long) bih[11]),
+	 l0 = ((unsigned long) bih[12] << 24) | ((unsigned long)bih[13] << 16)|
+	 ((unsigned long) bih[14] <<  8) | ((unsigned long) bih[15]),
+	 bih[16], bih[17]);
+  printf("  order   = %d %s%s%s%s%s\n", bih[18],
+	 bih[18] & JBG_HITOLO ? " HITOLO" : "",
+	 bih[18] & JBG_SEQ ? " SEQ" : "",
+	 bih[18] & JBG_ILEAVE ? " ILEAVE" : "",
+	 bih[18] & JBG_SMID ? " SMID" : "",
+	 bih[18] & 0xf0 ? " other" : "");
+  printf("  options = %d %s%s%s%s%s%s%s%s\n", bih[19],
+	 bih[19] & JBG_LRLTWO ? " LRLTWO" : "",
+	 bih[19] & JBG_VLENGTH ? " VLENGTH" : "",
+	 bih[19] & JBG_TPDON ? " TPDON" : "",
+	 bih[19] & JBG_TPBON ? " TPBON" : "",
+	 bih[19] & JBG_DPON ? " DPON" : "",
+	 bih[19] & JBG_DPPRIV ? " DPPRIV" : "",
+	 bih[19] & JBG_DPLAST ? " DPLAST" : "",
+	 bih[19] & 0x80 ? " other" : "");
+  printf("\n  %lu stripes, %d layers, %d planes\n\n",
+	 ((yd >> bih[1]) +  ((((1UL << bih[1]) - 1) & xd) != 0) + l0 - 1) / l0,
+	 bih[1] - bih[0], bih[2]);
+
+  return;
+}
+
+
+int main (int argc, char **argv)
+{
+    FILE *fin = stdin, *fout = stdout;
+    const char *fnin = "<stdin>", *fnout = "<stdout>";
+    int i, j, result;
+    int all_args = 0, files = 0;
+    struct jbg_dec_state s;
+    char *buffer;
+    unsigned char *p;
+    size_t len, cnt;
+    unsigned long xmax = 4294967295UL, ymax = 4294967295UL;
+    int plane = -1, use_graycode = 1, diagnose = 0;
+
+    pnm_init(&argc, argv);
+
+    buffer = malloc(BUFSIZE);
+    if (!buffer)
+        pm_error("Sorry, not enough memory available!");
+
+    /* parse command line arguments */
+    for (i = 1; i < argc; i++) {
+        if (!all_args && argv[i][0] == '-') {
+            if (argv[i][1] == '\0' && files == 0)
+                ++files;
+            else {
+                for (j = 1; j > 0 && argv[i][j]; j++) {
+                    switch(tolower(argv[i][j])) {
+                    case '-' :
+                        all_args = 1;
+                        break;
+                    case 'b':
+                        use_graycode = 0;
+                        break;
+                    case 'd':
+                        diagnose = 1;
+                        break;
+                    case 'x':
+                        if (++i >= argc)
+                            pm_error("-x needs a value");
+                        xmax = atol(argv[i]);
+                        j = -1;
+                        break;
+                    case 'y':
+                        if (++i >= argc)
+                            pm_error("-y needs a value");
+                        ymax = atol(argv[i]);
+                        j = -1;
+                        break;
+                    case 'p':
+                        if (++i >= argc)
+                            pm_error("-p needs a value");
+                        plane = atoi(argv[i]);
+                        j = -1;
+                        break;
+                    default:
+                        pm_error("Unrecognized option: %c", argv[i][j]);
+                    }
+                }
+            }
+        } else {
+            switch (files++) {
+            case 0:
+                if (argv[i][0] != '-' || argv[i][1] != '\0') {
+                    fnin = argv[i];
+                    fin = fopen(fnin, "rb");
+                    if (!fin)
+                        pm_error("Can't open input file '%s'", fnin);
+                }
+                if (diagnose) {
+                    diagnose_bie(fin);
+                    exit(0);
+                }
+                break;
+            case 1:
+                fnout = argv[i];
+                fout = fopen(fnout, "wb");
+                if (!fout)
+                    pm_error("Can't open output file '%s'", fnout);
+                break;
+            default:
+                pm_error("Too many non-option arguments");
+            }
+        }
+    }
+
+    /* send input file to decoder */
+    jbg_dec_init(&s);
+    jbg_dec_maxsize(&s, xmax, ymax);
+    result = JBG_EAGAIN;
+    do {
+        len = fread(buffer, 1, BUFSIZE, fin);
+        if (!len) break;
+        cnt = 0;
+        p = (unsigned char *) buffer;
+        while (len > 0 && (result == JBG_EAGAIN || result == JBG_EOK)) {
+            result = jbg_dec_in(&s, p, len, &cnt);
+            p += cnt;
+            len -= cnt;
+        }
+    } while (result == JBG_EAGAIN || result == JBG_EOK);
+    if (ferror(fin)) 
+        pm_error("Problem while reading input file '%s", fnin);
+    if (result != JBG_EOK && result != JBG_EOK_INTR) 
+        pm_error("Problem with input file '%s': %s\n", 
+                 fnin, jbg_strerror(result, JBG_EN));
+    if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) 
+        pm_error("Image has only %d planes!\n", jbg_dec_getplanes(&s));
+
+    {
+        /* Write it out */
+
+        int rows, cols;
+        int maxval;
+        int bpp;
+        int plane_to_write;
+
+        cols = jbg_dec_getwidth(&s);
+        rows = jbg_dec_getheight(&s);
+        maxval = pm_bitstomaxval(jbg_dec_getplanes(&s));
+        bpp = (jbg_dec_getplanes(&s)+7)/8;
+
+        if (jbg_dec_getplanes(&s) == 1) 
+            plane_to_write = 0;
+        else 
+            plane_to_write = plane;
+
+        if (plane_to_write >= 0) {
+            /* Write just one plane */
+            unsigned char * binary_image;
+
+            pm_message("WRITING PBM FILE");
+
+            binary_image=jbg_dec_getimage(&s, plane_to_write);
+            write_raw_pbm(fout, binary_image, cols, rows);
+        } else {
+            unsigned char *image;
+            pm_message("WRITING PGM FILE");
+
+            /* Write out all the planes */
+            /* What jbig.doc doesn't tell you is that jbg_dec_merge_planes
+               delivers the image in chunks, in consecutive calls to 
+               the data-out callback function.  And a row can span two
+               chunks.
+            */
+            image = malloc(cols*rows*bpp);
+            jbg_dec_merge_planes(&s, use_graycode, collect_image, image);
+            write_pnm(fout, image, bpp, rows, cols, maxval, PGM_TYPE);
+            free(image);
+        }
+    }
+  
+    pm_close(fout);
+
+    jbg_dec_free(&s);
+
+    return 0;
+}