diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2009-07-05 20:45:55 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2009-07-05 20:45:55 +0000 |
commit | 86f0bc22ea104a5f4c6c080c01b0f4c58055a66b (patch) | |
tree | 8ed784aefa330bea9e9e4a467d6b181dd31afeaa /converter | |
parent | c4b85320d842cac043c9d6cb68da2a7855f24caf (diff) | |
download | netpbm-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
Diffstat (limited to 'converter')
-rw-r--r-- | converter/pbm/Makefile | 5 | ||||
-rw-r--r-- | converter/pbm/cistopbm.c | 180 | ||||
-rw-r--r-- | converter/pbm/pbmtocis.c | 170 |
3 files changed, 353 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; +} |