?? jpeg.c
字號:
#include <stdio.h>/* * These macros are used to read the input file. * To reuse this code in another application, you might need to change these. */#define EXIT_FAILURE 0#define EXIT_SUCCESS 1unsigned int image_height, image_width;static FILE * infile; /* input JPEG file *//* Error exit handler */#define ERREXIT(msg) { fprintf(stderr, "%s\n", msg); return 0; }/* Read one byte, testing for EOF */static int read_1_byte (void) { int c; c = getc(infile); if (c == EOF) ERREXIT("Premature EOF in JPEG file"); return c;}/* Read 2 bytes, convert to unsigned int *//* All 2-byte quantities in JPEG markers are MSB first */static unsigned int read_2_bytes (void) { int c1, c2; c1 = getc(infile); if (c1 == EOF) ERREXIT("Premature EOF in JPEG file"); c2 = getc(infile); if (c2 == EOF) ERREXIT("Premature EOF in JPEG file"); return (((unsigned int) c1) << 8) + ((unsigned int) c2);}/* * JPEG markers consist of one or more 0xFF bytes, followed by a marker * code byte (which is not an FF). Here are the marker codes of interest * in this program. */#define M_SOF0 0xC0 /* Start Of Frame N */#define M_SOF1 0xC1 /* N indicates which compression process */#define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */#define M_SOF3 0xC3#define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */#define M_SOF6 0xC6#define M_SOF7 0xC7#define M_SOF9 0xC9#define M_SOF10 0xCA#define M_SOF11 0xCB#define M_SOF13 0xCD#define M_SOF14 0xCE#define M_SOF15 0xCF#define M_SOI 0xD8 /* Start Of Image (beginning of datastream) *//* * Find the next JPEG marker and return its marker code. * We expect at least one FF byte, possibly more if the compressor used FFs * to pad the file. * There could also be non-FF garbage between markers. The treatment of such * garbage is unspecified; we choose to skip over it but emit a warning msg. * NB: this routine must not be used after seeing SOS marker, since it will * not deal correctly with FF/00 sequences in the compressed image data... */static int next_marker (void) { int c; int discarded_bytes = 0; /* Find 0xFF byte; count and skip any non-FFs. */ c = read_1_byte(); while (c != 0xFF) { discarded_bytes++; c = read_1_byte(); } /* Get marker code byte, swallowing any duplicate FF bytes. Extra FFs * are legal as pad bytes, so don't count them in discarded_bytes. */ do { c = read_1_byte(); } while (c == 0xFF); if (discarded_bytes != 0) { fprintf(stderr, "Warning: garbage data found in JPEG file\n"); } return c;}/* * Read the initial marker, which should be SOI. * For a JFIF file, the first two bytes of the file should be literally * 0xFF M_SOI. To be more general, we could use next_marker, but if the * input file weren't actually JPEG at all, next_marker might read the whole * file and then return a misleading error message... */static int first_marker (void) { int c1, c2; c1 = getc(infile); c2 = getc(infile); if (c1 != 0xFF || c2 != M_SOI) ERREXIT("Not a JPEG file"); return c2;}/* * Most types of marker are followed by a variable-length parameter segment. * This routine skips over the parameters for any marker we don't otherwise * want to process. * Note that we MUST skip the parameter segment explicitly in order not to * be fooled by 0xFF bytes that might appear within the parameter segment; * such bytes do NOT introduce new markers. *//* Skip over an unknown or uninteresting variable-length marker */static void skip_variable (void) { unsigned int length; /* Get the marker parameter length count */ length = read_2_bytes(); /* Length includes itself, so must be at least 2 */ //if (length < 2) ERREXIT("Erroneous JPEG marker length"); if (length < 2) return; length -= 2; /* Skip over the remaining bytes */ while (length > 0) { (void) read_1_byte(); length--; }}/* * We are only interested in the image dimensions, so we stop at SOFn. */static int scan_JPEG_header(void) { int marker = 0;// Expect SOI at start of file if (first_marker() != M_SOI) ERREXIT("Expected SOI marker first");// Scan miscellaneous markers until we reach SOFn. for (;;) { marker = next_marker(); switch (marker) {// Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be,// treated as SOFn. C4 in particular is actually DHT. case M_SOF0: /* Baseline */ case M_SOF1: /* Extended sequential, Huffman */ case M_SOF2: /* Progressive, Huffman */ case M_SOF3: /* Lossless, Huffman */ case M_SOF5: /* Differential sequential, Huffman */ case M_SOF6: /* Differential progressive, Huffman */ case M_SOF7: /* Differential lossless, Huffman */ case M_SOF9: /* Extended sequential, arithmetic */ case M_SOF10: /* Progressive, arithmetic */ case M_SOF11: /* Lossless, arithmetic */ case M_SOF13: /* Differential sequential, arithmetic */ case M_SOF14: /* Differential progressive, arithmetic */ case M_SOF15: /* Differential lossless, arithmetic */ // Process SOFn (void) read_2_bytes(); /* usual parameter length count */ (void) read_1_byte(); image_height = read_2_bytes(); image_width = read_2_bytes(); return marker; break; default: /* Anything else just gets skipped */ skip_variable(); /* we assume it has a parameter count... */ break; } } /* end loop */}int GetJPEGSize(char* cszJpegFile, unsigned int* iWidth, unsigned int* iHeight ){ // Open the input file. if ((infile = fopen(cszJpegFile, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", cszJpegFile); return EXIT_FAILURE; } // Clear high word of 32 bit int (the size is only 16 bit) // (to be sure no trash is present...) image_height=0; image_width=0; // Scan the JPEG headers to get size // (saved in global vars image_width and image_height) if( scan_JPEG_header() == EXIT_FAILURE ) return EXIT_FAILURE; *iWidth = image_width; *iHeight = image_height; // All done, exit fclose(infile); return EXIT_SUCCESS; /* suppress no-return-value warnings */}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -