lib/jpegSize.c

Go to the documentation of this file.
00001 /* jpegSize - read a jpeg header and figure out dimensions of image.
00002  * Adapted by Galt Barber from Matthias Wandel's jhead program */
00003 #include "common.h"
00004 #include "jpegSize.h"
00005 
00006 /* sections containing width and height     */
00007 #define M_SOF0  0xC0            /* Start Of Frame N                        */
00008 #define M_SOF1  0xC1            /* N indicates which compression process   */
00009 #define M_SOF2  0xC2            /* Only SOF0-SOF2 are now in common use    */
00010 #define M_SOF3  0xC3
00011 #define M_SOF5  0xC5            /* NB: codes C4 and CC are NOT SOF markers */
00012 #define M_SOF6  0xC6
00013 #define M_SOF7  0xC7
00014 #define M_SOF9  0xC9
00015 #define M_SOF10 0xCA
00016 #define M_SOF11 0xCB
00017 #define M_SOF13 0xCD
00018 #define M_SOF14 0xCE
00019 #define M_SOF15 0xCF
00020 
00021 #define M_SOI   0xD8            /* Start Of Image (beginning of datastream)*/
00022 #define M_EOI   0xD9            /* End Of Image (end of datastream)        */
00023 #define M_SOS   0xDA            /* Start Of Scan (begins compressed data)  */
00024 #define M_JFIF  0xE0            /* Jfif marker                             */
00025 #define M_EXIF  0xE1            /* Exif marker                             */
00026 
00027 #define MAX_SECTIONS 40
00028 
00029 typedef unsigned char uchar;
00030 
00031 void jpegSize(char *fileName, int *width, int *height)
00032 /* Read image width and height.
00033  * Parse marker stream until SOS or EOI; */
00034 {
00035 FILE * infile = mustOpen(fileName, "r"); 
00036 int sectionsRead = 0;
00037 boolean done = FALSE;
00038 boolean foundJFIF = FALSE;
00039 /* Scan the JPEG headers. */
00040 if (fgetc(infile) != 0xff || fgetc(infile) != M_SOI)
00041     errAbort("error reading jpg header: %s",fileName);
00042 while(!done)
00043     {
00044     int itemlen;
00045     int marker = 0;
00046     int ll,lh, got;
00047     int a=0;
00048     uchar * data;
00049 
00050     if (sectionsRead >= MAX_SECTIONS)
00051         errAbort("Too many sections in jpg file: %s",fileName);
00052 
00053     for (a=0;a<7;a++)
00054         {
00055         marker = fgetc(infile);
00056         if (marker != 0xff) 
00057             break;
00058         if (a >= 6)
00059             errAbort("too many padding bytes: %s",fileName);
00060         }
00061 
00062     /* 0xff is legal padding, but if we get that many, something's wrong. */
00063     if (marker == 0xff)
00064         errAbort("too many padding bytes: %s",fileName);
00065 
00066     /* Read the length of the section. */
00067     lh = fgetc(infile);
00068     ll = fgetc(infile);
00069 
00070     itemlen = (lh << 8) | ll;
00071 
00072     if (itemlen < 2)
00073         errAbort("invalid jpeg marker: %s",fileName);
00074 
00075     data = (uchar *)needMem(itemlen);
00076     if (data == NULL)
00077         errAbort("Could not allocate %d bytes memory", itemlen);
00078 
00079     /* Store first two pre-read bytes. */
00080     data[0] = (uchar)lh;
00081     data[1] = (uchar)ll;
00082 
00083     got = fread(data+2, 1, itemlen-2, infile); /* Read the whole section. */
00084     if (got != itemlen-2)
00085         errAbort("Premature end of file?: %s",fileName);
00086     
00087     ++sectionsRead;
00088 
00089     switch(marker)
00090         {
00091         case M_SOS:   /* stop before hitting compressed data */
00092             done = TRUE;
00093             break;
00094         case M_EOI:   /* in case it's a tables-only JPEG stream */
00095             errAbort("No image in jpeg!: %s",fileName);
00096         case M_JFIF:
00097             /* Regular jpegs always have this tag, 
00098                exif images have the exif marker instead or in addition 
00099                - could add check to make sure this is present
00100             */
00101             foundJFIF = TRUE;
00102             break;
00103 
00104         case M_SOF0:
00105         case M_SOF1:
00106         case M_SOF2:
00107         case M_SOF3:
00108         case M_SOF5:
00109         case M_SOF6:
00110         case M_SOF7:
00111         case M_SOF9:
00112         case M_SOF10:
00113         case M_SOF11:
00114         case M_SOF13:
00115         case M_SOF14:       
00116         case M_SOF15:
00117             *height = data[3]*256+data[4];
00118             *width  = data[5]*256+data[6];
00119             done = TRUE;
00120             break;
00121         default:
00122             /* Skip any other sections. */
00123             break;
00124         }
00125         
00126     freez(&data);
00127     
00128     }
00129 fclose(infile);
00130 if (!foundJFIF)
00131     errAbort("JFIF marker not found jpeg: %s",fileName);
00132 return;
00133 }
00134 
00135 

Generated on Tue Dec 25 18:39:31 2007 for blat by  doxygen 1.5.2