mdtuyen / iphone-exif

Automatically exported from code.google.com/p/iphone-exif
1 stars 0 forks source link

EXFJpeg populateImageData breaks some values in EXIF #10

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Read and populate metadata from jpg file (iOS SDK 4.3)
EXFJpeg* jpegScanner = [[EXFJpeg alloc] init];
[jpegScanner scanImageData: jpegData];
EXFMetaData* exifMetaData = jpegScanner.exifMetaData;
NSMutableData* newJpegData = [[NSMutableData alloc] init];
[jpegScanner populateImageData:newJpegData :exifMetaData];

What is the expected output? What do you see instead?
This shound not change any EXIF/JFIF etc value.
How ever it seems it breaks some values in metadata.
Wrong  values are in the following tags:
ApertureValue, FNumber, FocalLength, ShutterSpeedValue

Correct values are in:
ColorSpace, Exif version, Pixel X/Y dimension and few more

Missing values:
ExposureProgra, ISO, SUbkect Are

I also noticed that some values are moved to other tags:
FocalLength moved to FNumber
ApertureValue moved to ExposureTime

What version of the product are you using? On what operating system?
0.9

Original issue reported on code.google.com by sly...@gmail.com on 12 Apr 2011 at 12:04

GoogleCodeExporter commented 9 years ago
Well, I fixed the problem. However it is not a real fix, but only workaround.

The problem was in file EXFMetaData.m, in function 
-(void) getDataFromMap: (NSDictionary*) dictionary :(NSMutableArray*) 
dataWriterArray: (UInt8**) bytes: (int) overflowOffset: (int) offsetBase

It calculates blockCount as:
int blockCount = (size *12 +2)  +4;
It is not OK, because if if tag is in unexpected format, is ignored, so the 
blockSize should be also decreased.

FIX:
Replace line 1431 in file XFMetaData.m:
int blockCount = (size *12 +2)  +4;
to:
int blockCount = [self getRealBlockCount:dictionary :sortedKeysArray];

And just over function 
-(void) getDataFromMap ...

add:
- (int) getRealBlockCount: (NSDictionary*) dictionary :(NSArray*) 
sortedKeysArray {
    int size = [sortedKeysArray count] ;
    int blockCount = (size *12 +2)  +4;
    for (int de =0;de <size;de++) {
        NSNumber *key = [sortedKeysArray objectAtIndex:de];
        id obj = [dictionary objectForKey:key];
        if (![obj isKindOfClass:[NSDictionary class]]) {
            EXFTag* tag = [self.keyedTagDefinitions objectForKey:key];
            id<EXFTagHandler> handler = [[self userKeyedHandlers] objectForKey:key];
            if (handler == nil) handler = [[self keyedHandlers] objectForKey:key];    
            if (handler == nil && tag.components <0) {
                if (![obj isKindOfClass:[NSData class]] && ![obj isKindOfClass:[NSString class]]){
                    // we have a problem here, don't count this tag to blockCount!
                    blockCount-=12;
                }
            }
        }
    }
    return blockCount;
}

Can anybody confirm that this problem really exists and my workaround really 
fixes it?

Original comment by sly...@gmail.com on 12 Apr 2011 at 9:10