1 /* jpeg parser by tom szymanski */
9 /* subroutines done by macros */
10 #define min(A,B) ((A)<(B) ? (A) : (B))
11 #define max(A,B) ((A)>(B) ? (A) : (B))
12 #define maxeql(A,B) if (A < (B)) A = (B);
13 #define mineql(A,B) if (A > (B)) A = (B);
14 #define eatarg0 (argc--, argv++)
15 #define arrayLength(A) ((sizeof A)/ (sizeof A[0]))
20 /* Routines to print error messages of varying severity */
22 /* externally visible variables */
26 void getname (char *arg) {
27 /* Save name of invoking program for use by error routines */
29 p = strrchr (arg, '/');
36 static void introduction (void) {
40 fprintf (stderr, "%s: ", myname);
43 void warn (char *fmt, ...) {
47 vfprintf (stderr, fmt, args);
53 void quit (char *fmt, ...) {
57 vfprintf (stderr, fmt, args);
64 void fatal (char *fmt, ...) {
68 vfprintf (stderr, fmt, args);
70 fprintf (stderr, "\nbetter get help!\n");
80 if (fread(&x, 1, 1, infile) == 0)
81 quit ("unexpected EOF");
92 void eatmarker (int kind) {
95 printf ("%02x len=%d\n", kind, l);
96 for (l -= 2; l > 0; l--)
100 char *sofName[16] = {
101 "Baseline sequential DCT - Huffman coding",
102 "Extended sequential DCT - Huffman coding",
103 "Progressive DCT - Huffman coding",
104 "Lossless - Huffman coding",
105 "4 is otherwise used",
106 "Sequential DCT - differential Huffman coding",
107 "Progressive DCT - differential Huffman coding",
108 "Lossless - differential Huffman coding",
110 "Extended Sequential DCT - arithmetic coding",
111 "Progressive DCT - arithmetic coding",
112 "Lossless - arithmetic coding",
113 "c is otherwise used",
114 "Sequential DCT - differential arithmetic coding",
115 "Progressive DCT - differential arithmetic coding",
116 "Lossless - differential arithmetic coding",
119 void get_sof (int kind) {
120 int i, length, height, width, precision, ncomponents;
126 ncomponents = get1();
127 printf ("SOF%d:\t%s\n", kind - 0xc0, sofName[kind - 0xc0]);
128 printf ("\t%d wide, %d high, %d deep, %d components\n",
129 width, height, precision, ncomponents);
130 for (i = 0; i < ncomponents; i++) {
134 printf ("\tcomponent %d: %d hsample, %d vsample, quantization table %d\n",
135 id, sf >> 4, sf & 0xf, tab);
139 void get_com (int kind) {
142 printf ("COM len=%d '", l);
143 for (l -= 2; l > 0; l--)
144 putchar (c = get1());
148 void get_app (int kind) {
153 printf ("APP%d len=%d\n", kind - 0xe0, l);
157 /* dump printable strings in comment */
158 for (l -= 2; l > 0; l--){
161 if(nbuf >= sizeof buf){
162 if(!first && nbuf == nok)
164 printf("%.*s", nbuf, buf);
171 if(nok >= sizeof buf)
173 printf("%.*s", nbuf, buf);
178 if(nok >= sizeof buf)
180 if(!first && nbuf == nok)
182 printf("%.*s", nbuf, buf);
186 void get_dac (int kind) {
195 printf ("DQT:\tp = %d, table = %d\n", p, t);
197 for (i = 0; i < 64; i++)
198 tab[i] = p ? get2() : get1();
200 for (i = 0; i < 64; i++)
201 printf ("\t%q[%02d] = %d\n", i, tab[i]);
206 void get_dqt (int kind) {
214 int l, tcth, p, i, j, v[16], vv[16][256];
216 printf ("DHT:\tclass = %d, table = %d\n", tcth >> 4, tcth & 0xf);
217 for (i = 0; i < 16; i++)
220 for (i = 0; i < 16; i++)
221 for (j = 0; j < v[i]; j++) {
226 for (i = 0; i < 16; i++)
227 printf ("\t%l[%02d] = %d\n", i+1, v[i]);
228 for (i = 0; i < 16; i++)
229 for (j = 0; j < v[i]; j++)
230 printf ("\t%v[%02d,%02d] = %d\n", i+1, j+1, vv[i][j]);
235 void get_dht (int kind) {
242 void get_sos (int kind) {
243 int i, length, ncomponents, id, dcac, ahal;
245 ncomponents = get1();
246 printf ("SOS:\t%d components\n", ncomponents);
247 for (i = 0; i < ncomponents; i++) {
250 printf ("\tcomponent %d: %d DC, %d AC\n", id, dcac >> 4, dcac & 0xf);
252 printf ("\tstart spectral %d\n", get1());
253 printf ("\tend spectral %d\n", get1());
255 printf ("\tah = %d, al = %d\n", ahal >> 4, ahal &0xf);
258 main (int argc, char *argv[]) {
259 int l, stuff, i, j, c;
260 while (argc > 1 && argv[1][0] == '-') {
261 switch (argv[1][1]) {
266 warn ("bad option '%c'", argv[1][1]);
271 infile = fopen (fname, "r");
273 quit ("can't open %s\n", fname);
275 // if (get1() != 0xff || get1() != 0xd8)
276 // quit ("not JFIF");
282 quit ("expected marker, got %2x", c);
288 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
289 case 0xc5: case 0xc6: case 0xc7:
290 case 0xc8: case 0xc9: case 0xca: case 0xcb:
291 case 0xcd: case 0xce: case 0xcf:
303 case 0xe0: case 0xe1: case 0xe2: case 0xe3:
304 case 0xe4: case 0xe5: case 0xe6: case 0xe7:
305 case 0xe8: case 0xe9: case 0xea: case 0xeb:
306 case 0xec: case 0xed: case 0xee: case 0xef:
320 if((c=getc(infile)) == EOF)
331 while ((c = get1()) != 0xff)
339 printf ("sequence length %d with %d stuffs\n", l, stuff);
340 if (0xd0 <= c && c <= 0xd7) {
341 printf ("restart %d\n", c - 0xd0);