FreeCalypso > hg > freecalypso-hwlab
comparison lunalcd/ppmtoimg.c @ 69:1e6f05ede5ca
lunalcd: ppmtoimg utility added
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 07 May 2020 00:12:54 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 68:72ff023ec6c9 | 69:1e6f05ede5ca |
|---|---|
| 1 /* | |
| 2 * This program converts a 176x220 pixel wallpaper image from PPM format | |
| 3 * into a raw binary image file that will be written into an ad hoc flash | |
| 4 * location with fc-loadtool; these images will then be displayed on our | |
| 5 * Luna LCD by a standalone target-utils program. | |
| 6 */ | |
| 7 | |
| 8 #include <stdio.h> | |
| 9 #include <ctype.h> | |
| 10 #include <stdlib.h> | |
| 11 | |
| 12 static char *ppm_filename; | |
| 13 static FILE *ppmfile; | |
| 14 static int ppm_is_ascii; /* P3 format instead of P6 */ | |
| 15 | |
| 16 /* | |
| 17 * This function reads one ASCII-encoded integer from a PPM file. | |
| 18 * It handles the white space and comment rules of the PPM format. | |
| 19 */ | |
| 20 static int | |
| 21 ppm_get_ascii_number() | |
| 22 { | |
| 23 int accum, c; | |
| 24 | |
| 25 do { | |
| 26 c = getc(ppmfile); | |
| 27 if (c < 0) { | |
| 28 badeof: fprintf(stderr, "%s: unexpected EOF\n", ppm_filename); | |
| 29 return(-1); | |
| 30 } | |
| 31 if (c == '#') { | |
| 32 do | |
| 33 c = getc(ppmfile); | |
| 34 while (c >= 0 && c != '\n'); | |
| 35 if (c != '\n') | |
| 36 goto badeof; | |
| 37 } | |
| 38 } while (isspace(c)); | |
| 39 if (!isdigit(c)) { | |
| 40 fprintf(stderr, | |
| 41 "%s: unexpected data where a number was expected\n", | |
| 42 ppm_filename); | |
| 43 return(-1); | |
| 44 } | |
| 45 for (accum = c - '0'; ; ) { | |
| 46 c = getc(ppmfile); | |
| 47 if (c < 0 || isspace(c)) | |
| 48 break; | |
| 49 if (!isdigit(c)) { | |
| 50 fprintf(stderr, | |
| 51 "%s: bad character in the middle of a number\n", | |
| 52 ppm_filename); | |
| 53 return(-1); | |
| 54 } | |
| 55 accum = accum * 10 + c - '0'; | |
| 56 } | |
| 57 return accum; | |
| 58 } | |
| 59 | |
| 60 /* | |
| 61 * This function reads and parses the PPM header of our input file. | |
| 62 */ | |
| 63 static int | |
| 64 ppm_read_header() | |
| 65 { | |
| 66 int magic1, magic2; | |
| 67 int rd; | |
| 68 | |
| 69 magic1 = getc(ppmfile); | |
| 70 magic2 = getc(ppmfile); | |
| 71 if (magic1 == 'P' && magic2 == '3') | |
| 72 ppm_is_ascii = 1; | |
| 73 else if (magic1 == 'P' && magic2 == '6') | |
| 74 ppm_is_ascii = 0; | |
| 75 else { | |
| 76 fprintf(stderr, "%s: P3 or P6 format expected\n", ppm_filename); | |
| 77 return(-1); | |
| 78 } | |
| 79 rd = ppm_get_ascii_number(); | |
| 80 if (rd < 0) | |
| 81 return(-1); | |
| 82 if (rd != 176) { | |
| 83 fprintf(stderr, "%s: width is not 176\n", ppm_filename); | |
| 84 return(-1); | |
| 85 } | |
| 86 rd = ppm_get_ascii_number(); | |
| 87 if (rd < 0) | |
| 88 return(-1); | |
| 89 if (rd != 220) { | |
| 90 fprintf(stderr, "%s: height is not 220\n", ppm_filename); | |
| 91 return(-1); | |
| 92 } | |
| 93 rd = ppm_get_ascii_number(); | |
| 94 if (rd < 0) | |
| 95 return(-1); | |
| 96 if (rd != 255) { | |
| 97 fprintf(stderr, "%s: maxval is not 255\n", ppm_filename); | |
| 98 return(-1); | |
| 99 } | |
| 100 return(0); | |
| 101 } | |
| 102 | |
| 103 /* | |
| 104 * This function reads a single R, G or B value from a PPM file. | |
| 105 */ | |
| 106 static int | |
| 107 ppm_get_pixval() | |
| 108 { | |
| 109 int c; | |
| 110 | |
| 111 if (ppm_is_ascii) | |
| 112 return ppm_get_ascii_number(); | |
| 113 c = getc(ppmfile); | |
| 114 if (c < 0) { | |
| 115 fprintf(stderr, "%s: EOF while reading binary pixel data\n", | |
| 116 ppm_filename); | |
| 117 return(-1); | |
| 118 } | |
| 119 return c; | |
| 120 } | |
| 121 | |
| 122 static int | |
| 123 ppm_get_rgb() | |
| 124 { | |
| 125 int r, g, b; | |
| 126 | |
| 127 r = ppm_get_pixval(); | |
| 128 if (r < 0) | |
| 129 return(-1); | |
| 130 g = ppm_get_pixval(); | |
| 131 if (g < 0) | |
| 132 return(-1); | |
| 133 b = ppm_get_pixval(); | |
| 134 if (b < 0) | |
| 135 return(-1); | |
| 136 /* convert to 5:6:5 */ | |
| 137 r >>= 3; | |
| 138 g >>= 2; | |
| 139 b >>= 3; | |
| 140 return (r << 11) | (g << 5) | b; | |
| 141 } | |
| 142 | |
| 143 main(argc, argv) | |
| 144 char **argv; | |
| 145 { | |
| 146 FILE *of; | |
| 147 int rc; | |
| 148 unsigned n; | |
| 149 | |
| 150 if (argc != 3) { | |
| 151 fprintf(stderr, "usage: %s ppmfile binfile\n", argv[0]); | |
| 152 exit(1); | |
| 153 } | |
| 154 ppm_filename = argv[1]; | |
| 155 ppmfile = fopen(ppm_filename, "r"); | |
| 156 if (!ppmfile) { | |
| 157 perror(ppm_filename); | |
| 158 exit(1); | |
| 159 } | |
| 160 rc = ppm_read_header(); | |
| 161 if (rc < 0) | |
| 162 exit(1); | |
| 163 of = fopen(argv[2], "w"); | |
| 164 if (!of) { | |
| 165 perror(argv[2]); | |
| 166 exit(1); | |
| 167 } | |
| 168 for (n = 0; n < 176*220; n++) { | |
| 169 rc = ppm_get_rgb(); | |
| 170 if (rc < 0) | |
| 171 exit(1); | |
| 172 putc(rc & 0xFF, of); | |
| 173 putc(rc >> 8, of); | |
| 174 } | |
| 175 fclose(of); | |
| 176 exit(0); | |
| 177 } |
