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