1 /* jpeg parser by tom szymanski */
10 /* subroutines done by macros */
11 #define min(A,B) ((A)<(B) ? (A) : (B))
12 #define max(A,B) ((A)>(B) ? (A) : (B))
13 #define maxeql(A,B) if (A < (B)) A = (B);
14 #define mineql(A,B) if (A > (B)) A = (B);
15 #define eatarg0 (argc--, argv++)
16 #define arrayLength(A) ((sizeof A)/ (sizeof A[0]))
21 /* Routines to print error messages of varying severity */
23 /* externally visible variables */
27 void getname (char *arg) {
28 /* Save name of invoking program for use by error routines */
30 p = strrchr (arg, '/');
37 static void introduction (void) {
41 fprintf (stderr, "%s: ", myname);
44 void warn (char *fmt, ...) {
48 vfprintf (stderr, fmt, args);
54 void quit (char *fmt, ...) {
58 vfprintf (stderr, fmt, args);
65 void fatal (char *fmt, ...) {
69 vfprintf (stderr, fmt, args);
71 fprintf (stderr, "\nbetter get help!\n");
81 if (fread(&x, 1, 1, infile) == 0)
82 quit ("unexpected EOF");
93 void eatmarker (int kind) {
96 printf ("%02x len=%d\n", kind, l);
97 for (l -= 2; l > 0; l--)
101 char *sofName[16] = {
102 "Baseline sequential DCT - Huffman coding",
103 "Extended sequential DCT - Huffman coding",
104 "Progressive DCT - Huffman coding",
105 "Lossless - Huffman coding",
106 "4 is otherwise used",
107 "Sequential DCT - differential Huffman coding",
108 "Progressive DCT - differential Huffman coding",
109 "Lossless - differential Huffman coding",
111 "Extended Sequential DCT - arithmetic coding",
112 "Progressive DCT - arithmetic coding",
113 "Lossless - arithmetic coding",
114 "c is otherwise used",
115 "Sequential DCT - differential arithmetic coding",
116 "Progressive DCT - differential arithmetic coding",
117 "Lossless - differential arithmetic coding"
120 void get_sof (int kind) {
121 int i, length, height, width, precision, ncomponents;
127 ncomponents = get1();
128 printf ("SOF%d:\t%s\n", kind - 0xc0, sofName[kind - 0xc0]);
129 printf ("\t%d wide, %d high, %d deep, %d components\n",
130 width, height, precision, ncomponents);
131 for (i = 0; i < ncomponents; i++) {
135 printf ("\tcomponent %d: %d hsample, %d vsample, quantization table %d\n",
136 id, sf >> 4, sf & 0xf, tab);
140 void get_com (int kind) {
143 printf ("COM len=%d '", l);
144 for (l -= 2; l > 0; l--)
145 putchar (c = get1());
149 void get_app (int kind) {
154 printf ("APP%d len=%d\n", kind - 0xe0, l);
158 /* dump printable strings in comment */
159 for (l -= 2; l > 0; l--){
162 if(nbuf >= sizeof buf){
163 if(!first && nbuf == nok)
165 printf("%.*s", nbuf, buf);
172 if(nok >= sizeof buf)
174 printf("%.*s", nbuf, buf);
179 if(nok >= sizeof buf)
181 if(!first && nbuf == nok)
183 printf("%.*s", nbuf, buf);
187 void get_dac (int kind) {
196 printf ("DQT:\tp = %d, table = %d\n", p, t);
198 for (i = 0; i < 64; i++)
199 tab[i] = p ? get2() : get1();
201 for (i = 0; i < 64; i++)
202 printf ("\t%%q[%02d] = %d\n", i, tab[i]);
207 void get_dqt (int kind) {
215 int l, tcth, i, j, v[16], vv[16][256];
217 printf ("DHT:\tclass = %d, table = %d\n", tcth >> 4, tcth & 0xf);
218 for (i = 0; i < 16; i++)
221 for (i = 0; i < 16; i++)
222 for (j = 0; j < v[i]; j++) {
227 for (i = 0; i < 16; i++)
228 printf ("\t%%l[%02d] = %d\n", i+1, v[i]);
229 for (i = 0; i < 16; i++)
230 for (j = 0; j < v[i]; j++)
231 printf ("\t%%v[%02d,%02d] = %d\n", i+1, j+1, vv[i][j]);
236 void get_dht (int kind) {
243 void get_sos (int kind) {
244 int i, length, ncomponents, id, dcac, ahal;
246 ncomponents = get1();
247 printf ("SOS:\t%d components\n", ncomponents);
248 for (i = 0; i < ncomponents; i++) {
251 printf ("\tcomponent %d: %d DC, %d AC\n", id, dcac >> 4, dcac & 0xf);
253 printf ("\tstart spectral %d\n", get1());
254 printf ("\tend spectral %d\n", get1());
256 printf ("\tah = %d, al = %d\n", ahal >> 4, ahal &0xf);
259 int main (int argc, char *argv[]) {
261 while (argc > 1 && argv[1][0] == '-') {
262 switch (argv[1][1]) {
267 warn ("bad option '%c'", argv[1][1]);
272 infile = fopen (fname, "r");
274 quit ("can't open %s\n", fname);
276 /* if (get1() != 0xff || get1() != 0xd8) */
277 /* quit ("not JFIF"); */
278 /* printf ("SOI\n"); */
279 /* get_app (0xe0); */
283 quit ("expected marker, got %2x", c);
289 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
290 case 0xc5: case 0xc6: case 0xc7:
291 case 0xc8: case 0xc9: case 0xca: case 0xcb:
292 case 0xcd: case 0xce: case 0xcf:
304 case 0xe0: case 0xe1: case 0xe2: case 0xe3:
305 case 0xe4: case 0xe5: case 0xe6: case 0xe7:
306 case 0xe8: case 0xe9: case 0xea: case 0xeb:
307 case 0xec: case 0xed: case 0xee: case 0xef:
321 if((c=getc(infile)) == EOF)
332 while ((c = get1()) != 0xff)
340 printf ("sequence length %d with %d stuffs\n", l, stuff);
341 if (0xd0 <= c && c <= 0xd7) {
342 printf ("restart %d\n", c - 0xd0);