Blame


1 28994509 2004-04-21 devnull /* jpeg parser by tom szymanski */
2 28994509 2004-04-21 devnull #include <stddef.h>
3 28994509 2004-04-21 devnull #include <stdlib.h>
4 28994509 2004-04-21 devnull #include <stdio.h>
5 28994509 2004-04-21 devnull #include <string.h>
6 28994509 2004-04-21 devnull #include <math.h>
7 28994509 2004-04-21 devnull #include <ctype.h>
8 28994509 2004-04-21 devnull
9 28994509 2004-04-21 devnull /* subroutines done by macros */
10 28994509 2004-04-21 devnull #define min(A,B) ((A)<(B) ? (A) : (B))
11 28994509 2004-04-21 devnull #define max(A,B) ((A)>(B) ? (A) : (B))
12 28994509 2004-04-21 devnull #define maxeql(A,B) if (A < (B)) A = (B);
13 28994509 2004-04-21 devnull #define mineql(A,B) if (A > (B)) A = (B);
14 28994509 2004-04-21 devnull #define eatarg0 (argc--, argv++)
15 28994509 2004-04-21 devnull #define arrayLength(A) ((sizeof A)/ (sizeof A[0]))
16 28994509 2004-04-21 devnull
17 28994509 2004-04-21 devnull FILE *infile;
18 28994509 2004-04-21 devnull char *fname;
19 28994509 2004-04-21 devnull
20 28994509 2004-04-21 devnull /* Routines to print error messages of varying severity */
21 28994509 2004-04-21 devnull
22 28994509 2004-04-21 devnull /* externally visible variables */
23 28994509 2004-04-21 devnull int warncnt;
24 28994509 2004-04-21 devnull char *myname;
25 28994509 2004-04-21 devnull
26 28994509 2004-04-21 devnull void getname (char *arg) {
27 28994509 2004-04-21 devnull /* Save name of invoking program for use by error routines */
28 28994509 2004-04-21 devnull register char *p;
29 28994509 2004-04-21 devnull p = strrchr (arg, '/');
30 28994509 2004-04-21 devnull if (p == NULL)
31 28994509 2004-04-21 devnull myname = arg;
32 28994509 2004-04-21 devnull else
33 28994509 2004-04-21 devnull myname = ++p;
34 28994509 2004-04-21 devnull }
35 28994509 2004-04-21 devnull
36 28994509 2004-04-21 devnull static void introduction (void) {
37 28994509 2004-04-21 devnull warncnt++;
38 28994509 2004-04-21 devnull fflush (stdout);
39 28994509 2004-04-21 devnull if (myname != NULL)
40 28994509 2004-04-21 devnull fprintf (stderr, "%s: ", myname);
41 28994509 2004-04-21 devnull }
42 28994509 2004-04-21 devnull
43 28994509 2004-04-21 devnull void warn (char *fmt, ...) {
44 28994509 2004-04-21 devnull va_list args;
45 28994509 2004-04-21 devnull introduction ();
46 28994509 2004-04-21 devnull va_start (args, fmt);
47 28994509 2004-04-21 devnull vfprintf (stderr, fmt, args);
48 28994509 2004-04-21 devnull va_end (args);
49 28994509 2004-04-21 devnull fputc ('\n', stderr);
50 28994509 2004-04-21 devnull fflush (stderr);
51 28994509 2004-04-21 devnull }
52 28994509 2004-04-21 devnull
53 28994509 2004-04-21 devnull void quit (char *fmt, ...) {
54 28994509 2004-04-21 devnull va_list args;
55 28994509 2004-04-21 devnull introduction ();
56 28994509 2004-04-21 devnull va_start (args, fmt);
57 28994509 2004-04-21 devnull vfprintf (stderr, fmt, args);
58 28994509 2004-04-21 devnull va_end (args);
59 28994509 2004-04-21 devnull fputc ('\n', stderr);
60 28994509 2004-04-21 devnull fflush (stderr);
61 28994509 2004-04-21 devnull exit (1);
62 28994509 2004-04-21 devnull }
63 28994509 2004-04-21 devnull
64 28994509 2004-04-21 devnull void fatal (char *fmt, ...) {
65 28994509 2004-04-21 devnull va_list args;
66 28994509 2004-04-21 devnull introduction ();
67 28994509 2004-04-21 devnull va_start (args, fmt);
68 28994509 2004-04-21 devnull vfprintf (stderr, fmt, args);
69 28994509 2004-04-21 devnull va_end (args);
70 28994509 2004-04-21 devnull fprintf (stderr, "\nbetter get help!\n");
71 28994509 2004-04-21 devnull fflush (stderr);
72 28994509 2004-04-21 devnull abort ();
73 28994509 2004-04-21 devnull }
74 28994509 2004-04-21 devnull
75 28994509 2004-04-21 devnull int toption = 0;
76 28994509 2004-04-21 devnull int dqt[16][64];
77 28994509 2004-04-21 devnull
78 28994509 2004-04-21 devnull int get1 (void) {
79 28994509 2004-04-21 devnull unsigned char x;
80 28994509 2004-04-21 devnull if (fread(&x, 1, 1, infile) == 0)
81 28994509 2004-04-21 devnull quit ("unexpected EOF");
82 28994509 2004-04-21 devnull return x;
83 28994509 2004-04-21 devnull }
84 28994509 2004-04-21 devnull
85 28994509 2004-04-21 devnull int get2 (void) {
86 28994509 2004-04-21 devnull int x;
87 28994509 2004-04-21 devnull
88 28994509 2004-04-21 devnull x = get1() << 8;
89 28994509 2004-04-21 devnull return x | get1();
90 28994509 2004-04-21 devnull }
91 28994509 2004-04-21 devnull
92 28994509 2004-04-21 devnull void eatmarker (int kind) {
93 28994509 2004-04-21 devnull int l, c;
94 28994509 2004-04-21 devnull l = get2();
95 28994509 2004-04-21 devnull printf ("%02x len=%d\n", kind, l);
96 28994509 2004-04-21 devnull for (l -= 2; l > 0; l--)
97 28994509 2004-04-21 devnull get1();
98 28994509 2004-04-21 devnull }
99 28994509 2004-04-21 devnull
100 28994509 2004-04-21 devnull char *sofName[16] = {
101 28994509 2004-04-21 devnull "Baseline sequential DCT - Huffman coding",
102 28994509 2004-04-21 devnull "Extended sequential DCT - Huffman coding",
103 28994509 2004-04-21 devnull "Progressive DCT - Huffman coding",
104 28994509 2004-04-21 devnull "Lossless - Huffman coding",
105 28994509 2004-04-21 devnull "4 is otherwise used",
106 28994509 2004-04-21 devnull "Sequential DCT - differential Huffman coding",
107 28994509 2004-04-21 devnull "Progressive DCT - differential Huffman coding",
108 28994509 2004-04-21 devnull "Lossless - differential Huffman coding",
109 28994509 2004-04-21 devnull "8 is reserved",
110 28994509 2004-04-21 devnull "Extended Sequential DCT - arithmetic coding",
111 28994509 2004-04-21 devnull "Progressive DCT - arithmetic coding",
112 28994509 2004-04-21 devnull "Lossless - arithmetic coding",
113 28994509 2004-04-21 devnull "c is otherwise used",
114 28994509 2004-04-21 devnull "Sequential DCT - differential arithmetic coding",
115 28994509 2004-04-21 devnull "Progressive DCT - differential arithmetic coding",
116 cbeb0b26 2006-04-01 devnull "Lossless - differential arithmetic coding"
117 28994509 2004-04-21 devnull };
118 28994509 2004-04-21 devnull
119 28994509 2004-04-21 devnull void get_sof (int kind) {
120 28994509 2004-04-21 devnull int i, length, height, width, precision, ncomponents;
121 28994509 2004-04-21 devnull int id, sf, tab;
122 28994509 2004-04-21 devnull length = get2();
123 28994509 2004-04-21 devnull precision = get1();
124 28994509 2004-04-21 devnull height = get2();
125 28994509 2004-04-21 devnull width = get2();
126 28994509 2004-04-21 devnull ncomponents = get1();
127 28994509 2004-04-21 devnull printf ("SOF%d:\t%s\n", kind - 0xc0, sofName[kind - 0xc0]);
128 28994509 2004-04-21 devnull printf ("\t%d wide, %d high, %d deep, %d components\n",
129 28994509 2004-04-21 devnull width, height, precision, ncomponents);
130 28994509 2004-04-21 devnull for (i = 0; i < ncomponents; i++) {
131 28994509 2004-04-21 devnull id = get1();
132 28994509 2004-04-21 devnull sf = get1();
133 28994509 2004-04-21 devnull tab = get1();
134 28994509 2004-04-21 devnull printf ("\tcomponent %d: %d hsample, %d vsample, quantization table %d\n",
135 28994509 2004-04-21 devnull id, sf >> 4, sf & 0xf, tab);
136 28994509 2004-04-21 devnull }
137 28994509 2004-04-21 devnull }
138 28994509 2004-04-21 devnull
139 28994509 2004-04-21 devnull void get_com (int kind) {
140 28994509 2004-04-21 devnull int l, c;
141 28994509 2004-04-21 devnull l = get2();
142 28994509 2004-04-21 devnull printf ("COM len=%d '", l);
143 28994509 2004-04-21 devnull for (l -= 2; l > 0; l--)
144 28994509 2004-04-21 devnull putchar (c = get1());
145 28994509 2004-04-21 devnull printf ("'\n");
146 28994509 2004-04-21 devnull }
147 28994509 2004-04-21 devnull
148 28994509 2004-04-21 devnull void get_app (int kind) {
149 28994509 2004-04-21 devnull int l, c, first;
150 28994509 2004-04-21 devnull char buf[6];
151 28994509 2004-04-21 devnull int nbuf, nok;
152 28994509 2004-04-21 devnull l = get2();
153 28994509 2004-04-21 devnull printf ("APP%d len=%d\n", kind - 0xe0, l);
154 28994509 2004-04-21 devnull nbuf = 0;
155 28994509 2004-04-21 devnull nok = 0;
156 28994509 2004-04-21 devnull first = 1;
157 28994509 2004-04-21 devnull /* dump printable strings in comment */
158 28994509 2004-04-21 devnull for (l -= 2; l > 0; l--){
159 28994509 2004-04-21 devnull c = get1();
160 28994509 2004-04-21 devnull if(isprint(c)){
161 28994509 2004-04-21 devnull if(nbuf >= sizeof buf){
162 28994509 2004-04-21 devnull if(!first && nbuf == nok)
163 28994509 2004-04-21 devnull printf(" ");
164 28994509 2004-04-21 devnull printf("%.*s", nbuf, buf);
165 28994509 2004-04-21 devnull nbuf = 0;
166 28994509 2004-04-21 devnull first = 0;
167 28994509 2004-04-21 devnull }
168 28994509 2004-04-21 devnull buf[nbuf++] = c;
169 28994509 2004-04-21 devnull nok++;
170 28994509 2004-04-21 devnull }else{
171 28994509 2004-04-21 devnull if(nok >= sizeof buf)
172 28994509 2004-04-21 devnull if(nbuf > 0)
173 28994509 2004-04-21 devnull printf("%.*s", nbuf, buf);
174 28994509 2004-04-21 devnull nbuf = 0;
175 28994509 2004-04-21 devnull nok = 0;
176 28994509 2004-04-21 devnull }
177 28994509 2004-04-21 devnull }
178 28994509 2004-04-21 devnull if(nok >= sizeof buf)
179 28994509 2004-04-21 devnull if(nbuf > 0){
180 28994509 2004-04-21 devnull if(!first && nbuf == nok)
181 28994509 2004-04-21 devnull printf(" ");
182 28994509 2004-04-21 devnull printf("%.*s", nbuf, buf);
183 28994509 2004-04-21 devnull }
184 28994509 2004-04-21 devnull }
185 28994509 2004-04-21 devnull
186 28994509 2004-04-21 devnull void get_dac (int kind) {
187 28994509 2004-04-21 devnull eatmarker (kind);
188 28994509 2004-04-21 devnull }
189 28994509 2004-04-21 devnull
190 28994509 2004-04-21 devnull int get1dqt (void) {
191 28994509 2004-04-21 devnull int t, p, i, *tab;
192 28994509 2004-04-21 devnull t = get1();
193 28994509 2004-04-21 devnull p = t >> 4;
194 28994509 2004-04-21 devnull t = t & 0xf;
195 28994509 2004-04-21 devnull printf ("DQT:\tp = %d, table = %d\n", p, t);
196 28994509 2004-04-21 devnull tab = &dqt[t][0];
197 28994509 2004-04-21 devnull for (i = 0; i < 64; i++)
198 28994509 2004-04-21 devnull tab[i] = p ? get2() : get1();
199 28994509 2004-04-21 devnull if (toption) {
200 28994509 2004-04-21 devnull for (i = 0; i < 64; i++)
201 28994509 2004-04-21 devnull printf ("\t%q[%02d] = %d\n", i, tab[i]);
202 28994509 2004-04-21 devnull }
203 28994509 2004-04-21 devnull return p ? 65 : 129;
204 28994509 2004-04-21 devnull }
205 28994509 2004-04-21 devnull
206 28994509 2004-04-21 devnull void get_dqt (int kind) {
207 28994509 2004-04-21 devnull int length;
208 28994509 2004-04-21 devnull length = get2() - 2;
209 28994509 2004-04-21 devnull while (length > 0)
210 28994509 2004-04-21 devnull length -= get1dqt();
211 28994509 2004-04-21 devnull }
212 28994509 2004-04-21 devnull
213 28994509 2004-04-21 devnull int get1dht (void) {
214 28994509 2004-04-21 devnull int l, tcth, p, i, j, v[16], vv[16][256];
215 28994509 2004-04-21 devnull tcth = get1();
216 28994509 2004-04-21 devnull printf ("DHT:\tclass = %d, table = %d\n", tcth >> 4, tcth & 0xf);
217 28994509 2004-04-21 devnull for (i = 0; i < 16; i++)
218 28994509 2004-04-21 devnull v[i] = get1();
219 28994509 2004-04-21 devnull l = 17;
220 28994509 2004-04-21 devnull for (i = 0; i < 16; i++)
221 28994509 2004-04-21 devnull for (j = 0; j < v[i]; j++) {
222 28994509 2004-04-21 devnull vv[i][j] = get1();
223 28994509 2004-04-21 devnull l += 1;
224 28994509 2004-04-21 devnull }
225 28994509 2004-04-21 devnull if (toption) {
226 28994509 2004-04-21 devnull for (i = 0; i < 16; i++)
227 28994509 2004-04-21 devnull printf ("\t%l[%02d] = %d\n", i+1, v[i]);
228 28994509 2004-04-21 devnull for (i = 0; i < 16; i++)
229 28994509 2004-04-21 devnull for (j = 0; j < v[i]; j++)
230 28994509 2004-04-21 devnull printf ("\t%v[%02d,%02d] = %d\n", i+1, j+1, vv[i][j]);
231 28994509 2004-04-21 devnull }
232 28994509 2004-04-21 devnull return l;
233 28994509 2004-04-21 devnull }
234 28994509 2004-04-21 devnull
235 28994509 2004-04-21 devnull void get_dht (int kind) {
236 28994509 2004-04-21 devnull int length;
237 28994509 2004-04-21 devnull length = get2() - 2;
238 28994509 2004-04-21 devnull while (length > 0)
239 28994509 2004-04-21 devnull length -= get1dht();
240 28994509 2004-04-21 devnull }
241 28994509 2004-04-21 devnull
242 28994509 2004-04-21 devnull void get_sos (int kind) {
243 28994509 2004-04-21 devnull int i, length, ncomponents, id, dcac, ahal;
244 28994509 2004-04-21 devnull length = get2();
245 28994509 2004-04-21 devnull ncomponents = get1();
246 28994509 2004-04-21 devnull printf ("SOS:\t%d components\n", ncomponents);
247 28994509 2004-04-21 devnull for (i = 0; i < ncomponents; i++) {
248 28994509 2004-04-21 devnull id = get1();
249 28994509 2004-04-21 devnull dcac = get1();
250 28994509 2004-04-21 devnull printf ("\tcomponent %d: %d DC, %d AC\n", id, dcac >> 4, dcac & 0xf);
251 28994509 2004-04-21 devnull }
252 28994509 2004-04-21 devnull printf ("\tstart spectral %d\n", get1());
253 28994509 2004-04-21 devnull printf ("\tend spectral %d\n", get1());
254 28994509 2004-04-21 devnull ahal = get1();
255 28994509 2004-04-21 devnull printf ("\tah = %d, al = %d\n", ahal >> 4, ahal &0xf);
256 28994509 2004-04-21 devnull }
257 28994509 2004-04-21 devnull
258 28994509 2004-04-21 devnull main (int argc, char *argv[]) {
259 28994509 2004-04-21 devnull int l, stuff, i, j, c;
260 28994509 2004-04-21 devnull while (argc > 1 && argv[1][0] == '-') {
261 28994509 2004-04-21 devnull switch (argv[1][1]) {
262 28994509 2004-04-21 devnull case 't':
263 28994509 2004-04-21 devnull toption = 1;
264 28994509 2004-04-21 devnull break;
265 28994509 2004-04-21 devnull default:
266 28994509 2004-04-21 devnull warn ("bad option '%c'", argv[1][1]);
267 28994509 2004-04-21 devnull }
268 28994509 2004-04-21 devnull eatarg0;
269 28994509 2004-04-21 devnull }
270 28994509 2004-04-21 devnull fname = argv[1];
271 28994509 2004-04-21 devnull infile = fopen (fname, "r");
272 28994509 2004-04-21 devnull if (infile == NULL)
273 28994509 2004-04-21 devnull quit ("can't open %s\n", fname);
274 28994509 2004-04-21 devnull Start:
275 cbeb0b26 2006-04-01 devnull /* if (get1() != 0xff || get1() != 0xd8) */
276 cbeb0b26 2006-04-01 devnull /* quit ("not JFIF"); */
277 cbeb0b26 2006-04-01 devnull /* printf ("SOI\n"); */
278 cbeb0b26 2006-04-01 devnull /* get_app (0xe0); */
279 28994509 2004-04-21 devnull for (;;) {
280 28994509 2004-04-21 devnull c = get1();
281 28994509 2004-04-21 devnull if (c != 0xff)
282 28994509 2004-04-21 devnull quit ("expected marker, got %2x", c);
283 28994509 2004-04-21 devnull do {
284 28994509 2004-04-21 devnull c = get1();
285 28994509 2004-04-21 devnull } while (c == 0xff);
286 28994509 2004-04-21 devnull marker:
287 28994509 2004-04-21 devnull switch (c) {
288 28994509 2004-04-21 devnull case 0xc0: case 0xc1: case 0xc2: case 0xc3:
289 28994509 2004-04-21 devnull case 0xc5: case 0xc6: case 0xc7:
290 28994509 2004-04-21 devnull case 0xc8: case 0xc9: case 0xca: case 0xcb:
291 28994509 2004-04-21 devnull case 0xcd: case 0xce: case 0xcf:
292 28994509 2004-04-21 devnull get_sof (c);
293 28994509 2004-04-21 devnull break;
294 28994509 2004-04-21 devnull case 0xc4:
295 28994509 2004-04-21 devnull get_dht (c);
296 28994509 2004-04-21 devnull break;
297 28994509 2004-04-21 devnull case 0xcc:
298 28994509 2004-04-21 devnull get_dac (c);
299 28994509 2004-04-21 devnull break;
300 28994509 2004-04-21 devnull case 0xd8:
301 28994509 2004-04-21 devnull printf ("SOI\n");
302 28994509 2004-04-21 devnull break;
303 28994509 2004-04-21 devnull case 0xe0: case 0xe1: case 0xe2: case 0xe3:
304 28994509 2004-04-21 devnull case 0xe4: case 0xe5: case 0xe6: case 0xe7:
305 28994509 2004-04-21 devnull case 0xe8: case 0xe9: case 0xea: case 0xeb:
306 28994509 2004-04-21 devnull case 0xec: case 0xed: case 0xee: case 0xef:
307 28994509 2004-04-21 devnull get_app(c);
308 28994509 2004-04-21 devnull break;
309 28994509 2004-04-21 devnull case 0xda:
310 28994509 2004-04-21 devnull get_sos (c);
311 28994509 2004-04-21 devnull goto newentropy;
312 28994509 2004-04-21 devnull case 0xdb:
313 28994509 2004-04-21 devnull get_dqt (c);
314 28994509 2004-04-21 devnull break;
315 28994509 2004-04-21 devnull case 0xfe:
316 28994509 2004-04-21 devnull get_com (c);
317 28994509 2004-04-21 devnull break;
318 28994509 2004-04-21 devnull case 0xd9:
319 28994509 2004-04-21 devnull printf ("EOI\n");
320 28994509 2004-04-21 devnull if((c=getc(infile)) == EOF)
321 28994509 2004-04-21 devnull exit(0);
322 28994509 2004-04-21 devnull ungetc(c, infile);
323 28994509 2004-04-21 devnull goto Start;
324 28994509 2004-04-21 devnull default:
325 28994509 2004-04-21 devnull eatmarker (c);
326 28994509 2004-04-21 devnull }
327 28994509 2004-04-21 devnull continue;
328 28994509 2004-04-21 devnull newentropy:
329 28994509 2004-04-21 devnull l = stuff = 0;
330 28994509 2004-04-21 devnull entropy:
331 28994509 2004-04-21 devnull while ((c = get1()) != 0xff)
332 28994509 2004-04-21 devnull l += 1;
333 28994509 2004-04-21 devnull while (c == 0xff)
334 28994509 2004-04-21 devnull c = get1();
335 28994509 2004-04-21 devnull if (c == 0) {
336 28994509 2004-04-21 devnull stuff += 1;
337 28994509 2004-04-21 devnull goto entropy;
338 28994509 2004-04-21 devnull }
339 28994509 2004-04-21 devnull printf ("sequence length %d with %d stuffs\n", l, stuff);
340 28994509 2004-04-21 devnull if (0xd0 <= c && c <= 0xd7) {
341 28994509 2004-04-21 devnull printf ("restart %d\n", c - 0xd0);
342 28994509 2004-04-21 devnull goto newentropy;
343 28994509 2004-04-21 devnull }
344 28994509 2004-04-21 devnull goto marker;
345 28994509 2004-04-21 devnull }
346 28994509 2004-04-21 devnull }