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