Created
July 30, 2022 13:20
-
-
Save wmcbrine/e753ce1da229c655f17f69ac57da93f9 to your computer and use it in GitHub Desktop.
Convert Compuserve RLE to Portable Bitmap format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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