Logo Search packages:      
Sourcecode: hitop version File versions

jpeg.cc

#include "jpeg.h"
#include <string.h>

#define M_SOF0  0xC0
#define M_SOF1  0xC1
#define M_SOF2  0xC2
#define M_SOF3  0xC3
#define M_SOF5  0xC5
#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
#define M_EOI   0xD9
#define M_SOS   0xDA
#define M_APP0  0xE0
#define M_COM   0xFE

static bool ReadByte(FILE *file, unsigned char& b){
  int ch=fgetc(file);
  if(ch==EOF) return false;
  b=(unsigned char)ch;
  return true;
}

static bool ReadWord(FILE *file, short& w){
  unsigned char hi,lo;
  int high,low;
  if(!ReadByte(file,hi)) return false;
  if(!ReadByte(file,lo)) return false;
  high=hi;
  low=lo;
  w=(high<<8)+low;
  return true;
}

static int JpegFirstMarker(FILE *file){
    unsigned char flag;
    unsigned char marker;

    /* move to the beginning of the file */
    if(fseek(file, 0, SEEK_SET) != 0)
    {
        return 0;
    }

    /* look for the start of image marker */
    if(ReadByte(file,flag) == 0)
    {
        return 0;
    }

    if(ReadByte(file,marker) == 0)
    {
        return 0;
    }

    /* start of image? */
    if((flag != 0xFF) || (marker != M_SOI))
    {
        return 0;
    }

    return 1;
}

static int JpegNextMarker(FILE *file, unsigned char *marker){
    unsigned char flag;
    int ok;

    /* move file pointer to next 0xFF flag */
    while((ok = ReadByte(file,flag)) == 1)
    {
        if(flag == 0xFF)
        {
            break;
        }
    }

    if(ok == 0)
    {
        return 0;
    }

    /* extra 0xFF flags are legal as padding, so move past them */
    while((ok = ReadByte(file,*marker)) == 1)
    {
        if(*marker != 0xFF)
        {
            break;
        }
    }

    /* exit condition really depends if a good marker was found */
    return ok;
}

bool JPEG::IsA(FILE *file){
    unsigned char marker;
    char signature[8];

    if(JpegFirstMarker(file) == 0)
    {
        return false;
    }

    if(JpegNextMarker(file, &marker) == 0)
    {
        return false;
    }

    /* should see an APP0 marker */
    if(marker != M_APP0)
    {
        return false;
    }

    /* file format is now pointing to JFIF header ... skip two bytes and */
    /* look for the signature */
    if(fseek(file, 2, SEEK_CUR) != 0)
    {
        return false;
    }

    if(fread(signature, 1, 5, file) != 5)
    {
        return false;
    }

    /* it all comes down to the signature being present */
    return strcmp(signature, "JFIF")==0;
}

bool JPEG::GetSize(FILE *file, int& height, int& width){
  if(!IsA(file)) return false;
    unsigned char marker;

    /* make sure we can find the first marker */
    if(JpegFirstMarker(file) == 0)
    {
        return false;
    }

    /* read file looking for SOF (start of frame) ... when it or */
    /* or SOS (start of scan, the compressed data) is reached, stop */
    while(JpegNextMarker(file, &marker) == 1)
    {
        /* if SOS, stop */
        if(marker == M_SOS)
        {
            break;
        }

        /* if not SOF, continue */
        if((marker < M_SOF0) || (marker > M_SOF15))
        {
            continue;
        }

        /* start of frame found ... process the dimension information */
        /* seek past the next three bytes, useless for this application */
        if(fseek(file, 3, SEEK_CUR) != 0)
        {
            return false;
        }

        short tx,ty;

        /* read the height and width and get outta here */
        if(ReadWord(file,ty) == 0)
        {
            return false;
        }

        if(ReadWord(file,tx) == 0)
        {
            return false;
        }

        height=ty;
        width=tx;

        return true;
    }

    /* didn't find the SOF or found the SOS */
    return false;
}

Generated by  Doxygen 1.6.0   Back to index