about summary refs log tree commit diff
path: root/converter/pbm/mrftopbm.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
commit1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch)
tree64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/pbm/mrftopbm.c
downloadnetpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/pbm/mrftopbm.c')
-rw-r--r--converter/pbm/mrftopbm.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/converter/pbm/mrftopbm.c b/converter/pbm/mrftopbm.c
new file mode 100644
index 00000000..696fe839
--- /dev/null
+++ b/converter/pbm/mrftopbm.c
@@ -0,0 +1,210 @@
+/* mrftopbm - convert mrf to pbm
+ * public domain by RJM
+ *
+ * Adapted to Netpbm by Bryan Henderson 2003.08.09.  Bryan got his copy from
+ * ftp://ibiblio.org/pub/linux/apps/convert, dated 1997.08.19.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "pm_c_util.h"
+#include "nstring.h"
+#include "pbm.h"
+
+
+static int bitbox;
+static int bitsleft;
+
+
+static void 
+bit_init(void) {
+    bitbox=0; 
+    bitsleft=0;
+}
+
+
+
+static int 
+bit_input(FILE * const in) {
+    if (bitsleft == 0)   {
+        bitbox = fgetc(in);
+        bitsleft = 8;
+    }
+    --bitsleft;
+    return((bitbox&(1<<bitsleft))?1:0);
+}
+
+
+
+static void 
+doSquare(FILE *          const in,
+          unsigned char * const image,
+          int             const ox,
+          int             const oy,
+          int             const w,
+          int             const size) {
+
+    if (size == 1 || bit_input(in)) { 
+        /* It's all black or all white.  Next bit says which. */
+
+        unsigned int const c = bit_input(in);
+
+        unsigned int y;
+
+        for (y = 0; y < size; ++y) {
+            unsigned int x;
+            for (x = 0; x < size; ++x)
+                image[(oy+y)*w+ox+x] = c;
+        }
+    } else {
+        /* not all one color, so recurse. */
+        doSquare(in, image, ox,      oy,     w, size >> 1);
+        doSquare(in, image, ox+size, oy,     w, size >> 1);
+        doSquare(in, image, ox,      oy+size,w, size >> 1);
+        doSquare(in, image, ox+size, oy+size,w, size >> 1);
+    }
+}
+
+
+
+static void
+writeOutput(FILE *                const ofP,
+            int                   const cols,
+            int                   const rows,
+            const unsigned char * const image) {
+            
+    /* w64 is units-of-64-bits width, h64 same for height */
+    unsigned int const w64 = (cols+63)/64;
+
+    bit * bitrow;
+    unsigned int row;
+
+    pbm_writepbminit(ofP, cols, rows, FALSE);
+
+    bitrow = pbm_allocrow(cols);
+
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+     
+        for (col = 0; col < cols; ++col)
+            bitrow[col] = 
+                (image[row * (w64*64) + col] == 1) ? PBM_WHITE : PBM_BLACK;
+
+        pbm_writepbmrow(ofP, bitrow, cols, FALSE);
+    }
+    pbm_freerow(bitrow);
+}
+
+
+
+static void
+readMrfImage(FILE *           const ifP,
+             bool             const expandAll,
+             unsigned char ** const imageP,
+             unsigned int *   const colsP,
+             unsigned int *   const rowsP) {
+
+    static unsigned char buf[128];
+    unsigned int rows;
+    unsigned int cols;
+    unsigned int w64, h64;
+
+    unsigned char * image;
+
+    fread(buf, 1, 13, ifP);
+
+    if (memcmp(buf, "MRF1", 4) != 0)
+        pm_error("Input is not an mrf image.  "
+                 "We know this because it does not start with 'MRF1'.");
+
+    if (buf[12] != 0)
+        pm_error("can't handle file subtype %u", buf[12]);
+
+    cols = (buf[4] << 24) | (buf[5] << 16) | (buf[06] << 8) | buf[07] << 0;
+    rows = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11] << 0;
+
+    /* w64 is units-of-64-bits width, h64 same for height */
+    w64 = (cols+63)/64;
+    h64 = (rows+63)/64;
+    if (expandAll) {
+        *colsP = w64*64;
+        *rowsP = h64*64;
+    } else {
+        *colsP = cols;
+        *rowsP = rows;
+    }
+
+    if (UINT_MAX/w64/64/h64/64 == 0)
+        pm_error("Ridiculously large, unprocessable image: %u cols x %u rows",
+                 cols, rows);
+
+    image = calloc(w64*h64*64*64,1);
+    if (image == NULL)
+        pm_error("Unable to get memory for raster");
+                 
+    /* now recursively input squares. */
+
+    bit_init();
+
+    {
+        unsigned int row;
+        for (row = 0; row < h64; ++row) {
+            unsigned int col;
+            for (col = 0; col < w64; ++col)
+                doSquare(ifP, image, col*64, row*64, w64*64, 64);
+        }
+    }
+    *imageP = image;
+}
+
+
+
+int 
+main(int argc, char *argv[]) {
+
+    FILE *ifP;
+    FILE *ofP;
+    unsigned char *image;
+    bool expandAll;
+    unsigned int cols, rows;
+
+    pbm_init(&argc, argv);
+
+    expandAll = FALSE;  /* initial assumption */
+
+    if (argc-1 >= 1 && STREQ(argv[1], "-a")) {
+        expandAll = TRUE;
+        argc--,argv++;
+    }
+
+    if (argc-1 > 1)
+        pm_error("Too many arguments: %d.  Only argument is input file",
+                 argc-1);
+
+    if (argc-1 == 1) 
+        ifP = pm_openr(argv[1]);
+    else
+        ifP = stdin;
+
+    ofP = stdout;
+
+    readMrfImage(ifP, expandAll, &image, &cols, &rows);
+    
+    pm_close(ifP);
+    
+    writeOutput(ofP, cols, rows, image);
+
+    free(image);
+
+    return 0;
+}
+
+
+
+
+
+