kolyaseg
kolyaseg

Reputation: 543

Can't read Exif info for some photos

I'm making photo renaming tool on Adobe AIR and has encountered a problem with reading EXIF info for some pictures. Those pictures do not vary from many others whose EXIF i can read and have been taken at the same time on the same camera.

I tried to use both exif reading libs: Exif Extractor and ExifInfo by shichiseki. And both of them can't read it.

I anylized the code of ExifInfo lib and found out that it returns null because those particluar photos don't have some unsigned byte (returned by ByteArray.readUnsignedByte() method).

The oddity is that Windows' Explorer shows exif info as in general like for other pictures.

UPDATE: i've just found the reason of losing those unsigned bytes. These are the photos to which i added keywords in Windows Explorer. So they still have exif info but lose those damn bytes.

UPDATE 2: Further research showed that normal picture (without tags) has unsigned bytes as follows:

b = 255
b = 216
b = 255
b = 224
b = 255
b = 225
b = 69
b = 120
b = 105
b = 102
b = 0
b = 0

And tagged one:

b = 255
b = 216
b = 255
b = 224
b = 255
b = 238

So it return false on that last "238" byte, which i guess, doesn't equal to one of [0xff, 0xe1]. Some pictures that Exif can't be read do not comply to other byte rules, stated as constants in ExifInfo class:

private const SOI_MAKER:Array = [0xff, 0xd8];
private const JFIF_MAKER:Array = [0xff, 0xe0];
private const APP1_MAKER:Array = [0xff, 0xe1];
private const EXIF_HEADER:Array = [0x45, 0x78, 0x69, 0x66, 0x00, 0x00];

UPDATE 3: My next try was shifting position of picture ByteArray's stream for 14 bytes (the place where needed 255 and 225 unsigned bytes reside) and it solved the problem.

Upvotes: 0

Views: 159

Answers (1)

kolyaseg
kolyaseg

Reputation: 543

So i edited a bit of the main class ExifInfo.as (shichiseki's lib) from

if ( !hasAPP1Maker(stream)) {
    return false;
}

to:

if ( !hasAPP1Maker(stream)) {
    stream.position += 14;
    if ( !hasAPP1Maker(stream)) {
        stream.position -= 14;
        return false;
    }
}

I don't actually understand why and what i really did. Just traced unsigned bytes for such pictures from 0 to 255 and found those bytes for APP1_MAKER constant a little further in a stream. So it works. Hope may help someone.

Upvotes: 1

Related Questions