about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-07-05 20:45:55 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-07-05 20:45:55 +0000
commit86f0bc22ea104a5f4c6c080c01b0f4c58055a66b (patch)
tree8ed784aefa330bea9e9e4a467d6b181dd31afeaa
parentc4b85320d842cac043c9d6cb68da2a7855f24caf (diff)
downloadnetpbm-mirror-86f0bc22ea104a5f4c6c080c01b0f4c58055a66b.tar.gz
netpbm-mirror-86f0bc22ea104a5f4c6c080c01b0f4c58055a66b.tar.xz
netpbm-mirror-86f0bc22ea104a5f4c6c080c01b0f4c58055a66b.zip
Add Cistopbm, Pbmtocis
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@947 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/pbm/Makefile5
-rw-r--r--converter/pbm/cistopbm.c180
-rw-r--r--converter/pbm/pbmtocis.c170
-rw-r--r--doc/HISTORY3
4 files changed, 356 insertions, 2 deletions
diff --git a/converter/pbm/Makefile b/converter/pbm/Makefile
index c859b105..0461eedc 100644
--- a/converter/pbm/Makefile
+++ b/converter/pbm/Makefile
@@ -7,10 +7,11 @@ VPATH=.:$(SRCDIR)/$(SUBDIR)
 
 include $(BUILDDIR)/config.mk
 
-PORTBINARIES =	atktopbm brushtopbm cmuwmtopbm ddbugtopbm g3topbm escp2topbm \
+PORTBINARIES =	atktopbm brushtopbm cistopbm cmuwmtopbm \
+		ddbugtopbm g3topbm escp2topbm \
 		icontopbm macptopbm mdatopbm mgrtopbm mrftopbm \
 		pbmto10x pbmto4425 pbmtoascii pbmtoatk \
-		pbmtobbnbg pbmtocmuwm pbmtodjvurle \
+		pbmtobbnbg pbmtocis pbmtocmuwm pbmtodjvurle \
 		pbmtoepsi pbmtoepson pbmtoescp2 \
 		pbmtog3 pbmtogem pbmtogo pbmtoibm23xx pbmtoicon pbmtolj \
 		pbmtoln03 pbmtolps \
diff --git a/converter/pbm/cistopbm.c b/converter/pbm/cistopbm.c
new file mode 100644
index 00000000..591e2aa5
--- /dev/null
+++ b/converter/pbm/cistopbm.c
@@ -0,0 +1,180 @@
+/*
+ *  cistopbm: Convert images in the CompuServe RLE format to PBM
+ *  Copyright (C) 2009  John Elliott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pbm.h"
+
+
+static void syntax(const char *prog)
+{
+        pm_usage(" { options } { input }\n\n"
+                 "Input file should be in CompuServe RLE format.\n"
+                 "Output file will be in PBM format.\n"
+                 "Options:\n"
+                 "-i, --inverse: Reverse black and white.\n"
+                 "--:            End of options\n\n"
+"cistopbm v1.01, Copyright 2009 John Elliott <jce@seasip.demon.co.uk>\n"
+"This program is redistributable under the terms of the GNU General Public\n"
+"License, version 2 or later.\n"
+                 );
+}
+
+int main(int argc, const char **argv)
+{
+    FILE *ifP;
+    int c[3];
+    int inoptions = 1;
+    int n, x, y;
+    int bw = PBM_BLACK;     /* Default colouring is white on black */
+    const char *inpname = NULL;
+    int height, width;
+    bit **bits;
+
+    pm_proginit(&argc, argv);
+
+    for (n = 1; n < argc; n++)
+    {
+        if (!strcmp(argv[n], "--"))
+        {
+            inoptions = 0;
+            continue;
+        }
+        if (inoptions)
+        {
+            if (pm_keymatch(argv[n], "-h", 2) ||
+                pm_keymatch(argv[n], "-H", 2) ||
+                pm_keymatch(argv[n], "--help", 6))
+            {
+                syntax(argv[0]);
+                return EXIT_SUCCESS;
+            }
+            if (pm_keymatch(argv[n], "-i", 2) ||
+                pm_keymatch(argv[n], "-I", 2) ||
+                pm_keymatch(argv[n], "--inverse", 9))
+            {
+                bw ^= (PBM_WHITE ^ PBM_BLACK);
+                continue;
+            }
+            if (argv[n][0] == '-' && argv[n][1] != 0)
+            {
+                pm_message("Unknown option: %s", argv[n]);
+                syntax(argv[0]);
+                return EXIT_FAILURE;
+            }
+        }
+
+        if (inpname == NULL) inpname = argv[n];
+        else { syntax(argv[0]); return EXIT_FAILURE; }
+    }
+    if (inpname == NULL) inpname = "-";
+    ifP  = pm_openr(inpname);
+
+    /* There may be junk before the magic number. If so, skip it. */
+    x = 0;
+    c[0] = c[1] = c[2] = EOF;
+
+    /* Read until the array c[] holds the magic number. */
+    do
+    {
+        c[0] = c[1];
+        c[1] = c[2];
+        c[2] = fgetc(ifP);
+
+        /* If character read was EOF, end of file was reached and magic number
+         * not found.
+         */
+        if (c[2] == EOF)
+        {
+            pm_error("Input file is not in CompuServe RLE format");
+        }
+        ++x;
+    } while (c[0] != 0x1B || c[1] != 0x47);
+
+    /* x = number of bytes read. Should be 3 if signature is at the start */
+    if (x > 3)
+    {
+        pm_message("Warning: %d bytes of junk skipped before image",
+                   x - 3);
+    }
+    /* Parse the resolution */
+    switch(c[2])
+    {
+    case 0x48:      height = 192; width = 256; break;
+    case 0x4D:      height =  96; width = 128; break;
+    default:        pm_error("Unknown resolution 0x%02x", c[2]);
+        break;
+    }
+    /* Convert the data */
+    bits = pbm_allocarray(width, height);
+    x = y = 0;
+    do
+    {
+        c[0] = fgetc(ifP);
+
+        /* Stop if we hit EOF or Escape */
+        if (c[0] == EOF)  break;        /* EOF */
+        if (c[0] == 0x1B) break;        /* End of graphics */
+        /* Other non-printing characters are ignored; some files contain a
+         * BEL
+         */
+        if (c[0] < 0x20)  continue;
+
+        /* Each character gives the number of pixels to draw in the appropriate
+         * colour.
+         */
+        for (n = 0x20; n < c[0]; n++)
+        {
+            if (x < width && y < height) bits[y][x] = bw;
+            x++;
+            /* Wrap at end of line */
+            if (x >= width)
+            {
+                x = 0;
+                y++;
+            }
+        }
+        /* And toggle colours */
+        bw ^= (PBM_WHITE ^ PBM_BLACK);
+    }
+    while (1);
+
+    /* See if the end-graphics signature (ESC G N) is present. */
+    c[1] = EOF;
+    if (c[0] == 0x1B)
+    {
+        c[1] = fgetc(ifP);
+        c[2] = fgetc(ifP);
+    }
+    if (c[0] != 0x1B || c[1] != 0x47 || c[2] != 0x4E)
+    {
+        pm_message("Warning: End-graphics signature not found");
+    }
+    /* See if we decoded the right number of pixels */
+    if (x != 0 || y != height)
+    {
+        pm_message("Warning: %d pixels found, should be %d",
+                   y * width + x, width * height);
+    }
+    pbm_writepbm(stdout, bits, width, height, 0);
+    pm_close(ifP);
+    return 0;       
+}
diff --git a/converter/pbm/pbmtocis.c b/converter/pbm/pbmtocis.c
new file mode 100644
index 00000000..9bb42c56
--- /dev/null
+++ b/converter/pbm/pbmtocis.c
@@ -0,0 +1,170 @@
+/*
+ *  cistopbm: Convert images in the CompuServe RLE format to PBM
+ *  Copyright (C) 2009  John Elliott
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pbm.h"
+
+/* The maximum length of a run. Limit it to 0x5E bytes so that it is always
+ * represented by a printable character 0x20-0x7E */
+#define MAXRUNLENGTH 0x5E
+
+static void syntax(const char *prog)
+{
+    pm_usage(" { options } { input } }\n\n"
+         "Input file should be in PBM format.\n"
+         "Output will be in CompuServe RLE format.\n"
+         "Options:\n"
+         "-i, --inverse: Reverse black and white.\n"
+         "-w, --whitebg: White background.\n"
+         "--:            End of options\n\n"
+"pbmtocis v1.00, Copyright 2009 John Elliott <jce@seasip.demon.co.uk>\n"
+"This program is redistributable under the terms of the GNU General Public\n"
+"License, version 2 or later.\n"
+         );
+}
+
+int main(int argc, const char **argv)
+{
+    FILE *ofP = stdout;
+    FILE *ifP;
+    int inoptions = 1;
+    int n, x, y;
+    int bg = PBM_BLACK; /* Default colouring is white on black */
+    int inverse = 0;
+    int cell, last, run;
+    const char *inpname = NULL;
+
+    int outh, outw;
+    int height, width;
+    bit **bits;
+
+    pm_proginit(&argc, argv);
+
+    for (n = 1; n < argc; n++)
+    {
+        if (!strcmp(argv[n], "--"))
+        {
+            inoptions = 0;
+            continue;
+        }
+        if (inoptions)
+        {
+            if (pm_keymatch(argv[n], "-h", 2) ||
+                pm_keymatch(argv[n], "-H", 2) ||
+                pm_keymatch(argv[n], "--help", 6))
+            {
+                syntax(argv[0]);
+                return EXIT_SUCCESS;
+            }
+            if (pm_keymatch(argv[n], "-i", 2) ||
+                pm_keymatch(argv[n], "-I", 2) ||
+                pm_keymatch(argv[n], "--inverse", 9))
+            {
+                inverse = 1;
+                continue;
+            }
+            if (pm_keymatch(argv[n], "-w", 2) ||
+                pm_keymatch(argv[n], "-W", 2) ||
+                pm_keymatch(argv[n], "--whitebg", 9))
+            {
+                bg = PBM_WHITE; 
+                continue;
+            }
+            if (argv[n][0] == '-' && argv[n][1] != 0)
+            {
+                pm_message("Unknown option: %s", argv[n]);
+                syntax(argv[0]);
+                return EXIT_FAILURE;
+            }
+        }
+
+        if (inpname == NULL) inpname = argv[n];
+        else { syntax(argv[0]); return EXIT_FAILURE; }
+    }
+    if (inpname == NULL) inpname = "-";
+    ifP  = pm_openr(inpname);
+
+    /* Load the PBM */
+    bits = pbm_readpbm(ifP, &width, &height);
+
+    if      (width <= 128 && height <= 96)  { outw = 128; outh = 96; }
+    else if (width <= 256 && height <= 192) { outw = 256; outh = 192; }
+    else
+    {
+        outw = 256;
+        outh = 192;
+        pm_message("Warning: Input file is larger than 256x192. "
+                "It will be cropped.");
+    }
+    /* Write the magic number */
+    fputc(0x1B, ofP);
+    fputc(0x47, ofP);
+    fputc((outw == 128) ? 0x4D : 0x48, ofP);
+
+    /* And now start encoding */
+    y = x = 0;
+    last = PBM_BLACK;
+    run = 0;
+    while (y < outh)
+    {
+        if (x < width && y < height)    
+        {
+            cell = bits[y][x];
+            if (inverse) cell ^= (PBM_BLACK ^ PBM_WHITE);
+        }
+        else cell = bg;
+
+        if (cell == last)   /* Cell is part of current run */
+        {
+            ++run;
+            if (run > MAXRUNLENGTH)
+            {       
+                fputc(0x20 + MAXRUNLENGTH, ofP);
+                fputc(0x20, ofP);
+                run -= MAXRUNLENGTH;
+            }   
+        }
+        else    /* change */
+        {
+            fputc(run + 0x20, ofP);
+            last = last ^ (PBM_BLACK ^ PBM_WHITE);
+            run = 1;
+        }
+        ++x;
+        if (x >= outw) { x = 0; ++y; }
+    }
+    if (last == bg) /* Last cell written was background. Write foreground */
+    {
+        fputc(run + 0x20, ofP);
+    }
+    else if (run)   /* Write background and foreground */
+    {
+        fputc(run + 0x20, ofP);
+        fputc(0x20, ofP);
+    }
+    /* Write the end-graphics signature */
+    fputc(0x1B, ofP);
+    fputc(0x47, ofP);
+    fputc(0x4E, ofP);
+    pm_close(ifP);
+    return 0;   
+}
diff --git a/doc/HISTORY b/doc/HISTORY
index b0280d98..173cee69 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -6,6 +6,9 @@ CHANGE HISTORY
 
 not yet  BJH  Release 10.48.00
 
+              Add pbmtocis, cistopbm.  Thanks John Elliott
+              <jce@seasip.demon.co.uk>.
+
 09.06.27 BJH  Release 10.47.00
 
               Add pamsistoaglyph.  Thanks Scott Pakin.