/* jpgsize.c - Don Yang (uguu.org) Reads JPEG image from stdin, and writes width and height to stdout. http://www.ijg.org/ http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure http://www.media.mit.edu/pia/Research/deepview/exif.html 2013-04-20 */ #include #define SHOW_MARKERS 0 static void GetFileSize(FILE *file, int *width, int *height) { unsigned char buffer[8]; int i; *width = *height = 0; /* Check SOI marker */ if( fread(buffer, 2, 1, file) != 1 || buffer[0] != 0xff || buffer[1] != 0xd8 ) { return; } for(;;) { /* Skip markers until we get a SOF marker */ do { if( (i = fgetc(file)) == EOF ) return; } while( i != 0xff ); /* Got the first byte (0xff) of segment, read second marker byte and payload. buffer[0] = marker byte buffer[1..2] = length buffer[3..7] = next 5 bytes of payload */ if( fread(buffer, 8, 1, file) != 1 ) return; if( buffer[0] >= 0xc0 && buffer[0] <= 0xcf && buffer[0] != 0xc4 ) { /* Found a SOF marker */ #if SHOW_MARKERS fprintf(stderr, "ff %02x: width=%02x%02x height=%02x%02x\n", buffer[0], buffer[4], buffer[5], buffer[6], buffer[7]); #endif *height = (buffer[4] << 8) | buffer[5]; *width = (buffer[6] << 8) | buffer[7]; return; } /* Skip over this segment. Bytes 1..2 contains the payload length, which will be adjusted for the 7 bytes we already read. */ #if SHOW_MARKERS fprintf(stderr, "ff %02x: length=%02x%02x\n", buffer[0], buffer[1], buffer[2]); #endif for(i = ((buffer[1] << 8) | buffer[2]) - 7; i > 0; i--) { if( fgetc(file) == EOF ) return; } } } int main(int argc, char **argv) { int width, height; GetFileSize(stdin, &width, &height); printf("%d %d\n", width, height); return 0; }