in Frameworks/ImageIO/CGImageSource.mm [1104:1510]
CFDictionaryRef readTIFFProperties(IWICMetadataQueryReader* imageMetadataReader) {
PROPVARIANT propertyValue;
PropVariantInit(&propertyValue);
NSMutableDictionary* properties = [[NSMutableDictionary alloc] init];
// TIFF Properties - Common
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=283}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[properties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyDPIHeight];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=282}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[properties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyDPIWidth];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=256}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[properties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyPixelWidth];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=256}", &propertyValue)) && propertyValue.vt == VT_UI4) {
[properties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyPixelWidth];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=257}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[properties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyPixelHeight];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=257}", &propertyValue)) && propertyValue.vt == VT_UI4) {
[properties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyPixelHeight];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=258}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[properties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyDepth];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=274}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[properties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyOrientation];
}
// TIFF Properties - Format-specific
NSMutableDictionary* tiffProperties = [[NSMutableDictionary alloc] init];
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=259}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[tiffProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyTIFFCompression];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=262}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[tiffProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyTIFFPhotometricInterpretation];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=270}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFImageDescription];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=271}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFMake];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=272}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFModel];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=274}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[tiffProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyTIFFOrientation];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=282}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[tiffProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyTIFFXResolution];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=283}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[tiffProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyTIFFYResolution];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=296}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[tiffProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyTIFFResolutionUnit];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=305}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFSoftware];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=306}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFDateTime];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=315}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFArtist];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=33432}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[tiffProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyTIFFCopyright];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/{ushort=41987}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[tiffProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyTIFFWhitePoint];
}
// Add the TIFF dictionary to the properties if there are any TIFF properties
if ([tiffProperties count] != 0) {
[properties setObject:tiffProperties forKey:(id)kCGImagePropertyTIFFDictionary];
}
CFRelease(tiffProperties);
// GPS Properties - TIFF - This is a copy of TIFF properties for JPEG but with different paths.
NSMutableDictionary* gpsProperties = [[NSMutableDictionary alloc] init];
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=6}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[gpsProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyGPSAltitude];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=5}", &propertyValue)) && propertyValue.vt == VT_UI1) {
[gpsProperties setObject:[NSNumber numberWithInt:propertyValue.bVal] forKey:(id)kCGImagePropertyGPSAltitudeRef];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=29}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[gpsProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyGPSDateStamp];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=11}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[gpsProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyGPSDOP];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=17}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[gpsProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyGPSImgDirection];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=16}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[gpsProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyGPSImgDirectionRef];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=2}", &propertyValue)) &&
propertyValue.vt == (VT_VECTOR | VT_UI8)) {
if (propertyValue.caub.cElems == 3) { // Validate number of fields
double degreesPart = (double)propertyValue.cauh.pElems[0].LowPart / propertyValue.cauh.pElems[0].HighPart;
double minutesPart = (double)propertyValue.cauh.pElems[1].LowPart / propertyValue.cauh.pElems[1].HighPart;
double secondsPart = (double)propertyValue.cauh.pElems[2].LowPart / propertyValue.cauh.pElems[2].HighPart;
[gpsProperties
setObject:[NSNumber numberWithDouble:degreesPart + minutesPart / c_minutesPerDegree + secondsPart / (c_secondsPerDegree)]
forKey:(id)kCGImagePropertyGPSLatitude];
}
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=1}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[gpsProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyGPSLatitudeRef];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=4}", &propertyValue)) &&
propertyValue.vt == (VT_VECTOR | VT_UI8)) {
if (propertyValue.caub.cElems == 3) { // Validate number of fields
double degreesPart = (double)propertyValue.cauh.pElems[0].LowPart / propertyValue.cauh.pElems[0].HighPart;
double minutesPart = (double)propertyValue.cauh.pElems[1].LowPart / propertyValue.cauh.pElems[1].HighPart;
double secondsPart = (double)propertyValue.cauh.pElems[2].LowPart / propertyValue.cauh.pElems[2].HighPart;
[gpsProperties
setObject:[NSNumber numberWithDouble:degreesPart + minutesPart / c_minutesPerDegree + secondsPart / (c_secondsPerDegree)]
forKey:(id)kCGImagePropertyGPSLongitude];
}
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=3}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[gpsProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyGPSLongitudeRef];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=13}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[gpsProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyGPSSpeed];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=12}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[gpsProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyGPSSpeedRef];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=7}", &propertyValue)) &&
propertyValue.vt == (VT_VECTOR | VT_UI8)) {
double timeStampHours = (double)propertyValue.cauh.pElems[0].LowPart / propertyValue.cauh.pElems[0].HighPart;
double timeStampMinutes = (double)propertyValue.cauh.pElems[1].LowPart / propertyValue.cauh.pElems[1].HighPart;
double timeStampSeconds = (double)propertyValue.cauh.pElems[2].LowPart / propertyValue.cauh.pElems[2].HighPart;
[gpsProperties setObject:[NSString stringWithFormat:@"%.2d:%.2d:%.2f", (int)timeStampHours, (int)timeStampMinutes, timeStampSeconds]
forKey:(id)kCGImagePropertyGPSTimeStamp];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=15}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[gpsProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyGPSTrack];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=14}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[gpsProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyGPSTrackRef];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/gps/{ushort=0}", &propertyValue)) &&
propertyValue.vt == (VT_VECTOR | VT_UI1)) {
if (propertyValue.caub.cElems == 4) {
NSMutableArray* gpsVersionArray = [NSMutableArray array];
for (int index = 0; index < 4; index++) {
[gpsVersionArray addObject:[NSNumber numberWithInt:propertyValue.caub.pElems[index]]];
}
[gpsProperties setObject:gpsVersionArray forKey:(id)kCGImagePropertyGPSVersion];
}
}
// Add the GPS dictionary to the properties if there are any GPS properties
if ([gpsProperties count] != 0) {
[properties setObject:gpsProperties forKey:(id)kCGImagePropertyGPSDictionary];
}
CFRelease(gpsProperties);
// Exif Properties - TIFF - This is a copy of Exif properties for JPEG but with different paths.
NSMutableDictionary* exifProperties = [[NSMutableDictionary alloc] init];
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=40962}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifPixelXDimension];
[properties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyPixelWidth];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=40962}", &propertyValue)) && propertyValue.vt == VT_UI4) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyExifPixelXDimension];
[properties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyPixelWidth];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=40963}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifPixelYDimension];
[properties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyPixelHeight];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=40963}", &propertyValue)) && propertyValue.vt == VT_UI4) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyExifPixelYDimension];
[properties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyPixelHeight];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=33434}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyExifExposureTime];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37378}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyExifApertureValue];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37379}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyExifBrightnessValue];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=36868}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[exifProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyExifDateTimeDigitized];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=36867}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[exifProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyExifDateTimeOriginal];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=41988}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyExifDigitalZoomRatio];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=41986}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifExposureMode];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=34850}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifExposureProgram];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37385}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifFlash];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=33437}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyExifFNumber];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37386}", &propertyValue)) && propertyValue.vt == VT_UI8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.uhVal.LowPart / propertyValue.uhVal.HighPart]
forKey:(id)kCGImagePropertyExifFocalLength];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=34867}", &propertyValue)) && propertyValue.vt == VT_UI4) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.ulVal] forKey:(id)kCGImagePropertyExifISOSpeedRatings];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=42035}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[exifProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyExifLensMake];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=42036}", &propertyValue)) && propertyValue.vt == VT_LPSTR) {
[exifProperties setObject:[NSString stringWithUTF8String:propertyValue.pszVal] forKey:(id)kCGImagePropertyExifLensModel];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37500}", &propertyValue)) && propertyValue.vt == VT_BLOB) {
[exifProperties setObject:[NSData dataWithBytes:propertyValue.blob.pBlobData length:propertyValue.blob.cbSize]
forKey:(id)kCGImagePropertyExifMakerNote];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37383}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifMeteringMode];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=41990}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifSceneCaptureType];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37377}", &propertyValue)) && propertyValue.vt == VT_I8) {
[exifProperties setObject:[NSNumber numberWithDouble:(double)propertyValue.hVal.LowPart / propertyValue.hVal.HighPart]
forKey:(id)kCGImagePropertyExifShutterSpeedValue];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=37510}", &propertyValue)) && propertyValue.vt == VT_LPWSTR) {
[exifProperties setObject:[[NSString alloc] initWithBytes:propertyValue.pwszVal
length:wcslen(propertyValue.pwszVal) * sizeof(wchar_t)
encoding:NSUnicodeStringEncoding]
forKey:(id)kCGImagePropertyExifUserComment];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=36864}", &propertyValue)) && propertyValue.vt == VT_BLOB) {
NSData* exifVersion = [NSData dataWithBytesNoCopy:propertyValue.blob.pBlobData length:propertyValue.blob.cbSize freeWhenDone:YES];
NSMutableArray* exifVersionArray = [NSMutableArray array];
char* exifVersionCharacters = (char*)[exifVersion bytes];
[exifVersionArray addObject:[NSNumber numberWithInt:exifVersionCharacters[1] - '0']];
[exifVersionArray addObject:[NSNumber numberWithInt:exifVersionCharacters[2] - '0']];
[exifVersionArray addObject:[NSNumber numberWithInt:exifVersionCharacters[3] - '0']];
[exifProperties setObject:exifVersionArray forKey:(id)kCGImagePropertyExifVersion];
}
PropVariantClear(&propertyValue);
if (SUCCEEDED(imageMetadataReader->GetMetadataByName(L"/ifd/exif/{ushort=41987}", &propertyValue)) && propertyValue.vt == VT_UI2) {
[exifProperties setObject:[NSNumber numberWithInt:propertyValue.uiVal] forKey:(id)kCGImagePropertyExifWhiteBalance];
}
// Add the Exif dictionary to the properties if there are any Exif properties
if ([exifProperties count] != 0) {
[properties setObject:exifProperties forKey:(id)kCGImagePropertyExifDictionary];
}
CFRelease(exifProperties);
return (CFDictionaryRef)properties;
}