Decoding the width and height of a JPEG (JFIF) file

http://www.64Lines.com »» Decoding the width and height of a JPEG (JFIF) file «

Overview

The width and height of a JPEG image might seem irrelevant to the usual programmer, but at times a challenge comes up when it becomes required. During a small JPEG importing routine that I was writing I had to pass the width and height of the image as variables that were separate from the data itself. My first thought was that it would be stored in the header of the file just like GIF file width and height are stored, but it was no so.

Source Code

Decoding Function C++ source code in 31 lines//Gets the JPEG size from the array of data passed to the function, file reference: http://www.obrador.com/essentialjpeg/headerinfo.htm
static char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height) {
   //Check for valid JPEG image
   int i=0;   // Keeps track of the position within the file
   if(data[i] == 0xFF && data[i+1] == 0xD8 && data[i+2] == 0xFF && data[i+3] == 0xE0) {
      i += 4;
      // Check for valid JPEG header (null terminated JFIF)
      if(data[i+2] == 'J' && data[i+3] == 'F' && data[i+4] == 'I' && data[i+5] == 'F' && data[i+6] == 0x00) {
         //Retrieve the block length of the first block since the first block will not contain the size of file
         unsigned short block_length = data[i] * 256 + data[i+1];
         while(i<data_size) {
            i+=block_length;               //Increase the file index to get to the next block
            if(i >= data_size) return false;   //Check to protect against segmentation faults
            if(data[i] != 0xFF) return false;   //Check that we are truly at the start of another block
            if(data[i+1] == 0xC0) {            //0xFFC0 is the "Start of frame" marker which contains the file size
               //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
               *height = data[i+5]*256 + data[i+6];
               *width = data[i+7]*256 + data[i+8];
               return true;
            }
            else
            {
               i+=2;                              //Skip the block marker
               block_length = data[i] * 256 + data[i+1];   //Go to the next block
            }
         }
         return false;                     //If this point is reached then no size was found
      }else{ return false; }                  //Not a valid JFIF string
         
   }else{ return false; }                     //Not a valid SOI header
}

References

JPEG Header Information - a great summary of the header markers, it was just what I needed for this simple script

Check out the other 64Lines.com articles, tutorials, and tools

All article content is copyright of Michael Petrov, 2013©.
The source code presented in the articles is distributed as freeware, please feel free to use it in your own projects - both commercial and non commercial.
Valid HTML 4.01 TransitionalValid CSS!