Skip to content

Instantly share code, notes, and snippets.

@wmcbrine
Created July 30, 2022 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmcbrine/e753ce1da229c655f17f69ac57da93f9 to your computer and use it in GitHub Desktop.
Save wmcbrine/e753ce1da229c655f17f69ac57da93f9 to your computer and use it in GitHub Desktop.
Convert Compuserve RLE to Portable Bitmap format
/* Convert Compuserve RLE images to Portable Bitmap format
* by William McBrine <wmcbrine@gmail.com>
* Placed in the public domain
*
* Version 2.0 - April 15, 2018
* - make P4 type of PBM instead of P1
* - only stop parsing on ESC or EOF
* - "medium" res are 96 lines
* Version 1.1 - October 16, 2005
* Version 1.0 - November 12, 2000
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *inp;
int c, width, pixels, maxwidth, maxlines, maxpix, last, done;
unsigned char acc;
if (argc > 1) {
inp = fopen(argv[1], "rb");
if (!inp)
return EXIT_FAILURE;
} else
inp = stdin;
c = fgetc(inp);
/* Normally first char is ESC, sometimes omitted */
if (27 == c)
c = fgetc(inp);
if ('G' == c)
c = fgetc(inp);
else
return EXIT_FAILURE;
switch (c) {
case 'H': /* High resolution (normal) */
maxwidth = 256;
maxlines = 192;
break;
case 'M': /* Medium resolution -- I've never seen
one of these, but just in case */
maxwidth = 128;
maxlines = 96;
break;
default:
return EXIT_FAILURE;
}
maxpix = maxwidth * maxlines;
width = 0;
pixels = 0;
last = 0;
done = 0;
acc = 0;
printf("P4\n%d %d\n", maxwidth, maxlines);
while (!done && ((c = fgetc(inp)) != EOF))
if (c >= ' ') {
c -= ' ';
last = !last;
while (c-- && !done) {
acc |= last;
width++;
pixels++;
if (8 == width) {
putchar(acc);
acc = 0;
width = 0;
if (pixels >= maxpix)
done = 1;
}
else
acc <<= 1;
}
} else
if (27 == c)
done = 1;
if (width)
putchar(acc << (7 - width));
if (argc > 1)
fclose(inp);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment