/* * Demonstracni priklad, ktery nacte a posleze vytiskne vsechny znacky, * ktere se nachazi v souboru typu JFIF/JPEG. * * Autor: Pavel Tisnovsky * * Pouziti: * jpeg_markers image.jpg */ #include <stdio.h> #include <stdlib.h> #include <string.h> // struktura pro uchovani zakladnich informaci o znackach typedef struct Marker { unsigned char value; char * marker; char * text; } Marker; // pole znamych znacek Marker markers[]={ {0xd8, "SOI", "Start Of Image"}, {0xd9, "EOI", "End Of Image"}, {0xd0, "RST0", "Restart Marker 0"}, {0xd1, "RST1", "Restart Marker 1"}, {0xd2, "RST2", "Restart Marker 2"}, {0xd3, "RST3", "Restart Marker 3"}, {0xd4, "RST4", "Restart Marker 4"}, {0xd5, "RST5", "Restart Marker 5"}, {0xd6, "RST6", "Restart Marker 6"}, {0xd7, "RST7", "Restart Marker 7"}, {0xda, "SOS", "Start Of Scan"}, {0xe0, "APP0", "Application Marker 0"}, {0xe1, "APP1", "Application Marker 1 (EXIF)"}, {0xe2, "APP2", "Application Marker 2 (EXIF)"}, {0xc4, "DHT", "Define Huffman Table"}, {0xcc, "DAC", "Define Arithmetic Table"}, {0xdb, "DQT", "Define Quantization Table"}, {0xdc, "DNL", "Define Number Of Lines"}, {0xdd, "DRI", "Define Restart Interval"}, {0xfe, "COM", "Comment"}, {0x01, "TEM", "usually causes a decoding error, may be ignored"}, {0xc0, "SOF0", "Start Of Frame (baseline JPEG)"}, {0xc1, "SOF1", "Start Of Frame (baseline JPEG)"}, {0xc2, "SOF2", "usually unsupported"}, {0xc3, "SOF3", "usually unsupported"}, {0xc5, "SOF5", "usually unsupported"}, {0xc6, "SOF6", "usually unsupported"}, {0xc7, "SOF7", "usually unsupported"}, {0xc9, "SOF9", "for arithmetic coding, usually unsupported"}, {0xca, "SOF10", "usually unsupported"}, {0xcb, "SOF11", "usually unsupported"}, {0xcd, "SOF13", "usually unsupported"}, {0xce, "SOF14", "usually unsupported"}, {0xce, "SOF14", "usually unsupported"}, {0xcf, "SOF15", "usually unsupported"}, {0xc8, "JPG", "undefined/reserved (causes decoding error)"}, {0xde, "DHP", "ignore (skip)"}, {0xdf, "EXP", "ignore (skip)"}, {0xef, "APP15", "ignore"}, {0xf0, "JPG0", "ignore (skip)"}, {0xfd, "JPG13", "ignore (skip)"}, {0x00, "***", "neznama znacka"}, // zarazka (musi byt na konci) }; /* * Tisk hodnoty znacky */ void printMarker(unsigned char byte1, unsigned char byte2, unsigned long int offset) { int i=0; // pokusit se najit znacku v poli markers (nebo alespon zarazku) while (markers[i].value!=0 && markers[i].value!=byte2) i++; printf("%10lu\t0x%08lx\t%02x%02x\t%s\t%s\n", offset, offset, byte1, byte2, markers[i].marker, markers[i].text); } /* * Funkce pro ziskani zakladnich udaju o souboru typu JFIF/JPEG */ void printJpegMarkers(FILE *fileJpeg) { int i; unsigned char byte1=0, byte2=0; printf("Offset dec\tOffset hex\tZnacka\tJmeno\tText\n"); // projit celym souborem while ((i=fgetc(fileJpeg))!=EOF) { // pokud byl predchozi byte nastaveny na 0xff if (byte1==0xff) { byte2=i; // a druhy byte je v rozsahu 0x01-0xfe if (byte2>=0x01 && byte2<=0xfe) { // jedna se o znacku printMarker(byte1, byte2, ftell(fileJpeg)-2); } // zabranit chybne detekci znacky byte1=0; } // test, zda je nacteny byt roven zacatku znacky if (i==0xff) { byte1=0xff; } } }; /* * Hlavni funkce konzolove aplikace */ int main(int argc, char *argv[]) { FILE *fileJpeg; // kontrola, jestli je z prikazoveho radku zadano jmeno souboru if (argc<=1) { printf("Pouziti jpeg_markers image.jpg\n"); return 1; } // pokus o otevreni souboru pro cteni fileJpeg=fopen(argv[1], "rb"); if (!fileJpeg) { printf("Chyba pri otevirani souboru %s pro cteni!\n", argv[1]); return 1; } // ziskani informaci o znackach ulozenych v souborech JFIF/JPEG printJpegMarkers(fileJpeg); if (fclose(fileJpeg)==EOF) { printf("Chyba pri zavirani souboru %s!\n", argv[1]); return 1; } return 0; } /* * finito */