/* jpeg parser by tom szymanski */
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>

/* subroutines done by macros */
#define min(A,B)	((A)<(B) ? (A) : (B))
#define max(A,B)	((A)>(B) ? (A) : (B))
#define maxeql(A,B)	if (A < (B)) A = (B);
#define mineql(A,B)	if (A > (B)) A = (B);
#define eatarg0		(argc--, argv++)
#define arrayLength(A) ((sizeof A)/ (sizeof A[0]))

FILE *infile;
char *fname;

/* Routines to print error messages of varying severity */

/* externally visible variables */
int   warncnt;
char *myname;

void getname (char *arg) {
	/* Save name of invoking program for use by error routines */
	register char *p;
	p = strrchr (arg, '/');
	if (p == NULL)
		myname = arg;
	else
		myname = ++p;
}

static void introduction (void) {
	warncnt++;
	fflush (stdout);
	if (myname != NULL)
		fprintf (stderr, "%s: ", myname);
}

void warn (char *fmt, ...) {
	va_list args;
	introduction ();
	va_start (args, fmt);
	vfprintf (stderr, fmt, args);
	va_end (args);
	fputc ('\n', stderr);
	fflush (stderr);
}

void quit (char *fmt, ...) {
	va_list args;
	introduction ();
	va_start (args, fmt);
	vfprintf (stderr, fmt, args);
	va_end (args);
	fputc ('\n', stderr);
	fflush (stderr);
	exit (1);
}

void fatal (char *fmt, ...) {
	va_list args;
	introduction ();
	va_start (args, fmt);
	vfprintf (stderr, fmt, args);
	va_end (args);
	fprintf (stderr, "\nbetter get help!\n");
	fflush (stderr);
	abort ();
}

int toption = 0;
int dqt[16][64];

int get1 (void) {
	unsigned char x;
	if (fread(&x, 1, 1, infile) == 0)
		quit ("unexpected EOF");
	return x;
}

int get2 (void) {
	int x;

	x = get1() << 8;
	return x | get1();
}

void eatmarker (int kind) {
	int l, c;
	l = get2();
	printf ("%02x len=%d\n", kind, l);
	for (l -= 2; l > 0; l--)
		get1();
}

char *sofName[16] = {
	"Baseline sequential DCT - Huffman coding",
	"Extended sequential DCT - Huffman coding",
	"Progressive DCT - Huffman coding",
	"Lossless - Huffman coding",
	"4 is otherwise used",
	"Sequential DCT - differential Huffman coding",
	"Progressive DCT - differential Huffman coding",
	"Lossless - differential Huffman coding",
	"8 is reserved",
	"Extended Sequential DCT - arithmetic coding",
	"Progressive DCT - arithmetic coding",
	"Lossless - arithmetic coding",
	"c is otherwise used",
	"Sequential DCT - differential arithmetic coding",
	"Progressive DCT - differential arithmetic coding",
	"Lossless - differential arithmetic coding"
};

void get_sof (int kind) {
	int i, length, height, width, precision, ncomponents;
	int id, sf, tab;
	length = get2();
	precision = get1();
	height = get2();
	width = get2();
	ncomponents = get1();
	printf ("SOF%d:\t%s\n", kind - 0xc0, sofName[kind - 0xc0]);
	printf ("\t%d wide, %d high, %d deep, %d components\n",
		width, height, precision, ncomponents);
	for (i = 0; i < ncomponents; i++) {
		id = get1();
		sf = get1();
		tab = get1();
		printf ("\tcomponent %d: %d hsample, %d vsample, quantization table %d\n",
			id, sf >> 4, sf & 0xf, tab);
	}		
}

void get_com (int kind) {
	int l, c;
	l = get2();
	printf ("COM len=%d '", l);
	for (l -= 2; l > 0; l--)
		putchar (c = get1());
	printf ("'\n");
}

void get_app (int kind) {
	int l, c, first;
	char buf[6];
	int nbuf, nok;
	l = get2();
	printf ("APP%d len=%d\n", kind - 0xe0, l);
	nbuf = 0;
	nok = 0;
	first = 1;
	/* dump printable strings in comment */
	for (l -= 2; l > 0; l--){
		c = get1();
		if(isprint(c)){
			if(nbuf >= sizeof buf){
				if(!first && nbuf == nok)
					printf(" ");
				printf("%.*s", nbuf, buf);
				nbuf = 0;
				first = 0;
			}
			buf[nbuf++] = c;
			nok++;
		}else{
			if(nok >= sizeof buf)
				if(nbuf > 0)
					printf("%.*s", nbuf, buf);
			nbuf = 0;
			nok = 0;
		}
	}
	if(nok >= sizeof buf)
		if(nbuf > 0){
			if(!first && nbuf == nok)
				printf(" ");
			printf("%.*s", nbuf, buf);
		}
}

void get_dac (int kind) {
	eatmarker (kind);
}

int get1dqt (void) {
	int t, p, i, *tab;
	t = get1();
	p = t >> 4;
	t = t & 0xf;
	printf ("DQT:\tp = %d, table = %d\n", p, t);
	tab = &dqt[t][0];
	for (i = 0; i < 64; i++)
		tab[i] = p ? get2() : get1();
	if (toption) {
		for (i = 0; i < 64; i++)
			printf ("\t%q[%02d] = %d\n", i, tab[i]);
	}
	return p ? 65 : 129;
}

void get_dqt (int kind) {
	int length;
	length = get2() - 2;
	while (length > 0)
		length -= get1dqt();
}

int get1dht (void) {
	int l, tcth, p, i, j, v[16], vv[16][256];
	tcth = get1();
	printf ("DHT:\tclass = %d, table = %d\n", tcth >> 4, tcth & 0xf);
	for (i = 0; i < 16; i++)
		v[i] = get1();
	l = 17;
	for (i = 0; i < 16; i++)
		for (j = 0; j < v[i]; j++) {
			vv[i][j] = get1();
			l += 1;
		}
	if (toption) {
		for (i = 0; i < 16; i++)
			printf ("\t%l[%02d] = %d\n", i+1, v[i]);
		for (i = 0; i < 16; i++)
			for (j = 0; j < v[i]; j++)
				printf ("\t%v[%02d,%02d] = %d\n", i+1, j+1, vv[i][j]);
	}
	return l;
}

void get_dht (int kind) {
	int length;
	length = get2() - 2;
	while (length > 0)
		length -= get1dht();
}

void get_sos (int kind) {
	int i, length, ncomponents, id, dcac, ahal;
	length = get2();
	ncomponents = get1();
	printf ("SOS:\t%d components\n", ncomponents);
	for (i = 0; i < ncomponents; i++) {
		id = get1();
		dcac = get1();
		printf ("\tcomponent %d: %d DC, %d AC\n", id, dcac >> 4, dcac & 0xf);
	}
	printf ("\tstart spectral %d\n", get1());
	printf ("\tend spectral %d\n", get1());
	ahal = get1();
	printf ("\tah = %d, al = %d\n", ahal >> 4, ahal &0xf);
}

main (int argc, char *argv[]) {
	int l, stuff, i, j, c;
	while (argc > 1 && argv[1][0] == '-') {
		switch (argv[1][1]) {
		case 't':
			toption = 1;
			break;
		default:
			warn ("bad option '%c'", argv[1][1]);
		}
		eatarg0;
	}
	fname = argv[1];
	infile = fopen (fname, "r");
	if (infile == NULL)
		quit ("can't open %s\n", fname);
    Start:
/*	if (get1() != 0xff || get1() != 0xd8) */
/*		quit ("not JFIF"); */
/*	printf ("SOI\n"); */
/*	get_app (0xe0); */
	for (;;) {
		c = get1();
		if (c != 0xff)
			quit ("expected marker, got %2x", c);
		do {
			c = get1();
		} while (c == 0xff);
marker:
		switch (c) {
		case 0xc0: case 0xc1: case 0xc2: case 0xc3:
		case 0xc5: case 0xc6: case 0xc7:
		case 0xc8: case 0xc9: case 0xca: case 0xcb:
		case 0xcd: case 0xce: case 0xcf:
			get_sof (c);
			break;
		case 0xc4:
			get_dht (c);
			break;
		case 0xcc:
			get_dac (c);
			break;
		case 0xd8:
			printf ("SOI\n");
			break;
		case 0xe0: case 0xe1: case 0xe2: case 0xe3: 
		case 0xe4: case 0xe5: case 0xe6: case 0xe7: 
		case 0xe8: case 0xe9: case 0xea: case 0xeb: 
		case 0xec: case 0xed: case 0xee: case 0xef: 
			get_app(c);
			break;
		case 0xda:
			get_sos (c);
			goto newentropy;
		case 0xdb:
			get_dqt (c);
			break;
		case 0xfe:
			get_com (c);
			break;
		case 0xd9:
			printf ("EOI\n");
			if((c=getc(infile)) == EOF)
				exit(0);
			ungetc(c, infile);
			goto Start;
		default:
			eatmarker (c);
		}
		continue;
newentropy:
		l = stuff = 0;
entropy:
		while ((c = get1()) != 0xff)
			l += 1;
		while (c == 0xff)
			c = get1();
		if (c == 0) {
			stuff += 1;
			goto entropy;
		}
		printf ("sequence length %d with %d stuffs\n", l, stuff);
		if (0xd0 <= c && c <= 0xd7) {
			printf ("restart %d\n", c - 0xd0);
			goto newentropy;
		}
		goto marker;
	}
}
