#include #include #include #include #include #include #include extern const char *__progname; static int file_fd; static const char *filename; static const unsigned char *file; static unsigned int filesize; static unsigned int moov_at = 0; static unsigned int moov_len = 0; static unsigned int mdat_at = 0; static unsigned int mdat_len = 0; #define FOURCHAR(a,b,c,d) ( ((a) * 0x01000000) + \ ((b) * 0x010000) + \ ((c) * 0x0100) + \ ((d) * 0x01) ) static void usage(void) { fprintf(stderr,"Usage: %s filename\n",__progname); exit(1); } static void map_file(const char *name) { struct stat stb; void *mmrv; filename = name; file_fd = open(name,O_RDONLY,0); if (file_fd < 0) { fprintf(stderr,"%s: %s: %s\n",__progname,name,strerror(errno)); exit(1); } fstat(file_fd,&stb); filesize = stb.st_size; if (filesize != stb.st_size) { fprintf(stderr,"%s: %s: too large\n",__progname,name); exit(1); } mmrv = mmap(0,stb.st_size,PROT_READ,MAP_FILE|MAP_SHARED,file_fd,0); if (mmrv == MAP_FAILED) { fprintf(stderr,"%s: mmap %s: %s\n",__progname,name,strerror(errno)); exit(1); } file = mmrv; } static unsigned int get4be(unsigned int o) { return( (file[o ] * 0x01000000) + (file[o+1] * 0x010000) + (file[o+2] * 0x0100) + (file[o+3] * 0x01) ); } static void print_4_vis(FILE *to, const unsigned char *d) { int i; for (i=4;i>0;i--) { if (*d < 32) { fprintf(to,"^%c",64+*d); } else if (*d < 127) { putc(*d,to); } else if (*d == 127) { fprintf(to,"^?"); } else if (*d < 160) { fprintf(to,"^%c",64+*d); } else { putc(*d,to); } d ++; } } static void scan_chunks(unsigned int start, unsigned int len, void (*chunk)(const unsigned char [4], unsigned int, unsigned int)) { unsigned int o; unsigned int l; o = 0; while (1) { if (o == len) break; if (o+8 > len) { printf("chunk overrun 1 (%u+8 > %u)\n",o,len); exit(1); } l = get4be(start+o); if (l == 1) { printf("64-bit chunk length at %u+%u\n",start,o); exit(1); } if (l < 8) { printf("runt chunk (%u) at %u+%u\n",l,start,o); exit(1); } printf("%08x+%08x: chunk len=%x type=",start,o,l); print_4_vis(stdout,file+start+o+4); printf("\n"); if (o+l > len) { printf("chunk overrun 2 (%u+%u > %u)\n",o,l,len); exit(1); } (*chunk)(file+start+o+4,start+o+8,l-8); o += l; } } static void file_chunk(const unsigned char type[4], unsigned int data, unsigned int len) { int i; switch (FOURCHAR(type[0],type[1],type[2],type[3])) { default: printf("skipping unknown chunk\n"); return; case FOURCHAR('f','t','y','p'): if (len < 8) { printf("ftyp chunk too small (%u)\n",len); return; } if (len % 4) { printf("ftyp chunk length (%u) isn't a multiple of 4\n",len); return; } printf("ftyp: major `"); print_4_vis(stdout,file+data); printf("' minor %08x compat:",get4be(data+4)); for (i=8;i