#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>

typedef struct t_imgsiz 
{
  int width, height, ok;
} t_imgsiz;

void
war(const char *fmt,...)
{
	va_list ap;
	va_start(ap, fmt);

	fprintf(stderr, "imghtml:");
	vfprintf(stderr, fmt, ap);
	fprintf(stderr, "\n");

	va_end(ap);
	
} /* err*/
int
is_magic(char *buf, char *magic)
{
	for(;*magic;magic++,buf++)
	{
		if(*magic != *buf)
		{
			return 0;
		}
	}
	return -1;
} /* cmpmagic */
#define MAGIC_JPG "\xff\xd8"
#define MAGIC_GIF "GIF"
#define MAGIC_PNG "\x89PNG"
#define MAGIC_IHDR "IHDR"

t_imgsiz
imgsize_png(FILE *f)
{
	unsigned char b[100];

	t_imgsiz ret;

	ret.ok =  0;
	fseek(f, 12, SEEK_SET);
	fread(b, 4, 3, f);
	if( ! is_magic(b, MAGIC_IHDR) )
	{
		return ret;
	}

	ret.width = (int)b[7] + 256 * (int) b[6];
	ret.height = (int)b[11] + 256 * (int) b[10];

	ret.ok = 1;
	return ret;
} /* imgsize_png */

t_imgsiz
imgsize_gif(FILE *f)
{
	t_imgsiz ret;

	ret.ok =  0;
	fseek(f, 6, SEEK_SET);
	ret.width = getc(f);
	ret.width += 256*getc(f);
	if (ret.width<0) return ret;

	ret.height = getc(f);
	ret.height += 256*getc(f);
	if (ret.height<0) return ret;

	ret.ok = 1;

	return ret;
} /* imgsize_gif */

t_imgsiz
imgsize_jpg(FILE *f)
{
	int i;
	int length;
	t_imgsiz ret;

	ret.ok =  0;
	fseek(f, 2, SEEK_SET);
	while (1) {
		for ( ; getc(f) != 255; ) ;
		for ( ; (i = getc(f)) == 255; ) ;
		if (i == 0xDA || i == 0xD9) {
			break;
		}
		else if (i >= 0xC0 && i <= 0xCF) {
			fseek(f, 3, SEEK_CUR);
			ret.height = 256*getc(f);
			ret.height += getc(f);
			if (ret.height<0) break ;
			ret.width = 256*getc(f);
			ret.width += getc(f);
			if (ret.width<0) break;
			ret.ok = 1;
			break;
		}
		else {
			length = 256*getc(f);
			length += getc(f);
			if (length < 2) {
				break;
			}
			else{
				fseek(f, length - 2, SEEK_CUR);
			}
		}
	}/* while */

	return ret;
} /* imgsize_jpg */

t_imgsiz
imgsize(char *fname)
{
	FILE *f;
	char b[100];
	int rt;

	t_imgsiz ret;
	ret.ok = 0;
	f = fopen(fname, "rb");
	if( f == NULL )
	{
		war("cannt open file %s", fname);
	        return ret;
	}
	
	rt = fread(b, 10, 1, f);

	if(rt != 1)
	{
		war("cannt read fst 10 bytes.");
	        fclose(f);
	        return ret;
	}
	if( is_magic(b, MAGIC_JPG) )
	{
		ret = imgsize_jpg(f);
	}
	else if( is_magic(b, MAGIC_GIF) )
	{
		ret = imgsize_gif(f);
	}
	else if( is_magic(b, MAGIC_PNG))
	{
		ret = imgsize_png(f);
	}
	if( ret.ok == 0)
	{
		war("broken file %s", fname);
	}
	fclose(f);
	return ret;
} /* imgsize */

#define PARS_BUFF_SIZ 4096
char pars_buff[PARS_BUFF_SIZ];
int pars_buff_top;
FILE *fin;
FILE *fout;

void
do_img()
{
	t_imgsiz imgsiz;

	imgsiz = imgsize(pars_buff);
	if(imgsiz.ok == 0)
	{ /* nerozpoznal jsem tento image skoda */
		return;
	}
	fprintf(fout, " height=\"%i\" width=\"%i\"", 
			imgsiz.height,
			imgsiz.width);
} /* do_img */




int
my_getc()
{
	return fgetc(fin);
} /* my_getc */

int
my_ungetc(int c)
{
	return  ungetc(c, fin);
} /* my_ungetc */ 

void
my_puts(char *s)
{
	fprintf(fout, "%s", s);
} /* my_puts */

void
my_putc(int c)
{
	fprintf(fout, "%c", c);
} /* my_puts */

/*
 * -1 EOF 
 * -2 >
 * 1 ok nalezeno
 */
int
find_str(char *s)
{
	int c;
	int si = 0;
#if DB
	printf("[searching for %s]", s);
#endif
	while(EOF != (c  = my_getc()))
	{
		my_putc(c);
		if( c == '>' )
		{
			return -2;
		}
		if( tolower(c) == s[si] )
		{
			si++;
			if(s[si] == '\0')
			{
				return 1;
			}
		}
		else
		{
			si = 0;
		}
	}
	return EOF;
}  /* find_str */

int
find_uv()
{
	int c;
#if DB
	printf("[searching for uv]");
#endif
	pars_buff_top = 0;
	while(EOF != (c = my_getc()))
	{
		my_putc(c);
		if(c == '"')
		{
			pars_buff[pars_buff_top] = '\0';
			return 1;
		}
		pars_buff[pars_buff_top++] = c;
	}
	return -1;
}

int
do_it()
{
	int rt;
	while( EOF != (rt = find_str("<img")))
	{
		if( rt == -2 )
		{
			continue;
		}
		rt = find_str("src=\"");

		if(rt == -2)
		{ /* <img> ale neobsahje src= ... hm... */
			continue;
		}

		if(rt == EOF)
		{ /* eof in <img...  hmm...  */
			break;
		}

		rt = find_uv();
		if( rt == EOF )
		{ /* eof in src="....  hmm... */
			break;
		}
		/* no konecne */

		do_img();
	}
	return 1;
} /* do_it */


int
main()
{
	fin =  stdin;
	fout =  stdout;
	do_it();
	return 0;
}
