# HG changeset patch # User Mychaela Falconia # Date 1588810374 0 # Node ID 1e6f05ede5ca4466101417c7d6ad3820d6a2081f # Parent 72ff023ec6c94350818c2225da04148c6d1209f0 lunalcd: ppmtoimg utility added diff -r 72ff023ec6c9 -r 1e6f05ede5ca .hgignore --- a/.hgignore Fri May 01 03:18:08 2020 +0000 +++ b/.hgignore Thu May 07 00:12:54 2020 +0000 @@ -20,3 +20,4 @@ ^lunalcd/gen-ht-init$ ^lunalcd/gen-st-init$ ^lunalcd/ppmtocmd$ +^lunalcd/ppmtoimg$ diff -r 72ff023ec6c9 -r 1e6f05ede5ca lunalcd/Makefile --- a/lunalcd/Makefile Fri May 01 03:18:08 2020 +0000 +++ b/lunalcd/Makefile Thu May 07 00:12:54 2020 +0000 @@ -1,6 +1,6 @@ CC= gcc CFLAGS= -O2 -PROGS= gen-ht-init gen-st-init ppmtocmd +PROGS= gen-ht-init gen-st-init ppmtocmd ppmtoimg HTINIT_OBJS= common.o initmain.o haoran.o STINIT_OBJS= common.o initmain.o startek.o @@ -17,5 +17,8 @@ ppmtocmd: ${PPMCONV_OBJS} ${CC} -o $@ ${PPMCONV_OBJS} +ppmtoimg: ppmtoimg.c + ${CC} ${CFLAGS} -o $@ $@.c + clean: rm -f ${PROGS} *.o diff -r 72ff023ec6c9 -r 1e6f05ede5ca lunalcd/ppmtoimg.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lunalcd/ppmtoimg.c Thu May 07 00:12:54 2020 +0000 @@ -0,0 +1,177 @@ +/* + * This program converts a 176x220 pixel wallpaper image from PPM format + * into a raw binary image file that will be written into an ad hoc flash + * location with fc-loadtool; these images will then be displayed on our + * Luna LCD by a standalone target-utils program. + */ + +#include +#include +#include + +static char *ppm_filename; +static FILE *ppmfile; +static int ppm_is_ascii; /* P3 format instead of P6 */ + +/* + * This function reads one ASCII-encoded integer from a PPM file. + * It handles the white space and comment rules of the PPM format. + */ +static int +ppm_get_ascii_number() +{ + int accum, c; + + do { + c = getc(ppmfile); + if (c < 0) { +badeof: fprintf(stderr, "%s: unexpected EOF\n", ppm_filename); + return(-1); + } + if (c == '#') { + do + c = getc(ppmfile); + while (c >= 0 && c != '\n'); + if (c != '\n') + goto badeof; + } + } while (isspace(c)); + if (!isdigit(c)) { + fprintf(stderr, + "%s: unexpected data where a number was expected\n", + ppm_filename); + return(-1); + } + for (accum = c - '0'; ; ) { + c = getc(ppmfile); + if (c < 0 || isspace(c)) + break; + if (!isdigit(c)) { + fprintf(stderr, + "%s: bad character in the middle of a number\n", + ppm_filename); + return(-1); + } + accum = accum * 10 + c - '0'; + } + return accum; +} + +/* + * This function reads and parses the PPM header of our input file. + */ +static int +ppm_read_header() +{ + int magic1, magic2; + int rd; + + magic1 = getc(ppmfile); + magic2 = getc(ppmfile); + if (magic1 == 'P' && magic2 == '3') + ppm_is_ascii = 1; + else if (magic1 == 'P' && magic2 == '6') + ppm_is_ascii = 0; + else { + fprintf(stderr, "%s: P3 or P6 format expected\n", ppm_filename); + return(-1); + } + rd = ppm_get_ascii_number(); + if (rd < 0) + return(-1); + if (rd != 176) { + fprintf(stderr, "%s: width is not 176\n", ppm_filename); + return(-1); + } + rd = ppm_get_ascii_number(); + if (rd < 0) + return(-1); + if (rd != 220) { + fprintf(stderr, "%s: height is not 220\n", ppm_filename); + return(-1); + } + rd = ppm_get_ascii_number(); + if (rd < 0) + return(-1); + if (rd != 255) { + fprintf(stderr, "%s: maxval is not 255\n", ppm_filename); + return(-1); + } + return(0); +} + +/* + * This function reads a single R, G or B value from a PPM file. + */ +static int +ppm_get_pixval() +{ + int c; + + if (ppm_is_ascii) + return ppm_get_ascii_number(); + c = getc(ppmfile); + if (c < 0) { + fprintf(stderr, "%s: EOF while reading binary pixel data\n", + ppm_filename); + return(-1); + } + return c; +} + +static int +ppm_get_rgb() +{ + int r, g, b; + + r = ppm_get_pixval(); + if (r < 0) + return(-1); + g = ppm_get_pixval(); + if (g < 0) + return(-1); + b = ppm_get_pixval(); + if (b < 0) + return(-1); + /* convert to 5:6:5 */ + r >>= 3; + g >>= 2; + b >>= 3; + return (r << 11) | (g << 5) | b; +} + +main(argc, argv) + char **argv; +{ + FILE *of; + int rc; + unsigned n; + + if (argc != 3) { + fprintf(stderr, "usage: %s ppmfile binfile\n", argv[0]); + exit(1); + } + ppm_filename = argv[1]; + ppmfile = fopen(ppm_filename, "r"); + if (!ppmfile) { + perror(ppm_filename); + exit(1); + } + rc = ppm_read_header(); + if (rc < 0) + exit(1); + of = fopen(argv[2], "w"); + if (!of) { + perror(argv[2]); + exit(1); + } + for (n = 0; n < 176*220; n++) { + rc = ppm_get_rgb(); + if (rc < 0) + exit(1); + putc(rc & 0xFF, of); + putc(rc >> 8, of); + } + fclose(of); + exit(0); +}