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 } |