#include<stdio.h>

#define word(p)	((unsigned)(p)[0] | (unsigned)(p)[1] << 8 | \
			(unsigned)(p)[2] << 16 | (unsigned)(p)[3] << 24)

#define MASK_STR	"YET11.ITaRu.MiKiPoN.ShiNoRi-"
#define MASK_LEN	28 


int read_jpeg( FILE *fp, int len )
{
	int c;
	int count;
	int mask_index;

	putchar(0xff);
	putchar(0xd8);
	len -= 2;

	count = 4094;
	mask_index = 2;
	while( len-- ){
		c = fgetc(fp);
		if( c == EOF )
			return -1;
		putchar( c ^ MASK_STR[mask_index++] );
		if( --count == 0 ){
			count = 4096;
			mask_index = 0;
		}else
			mask_index %= MASK_LEN;
	}
	return 0;
}


int read_bmp( FILE *fp, int len )
{
	int c;
	int count;

	putchar('B');
	putchar('M');
	len -= 2;

	while( len-- ){
		c = fgetc(fp);
		if( c == EOF )
			return -1;
		if( c == 0xf0 ){
			count = fgetc(fp);
			if( count == EOF )
				return -1;
			if( count <= 0x02 ){
				c = 0xf0;
			}else{
				c = fgetc(fp);
				if( c == EOF )
					return -1;
			}
			while( count-- )
				putchar(c);
		}else{
			putchar(c);
		}
	}
	return 0;
}

int main( int argc, char **argv )
{
	FILE *fp;
	int i,num_entry;
	int offset,len;
	unsigned char buf[16];

	if( argc < 2 || argc > 3 ){
		fprintf(stderr,"usage: %s DAT_file [data_number]\n",argv[0]);
		return 1;
	}

	fp = fopen(argv[1],"r");
	if( fp == NULL ){
		perror("fopen");
		return 1;
	}


	if( fread(buf,14,1,fp) < 1 ){
		perror("fread");
		return 1;
	}
	num_entry = word(buf+10);

	if( argc == 2 ){
		printf("%d\n",num_entry);
		return 0;
	}

	i = atoi( argv[2] );
	if( i < 0 || i >= num_entry ){
		fprintf(stderr,"invalid data number.\n");
		return 1;
	}
	if( i > 0 ){
		if( fseek(fp,i*8,SEEK_CUR) < 0 ){
			perror("fseek");
			return 1;
		}
	}
	if( fread(buf,8,1,fp) < 1 ){
		perror("fread");
		return 1;
	}
	offset = word(buf);
	len = word(buf+4);
	if( fseek(fp,offset,SEEK_SET) < 0 ){
		perror("fseek");
		return 1;
	}
	if( fread(buf,2,1,fp) < 1 ){
		perror("fread");
		return 1;
	}

	if( buf[0] == 0xa6 && buf[1] == 0x9d )
		return read_jpeg(fp,len) < 0 ? 1 : 0;

	if( buf[0] == 'B' && buf[1] == 'M' )
		return read_bmp(fp,len) < 0 ? 1 : 0;


	putchar(buf[0]);
	putchar(buf[1]);
	len -= 2;
	while( len-- ){
		i = fgetc(fp);
		if( i == EOF ){
			perror("fgetc");
			return 1;
		}
		putchar(i);
	}
	return 0;
}
