Back to index

scribus-ng  1.3.4.dfsg+svn20071115
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
ExifData Class Reference

#include <exif.h>

Collaboration diagram for ExifData:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ExifData ()
bool scan (const QString &)
QString getCameraMake ()
QString getCameraModel ()
QString getDateTime ()
int getOrientation ()
int getHeight ()
int getWidth ()
int getIsColor ()
int getProcess ()
int getFlashUsed ()
float getFocalLength ()
float getExposureTime ()
float getApertureFNumber ()
float getDistance ()
int getWhitebalance ()
int getMeteringMode ()
float getCCDWidth ()
float getExposureBias ()
int getExposureProgram ()
int getISOequivalent ()
int getCompressionLevel ()
QString getUserComment ()
QString getComment ()
QImage getThumbnail ()
bool isThumbnailSane ()
bool isNullThumbnail ()

Public Attributes

bool exifDataValid

Private Member Functions

int ReadJpegSections (QFile &infile, ReadMode_t ReadMode)
void DiscardData (void)
int Get16u (void *Short)
int Get32s (void *Long)
unsigned Get32u (void *Long)
double ConvertAnyFormat (void *ValuePtr, int Format)
void ProcessExifDir (unsigned char *DirStart, unsigned char *OffsetBase, unsigned ExifLength)
void process_COM (const uchar *Data, int length)
void process_SOFn (const uchar *Data, int marker)
int Get16m (const void *Short)
void process_EXIF (unsigned char *CharBuf, unsigned int length)
int Exif2tm (struct tm *timeptr, char *ExifTime)

Private Attributes

Section_t Sections [MAX_SECTIONS]
QString CameraMake
QString CameraModel
QString DateTime
int Orientation
int Height
int Width
int ExifImageLength
int ExifImageWidth
int IsColor
int Process
int FlashUsed
float FocalLength
float ExposureTime
float ApertureFNumber
float Distance
int Whitebalance
int MeteringMode
float CCDWidth
float ExposureBias
int ExposureProgram
int ISOequivalent
int CompressionLevel
QString UserComment
QString Comment
QImage Thumbnail

Detailed Description

Definition at line 50 of file exif.h.


Constructor & Destructor Documentation


Member Function Documentation

double ExifData::ConvertAnyFormat ( void *  ValuePtr,
int  Format 
) [private]

Definition at line 422 of file exif.cpp.

{
    double Value;
    Value = 0;

    switch(Format){
        case FMT_SBYTE:     Value = *(signed char *)ValuePtr;  break;
        case FMT_BYTE:      Value = *(uchar *)ValuePtr;        break;

        case FMT_USHORT:    Value = Get16u(ValuePtr);          break;

        case FMT_ULONG:     Value = Get32u(ValuePtr);          break;

        case FMT_URATIONAL:
        case FMT_SRATIONAL:
            {
                int Num,Den;
                Num = Get32s(ValuePtr);
                Den = Get32s(4+(char *)ValuePtr);
                if (Den == 0){
                    Value = 0;
                }else{
                    Value = (double)Num/Den;
                }
                break;
            }

        case FMT_SSHORT:    Value = (signed short)Get16u(ValuePtr);  break;
        case FMT_SLONG:     Value = Get32s(ValuePtr);                break;

        // Not sure if this is correct (never seen float used in Exif format)
        case FMT_SINGLE:    Value = (double)*(float *)ValuePtr;      break;
        case FMT_DOUBLE:    Value = *(double *)ValuePtr;             break;
    }
    return Value;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ExifData::DiscardData ( void  ) [private]

Definition at line 378 of file exif.cpp.

{
    for (int a=0; a < SectionsRead; a++)
        free(Sections[a].Data);
    SectionsRead = 0;
}

Here is the caller graph for this function:

int ExifData::Exif2tm ( struct tm *  timeptr,
char *  ExifTime 
) [private]

Definition at line 848 of file exif.cpp.

{
    int a;

    timeptr->tm_wday = -1;

    // Check for format: YYYY:MM:DD HH:MM:SS format.
    a = sscanf(ExifTime, "%d:%d:%d %d:%d:%d",
            &timeptr->tm_year, &timeptr->tm_mon, &timeptr->tm_mday,
            &timeptr->tm_hour, &timeptr->tm_min, &timeptr->tm_sec);

    if (a == 6){
        timeptr->tm_isdst = -1;
        timeptr->tm_mon -= 1;      // Adjust for unix zero-based months
        timeptr->tm_year -= 1900;  // Adjust for year starting at 1900
        return true; // worked.
    }

    return false; // Wasn't in Exif date format.
}
int ExifData::Get16m ( const void *  Short) [private]

Definition at line 784 of file exif.cpp.

{
    return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
}

Here is the caller graph for this function:

int ExifData::Get16u ( void *  Short) [private]

Definition at line 388 of file exif.cpp.

{
    if (MotorolaOrder){
        return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
    }else{
        return (((uchar *)Short)[1] << 8) | ((uchar *)Short)[0];
    }
}

Here is the caller graph for this function:

int ExifData::Get32s ( void *  Long) [private]

Definition at line 400 of file exif.cpp.

{
    if (MotorolaOrder){
        return  ((( char *)Long)[0] << 24) | (((uchar *)Long)[1] << 16)
              | (((uchar *)Long)[2] << 8 ) | (((uchar *)Long)[3] << 0 );
    }else{
        return  ((( char *)Long)[3] << 24) | (((uchar *)Long)[2] << 16)
              | (((uchar *)Long)[1] << 8 ) | (((uchar *)Long)[0] << 0 );
    }
}

Here is the caller graph for this function:

unsigned ExifData::Get32u ( void *  Long) [private]

Definition at line 414 of file exif.cpp.

{
    return (unsigned)Get32s(Long) & 0xffffffff;
}

Here is the call graph for this function:

Here is the caller graph for this function:

float ExifData::getApertureFNumber ( ) [inline]

Definition at line 103 of file exif.h.

{ return ApertureFNumber; }

Here is the caller graph for this function:

QString ExifData::getCameraMake ( ) [inline]

Definition at line 92 of file exif.h.

{ return CameraMake; }

Here is the caller graph for this function:

QString ExifData::getCameraModel ( ) [inline]

Definition at line 93 of file exif.h.

{ return CameraModel; }

Here is the caller graph for this function:

float ExifData::getCCDWidth ( ) [inline]

Definition at line 107 of file exif.h.

{ return CCDWidth; }
QString ExifData::getComment ( ) [inline]

Definition at line 113 of file exif.h.

{ return Comment; }

Here is the caller graph for this function:

Definition at line 111 of file exif.h.

{ return CompressionLevel; }
QString ExifData::getDateTime ( ) [inline]

Definition at line 94 of file exif.h.

{ return DateTime; }

Here is the caller graph for this function:

float ExifData::getDistance ( ) [inline]

Definition at line 104 of file exif.h.

{ return Distance; }
float ExifData::getExposureBias ( ) [inline]

Definition at line 108 of file exif.h.

{ return ExposureBias; }

Definition at line 109 of file exif.h.

{ return ExposureProgram; }
float ExifData::getExposureTime ( ) [inline]

Definition at line 102 of file exif.h.

{ return ExposureTime; }

Here is the caller graph for this function:

Definition at line 100 of file exif.h.

{ return FlashUsed; }
float ExifData::getFocalLength ( ) [inline]

Definition at line 101 of file exif.h.

{ return FocalLength; }
int ExifData::getHeight ( ) [inline]

Definition at line 96 of file exif.h.

{ return Height; }

Here is the caller graph for this function:

int ExifData::getIsColor ( ) [inline]

Definition at line 98 of file exif.h.

{ return IsColor; }

Definition at line 110 of file exif.h.

{ return ISOequivalent; }

Here is the caller graph for this function:

Definition at line 106 of file exif.h.

{ return MeteringMode; }

Definition at line 95 of file exif.h.

{ return Orientation; }
int ExifData::getProcess ( ) [inline]

Definition at line 99 of file exif.h.

{ return Process; }

Definition at line 956 of file exif.cpp.

                              {
  if (!isThumbnailSane()) return NULL;
  if (!Orientation || Orientation == 1) return Thumbnail;

  // now fix orientation
  QWMatrix M;
  QWMatrix flip= QWMatrix(-1,0,0,1,0,0);
  switch (Orientation) {  // notice intentional fallthroughs
    case 2: M = flip; break;
    case 4: M = flip;
    case 3: M.rotate(180); break;
    case 5: M = flip;
    case 6: M.rotate(90); break;
    case 7: M = flip;
    case 8: M.rotate(270); break;
    default: break; // should never happen
  }
  return Thumbnail.xForm(M);
}

Here is the call graph for this function:

Here is the caller graph for this function:

QString ExifData::getUserComment ( ) [inline]

Definition at line 112 of file exif.h.

{ return UserComment; }

Here is the caller graph for this function:

Definition at line 105 of file exif.h.

{ return Whitebalance; }
int ExifData::getWidth ( ) [inline]

Definition at line 97 of file exif.h.

{ return Width; }

Here is the caller graph for this function:

Definition at line 116 of file exif.h.

{ return !isThumbnailSane(); }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 938 of file exif.cpp.

                               {
  if (Thumbnail.isNull()) return false;

  // check whether thumbnail dimensions match the image
  // not foolproof, but catches some altered images (jpegtran -rotate)
  if (ExifImageLength != 0 && ExifImageLength != Height) return false;
  if (ExifImageWidth != 0 && ExifImageWidth != Width) return false;
  if (Thumbnail.width() == 0 || Thumbnail.height() == 0) return false;
  if (Height == 0 || Width == 0) return false;
  double d = (double)Height/Width*Thumbnail.width()/Thumbnail.height();
  return (1-JPEG_TOL < d) && (d < 1+JPEG_TOL);
}

Here is the caller graph for this function:

void ExifData::process_COM ( const uchar Data,
int  length 
) [private]

Definition at line 753 of file exif.cpp.

{
    Comment = QString::fromUtf8((char *)Data+2, (length-2));
}

Here is the caller graph for this function:

void ExifData::process_EXIF ( unsigned char *  CharBuf,
unsigned int  length 
) [private]

Definition at line 794 of file exif.cpp.

{
    ExifData::FlashUsed = 0; // If it s from a digicam, and it used flash, it says so.

    FocalplaneXRes = 0;
    FocalplaneUnits = 0;
    ExifImageWidth = 0;
    ExifImageLength = 0;

    {   // Check the EXIF header component
        static const uchar ExifHeader[] = "Exif\0\0";
        if (memcmp(CharBuf+2, ExifHeader,6)){
                return ;
//            throw FatalError("Incorrect Exif header");
        }
    }

    if (memcmp(CharBuf+8,"II",2) == 0){
        // printf("Exif section in Intel order\n");
        MotorolaOrder = 0;
    }else{
        if (memcmp(CharBuf+8,"MM",2) == 0){
            // printf("Exif section in Motorola order\n");
            MotorolaOrder = 1;
        }else{
                return ;
//            throw FatalError("Invalid Exif alignment marker.");
        }
    }

    // Check the next two values for correctness.
    if (Get16u(CharBuf+10) != 0x2a
      || Get32u(CharBuf+12) != 0x08){
                return ;
//        throw FatalError("Invalid Exif start (1)");
    }

    LastExifRefd = CharBuf;

    // First directory starts 16 bytes in.  Offsets start at 8 bytes in.
    ProcessExifDir(CharBuf+16, CharBuf+8, length-6);

    // This is how far the interesting (non thumbnail) part of the exif went.
    ExifSettingsLength = LastExifRefd - CharBuf;

    // Compute the CCD width, in milimeters.
    if (FocalplaneXRes != 0){
        ExifData::CCDWidth = (float)(ExifImageWidth * FocalplaneUnits / FocalplaneXRes);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ExifData::process_SOFn ( const uchar Data,
int  marker 
) [private]

Definition at line 762 of file exif.cpp.

{
    int data_precision, num_components;

    data_precision = Data[2];
    ExifData::Height = Get16m(Data+3);
    ExifData::Width = Get16m(Data+5);
    num_components = Data[7];

    if (num_components == 3){
        ExifData::IsColor = 1;
    }else{
        ExifData::IsColor = 0;
    }

    ExifData::Process = marker;

}

Here is the call graph for this function:

Here is the caller graph for this function:

void ExifData::ProcessExifDir ( unsigned char *  DirStart,
unsigned char *  OffsetBase,
unsigned  ExifLength 
) [private]

Definition at line 462 of file exif.cpp.

{
    int de;
    int a;
    int NumDirEntries;
    unsigned ThumbnailOffset = 0;
    unsigned ThumbnailSize = 0;

    NumDirEntries = Get16u(DirStart);
    #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))

    {
        unsigned char * DirEnd;
        DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries);
        if (DirEnd+4 > (OffsetBase+ExifLength)){
            if (DirEnd+2 == OffsetBase+ExifLength || DirEnd == OffsetBase+ExifLength){
                // Version 1.3 of jhead would truncate a bit too much.
                // This also caught later on as well.
            }else{
                // Note: Files that had thumbnails trimmed with jhead 1.3 or earlier
                // might trigger this.
                return;
//                throw FatalError("Illegally sized directory");
            }
        }
        if (DirEnd < LastExifRefd) LastExifRefd = DirEnd;
    }

    for (de=0;de<NumDirEntries;de++){
        int Tag, Format, Components;
        unsigned char * ValuePtr;
        int ByteCount;
        char * DirEntry;
        DirEntry = (char *)DIR_ENTRY_ADDR(DirStart, de);

        Tag = Get16u(DirEntry);
        Format = Get16u(DirEntry+2);
        Components = Get32u(DirEntry+4);

        if ((Format-1) >= NUM_FORMATS) {
            // (-1) catches illegal zero case as unsigned underflows to positive large.
                return;
//            throw FatalError("Illegal format code in EXIF dir");
        }

        ByteCount = Components * BytesPerFormat[Format];

        if (ByteCount > 4){
            unsigned OffsetVal;
            OffsetVal = Get32u(DirEntry+8);
            // If its bigger than 4 bytes, the dir entry contains an offset.
            if (OffsetVal+ByteCount > ExifLength){
                // Bogus pointer offset and / or bytecount value
                //printf("Offset %d bytes %d ExifLen %d\n",OffsetVal, ByteCount, ExifLength);

                return ;
//                throw FatalError("Illegal pointer offset value in EXIF");
            }
            ValuePtr = OffsetBase+OffsetVal;
        }else{
            // 4 bytes or less and value is in the dir entry itself
            ValuePtr = (unsigned char *)DirEntry+8;
        }

        if (LastExifRefd < ValuePtr+ByteCount){
            // Keep track of last byte in the exif header that was actually referenced.
            // That way, we know where the discardable thumbnail data begins.
            LastExifRefd = ValuePtr+ByteCount;
        }

        // Extract useful components of tag
        switch(Tag){

            case TAG_MAKE:
                ExifData::CameraMake = QString((char*)ValuePtr);
                break;

            case TAG_MODEL:
                ExifData::CameraModel = QString((char*)ValuePtr);
              break;

            case TAG_ORIENTATION:
                Orientation = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_DATETIME_ORIGINAL:
              DateTime = QString((char*)ValuePtr);
                break;

            case TAG_USERCOMMENT:
                // Olympus has this padded with trailing spaces.  Remove these first.
                for (a=ByteCount;;){
                    a--;
                    if ((ValuePtr)[a] == ' '){
                        (ValuePtr)[a] = '\0';
                    }else{
                        break;
                    }
                    if (a == 0) break;
                }

                // Copy the comment
                if (memcmp(ValuePtr, "ASCII",5) == 0){
                    for (a=5;a<10;a++){
                        int c;
                        c = (ValuePtr)[a];
                        if (c != '\0' && c != ' '){
                            //strncpy(ImageInfo.Comments, (const char*)(a+ValuePtr), 199);
                            UserComment.sprintf("%s", (const char*)(a+ValuePtr));
                            break;
                        }
                    }
                }else{
                    //strncpy(ImageInfo.Comments, (const char*)ValuePtr, 199);
                    UserComment.sprintf("%s", (const char*)ValuePtr);
                }
                break;

            case TAG_FNUMBER:
                // Simplest way of expressing aperture, so I trust it the most.
                // (overwrite previously computd value if there is one)
              ExifData::ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_APERTURE:
            case TAG_MAXAPERTURE:
                // More relevant info always comes earlier, so only use this field if we don't
                // have appropriate aperture information yet.
                if (ExifData::ApertureFNumber == 0){
                    ExifData::ApertureFNumber
                        = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)*0.5);
                }
                break;

            case TAG_FOCALLENGTH:
                // Nice digital cameras actually save the focal length as a function
                // of how far they are zoomed in.
                ExifData::FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_SUBJECT_DISTANCE:
                // Inidcates the distacne the autofocus camera is focused to.
                // Tends to be less accurate as distance increases.
                ExifData::Distance = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXPOSURETIME:
                // Simplest way of expressing exposure time, so I trust it most.
                // (overwrite previously computd value if there is one)
                ExifData::ExposureTime = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_SHUTTERSPEED:
                // More complicated way of expressing exposure time, so only use
                // this value if we don't already have it from somewhere else.
                if (ExifData::ExposureTime == 0){
                    ExifData::ExposureTime
                        = (float)(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)));
                }
                break;

            case TAG_FLASH:
              ExifData::FlashUsed = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXIF_IMAGELENGTH:
                ExifImageLength = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXIF_IMAGEWIDTH:
                ExifImageWidth = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_FOCALPLANEXRES:
                FocalplaneXRes = ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_FOCALPLANEUNITS:
                switch((int)ConvertAnyFormat(ValuePtr, Format)){
                    case 1: FocalplaneUnits = 25.4; break; // inch
                    case 2:
                        // According to the information I was using, 2 means meters.
                        // But looking at the Cannon powershot's files, inches is the only
                        // sensible value.
                        FocalplaneUnits = 25.4;
                        break;

                    case 3: FocalplaneUnits = 10;   break;  // centimeter
                    case 4: FocalplaneUnits = 1;    break;  // milimeter
                    case 5: FocalplaneUnits = .001; break;  // micrometer
                }
                break;

                // Remaining cases contributed by: Volker C. Schoech (schoech@gmx.de)

            case TAG_EXPOSURE_BIAS:
              ExifData::ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format);
              break;

            case TAG_WHITEBALANCE:
                 ExifData::Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format);
               break;

            case TAG_METERING_MODE:
                ExifData::MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXPOSURE_PROGRAM:
                ExifData::ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_ISO_EQUIVALENT:
                ExifData::ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
                if ( ExifData::ISOequivalent < 50 ) ExifData::ISOequivalent *= 200;
                break;

            case TAG_COMPRESSION_LEVEL:
                ExifData::CompressionLevel = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_THUMBNAIL_OFFSET:
                ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_THUMBNAIL_LENGTH:
                ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format);
                break;

        }

        if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
            unsigned char * SubdirStart;
            SubdirStart = OffsetBase + Get32u(ValuePtr);
            if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength){
                return ;
//                throw FatalError("Illegal subdirectory link");
            }
            ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
            continue;
        }
    }

    {
        // In addition to linking to subdirectories via exif tags,
        // there's also a potential link to another directory at the end of each
        // directory.  this has got to be the result of a comitee!
        unsigned char * SubdirStart;
        unsigned Offset;

        if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){
            Offset = Get32u(DIR_ENTRY_ADDR(DirStart, NumDirEntries));
           // There is at least one jpeg from an HP camera having an Offset of almost MAXUINT.
           // Adding OffsetBase to it produces an overflow, so compare with ExifLength here.
           // See http://bugs.kde.org/show_bug.cgi?id=54542
           if (Offset && Offset < ExifLength){
                SubdirStart = OffsetBase + Offset;
                if (SubdirStart > OffsetBase+ExifLength){
                    if (SubdirStart < OffsetBase+ExifLength+20){
                        // Jhead 1.3 or earlier would crop the whole directory!
                        // As Jhead produces this form of format incorrectness,
                        // I'll just let it pass silently
                        qDebug("Thumbnail removed with Jhead 1.3 or earlier");
                    }else{
                return ;
 //                       throw FatalError("Illegal subdirectory link 2");
                    }
                }else{
                    if (SubdirStart <= OffsetBase+ExifLength){
                        ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
                    }
                }
            }
        }else{
            // The exif header ends before the last next directory pointer.
        }
    }

    if (ThumbnailSize && ThumbnailOffset){
        if (ThumbnailSize + ThumbnailOffset <= ExifLength){
            // The thumbnail pointer appears to be valid.  Store it.
           Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG");
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ExifData::ReadJpegSections ( QFile &  infile,
ReadMode_t  ReadMode 
) [private]

Definition at line 220 of file exif.cpp.

{
    int a;

    a = infile.getch();

    if (a != 0xff || infile.getch() != M_SOI) {
        SectionsRead = 0;
        return false;
    }
    for(SectionsRead = 0; SectionsRead < MAX_SECTIONS-1; ){
        int marker = 0;
        int got;
        unsigned int ll,lh;
        unsigned int itemlen;
        uchar * Data;

        for (a=0;a<7;a++){
            marker = infile.getch();
            if (marker != 0xff) break;

            if (a >= 6){

                qDebug("too many padding bytes");
                return false;

            }
        }

        if (marker == 0xff){
            // 0xff is legal padding, but if we get that many, something's wrong.
                return false;
//            throw FatalError("too many padding bytes!");
        }

        Sections[SectionsRead].Type = marker;

        // Read the length of the section.
        lh = (uchar) infile.getch();
        ll = (uchar) infile.getch();

        itemlen = (lh << 8) | ll;

        if (itemlen < 2) {
                return false;
 //           throw FatalError("invalid marker");
        }

        Sections[SectionsRead].Size = itemlen;

        Data = (uchar *)malloc(itemlen+1); // Add 1 to allow sticking a 0 at the end.
        Sections[SectionsRead].Data = Data;

        // Store first two pre-read bytes.
        Data[0] = (uchar)lh;
        Data[1] = (uchar)ll;

        got = infile.readBlock((char*)Data+2, itemlen-2); // Read the whole section.
        if (( unsigned ) got != itemlen-2){
                return false;
//            throw FatalError("reading from file");
        }
        SectionsRead++;

        switch(marker){

            case M_SOS:   // stop before hitting compressed data
                // If reading entire image is requested, read the rest of the data.
                if (ReadMode & READ_IMAGE){
                    unsigned long size;

                    size = QMAX( 0ul, infile.size()-infile.at() );
                    Data = (uchar *)malloc(size);
                    if (Data == NULL){
                return false;
//                        throw FatalError("could not allocate data for entire image");
                    }

                    got = infile.readBlock((char*)Data,  size);
                    if (( unsigned ) got != size){
                return false;
 //                       throw FatalError("could not read the rest of the image");
                    }

                    Sections[SectionsRead].Data = Data;
                    Sections[SectionsRead].Size = size;
                    Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
                    SectionsRead ++;
                    //HaveAll = 1;
                }
                return true;

            case M_EOI:   // in case it's a tables-only JPEG stream
                qDebug("No image in jpeg!");
                return false;

            case M_COM: // Comment section
              // pieczy 2002-02-12
              // now the User comment goes to UserComment
              // so we can store a Comment section also in READ_EXIF mode
              process_COM(Data, itemlen);
                break;

            case M_JFIF:
                // Regular jpegs always have this tag, exif images have the exif
                // marker instead, althogh ACDsee will write images with both markers.
                // this program will re-create this marker on absence of exif marker.
                // hence no need to keep the copy from the file.
                free(Sections[--SectionsRead].Data);
                break;

            case M_EXIF:
                // Seen files from some 'U-lead' software with Vivitar scanner
                // that uses marker 31 for non exif stuff.  Thus make sure
                // it says 'Exif' in the section before treating it as exif.
                if ((ReadMode & READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0)
                {
                    process_EXIF((uchar *)Data, itemlen); // FIXME: This call
                     // requires Data to be array of at least 8 bytes. Code
                     // above only checks for itemlen < 2.
                                   exifDataValid = true;
                }
                else
                {
                    // Discard this section.
                    free(Sections[--SectionsRead].Data);
//                    return false;
                }
                break;

            case M_SOF0:
            case M_SOF1:
            case M_SOF2:
            case M_SOF3:
            case M_SOF5:
            case M_SOF6:
            case M_SOF7:
            case M_SOF9:
            case M_SOF10:
            case M_SOF11:
            case M_SOF13:
            case M_SOF14:
            case M_SOF15:
                process_SOFn(Data, marker); //FIXME: This call requires Data to
              // be array of at least 8 bytes. Code above only checks for 
              // itemlen < 2.
            default:
                break;
                break;
        }
    }
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool ExifData::scan ( const QString &  path)

Definition at line 897 of file exif.cpp.

{
    int ret;

    QFile f(path);
    if ( !f.open(IO_ReadOnly) )
        return false;

//    try {
        // Scan the JPEG headers.
        ret = ReadJpegSections(f, READ_EXIF);
/*    }
    catch (FatalError& e) {
        e.debug_print();
        f.close();
        return false;
    }
*/
    if (ret == false){
        DiscardData();
        f.close();
        return false;
    }
    f.close();
    DiscardData();

    //now make the strings clean,
    // for exmaple my Casio is a "QV-4000   "
    CameraMake = CameraMake.stripWhiteSpace();
    CameraModel = CameraModel.stripWhiteSpace();
    UserComment = UserComment.stripWhiteSpace();
    Comment = Comment.stripWhiteSpace();
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

float ExifData::ApertureFNumber [private]

Definition at line 63 of file exif.h.

QString ExifData::CameraMake [private]

Definition at line 52 of file exif.h.

QString ExifData::CameraModel [private]

Definition at line 53 of file exif.h.

float ExifData::CCDWidth [private]

Definition at line 67 of file exif.h.

QString ExifData::Comment [private]

Definition at line 73 of file exif.h.

Definition at line 71 of file exif.h.

QString ExifData::DateTime [private]

Definition at line 54 of file exif.h.

float ExifData::Distance [private]

Definition at line 64 of file exif.h.

Definition at line 117 of file exif.h.

Definition at line 57 of file exif.h.

Definition at line 57 of file exif.h.

float ExifData::ExposureBias [private]

Definition at line 68 of file exif.h.

Definition at line 69 of file exif.h.

float ExifData::ExposureTime [private]

Definition at line 62 of file exif.h.

Definition at line 60 of file exif.h.

float ExifData::FocalLength [private]

Definition at line 61 of file exif.h.

int ExifData::Height [private]

Definition at line 56 of file exif.h.

Definition at line 58 of file exif.h.

Definition at line 70 of file exif.h.

Definition at line 66 of file exif.h.

Definition at line 55 of file exif.h.

Definition at line 59 of file exif.h.

Definition at line 51 of file exif.h.

QImage ExifData::Thumbnail [private]

Definition at line 74 of file exif.h.

QString ExifData::UserComment [private]

Definition at line 72 of file exif.h.

Definition at line 65 of file exif.h.

int ExifData::Width [private]

Definition at line 56 of file exif.h.


The documentation for this class was generated from the following files: