1 /*****************************************************************************/
2 // Copyright 2006-2008 Adobe Systems Incorporated
3 // All Rights Reserved.
4 //
5 // NOTICE: Adobe permits you to use, modify, and distribute this file in
6 // accordance with the terms of the Adobe license agreement accompanying it.
7 /*****************************************************************************/
8
9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_parse_utils.cpp#3 $ */
10 /* $DateTime: 2012/06/06 12:08:58 $ */
11 /* $Change: 833617 $ */
12 /* $Author: tknoll $ */
13
14 /*****************************************************************************/
15
16 #include "dng_parse_utils.h"
17
18 #include "dng_date_time.h"
19 #include "dng_globals.h"
20 #include "dng_ifd.h"
21 #include "dng_tag_codes.h"
22 #include "dng_tag_types.h"
23 #include "dng_tag_values.h"
24 #include "dng_types.h"
25 #include "dng_stream.h"
26 #include "dng_exceptions.h"
27 #include "dng_utils.h"
28
29 /*****************************************************************************/
30
31 #if qDNGValidate
32
33 /*****************************************************************************/
34
35 struct dng_name_table
36 {
37 uint32 key;
38 const char *name;
39 };
40
41 /*****************************************************************************/
42
LookupName(uint32 key,const dng_name_table * table,uint32 table_entries)43 static const char * LookupName (uint32 key,
44 const dng_name_table *table,
45 uint32 table_entries)
46 {
47
48 for (uint32 index = 0; index < table_entries; index++)
49 {
50
51 if (key == table [index] . key)
52 {
53
54 return table [index] . name;
55
56 }
57
58 }
59
60 return NULL;
61
62 }
63
64 /*****************************************************************************/
65
LookupParentCode(uint32 parentCode)66 const char * LookupParentCode (uint32 parentCode)
67 {
68
69 const dng_name_table kParentCodeNames [] =
70 {
71 { 0, "IFD 0" },
72 { tcExifIFD, "Exif IFD" },
73 { tcGPSInfo, "GPS IFD" },
74 { tcInteroperabilityIFD, "Interoperability IFD" },
75 { tcKodakDCRPrivateIFD, "Kodak DCR Private IFD" },
76 { tcKodakKDCPrivateIFD, "Kodak KDC Private IFD" },
77 { tcCanonMakerNote, "Canon MakerNote" },
78 { tcEpsonMakerNote, "Epson MakerNote" },
79 { tcFujiMakerNote, "Fuji MakerNote" },
80 { tcHasselbladMakerNote, "Hasselblad MakerNote" },
81 { tcKodakMakerNote, "Kodak MakerNote" },
82 { tcKodakMakerNote65280, "Kodak MakerNote 65280" },
83 { tcLeicaMakerNote, "Leica MakerNote" },
84 { tcMamiyaMakerNote, "Mamiya MakerNote" },
85 { tcMinoltaMakerNote, "Minolta MakerNote" },
86 { tcNikonMakerNote, "Nikon MakerNote" },
87 { tcOlympusMakerNote, "Olympus MakerNote" },
88 { tcOlympusMakerNote8208, "Olympus MakerNote 8208" },
89 { tcOlympusMakerNote8224, "Olympus MakerNote 8224" },
90 { tcOlympusMakerNote8240, "Olympus MakerNote 8240" },
91 { tcOlympusMakerNote8256, "Olympus MakerNote 8256" },
92 { tcOlympusMakerNote8272, "Olympus MakerNote 8272" },
93 { tcOlympusMakerNote12288, "Olympus MakerNote 12288" },
94 { tcPanasonicMakerNote, "Panasonic MakerNote" },
95 { tcPentaxMakerNote, "Pentax MakerNote" },
96 { tcPhaseOneMakerNote, "Phase One MakerNote" },
97 { tcRicohMakerNote, "Ricoh MakerNote" },
98 { tcRicohMakerNoteCameraInfo, "Ricoh MakerNote Camera Info" },
99 { tcSonyMakerNote, "Sony MakerNote" },
100 { tcSonyMakerNoteSubInfo, "Sony MakerNote SubInfo" },
101 { tcSonyPrivateIFD1, "Sony Private IFD 1" },
102 { tcSonyPrivateIFD2, "Sony Private IFD 2" },
103 { tcSonyPrivateIFD3A, "Sony Private IFD 3A" },
104 { tcSonyPrivateIFD3B, "Sony Private IFD 3B" },
105 { tcSonyPrivateIFD3C, "Sony Private IFD 3C" },
106 { tcCanonCRW, "Canon CRW" },
107 { tcContaxRAW, "Contax RAW" },
108 { tcFujiRAF, "Fuji RAF" },
109 { tcLeafMOS, "Leaf MOS" },
110 { tcMinoltaMRW, "Minolta MRW" },
111 { tcPanasonicRAW, "Panasonic RAW" },
112 { tcFoveonX3F, "Foveon X3F" },
113 { tcJPEG, "JPEG" },
114 { tcAdobePSD, "Adobe PSD" }
115 };
116
117 const char *name = LookupName (parentCode,
118 kParentCodeNames,
119 sizeof (kParentCodeNames ) /
120 sizeof (kParentCodeNames [0]));
121
122 if (name)
123 {
124 return name;
125 }
126
127 static char s [32];
128
129 if (parentCode >= tcFirstSubIFD &&
130 parentCode <= tcLastSubIFD)
131 {
132
133 sprintf (s, "SubIFD %u", (unsigned) (parentCode - tcFirstSubIFD + 1));
134
135 }
136
137 else if (parentCode >= tcFirstChainedIFD &&
138 parentCode <= tcLastChainedIFD)
139 {
140
141 sprintf (s, "Chained IFD %u", (unsigned) (parentCode - tcFirstChainedIFD + 1));
142
143 }
144
145 else
146 {
147
148 sprintf (s, "ParentIFD %u", (unsigned) parentCode);
149
150 }
151
152 return s;
153
154 }
155
156 /*****************************************************************************/
157
LookupTagCode(uint32 parentCode,uint32 tagCode)158 const char * LookupTagCode (uint32 parentCode,
159 uint32 tagCode)
160 {
161
162 const dng_name_table kTagNames [] =
163 {
164 { tcNewSubFileType, "NewSubFileType" },
165 { tcSubFileType, "SubFileType" },
166 { tcImageWidth, "ImageWidth" },
167 { tcImageLength, "ImageLength" },
168 { tcBitsPerSample, "BitsPerSample" },
169 { tcCompression, "Compression" },
170 { tcPhotometricInterpretation, "PhotometricInterpretation" },
171 { tcThresholding, "Thresholding" },
172 { tcCellWidth, "CellWidth" },
173 { tcCellLength, "CellLength" },
174 { tcFillOrder, "FillOrder" },
175 { tcImageDescription, "ImageDescription" },
176 { tcMake, "Make" },
177 { tcModel, "Model" },
178 { tcStripOffsets, "StripOffsets" },
179 { tcOrientation, "Orientation" },
180 { tcSamplesPerPixel, "SamplesPerPixel" },
181 { tcRowsPerStrip, "RowsPerStrip" },
182 { tcStripByteCounts, "StripByteCounts" },
183 { tcMinSampleValue, "MinSampleValue" },
184 { tcMaxSampleValue, "MaxSampleValue" },
185 { tcXResolution, "XResolution" },
186 { tcYResolution, "YResolution" },
187 { tcPlanarConfiguration, "PlanarConfiguration" },
188 { tcFreeOffsets, "FreeOffsets" },
189 { tcFreeByteCounts, "FreeByteCounts" },
190 { tcGrayResponseUnit, "GrayResponseUnit" },
191 { tcGrayResponseCurve, "GrayResponseCurve" },
192 { tcResolutionUnit, "ResolutionUnit" },
193 { tcTransferFunction, "TransferFunction" },
194 { tcSoftware, "Software" },
195 { tcDateTime, "DateTime" },
196 { tcArtist, "Artist" },
197 { tcHostComputer, "HostComputer" },
198 { tcWhitePoint, "WhitePoint" },
199 { tcPrimaryChromaticities, "PrimaryChromaticities" },
200 { tcColorMap, "ColorMap" },
201 { tcTileWidth, "TileWidth" },
202 { tcTileLength, "TileLength" },
203 { tcTileOffsets, "TileOffsets" },
204 { tcTileByteCounts, "TileByteCounts" },
205 { tcSubIFDs, "SubIFDs" },
206 { tcExtraSamples, "ExtraSamples" },
207 { tcSampleFormat, "SampleFormat" },
208 { tcJPEGTables, "JPEGTables" },
209 { tcJPEGProc, "JPEGProc" },
210 { tcJPEGInterchangeFormat, "JPEGInterchangeFormat" },
211 { tcJPEGInterchangeFormatLength, "JPEGInterchangeFormatLength" },
212 { tcYCbCrCoefficients, "YCbCrCoefficients" },
213 { tcYCbCrSubSampling, "YCbCrSubSampling" },
214 { tcYCbCrPositioning, "YCbCrPositioning" },
215 { tcReferenceBlackWhite, "ReferenceBlackWhite" },
216 { tcXMP, "XMP" },
217 { tcKodakCameraSerialNumber, "KodakCameraSerialNumber" },
218 { tcCFARepeatPatternDim, "CFARepeatPatternDim" },
219 { tcCFAPattern, "CFAPattern" },
220 { tcBatteryLevel, "BatteryLevel" },
221 { tcKodakDCRPrivateIFD, "KodakDCRPrivateIFD" },
222 { tcCopyright, "Copyright" },
223 { tcExposureTime, "ExposureTime" },
224 { tcFNumber, "FNumber" },
225 { tcIPTC_NAA, "IPTC/NAA" },
226 { tcLeafPKTS, "LeafPKTS" },
227 { tcAdobeData, "AdobeData" },
228 { tcExifIFD, "ExifIFD" },
229 { tcICCProfile, "ICCProfile" },
230 { tcExposureProgram, "ExposureProgram" },
231 { tcSpectralSensitivity, "SpectralSensitivity" },
232 { tcGPSInfo, "GPSInfo" },
233 { tcISOSpeedRatings, "ISOSpeedRatings" },
234 { tcOECF, "OECF" },
235 { tcInterlace, "Interlace" },
236 { tcTimeZoneOffset, "TimeZoneOffset" },
237 { tcSelfTimerMode, "SelfTimerMode" },
238 { tcSensitivityType, "SensitivityType" },
239 { tcStandardOutputSensitivity, "StandardOutputSensitivity" },
240 { tcRecommendedExposureIndex, "RecommendedExposureIndex" },
241 { tcISOSpeed, "ISOSpeed" },
242 { tcISOSpeedLatitudeyyy, "ISOSpeedLatitudeyyy" },
243 { tcISOSpeedLatitudezzz, "ISOSpeedLatitudezzz" },
244 { tcExifVersion, "ExifVersion" },
245 { tcDateTimeOriginal, "DateTimeOriginal" },
246 { tcDateTimeDigitized, "DateTimeDigitized" },
247 { tcComponentsConfiguration, "ComponentsConfiguration" },
248 { tcCompressedBitsPerPixel, "CompressedBitsPerPixel" },
249 { tcShutterSpeedValue, "ShutterSpeedValue" },
250 { tcApertureValue, "ApertureValue" },
251 { tcBrightnessValue, "BrightnessValue" },
252 { tcExposureBiasValue, "ExposureBiasValue" },
253 { tcMaxApertureValue, "MaxApertureValue" },
254 { tcSubjectDistance, "SubjectDistance" },
255 { tcMeteringMode, "MeteringMode" },
256 { tcLightSource, "LightSource" },
257 { tcFlash, "Flash" },
258 { tcFocalLength, "FocalLength" },
259 { tcFlashEnergy, "FlashEnergy" },
260 { tcSpatialFrequencyResponse, "SpatialFrequencyResponse" },
261 { tcNoise, "Noise" },
262 { tcFocalPlaneXResolution, "FocalPlaneXResolution" },
263 { tcFocalPlaneYResolution, "FocalPlaneYResolution" },
264 { tcFocalPlaneResolutionUnit, "FocalPlaneResolutionUnit" },
265 { tcImageNumber, "ImageNumber" },
266 { tcSecurityClassification, "SecurityClassification" },
267 { tcImageHistory, "ImageHistory" },
268 { tcSubjectArea, "SubjectArea" },
269 { tcExposureIndex, "ExposureIndex" },
270 { tcTIFF_EP_StandardID, "TIFF/EPStandardID" },
271 { tcSensingMethod, "SensingMethod" },
272 { tcMakerNote, "MakerNote" },
273 { tcUserComment, "UserComment" },
274 { tcSubsecTime, "SubsecTime" },
275 { tcSubsecTimeOriginal, "SubsecTimeOriginal" },
276 { tcSubsecTimeDigitized, "SubsecTimeDigitized" },
277 { tcAdobeLayerData, "AdobeLayerData" },
278 { tcFlashPixVersion, "FlashPixVersion" },
279 { tcColorSpace, "ColorSpace" },
280 { tcPixelXDimension, "PixelXDimension" },
281 { tcPixelYDimension, "PixelYDimension" },
282 { tcRelatedSoundFile, "RelatedSoundFile" },
283 { tcInteroperabilityIFD, "InteroperabilityIFD" },
284 { tcFlashEnergyExif, "FlashEnergyExif" },
285 { tcSpatialFrequencyResponseExif, "SpatialFrequencyResponseExif" },
286 { tcFocalPlaneXResolutionExif, "FocalPlaneXResolutionExif" },
287 { tcFocalPlaneYResolutionExif, "FocalPlaneYResolutionExif" },
288 { tcFocalPlaneResolutionUnitExif, "FocalPlaneResolutionUnitExif" },
289 { tcSubjectLocation, "SubjectLocation" },
290 { tcExposureIndexExif, "ExposureIndexExif" },
291 { tcSensingMethodExif, "SensingMethodExif" },
292 { tcFileSource, "FileSource" },
293 { tcSceneType, "SceneType" },
294 { tcCFAPatternExif, "CFAPatternExif" },
295 { tcCustomRendered, "CustomRendered" },
296 { tcExposureMode, "ExposureMode" },
297 { tcWhiteBalance, "WhiteBalance" },
298 { tcDigitalZoomRatio, "DigitalZoomRatio" },
299 { tcFocalLengthIn35mmFilm, "FocalLengthIn35mmFilm" },
300 { tcSceneCaptureType, "SceneCaptureType" },
301 { tcGainControl, "GainControl" },
302 { tcContrast, "Contrast" },
303 { tcSaturation, "Saturation" },
304 { tcSharpness, "Sharpness" },
305 { tcDeviceSettingDescription, "DeviceSettingDescription" },
306 { tcSubjectDistanceRange, "SubjectDistanceRange" },
307 { tcImageUniqueID, "ImageUniqueID" },
308 { tcCameraOwnerNameExif, "CameraOwnerNameExif" },
309 { tcCameraSerialNumberExif, "CameraSerialNumberExif" },
310 { tcLensSpecificationExif, "LensSpecificationExif" },
311 { tcLensMakeExif, "LensMakeExif" },
312 { tcLensModelExif, "LensModelExif" },
313 { tcLensSerialNumberExif, "LensSerialNumberExif" },
314 { tcGamma, "Gamma" },
315 { tcPrintImageMatchingInfo, "PrintImageMatchingInfo" },
316 { tcDNGVersion, "DNGVersion" },
317 { tcDNGBackwardVersion, "DNGBackwardVersion" },
318 { tcUniqueCameraModel, "UniqueCameraModel" },
319 { tcLocalizedCameraModel, "LocalizedCameraModel" },
320 { tcCFAPlaneColor, "CFAPlaneColor" },
321 { tcCFALayout, "CFALayout" },
322 { tcLinearizationTable, "LinearizationTable" },
323 { tcBlackLevelRepeatDim, "BlackLevelRepeatDim" },
324 { tcBlackLevel, "BlackLevel" },
325 { tcBlackLevelDeltaH, "BlackLevelDeltaH" },
326 { tcBlackLevelDeltaV, "BlackLevelDeltaV" },
327 { tcWhiteLevel, "WhiteLevel" },
328 { tcDefaultScale, "DefaultScale" },
329 { tcDefaultCropOrigin, "DefaultCropOrigin" },
330 { tcDefaultCropSize, "DefaultCropSize" },
331 { tcDefaultUserCrop, "DefaultUserCrop" },
332 { tcColorMatrix1, "ColorMatrix1" },
333 { tcColorMatrix2, "ColorMatrix2" },
334 { tcCameraCalibration1, "CameraCalibration1" },
335 { tcCameraCalibration2, "CameraCalibration2" },
336 { tcReductionMatrix1, "ReductionMatrix1" },
337 { tcReductionMatrix2, "ReductionMatrix2" },
338 { tcAnalogBalance, "AnalogBalance" },
339 { tcAsShotNeutral, "AsShotNeutral" },
340 { tcAsShotWhiteXY, "AsShotWhiteXY" },
341 { tcBaselineExposure, "BaselineExposure" },
342 { tcBaselineNoise, "BaselineNoise" },
343 { tcBaselineSharpness, "BaselineSharpness" },
344 { tcBayerGreenSplit, "BayerGreenSplit" },
345 { tcLinearResponseLimit, "LinearResponseLimit" },
346 { tcCameraSerialNumber, "CameraSerialNumber" },
347 { tcLensInfo, "LensInfo" },
348 { tcChromaBlurRadius, "ChromaBlurRadius" },
349 { tcAntiAliasStrength, "AntiAliasStrength" },
350 { tcShadowScale, "ShadowScale" },
351 { tcDNGPrivateData, "DNGPrivateData" },
352 { tcMakerNoteSafety, "MakerNoteSafety" },
353 { tcCalibrationIlluminant1, "CalibrationIlluminant1" },
354 { tcCalibrationIlluminant2, "CalibrationIlluminant2" },
355 { tcBestQualityScale, "BestQualityScale" },
356 { tcRawDataUniqueID, "RawDataUniqueID" },
357 { tcOriginalRawFileName, "OriginalRawFileName" },
358 { tcOriginalRawFileData, "OriginalRawFileData" },
359 { tcActiveArea, "ActiveArea" },
360 { tcMaskedAreas, "MaskedAreas" },
361 { tcAsShotICCProfile, "AsShotICCProfile" },
362 { tcAsShotPreProfileMatrix, "AsShotPreProfileMatrix" },
363 { tcCurrentICCProfile, "CurrentICCProfile" },
364 { tcCurrentPreProfileMatrix, "CurrentPreProfileMatrix" },
365 { tcColorimetricReference, "ColorimetricReference" },
366 { tcCameraCalibrationSignature, "CameraCalibrationSignature" },
367 { tcProfileCalibrationSignature, "ProfileCalibrationSignature" },
368 { tcExtraCameraProfiles, "ExtraCameraProfiles" },
369 { tcAsShotProfileName, "AsShotProfileName" },
370 { tcNoiseReductionApplied, "NoiseReductionApplied" },
371 { tcProfileName, "ProfileName" },
372 { tcProfileHueSatMapDims, "ProfileHueSatMapDims" },
373 { tcProfileHueSatMapData1, "ProfileHueSatMapData1" },
374 { tcProfileHueSatMapData2, "ProfileHueSatMapData2" },
375 { tcProfileHueSatMapEncoding, "ProfileHueSatMapEncoding" },
376 { tcProfileToneCurve, "ProfileToneCurve" },
377 { tcProfileEmbedPolicy, "ProfileEmbedPolicy" },
378 { tcProfileCopyright, "ProfileCopyright" },
379 { tcForwardMatrix1, "ForwardMatrix1" },
380 { tcForwardMatrix2, "ForwardMatrix2" },
381 { tcPreviewApplicationName, "PreviewApplicationName" },
382 { tcPreviewApplicationVersion, "PreviewApplicationVersion" },
383 { tcPreviewSettingsName, "PreviewSettingsName" },
384 { tcPreviewSettingsDigest, "PreviewSettingsDigest" },
385 { tcPreviewColorSpace, "PreviewColorSpace" },
386 { tcPreviewDateTime, "PreviewDateTime" },
387 { tcRawImageDigest, "RawImageDigest" },
388 { tcOriginalRawFileDigest, "OriginalRawFileDigest" },
389 { tcSubTileBlockSize, "SubTileBlockSize" },
390 { tcRowInterleaveFactor, "RowInterleaveFactor" },
391 { tcProfileLookTableDims, "ProfileLookTableDims" },
392 { tcProfileLookTableData, "ProfileLookTableData" },
393 { tcProfileLookTableEncoding, "ProfileLookTableEncoding" },
394 { tcBaselineExposureOffset, "BaselineExposureOffset" },
395 { tcDefaultBlackRender, "DefaultBlackRender" },
396 { tcOpcodeList1, "OpcodeList1" },
397 { tcOpcodeList2, "OpcodeList2" },
398 { tcOpcodeList3, "OpcodeList3" },
399 { tcNoiseProfile, "NoiseProfile" },
400 { tcOriginalDefaultFinalSize, "OriginalDefaultFinalSize" },
401 { tcOriginalBestQualityFinalSize, "OriginalBestQualityFinalSize" },
402 { tcOriginalDefaultCropSize, "OriginalDefaultCropSize" },
403 { tcProfileHueSatMapEncoding, "ProfileHueSatMapEncoding" },
404 { tcProfileLookTableEncoding, "ProfileLookTableEncoding" },
405 { tcBaselineExposureOffset, "BaselineExposureOffset" },
406 { tcDefaultBlackRender, "DefaultBlackRender" },
407 { tcNewRawImageDigest, "NewRawImageDigest" },
408 { tcRawToPreviewGain, "RawToPreviewGain" },
409 { tcCacheBlob, "CacheBlob" },
410 { tcKodakKDCPrivateIFD, "KodakKDCPrivateIFD" }
411 };
412
413 const dng_name_table kGPSTagNames [] =
414 {
415 { tcGPSVersionID, "GPSVersionID" },
416 { tcGPSLatitudeRef, "GPSLatitudeRef" },
417 { tcGPSLatitude, "GPSLatitude" },
418 { tcGPSLongitudeRef, "GPSLongitudeRef" },
419 { tcGPSLongitude, "GPSLongitude" },
420 { tcGPSAltitudeRef, "GPSAltitudeRef" },
421 { tcGPSAltitude, "GPSAltitude" },
422 { tcGPSTimeStamp, "GPSTimeStamp" },
423 { tcGPSSatellites, "GPSSatellites" },
424 { tcGPSStatus, "GPSStatus" },
425 { tcGPSMeasureMode, "GPSMeasureMode" },
426 { tcGPSDOP, "GPSDOP" },
427 { tcGPSSpeedRef, "GPSSpeedRef" },
428 { tcGPSSpeed, "GPSSpeed" },
429 { tcGPSTrackRef, "GPSTrackRef" },
430 { tcGPSTrack, "GPSTrack" },
431 { tcGPSImgDirectionRef, "GPSImgDirectionRef" },
432 { tcGPSImgDirection, "GPSImgDirection" },
433 { tcGPSMapDatum, "GPSMapDatum" },
434 { tcGPSDestLatitudeRef, "GPSDestLatitudeRef" },
435 { tcGPSDestLatitude, "GPSDestLatitude" },
436 { tcGPSDestLongitudeRef, "GPSDestLongitudeRef" },
437 { tcGPSDestLongitude, "GPSDestLongitude" },
438 { tcGPSDestBearingRef, "GPSDestBearingRef" },
439 { tcGPSDestBearing, "GPSDestBearing" },
440 { tcGPSDestDistanceRef, "GPSDestDistanceRef" },
441 { tcGPSDestDistance, "GPSDestDistance" },
442 { tcGPSProcessingMethod, "GPSProcessingMethod" },
443 { tcGPSAreaInformation, "GPSAreaInformation" },
444 { tcGPSDateStamp, "GPSDateStamp" },
445 { tcGPSDifferential, "GPSDifferential" },
446 { tcGPSHPositioningError, "GPSHPositioningError" },
447 };
448
449 const dng_name_table kInteroperabilityTagNames [] =
450 {
451 { tcInteroperabilityIndex, "InteroperabilityIndex" },
452 { tcInteroperabilityVersion, "InteroperabilityVersion" },
453 { tcRelatedImageFileFormat, "RelatedImageFileFormat" },
454 { tcRelatedImageWidth, "RelatedImageWidth" },
455 { tcRelatedImageLength, "RelatedImageLength" }
456 };
457
458 const dng_name_table kFujiTagNames [] =
459 {
460 { tcFujiHeader, "FujiHeader" },
461 { tcFujiRawInfo1, "FujiRawInfo1" },
462 { tcFujiRawInfo2, "FujiRawInfo2" }
463 };
464
465 const dng_name_table kContaxTagNames [] =
466 {
467 { tcContaxHeader, "ContaxHeader" }
468 };
469
470 const char *name = NULL;
471
472 if (parentCode == 0 ||
473 parentCode == tcExifIFD ||
474 parentCode == tcLeafMOS ||
475 (parentCode >= tcFirstSubIFD && parentCode <= tcLastSubIFD) ||
476 (parentCode >= tcFirstChainedIFD && parentCode <= tcLastChainedIFD))
477 {
478
479 name = LookupName (tagCode,
480 kTagNames,
481 sizeof (kTagNames ) /
482 sizeof (kTagNames [0]));
483
484 }
485
486 else if (parentCode == tcGPSInfo)
487 {
488
489 name = LookupName (tagCode,
490 kGPSTagNames,
491 sizeof (kGPSTagNames ) /
492 sizeof (kGPSTagNames [0]));
493
494 }
495
496 else if (parentCode == tcInteroperabilityIFD)
497 {
498
499 name = LookupName (tagCode,
500 kInteroperabilityTagNames,
501 sizeof (kInteroperabilityTagNames ) /
502 sizeof (kInteroperabilityTagNames [0]));
503
504 }
505
506 else if (parentCode == tcFujiRAF)
507 {
508
509 name = LookupName (tagCode,
510 kFujiTagNames,
511 sizeof (kFujiTagNames ) /
512 sizeof (kFujiTagNames [0]));
513
514 }
515
516 else if (parentCode == tcContaxRAW)
517 {
518
519 name = LookupName (tagCode,
520 kContaxTagNames,
521 sizeof (kContaxTagNames ) /
522 sizeof (kContaxTagNames [0]));
523
524 }
525
526 if (name)
527 {
528 return name;
529 }
530
531 static char s [32];
532
533 if (parentCode == tcCanonCRW)
534 {
535 sprintf (s, "CRW_%04X", (unsigned) tagCode);
536 }
537
538 else if (parentCode == tcMinoltaMRW)
539 {
540
541 char c1 = (char) ((tagCode >> 24) & 0xFF);
542 char c2 = (char) ((tagCode >> 16) & 0xFF);
543 char c3 = (char) ((tagCode >> 8) & 0xFF);
544 char c4 = (char) ((tagCode ) & 0xFF);
545
546 if (c1 < ' ') c1 = '_';
547 if (c2 < ' ') c2 = '_';
548 if (c3 < ' ') c3 = '_';
549 if (c4 < ' ') c4 = '_';
550
551 sprintf (s, "MRW%c%c%c%c", c1, c2, c3, c4);
552
553 }
554
555 else if (parentCode == tcFujiRawInfo1)
556 {
557 sprintf (s, "RAF1_%04X", (unsigned) tagCode);
558 }
559
560 else if (parentCode == tcFujiRawInfo2)
561 {
562 sprintf (s, "RAF2_%04X", (unsigned) tagCode);
563 }
564
565 else
566 {
567 sprintf (s, "Tag%u", (unsigned) tagCode);
568 }
569
570 return s;
571
572 }
573
574 /*****************************************************************************/
575
LookupTagType(uint32 tagType)576 const char * LookupTagType (uint32 tagType)
577 {
578
579 const dng_name_table kTagTypeNames [] =
580 {
581 { ttByte, "Byte" },
582 { ttAscii, "ASCII" },
583 { ttShort, "Short" },
584 { ttLong, "Long" },
585 { ttRational, "Rational" },
586 { ttSByte, "SByte" },
587 { ttUndefined, "Undefined" },
588 { ttSShort, "SShort" },
589 { ttSLong, "SLong" },
590 { ttSRational, "SRational" },
591 { ttFloat, "Float" },
592 { ttDouble, "Double" },
593 { ttIFD, "IFD" },
594 { ttUnicode, "Unicode" },
595 { ttComplex, "Complex" }
596 };
597
598 const char *name = LookupName (tagType,
599 kTagTypeNames,
600 sizeof (kTagTypeNames ) /
601 sizeof (kTagTypeNames [0]));
602
603 if (name)
604 {
605 return name;
606 }
607
608 static char s [32];
609
610 sprintf (s, "Type%u", (unsigned) tagType);
611
612 return s;
613
614 }
615
616 /*****************************************************************************/
617
LookupNewSubFileType(uint32 key)618 const char * LookupNewSubFileType (uint32 key)
619 {
620
621 const dng_name_table kNewSubFileTypeNames [] =
622 {
623 { sfMainImage , "Main Image" },
624 { sfPreviewImage , "Preview Image" },
625 { sfTransparencyMask , "Transparency Mask" },
626 { sfPreviewMask , "Preview Mask" },
627 { sfAltPreviewImage , "Alt Preview Image" }
628 };
629
630 const char *name = LookupName (key,
631 kNewSubFileTypeNames,
632 sizeof (kNewSubFileTypeNames ) /
633 sizeof (kNewSubFileTypeNames [0]));
634
635 if (name)
636 {
637 return name;
638 }
639
640 static char s [32];
641
642 sprintf (s, "%u", (unsigned) key);
643
644 return s;
645
646 }
647
648 /*****************************************************************************/
649
LookupCompression(uint32 key)650 const char * LookupCompression (uint32 key)
651 {
652
653 const dng_name_table kCompressionNames [] =
654 {
655 { ccUncompressed, "Uncompressed" },
656 { ccLZW, "LZW" },
657 { ccOldJPEG, "Old JPEG" },
658 { ccJPEG, "JPEG" },
659 { ccDeflate, "Deflate" },
660 { ccPackBits, "PackBits" },
661 { ccOldDeflate, "OldDeflate" },
662 { ccLossyJPEG, "Lossy JPEG" }
663 };
664
665 const char *name = LookupName (key,
666 kCompressionNames,
667 sizeof (kCompressionNames ) /
668 sizeof (kCompressionNames [0]));
669
670 if (name)
671 {
672 return name;
673 }
674
675 static char s [32];
676
677 sprintf (s, "%u", (unsigned) key);
678
679 return s;
680
681 }
682
683 /*****************************************************************************/
684
LookupPredictor(uint32 key)685 const char * LookupPredictor (uint32 key)
686 {
687
688 const dng_name_table kPredictorNames [] =
689 {
690 { cpNullPredictor, "NullPredictor" },
691 { cpHorizontalDifference, "HorizontalDifference" },
692 { cpFloatingPoint, "FloatingPoint" },
693 { cpHorizontalDifferenceX2, "HorizontalDifferenceX2" },
694 { cpHorizontalDifferenceX4, "HorizontalDifferenceX4" },
695 { cpFloatingPointX2, "FloatingPointX2" },
696 { cpFloatingPointX4, "FloatingPointX4" }
697 };
698
699 const char *name = LookupName (key,
700 kPredictorNames,
701 sizeof (kPredictorNames ) /
702 sizeof (kPredictorNames [0]));
703
704 if (name)
705 {
706 return name;
707 }
708
709 static char s [32];
710
711 sprintf (s, "%u", (unsigned) key);
712
713 return s;
714
715 }
716
717 /*****************************************************************************/
718
LookupSampleFormat(uint32 key)719 const char * LookupSampleFormat (uint32 key)
720 {
721
722 const dng_name_table kSampleFormatNames [] =
723 {
724 { sfUnsignedInteger, "UnsignedInteger" },
725 { sfSignedInteger, "SignedInteger" },
726 { sfFloatingPoint, "FloatingPoint" },
727 { sfUndefined, "Undefined" }
728 };
729
730 const char *name = LookupName (key,
731 kSampleFormatNames,
732 sizeof (kSampleFormatNames ) /
733 sizeof (kSampleFormatNames [0]));
734
735 if (name)
736 {
737 return name;
738 }
739
740 static char s [32];
741
742 sprintf (s, "%u", (unsigned) key);
743
744 return s;
745
746 }
747
748 /*****************************************************************************/
749
LookupPhotometricInterpretation(uint32 key)750 const char * LookupPhotometricInterpretation (uint32 key)
751 {
752
753 const dng_name_table kPhotometricInterpretationNames [] =
754 {
755 { piWhiteIsZero, "WhiteIsZero" },
756 { piBlackIsZero, "BlackIsZero" },
757 { piRGB, "RGB" },
758 { piRGBPalette, "RGBPalette" },
759 { piTransparencyMask, "TransparencyMask" },
760 { piCMYK, "CMYK" },
761 { piYCbCr, "YCbCr" },
762 { piCIELab, "CIELab" },
763 { piICCLab, "ICCLab" },
764 { piCFA, "CFA" },
765 { piLinearRaw, "LinearRaw" }
766 };
767
768 const char *name = LookupName (key,
769 kPhotometricInterpretationNames,
770 sizeof (kPhotometricInterpretationNames ) /
771 sizeof (kPhotometricInterpretationNames [0]));
772
773 if (name)
774 {
775 return name;
776 }
777
778 static char s [32];
779
780 sprintf (s, "%u", (unsigned) key);
781
782 return s;
783
784 }
785
786 /*****************************************************************************/
787
LookupOrientation(uint32 key)788 const char * LookupOrientation (uint32 key)
789 {
790
791 const dng_name_table kOrientationNames [] =
792 {
793 { 1, "1 - 0th row is top, 0th column is left" },
794 { 2, "2 - 0th row is top, 0th column is right" },
795 { 3, "3 - 0th row is bottom, 0th column is right" },
796 { 4, "4 - 0th row is bottom, 0th column is left" },
797 { 5, "5 - 0th row is left, 0th column is top" },
798 { 6, "6 - 0th row is right, 0th column is top" },
799 { 7, "7 - 0th row is right, 0th column is bottom" },
800 { 8, "8 - 0th row is left, 0th column is bottom" },
801 { 9, "9 - unknown" }
802 };
803
804 const char *name = LookupName (key,
805 kOrientationNames,
806 sizeof (kOrientationNames ) /
807 sizeof (kOrientationNames [0]));
808
809 if (name)
810 {
811 return name;
812 }
813
814 static char s [32];
815
816 sprintf (s, "%u", (unsigned) key);
817
818 return s;
819
820 }
821
822 /*****************************************************************************/
823
LookupResolutionUnit(uint32 key)824 const char * LookupResolutionUnit (uint32 key)
825 {
826
827 const dng_name_table kResolutionUnitNames [] =
828 {
829 { ruNone, "None" },
830 { ruInch, "Inch" },
831 { ruCM, "cm" },
832 { ruMM, "mm" },
833 { ruMicroM, "Micrometer" }
834 };
835
836 const char *name = LookupName (key,
837 kResolutionUnitNames,
838 sizeof (kResolutionUnitNames ) /
839 sizeof (kResolutionUnitNames [0]));
840
841 if (name)
842 {
843 return name;
844 }
845
846 static char s [32];
847
848 sprintf (s, "%u", (unsigned) key);
849
850 return s;
851
852 }
853
854 /*****************************************************************************/
855
LookupCFAColor(uint32 key)856 const char * LookupCFAColor (uint32 key)
857 {
858
859 const dng_name_table kCFAColorNames [] =
860 {
861 { 0, "Red" },
862 { 1, "Green" },
863 { 2, "Blue" },
864 { 3, "Cyan" },
865 { 4, "Magenta" },
866 { 5, "Yellow" },
867 { 6, "White" }
868 };
869
870 const char *name = LookupName (key,
871 kCFAColorNames,
872 sizeof (kCFAColorNames ) /
873 sizeof (kCFAColorNames [0]));
874
875 if (name)
876 {
877 return name;
878 }
879
880 static char s [32];
881
882 sprintf (s, "Color%u", (unsigned) key);
883
884 return s;
885
886 }
887
888 /*****************************************************************************/
889
LookupSensingMethod(uint32 key)890 const char * LookupSensingMethod (uint32 key)
891 {
892
893 const dng_name_table kSensingMethodNames [] =
894 {
895 { 0, "Undefined" },
896 { 1, "MonochromeArea" },
897 { 2, "OneChipColorArea" },
898 { 3, "TwoChipColorArea" },
899 { 4, "ThreeChipColorArea" },
900 { 5, "ColorSequentialArea" },
901 { 6, "MonochromeLinear" },
902 { 7, "TriLinear" },
903 { 8, "ColorSequentialLinear" }
904 };
905
906 const char *name = LookupName (key,
907 kSensingMethodNames,
908 sizeof (kSensingMethodNames ) /
909 sizeof (kSensingMethodNames [0]));
910
911 if (name)
912 {
913 return name;
914 }
915
916 static char s [32];
917
918 sprintf (s, "%u", (unsigned) key);
919
920 return s;
921
922 }
923
924 /*****************************************************************************/
925
LookupExposureProgram(uint32 key)926 const char * LookupExposureProgram (uint32 key)
927 {
928
929 const dng_name_table kExposureProgramNames [] =
930 {
931 { epUnidentified, "Unidentified" },
932 { epManual, "Manual" },
933 { epProgramNormal, "Program Normal" },
934 { epAperturePriority, "Aperture Priority" },
935 { epShutterPriority, "Shutter Priority" },
936 { epProgramCreative, "Program Creative" },
937 { epProgramAction, "Program Action" },
938 { epPortraitMode, "Portrait Mode" },
939 { epLandscapeMode, "Landscape Mode" }
940 };
941
942 const char *name = LookupName (key,
943 kExposureProgramNames,
944 sizeof (kExposureProgramNames ) /
945 sizeof (kExposureProgramNames [0]));
946
947 if (name)
948 {
949 return name;
950 }
951
952 static char s [32];
953
954 sprintf (s, "%u", (unsigned) key);
955
956 return s;
957
958 }
959
960 /*****************************************************************************/
961
LookupMeteringMode(uint32 key)962 const char * LookupMeteringMode (uint32 key)
963 {
964
965 const dng_name_table kMeteringModeNames [] =
966 {
967 { mmUnidentified, "Unknown" },
968 { mmAverage, "Average" },
969 { mmCenterWeightedAverage, "CenterWeightedAverage" },
970 { mmSpot, "Spot" },
971 { mmMultiSpot, "MultiSpot" },
972 { mmPattern, "Pattern" },
973 { mmPartial, "Partial" },
974 { mmOther, "Other" }
975 };
976
977 const char *name = LookupName (key,
978 kMeteringModeNames,
979 sizeof (kMeteringModeNames ) /
980 sizeof (kMeteringModeNames [0]));
981
982 if (name)
983 {
984 return name;
985 }
986
987 static char s [32];
988
989 sprintf (s, "%u", (unsigned) key);
990
991 return s;
992
993 }
994
995 /*****************************************************************************/
996
LookupLightSource(uint32 key)997 const char * LookupLightSource (uint32 key)
998 {
999
1000 const dng_name_table kLightSourceNames [] =
1001 {
1002 { lsUnknown, "Unknown" },
1003 { lsDaylight, "Daylight" },
1004 { lsFluorescent, "Fluorescent" },
1005 { lsTungsten, "Tungsten (incandescent light)" },
1006 { lsFlash, "Flash" },
1007 { lsFineWeather, "Fine weather" },
1008 { lsCloudyWeather, "Cloudy weather" },
1009 { lsShade, "Shade" },
1010 { lsDaylightFluorescent, "Daylight fluorescent (D 5700 - 7100K)" },
1011 { lsDayWhiteFluorescent, "Day white fluorescent (N 4600 - 5500K)" },
1012 { lsCoolWhiteFluorescent, "Cool white fluorescent (W 3800 - 4500K)" },
1013 { lsWhiteFluorescent, "White fluorescent (WW 3250 - 3800K)" },
1014 { lsWarmWhiteFluorescent, "Warm white fluorescent (L 2600 - 3250K)" },
1015 { lsStandardLightA, "Standard light A" },
1016 { lsStandardLightB, "Standard light B" },
1017 { lsStandardLightC, "Standard light C" },
1018 { lsD55, "D55" },
1019 { lsD65, "D65" },
1020 { lsD75, "D75" },
1021 { lsD50, "D50" },
1022 { lsISOStudioTungsten, "ISO studio tungsten" },
1023 { lsOther, "Other" }
1024 };
1025
1026 const char *name = LookupName (key,
1027 kLightSourceNames,
1028 sizeof (kLightSourceNames ) /
1029 sizeof (kLightSourceNames [0]));
1030
1031 if (name)
1032 {
1033 return name;
1034 }
1035
1036 static char s [32];
1037
1038 if (key & 0x08000)
1039 {
1040
1041 sprintf (s, "%uK", (unsigned) (key & 0x7FFF));
1042
1043 }
1044
1045 else
1046 {
1047
1048 sprintf (s, "%u", (unsigned) key);
1049
1050 }
1051
1052 return s;
1053
1054 }
1055
1056 /*****************************************************************************/
1057
LookupColorSpace(uint32 key)1058 const char * LookupColorSpace (uint32 key)
1059 {
1060
1061 const dng_name_table kColorSpaceNames [] =
1062 {
1063 { 1, "sRGB" },
1064 { 0xFFFF, "Uncalibrated" }
1065 };
1066
1067 const char *name = LookupName (key,
1068 kColorSpaceNames,
1069 sizeof (kColorSpaceNames ) /
1070 sizeof (kColorSpaceNames [0]));
1071
1072 if (name)
1073 {
1074 return name;
1075 }
1076
1077 static char s [32];
1078
1079 sprintf (s, "%u", (unsigned) key);
1080
1081 return s;
1082
1083 }
1084
1085 /*****************************************************************************/
1086
LookupFileSource(uint32 key)1087 const char * LookupFileSource (uint32 key)
1088 {
1089
1090 const dng_name_table kFileSourceNames [] =
1091 {
1092 { 3, "DSC" }
1093 };
1094
1095 const char *name = LookupName (key,
1096 kFileSourceNames,
1097 sizeof (kFileSourceNames ) /
1098 sizeof (kFileSourceNames [0]));
1099
1100 if (name)
1101 {
1102 return name;
1103 }
1104
1105 static char s [32];
1106
1107 sprintf (s, "%u", (unsigned) key);
1108
1109 return s;
1110
1111 }
1112
1113 /*****************************************************************************/
1114
LookupSceneType(uint32 key)1115 const char * LookupSceneType (uint32 key)
1116 {
1117
1118 const dng_name_table kSceneTypeNames [] =
1119 {
1120 { 1, "A directly photographed image" }
1121 };
1122
1123 const char *name = LookupName (key,
1124 kSceneTypeNames,
1125 sizeof (kSceneTypeNames ) /
1126 sizeof (kSceneTypeNames [0]));
1127
1128 if (name)
1129 {
1130 return name;
1131 }
1132
1133 static char s [32];
1134
1135 sprintf (s, "%u", (unsigned) key);
1136
1137 return s;
1138
1139 }
1140
1141 /*****************************************************************************/
1142
LookupCustomRendered(uint32 key)1143 const char * LookupCustomRendered (uint32 key)
1144 {
1145
1146 const dng_name_table kCustomRenderedNames [] =
1147 {
1148 { 0, "Normal process" },
1149 { 1, "Custom process" }
1150 };
1151
1152 const char *name = LookupName (key,
1153 kCustomRenderedNames,
1154 sizeof (kCustomRenderedNames ) /
1155 sizeof (kCustomRenderedNames [0]));
1156
1157 if (name)
1158 {
1159 return name;
1160 }
1161
1162 static char s [32];
1163
1164 sprintf (s, "%u", (unsigned) key);
1165
1166 return s;
1167
1168 }
1169
1170 /*****************************************************************************/
1171
LookupExposureMode(uint32 key)1172 const char * LookupExposureMode (uint32 key)
1173 {
1174
1175 const dng_name_table kExposureModeNames [] =
1176 {
1177 { 0, "Auto exposure" },
1178 { 1, "Manual exposure" },
1179 { 2, "Auto bracket" }
1180 };
1181
1182 const char *name = LookupName (key,
1183 kExposureModeNames,
1184 sizeof (kExposureModeNames ) /
1185 sizeof (kExposureModeNames [0]));
1186
1187 if (name)
1188 {
1189 return name;
1190 }
1191
1192 static char s [32];
1193
1194 sprintf (s, "%u", (unsigned) key);
1195
1196 return s;
1197
1198 }
1199
1200 /*****************************************************************************/
1201
LookupWhiteBalance(uint32 key)1202 const char * LookupWhiteBalance (uint32 key)
1203 {
1204
1205 const dng_name_table kWhiteBalanceNames [] =
1206 {
1207 { 0, "Auto white balance" },
1208 { 1, "Manual white balance" }
1209 };
1210
1211 const char *name = LookupName (key,
1212 kWhiteBalanceNames,
1213 sizeof (kWhiteBalanceNames ) /
1214 sizeof (kWhiteBalanceNames [0]));
1215
1216 if (name)
1217 {
1218 return name;
1219 }
1220
1221 static char s [32];
1222
1223 sprintf (s, "%u", (unsigned) key);
1224
1225 return s;
1226
1227 }
1228
1229 /*****************************************************************************/
1230
LookupSceneCaptureType(uint32 key)1231 const char * LookupSceneCaptureType (uint32 key)
1232 {
1233
1234 const dng_name_table kSceneCaptureTypeNames [] =
1235 {
1236 { 0, "Standard" },
1237 { 1, "Landscape" },
1238 { 2, "Portrait" },
1239 { 3, "Night scene" }
1240 };
1241
1242 const char *name = LookupName (key,
1243 kSceneCaptureTypeNames,
1244 sizeof (kSceneCaptureTypeNames ) /
1245 sizeof (kSceneCaptureTypeNames [0]));
1246
1247 if (name)
1248 {
1249 return name;
1250 }
1251
1252 static char s [32];
1253
1254 sprintf (s, "%u", (unsigned) key);
1255
1256 return s;
1257
1258 }
1259
1260 /*****************************************************************************/
1261
LookupGainControl(uint32 key)1262 const char * LookupGainControl (uint32 key)
1263 {
1264
1265 const dng_name_table kGainControlNames [] =
1266 {
1267 { 0, "None" },
1268 { 1, "Low gain up" },
1269 { 2, "High gain up" },
1270 { 3, "Low gain down" },
1271 { 4, "High gain down" }
1272 };
1273
1274 const char *name = LookupName (key,
1275 kGainControlNames,
1276 sizeof (kGainControlNames ) /
1277 sizeof (kGainControlNames [0]));
1278
1279 if (name)
1280 {
1281 return name;
1282 }
1283
1284 static char s [32];
1285
1286 sprintf (s, "%u", (unsigned) key);
1287
1288 return s;
1289
1290 }
1291
1292 /*****************************************************************************/
1293
LookupContrast(uint32 key)1294 const char * LookupContrast (uint32 key)
1295 {
1296
1297 const dng_name_table kContrastNames [] =
1298 {
1299 { 0, "Normal" },
1300 { 1, "Soft" },
1301 { 2, "Hard" }
1302 };
1303
1304 const char *name = LookupName (key,
1305 kContrastNames,
1306 sizeof (kContrastNames ) /
1307 sizeof (kContrastNames [0]));
1308
1309 if (name)
1310 {
1311 return name;
1312 }
1313
1314 static char s [32];
1315
1316 sprintf (s, "%u", (unsigned) key);
1317
1318 return s;
1319
1320 }
1321
1322 /*****************************************************************************/
1323
LookupSaturation(uint32 key)1324 const char * LookupSaturation (uint32 key)
1325 {
1326
1327 const dng_name_table kSaturationNames [] =
1328 {
1329 { 0, "Normal" },
1330 { 1, "Low saturation" },
1331 { 2, "High saturation" }
1332 };
1333
1334 const char *name = LookupName (key,
1335 kSaturationNames,
1336 sizeof (kSaturationNames ) /
1337 sizeof (kSaturationNames [0]));
1338
1339 if (name)
1340 {
1341 return name;
1342 }
1343
1344 static char s [32];
1345
1346 sprintf (s, "%u", (unsigned) key);
1347
1348 return s;
1349
1350 }
1351
1352 /*****************************************************************************/
1353
LookupSharpness(uint32 key)1354 const char * LookupSharpness (uint32 key)
1355 {
1356
1357 const dng_name_table kSharpnessNames [] =
1358 {
1359 { 0, "Normal" },
1360 { 1, "Soft" },
1361 { 2, "Hard" }
1362 };
1363
1364 const char *name = LookupName (key,
1365 kSharpnessNames,
1366 sizeof (kSharpnessNames ) /
1367 sizeof (kSharpnessNames [0]));
1368
1369 if (name)
1370 {
1371 return name;
1372 }
1373
1374 static char s [32];
1375
1376 sprintf (s, "%u", (unsigned) key);
1377
1378 return s;
1379
1380 }
1381
1382 /*****************************************************************************/
1383
LookupSubjectDistanceRange(uint32 key)1384 const char * LookupSubjectDistanceRange (uint32 key)
1385 {
1386
1387 const dng_name_table kSubjectDistanceRangeNames [] =
1388 {
1389 { 0, "Unknown" },
1390 { 1, "Macro" },
1391 { 2, "Close view" },
1392 { 3, "Distant view" }
1393 };
1394
1395 const char *name = LookupName (key,
1396 kSubjectDistanceRangeNames,
1397 sizeof (kSubjectDistanceRangeNames ) /
1398 sizeof (kSubjectDistanceRangeNames [0]));
1399
1400 if (name)
1401 {
1402 return name;
1403 }
1404
1405 static char s [32];
1406
1407 sprintf (s, "%u", (unsigned) key);
1408
1409 return s;
1410
1411 }
1412
1413 /*****************************************************************************/
1414
LookupComponent(uint32 key)1415 const char * LookupComponent (uint32 key)
1416 {
1417
1418 const dng_name_table kComponentNames [] =
1419 {
1420 { 0, "-" },
1421 { 1, "Y" },
1422 { 2, "Cb" },
1423 { 3, "Cr" },
1424 { 4, "R" },
1425 { 5, "G" },
1426 { 6, "B" }
1427 };
1428
1429 const char *name = LookupName (key,
1430 kComponentNames,
1431 sizeof (kComponentNames ) /
1432 sizeof (kComponentNames [0]));
1433
1434 if (name)
1435 {
1436 return name;
1437 }
1438
1439 static char s [32];
1440
1441 sprintf (s, "%u", (unsigned) key);
1442
1443 return s;
1444
1445 }
1446
1447 /*****************************************************************************/
1448
LookupCFALayout(uint32 key)1449 const char * LookupCFALayout (uint32 key)
1450 {
1451
1452 const dng_name_table kCFALayoutNames [] =
1453 {
1454 { 1, "Rectangular (or square) layout" },
1455 { 2, "Staggered layout A: even columns are offset down by 1/2 row" },
1456 { 3, "Staggered layout B: even columns are offset up by 1/2 row" },
1457 { 4, "Staggered layout C: even rows are offset right by 1/2 column" },
1458 { 5, "Staggered layout D: even rows are offset left by 1/2 column" },
1459 { 6, "Staggered layout E: even rows are offset up by 1/2 row, even columns are offset left by 1/2 column" },
1460 { 7, "Staggered layout F: even rows are offset up by 1/2 row, even columns are offset right by 1/2 column" },
1461 { 8, "Staggered layout G: even rows are offset down by 1/2 row, even columns are offset left by 1/2 column" },
1462 { 9, "Staggered layout H: even rows are offset down by 1/2 row, even columns are offset right by 1/2 column" }
1463 };
1464
1465 const char *name = LookupName (key,
1466 kCFALayoutNames,
1467 sizeof (kCFALayoutNames ) /
1468 sizeof (kCFALayoutNames [0]));
1469
1470 if (name)
1471 {
1472 return name;
1473 }
1474
1475 static char s [32];
1476
1477 sprintf (s, "%u", (unsigned) key);
1478
1479 return s;
1480
1481 }
1482
1483 /*****************************************************************************/
1484
LookupMakerNoteSafety(uint32 key)1485 const char * LookupMakerNoteSafety (uint32 key)
1486 {
1487
1488 const dng_name_table kMakerNoteSafetyNames [] =
1489 {
1490 { 0, "Unsafe" },
1491 { 1, "Safe" }
1492 };
1493
1494 const char *name = LookupName (key,
1495 kMakerNoteSafetyNames,
1496 sizeof (kMakerNoteSafetyNames ) /
1497 sizeof (kMakerNoteSafetyNames [0]));
1498
1499 if (name)
1500 {
1501 return name;
1502 }
1503
1504 static char s [32];
1505
1506 sprintf (s, "%u", (unsigned) key);
1507
1508 return s;
1509
1510 }
1511
1512 /*****************************************************************************/
1513
LookupColorimetricReference(uint32 key)1514 const char * LookupColorimetricReference (uint32 key)
1515 {
1516
1517 const dng_name_table kColorimetricReferenceNames [] =
1518 {
1519 { crSceneReferred, "Scene Referred" },
1520 { crICCProfilePCS, "ICC Profile PCS" }
1521 };
1522
1523 const char *name = LookupName (key,
1524 kColorimetricReferenceNames,
1525 sizeof (kColorimetricReferenceNames ) /
1526 sizeof (kColorimetricReferenceNames [0]));
1527
1528 if (name)
1529 {
1530 return name;
1531 }
1532
1533 static char s [32];
1534
1535 sprintf (s, "%u", (unsigned) key);
1536
1537 return s;
1538
1539 }
1540
1541 /*****************************************************************************/
1542
LookupPreviewColorSpace(uint32 key)1543 const char * LookupPreviewColorSpace (uint32 key)
1544 {
1545
1546 const dng_name_table kPreviewColorSpaceNames [] =
1547 {
1548 { previewColorSpace_Unknown , "Unknown" },
1549 { previewColorSpace_GrayGamma22, "Gray Gamma 2.2" },
1550 { previewColorSpace_sRGB , "sRGB" },
1551 { previewColorSpace_AdobeRGB , "Adobe RGB (1998)" },
1552 { previewColorSpace_ProPhotoRGB, "Pro Photo RGB" }
1553 };
1554
1555 const char *name = LookupName (key,
1556 kPreviewColorSpaceNames,
1557 sizeof (kPreviewColorSpaceNames ) /
1558 sizeof (kPreviewColorSpaceNames [0]));
1559
1560 if (name)
1561 {
1562 return name;
1563 }
1564
1565 static char s [32];
1566
1567 sprintf (s, "%u", (unsigned) key);
1568
1569 return s;
1570
1571 }
1572
1573 /*****************************************************************************/
1574
LookupJPEGMarker(uint32 key)1575 const char * LookupJPEGMarker (uint32 key)
1576 {
1577
1578 const dng_name_table kJPEGMarkerNames [] =
1579 {
1580 { M_TEM, "TEM" },
1581 { M_SOF0, "SOF0" },
1582 { M_SOF1, "SOF1" },
1583 { M_SOF2, "SOF2" },
1584 { M_SOF3, "SOF3" },
1585 { M_DHT, "DHT" },
1586 { M_SOF5, "SOF5" },
1587 { M_SOF6, "SOF6" },
1588 { M_SOF7, "SOF7" },
1589 { M_JPG, "JPG" },
1590 { M_SOF9, "SOF9" },
1591 { M_SOF10, "SOF10" },
1592 { M_SOF11, "SOF11" },
1593 { M_DAC, "DAC" },
1594 { M_SOF13, "SOF13" },
1595 { M_SOF14, "SOF14" },
1596 { M_SOF15, "SOF15" },
1597 { M_RST0, "RST0" },
1598 { M_RST1, "RST1" },
1599 { M_RST2, "RST2" },
1600 { M_RST3, "RST3" },
1601 { M_RST4, "RST4" },
1602 { M_RST5, "RST5" },
1603 { M_RST6, "RST6" },
1604 { M_RST7, "RST7" },
1605 { M_SOI, "SOI" },
1606 { M_EOI, "EOI" },
1607 { M_SOS, "SOS" },
1608 { M_DQT, "DQT" },
1609 { M_DNL, "DNL" },
1610 { M_DRI, "DRI" },
1611 { M_DHP, "DHP" },
1612 { M_EXP, "EXP" },
1613 { M_APP0, "APP0" },
1614 { M_APP1, "APP1" },
1615 { M_APP2, "APP2" },
1616 { M_APP3, "APP3" },
1617 { M_APP4, "APP4" },
1618 { M_APP5, "APP5" },
1619 { M_APP6, "APP6" },
1620 { M_APP7, "APP7" },
1621 { M_APP8, "APP8" },
1622 { M_APP9, "APP9" },
1623 { M_APP10, "APP10" },
1624 { M_APP11, "APP11" },
1625 { M_APP12, "APP12" },
1626 { M_APP13, "APP13" },
1627 { M_APP14, "APP14" },
1628 { M_APP15, "APP15" },
1629 { M_JPG0, "JPG0" },
1630 { M_JPG1, "JPG1" },
1631 { M_JPG2, "JPG2" },
1632 { M_JPG3, "JPG3" },
1633 { M_JPG4, "JPG4" },
1634 { M_JPG5, "JPG5" },
1635 { M_JPG6, "JPG6" },
1636 { M_JPG7, "JPG7" },
1637 { M_JPG8, "JPG8" },
1638 { M_JPG9, "JPG9" },
1639 { M_JPG10, "JPG10" },
1640 { M_JPG11, "JPG11" },
1641 { M_JPG12, "JPG12" },
1642 { M_JPG13, "JPG13" },
1643 { M_COM, "COM" },
1644 { M_ERROR, "ERROR" }
1645 };
1646
1647 const char *name = LookupName (key,
1648 kJPEGMarkerNames,
1649 sizeof (kJPEGMarkerNames ) /
1650 sizeof (kJPEGMarkerNames [0]));
1651
1652 if (name)
1653 {
1654 return name;
1655 }
1656
1657 static char s [32];
1658
1659 sprintf (s, "0x%02X", (unsigned) key);
1660
1661 return s;
1662
1663 }
1664
1665 /*****************************************************************************/
1666
LookupSensitivityType(uint32 key)1667 const char * LookupSensitivityType (uint32 key)
1668 {
1669
1670 const dng_name_table kSensitivityTypeNames [] =
1671 {
1672 { stUnknown, "Unknown" },
1673 { stStandardOutputSensitivity, "Standard Output Sensitivity (SOS)" },
1674 { stRecommendedExposureIndex, "Recommended Exposure Index (REI)" },
1675 { stISOSpeed, "ISO Speed" },
1676 { stSOSandREI, "Standard Output Sensitivity (SOS) and Recommended Exposure Index (REI)" },
1677 { stSOSandISOSpeed, "Standard Output Sensitivity (SOS) and ISO Speed" },
1678 { stREIandISOSpeed, "Recommended Exposure Index (REI) and ISO Speed" },
1679 { stSOSandREIandISOSpeed, "Standard Output Sensitivity (SOS) and Recommended Exposure Index (REI) and ISO Speed" },
1680 };
1681
1682 const char *name = LookupName (key,
1683 kSensitivityTypeNames,
1684 sizeof (kSensitivityTypeNames ) /
1685 sizeof (kSensitivityTypeNames [0]));
1686
1687 if (name)
1688 {
1689 return name;
1690 }
1691
1692 static char s [32];
1693
1694 sprintf (s, "%u", (unsigned) key);
1695
1696 return s;
1697
1698 }
1699
1700 /*****************************************************************************/
1701
DumpHexAscii(dng_stream & stream,uint32 count)1702 void DumpHexAscii (dng_stream &stream,
1703 uint32 count)
1704 {
1705
1706 uint32 rows = (count + 15) >> 4;
1707
1708 if (rows > gDumpLineLimit)
1709 rows = gDumpLineLimit;
1710
1711 for (uint32 row = 0; row < rows; row++)
1712 {
1713
1714 printf (" ");
1715
1716 uint32 col;
1717
1718 uint32 cols = count - (row << 4);
1719
1720 if (cols > 16)
1721 cols = 16;
1722
1723 uint8 x [16];
1724
1725 for (col = 0; col < 16; col++)
1726 {
1727
1728 x [col] = ' ';
1729
1730 if (col < cols)
1731 {
1732
1733 x [col] = stream.Get_uint8 ();
1734
1735 printf ("%02x ", x [col]);
1736
1737 }
1738
1739 else
1740 {
1741 printf (" ");
1742 }
1743
1744 }
1745
1746 printf (" ");
1747
1748 for (col = 0; col < 16; col++)
1749 {
1750
1751 if (x [col] >= (uint8) ' ' && x [col] <= (uint8) '~')
1752 {
1753 printf ("%c", x [col]);
1754 }
1755
1756 else
1757 {
1758 printf (".");
1759 }
1760
1761 }
1762
1763 printf ("\n");
1764
1765 }
1766
1767 if (count > rows * 16)
1768 {
1769 printf (" ... %u more bytes\n", (unsigned) (count - rows * 16));
1770 }
1771
1772 }
1773
1774 /*****************************************************************************/
1775
DumpHexAscii(const uint8 * buf,uint32 count)1776 void DumpHexAscii (const uint8 *buf,
1777 uint32 count)
1778 {
1779
1780 uint32 rows = (count + 15) >> 4;
1781
1782 if (rows > gDumpLineLimit)
1783 rows = gDumpLineLimit;
1784
1785 for (uint32 row = 0; row < rows; row++)
1786 {
1787
1788 printf (" ");
1789
1790 uint32 col;
1791
1792 uint32 cols = count - (row << 4);
1793
1794 if (cols > 16)
1795 cols = 16;
1796
1797 uint8 x [16];
1798
1799 for (col = 0; col < 16; col++)
1800 {
1801
1802 x [col] = ' ';
1803
1804 if (col < cols)
1805 {
1806
1807 x [col] = *(buf++);
1808
1809 printf ("%02x ", x [col]);
1810
1811 }
1812
1813 else
1814 {
1815 printf (" ");
1816 }
1817
1818 }
1819
1820 printf (" ");
1821
1822 for (col = 0; col < 16; col++)
1823 {
1824
1825 if (x [col] >= (uint8) ' ' && x [col] <= (uint8) '~')
1826 {
1827 printf ("%c", x [col]);
1828 }
1829
1830 else
1831 {
1832 printf (".");
1833 }
1834
1835 }
1836
1837 printf ("\n");
1838
1839 }
1840
1841 if (count > rows * 16)
1842 {
1843 printf (" ... %u more bytes\n", (unsigned) (count - rows * 16));
1844 }
1845
1846 }
1847
1848 /*****************************************************************************/
1849
DumpXMP(dng_stream & stream,uint32 count)1850 void DumpXMP (dng_stream &stream,
1851 uint32 count)
1852 {
1853
1854 uint32 lineLength = 0;
1855
1856 while (count > 0)
1857 {
1858
1859 uint32 x = stream.Get_uint8 ();
1860
1861 if (x == 0) break;
1862
1863 count--;
1864
1865 if (lineLength == 0)
1866 {
1867
1868 printf ("XMP: ");
1869
1870 lineLength = 5;
1871
1872 }
1873
1874 if (x == '\n' ||
1875 x == '\r')
1876 {
1877
1878 printf ("\n");
1879
1880 lineLength = 0;
1881
1882 }
1883
1884 else
1885 {
1886
1887 if (lineLength >= 128)
1888 {
1889
1890 printf ("\nXMP: ");
1891
1892 lineLength = 5;
1893
1894 }
1895
1896 if (x >= ' ' && x <= '~')
1897 {
1898
1899 printf ("%c", (char) x);
1900
1901 lineLength += 1;
1902
1903 }
1904
1905 else
1906 {
1907
1908 printf ("\\%03o", (unsigned) x);
1909
1910 lineLength += 4;
1911
1912 }
1913
1914 }
1915
1916 }
1917
1918 if (lineLength != 0)
1919 {
1920
1921 printf ("\n");
1922
1923 }
1924
1925 }
1926
1927 /*****************************************************************************/
1928
DumpString(const dng_string & s)1929 void DumpString (const dng_string &s)
1930 {
1931
1932 const uint32 kMaxDumpString = gDumpLineLimit * 64;
1933
1934 printf ("\"");
1935
1936 const char *ss = s.Get ();
1937
1938 uint32 total = 0;
1939
1940 while (*ss != 0 && total++ < kMaxDumpString)
1941 {
1942
1943 uint32 c = dng_string::DecodeUTF8 (ss);
1944
1945 if (c >= ' ' && c <= '~')
1946 {
1947 printf ("%c", (char) c);
1948 }
1949
1950 else switch (c)
1951 {
1952
1953 case '\t':
1954 {
1955 printf ("\\t");
1956 break;
1957 }
1958
1959 case '\n':
1960 {
1961 printf ("\\n");
1962 break;
1963 }
1964
1965 case '\r':
1966 {
1967 printf ("\\r");
1968 break;
1969 }
1970
1971 default:
1972 {
1973 printf ("[%X]", (unsigned) c);
1974 }
1975
1976 }
1977
1978 }
1979
1980 uint32 extra = (uint32) strlen (ss);
1981
1982 if (extra > 0)
1983 {
1984 printf ("...\" (%u more bytes)", (unsigned) extra);
1985 }
1986
1987 else
1988 {
1989 printf ("\"");
1990 }
1991
1992 }
1993
1994 /*****************************************************************************/
1995
DumpTagValues(dng_stream & stream,const char * entry_name,uint32 parentCode,uint32 tagCode,uint32 tagType,uint32 tagCount,const char * tag_name)1996 void DumpTagValues (dng_stream &stream,
1997 const char *entry_name,
1998 uint32 parentCode,
1999 uint32 tagCode,
2000 uint32 tagType,
2001 uint32 tagCount,
2002 const char *tag_name)
2003 {
2004
2005 const uint32 kMaxDumpSingleLine = 4;
2006
2007 const uint32 kMaxDumpArray = Max_uint32 (gDumpLineLimit, kMaxDumpSingleLine);
2008
2009 printf ("%s:", tag_name ? tag_name
2010 : LookupTagCode (parentCode, tagCode));
2011
2012 switch (tagType)
2013 {
2014
2015 case ttShort:
2016 case ttLong:
2017 case ttIFD:
2018 case ttSByte:
2019 case ttSShort:
2020 case ttSLong:
2021 case ttRational:
2022 case ttSRational:
2023 case ttFloat:
2024 case ttDouble:
2025 {
2026
2027 if (tagCount > kMaxDumpSingleLine)
2028 {
2029
2030 printf (" %u entries", (unsigned) tagCount);
2031
2032 }
2033
2034 for (uint32 j = 0; j < tagCount && j < kMaxDumpArray; j++)
2035 {
2036
2037 if (tagCount <= kMaxDumpSingleLine)
2038 {
2039
2040 if (j == 0)
2041 {
2042
2043 printf (" %s =", entry_name);
2044
2045 }
2046
2047 printf (" ");
2048
2049 }
2050
2051 else
2052 {
2053
2054 printf ("\n %s [%u] = ", entry_name, (unsigned) j);
2055
2056 }
2057
2058 switch (tagType)
2059 {
2060
2061 case ttByte:
2062 case ttShort:
2063 case ttLong:
2064 case ttIFD:
2065 {
2066
2067 uint32 x = stream.TagValue_uint32 (tagType);
2068
2069 printf ("%u", (unsigned) x);
2070
2071 break;
2072
2073 }
2074
2075 case ttSByte:
2076 case ttSShort:
2077 case ttSLong:
2078 {
2079
2080 int32 x = stream.TagValue_int32 (tagType);
2081
2082 printf ("%d", (int) x);
2083
2084 break;
2085
2086 }
2087
2088 case ttRational:
2089 {
2090
2091 dng_urational x = stream.TagValue_urational (tagType);
2092
2093 printf ("%u/%u", (unsigned) x.n, (unsigned) x.d);
2094
2095 break;
2096
2097 }
2098
2099 case ttSRational:
2100 {
2101
2102 dng_srational x = stream.TagValue_srational (tagType);
2103
2104 printf ("%d/%d", (int) x.n, (int) x.d);
2105
2106 break;
2107
2108 }
2109
2110 default:
2111 {
2112
2113 real64 x = stream.TagValue_real64 (tagType);
2114
2115 printf ("%f", x);
2116
2117 }
2118
2119 }
2120
2121 }
2122
2123 printf ("\n");
2124
2125 if (tagCount > kMaxDumpArray)
2126 {
2127
2128 printf (" ... %u more entries\n", (unsigned) (tagCount - kMaxDumpArray));
2129
2130 }
2131
2132 break;
2133
2134 }
2135
2136 case ttAscii:
2137 {
2138
2139 dng_string s;
2140
2141 ParseStringTag (stream,
2142 parentCode,
2143 tagCode,
2144 tagCount,
2145 s,
2146 false);
2147
2148 printf (" ");
2149
2150 DumpString (s);
2151
2152 printf ("\n");
2153
2154 break;
2155
2156 }
2157
2158 default:
2159 {
2160
2161 uint32 tagSize = tagCount * TagTypeSize (tagType);
2162
2163 if (tagCount == 1 && (tagType == ttByte ||
2164 tagType == ttUndefined))
2165 {
2166
2167 uint8 x = stream.Get_uint8 ();
2168
2169 printf (" %s = %u\n", LookupTagType (tagType), x);
2170
2171 }
2172
2173 else
2174 {
2175
2176 printf (" %s, size = %u\n", LookupTagType (tagType), (unsigned) tagSize);
2177
2178 DumpHexAscii (stream, tagSize);
2179
2180 }
2181
2182 }
2183
2184 }
2185
2186 }
2187
2188 /*****************************************************************************/
2189
DumpMatrix(const dng_matrix & m)2190 void DumpMatrix (const dng_matrix &m)
2191 {
2192
2193 for (uint32 row = 0; row < m.Rows (); row++)
2194 {
2195
2196 for (uint32 col = 0; col < m.Cols (); col++)
2197 {
2198
2199 if (col == 0)
2200 printf (" ");
2201 else
2202 printf (" ");
2203
2204 printf ("%8.4f", m [row] [col]);
2205
2206 }
2207
2208 printf ("\n");
2209
2210 }
2211
2212 }
2213
2214 /*****************************************************************************/
2215
DumpVector(const dng_vector & v)2216 void DumpVector (const dng_vector &v)
2217 {
2218
2219 for (uint32 index = 0; index < v.Count (); index++)
2220 {
2221
2222 printf (" %0.4f", v [index]);
2223
2224 }
2225
2226 printf ("\n");
2227
2228 }
2229
2230 /*****************************************************************************/
2231
DumpDateTime(const dng_date_time & dt)2232 void DumpDateTime (const dng_date_time &dt)
2233 {
2234
2235 printf ("%04d:%02d:%02d %02d:%02d:%02d",
2236 (int) dt.fYear,
2237 (int) dt.fMonth,
2238 (int) dt.fDay,
2239 (int) dt.fHour,
2240 (int) dt.fMinute,
2241 (int) dt.fSecond);
2242
2243 }
2244
2245 /*****************************************************************************/
2246
DumpExposureTime(real64 x)2247 void DumpExposureTime (real64 x)
2248 {
2249
2250 if (x > 0.0)
2251 {
2252
2253 if (x >= 0.25)
2254 {
2255 printf ("%0.2f sec", x);
2256 }
2257
2258 else if (x >= 0.01)
2259 {
2260 printf ("1/%0.1f sec", 1.0 / x);
2261 }
2262
2263 else
2264 {
2265 printf ("1/%0.0f sec", 1.0 / x);
2266 }
2267
2268 }
2269
2270 else
2271 {
2272
2273 printf ("<invalid>");
2274
2275 }
2276
2277 }
2278
2279 /*****************************************************************************/
2280
DumpFingerprint(const dng_fingerprint & p)2281 void DumpFingerprint (const dng_fingerprint &p)
2282 {
2283
2284 printf ("<");
2285
2286 for (uint32 j = 0; j < 16; j++)
2287 {
2288 printf ("%02x", p.data [j]);
2289 }
2290
2291 printf (">");
2292
2293 }
2294
2295 /*****************************************************************************/
2296
DumpHueSatMap(dng_stream & stream,uint32 hues,uint32 sats,uint32 vals,bool skipSat0)2297 void DumpHueSatMap (dng_stream &stream,
2298 uint32 hues,
2299 uint32 sats,
2300 uint32 vals,
2301 bool skipSat0)
2302 {
2303
2304 uint32 doneLines = 0;
2305 uint32 skipLines = 0;
2306
2307 for (uint32 v = 0; v < vals; v++)
2308 {
2309
2310 for (uint32 h = 0; h < hues; h++)
2311 {
2312
2313 for (uint32 s = skipSat0 ? 1 : 0; s < sats; s++)
2314 {
2315
2316 real32 dh = stream.Get_real32 ();
2317 real32 ds = stream.Get_real32 ();
2318 real32 dv = stream.Get_real32 ();
2319
2320 if (gDumpLineLimit == 0 ||
2321 gDumpLineLimit > doneLines)
2322 {
2323
2324 doneLines++;
2325
2326 if (vals == 1)
2327 {
2328
2329 printf (" h [%2u] s [%2u]: h=%8.4f s=%6.4f v=%6.4f\n",
2330 (unsigned) h,
2331 (unsigned) s,
2332 (double) dh,
2333 (double) ds,
2334 (double) dv);
2335
2336 }
2337
2338 else
2339 {
2340
2341 printf (" v [%2u] h [%2u] s [%2u]: h=%8.4f s=%6.4f v=%6.4f\n",
2342 (unsigned) v,
2343 (unsigned) h,
2344 (unsigned) s,
2345 (double) dh,
2346 (double) ds,
2347 (double) dv);
2348
2349 }
2350
2351 }
2352
2353 else
2354 {
2355
2356 skipLines++;
2357
2358 }
2359
2360 }
2361
2362 }
2363
2364 }
2365
2366 if (skipLines > 0)
2367 {
2368
2369 printf (" ... %u more entries\n", (unsigned) skipLines);
2370
2371 }
2372
2373 }
2374
2375 /*****************************************************************************/
2376
2377 #endif
2378
2379 /*****************************************************************************/
2380
CheckTagType(uint32 parentCode,uint32 tagCode,uint32 tagType,uint16 validType0,uint16 validType1,uint16 validType2,uint16 validType3)2381 bool CheckTagType (uint32 parentCode,
2382 uint32 tagCode,
2383 uint32 tagType,
2384 uint16 validType0,
2385 uint16 validType1,
2386 uint16 validType2,
2387 uint16 validType3)
2388 {
2389
2390 if (tagType != validType0 &&
2391 tagType != validType1 &&
2392 tagType != validType2 &&
2393 tagType != validType3)
2394 {
2395
2396 #if qDNGValidate
2397
2398 {
2399
2400 char message [256];
2401
2402 sprintf (message,
2403 "%s %s has unexpected type (%s)",
2404 LookupParentCode (parentCode),
2405 LookupTagCode (parentCode, tagCode),
2406 LookupTagType (tagType));
2407
2408 ReportWarning (message);
2409
2410 }
2411
2412 #else
2413
2414 (void) parentCode; // Unused
2415 (void) tagCode; // Unused
2416
2417 #endif
2418
2419 return false;
2420
2421 }
2422
2423 return true;
2424
2425 }
2426
2427 /*****************************************************************************/
2428
CheckTagCount(uint32 parentCode,uint32 tagCode,uint32 tagCount,uint32 minCount,uint32 maxCount)2429 bool CheckTagCount (uint32 parentCode,
2430 uint32 tagCode,
2431 uint32 tagCount,
2432 uint32 minCount,
2433 uint32 maxCount)
2434 {
2435
2436 if (maxCount < minCount)
2437 maxCount = minCount;
2438
2439 if (tagCount < minCount ||
2440 tagCount > maxCount)
2441 {
2442
2443 #if qDNGValidate
2444
2445 {
2446
2447 char message [256];
2448
2449 sprintf (message,
2450 "%s %s has unexpected count (%u)",
2451 LookupParentCode (parentCode),
2452 LookupTagCode (parentCode, tagCode),
2453 (unsigned) tagCount);
2454
2455 ReportWarning (message);
2456
2457 }
2458
2459 #else
2460
2461 (void) parentCode; // Unused
2462 (void) tagCode; // Unused
2463
2464 #endif
2465
2466 return false;
2467
2468 }
2469
2470 return true;
2471
2472 }
2473
2474 /*****************************************************************************/
2475
CheckColorImage(uint32 parentCode,uint32 tagCode,uint32 colorPlanes)2476 bool CheckColorImage (uint32 parentCode,
2477 uint32 tagCode,
2478 uint32 colorPlanes)
2479 {
2480
2481 if (colorPlanes == 0)
2482 {
2483
2484 #if qDNGValidate
2485
2486 {
2487
2488 char message [256];
2489
2490 sprintf (message,
2491 "%s %s is not allowed with unknown color plane count "
2492 " (missing ColorMatrix1 tag?)",
2493 LookupParentCode (parentCode),
2494 LookupTagCode (parentCode, tagCode));
2495
2496 ReportWarning (message);
2497
2498 }
2499
2500 #else
2501
2502 (void) parentCode; // Unused
2503 (void) tagCode; // Unused
2504
2505 #endif
2506
2507 return false;
2508
2509 }
2510
2511 if (colorPlanes == 1)
2512 {
2513
2514 #if qDNGValidate
2515
2516 {
2517
2518 char message [256];
2519
2520 sprintf (message,
2521 "%s %s is not allowed with monochrome images",
2522 LookupParentCode (parentCode),
2523 LookupTagCode (parentCode, tagCode));
2524
2525 ReportWarning (message);
2526
2527 }
2528
2529 #endif
2530
2531 return false;
2532
2533 }
2534
2535 return true;
2536
2537 }
2538
2539 /*****************************************************************************/
2540
CheckMainIFD(uint32 parentCode,uint32 tagCode,uint32 newSubFileType)2541 bool CheckMainIFD (uint32 parentCode,
2542 uint32 tagCode,
2543 uint32 newSubFileType)
2544 {
2545
2546 if (newSubFileType != sfMainImage)
2547 {
2548
2549 #if qDNGValidate
2550
2551 {
2552
2553 char message [256];
2554
2555 sprintf (message,
2556 "%s %s is not allowed IFDs with NewSubFileType != 0",
2557 LookupParentCode (parentCode),
2558 LookupTagCode (parentCode, tagCode));
2559
2560 ReportWarning (message);
2561
2562 }
2563
2564 #else
2565
2566 (void) parentCode; // Unused
2567 (void) tagCode; // Unused
2568
2569 #endif
2570
2571 return false;
2572
2573 }
2574
2575 return true;
2576
2577 }
2578
2579 /*****************************************************************************/
2580
CheckRawIFD(uint32 parentCode,uint32 tagCode,uint32 photometricInterpretation)2581 bool CheckRawIFD (uint32 parentCode,
2582 uint32 tagCode,
2583 uint32 photometricInterpretation)
2584 {
2585
2586 if (photometricInterpretation != piCFA &&
2587 photometricInterpretation != piLinearRaw)
2588 {
2589
2590 #if qDNGValidate
2591
2592 {
2593
2594 char message [256];
2595
2596 sprintf (message,
2597 "%s %s is not allowed in IFDs with a non-raw PhotometricInterpretation",
2598 LookupParentCode (parentCode),
2599 LookupTagCode (parentCode, tagCode));
2600
2601 ReportWarning (message);
2602
2603 }
2604
2605 #else
2606
2607 (void) parentCode; // Unused
2608 (void) tagCode; // Unused
2609
2610 #endif
2611
2612 return false;
2613
2614 }
2615
2616 return true;
2617
2618 }
2619
2620 /*****************************************************************************/
2621
CheckCFA(uint32 parentCode,uint32 tagCode,uint32 photometricInterpretation)2622 bool CheckCFA (uint32 parentCode,
2623 uint32 tagCode,
2624 uint32 photometricInterpretation)
2625 {
2626
2627 if (photometricInterpretation != piCFA)
2628 {
2629
2630 #if qDNGValidate
2631
2632 {
2633
2634 char message [256];
2635
2636 sprintf (message,
2637 "%s %s is not allowed in IFDs with a non-CFA PhotometricInterpretation",
2638 LookupParentCode (parentCode),
2639 LookupTagCode (parentCode, tagCode));
2640
2641 ReportWarning (message);
2642
2643 }
2644
2645 #else
2646
2647 (void) parentCode; // Unused
2648 (void) tagCode; // Unused
2649
2650 #endif
2651
2652 return false;
2653
2654 }
2655
2656 return true;
2657
2658 }
2659
2660 /*****************************************************************************/
2661
ParseStringTag(dng_stream & stream,uint32 parentCode,uint32 tagCode,uint32 tagCount,dng_string & s,bool trimBlanks)2662 void ParseStringTag (dng_stream &stream,
2663 uint32 parentCode,
2664 uint32 tagCode,
2665 uint32 tagCount,
2666 dng_string &s,
2667 bool trimBlanks)
2668 {
2669
2670 if (tagCount == 0 ||
2671 tagCount == 0xFFFFFFFF)
2672 {
2673
2674 s.Clear ();
2675
2676 return;
2677
2678 }
2679
2680 dng_memory_data temp_buffer (tagCount + 1);
2681
2682 char *buffer = temp_buffer.Buffer_char ();
2683
2684 stream.Get (buffer, tagCount);
2685
2686 // Make sure the string is null terminated.
2687
2688 if (buffer [tagCount - 1] != 0)
2689 {
2690
2691 buffer [tagCount] = 0;
2692
2693 #if qDNGValidate
2694
2695 {
2696
2697 bool hasNull = false;
2698
2699 for (uint32 j = 0; j < tagCount; j++)
2700 {
2701
2702 if (buffer [j] == 0)
2703 {
2704
2705 hasNull = true;
2706
2707 break;
2708
2709 }
2710
2711 }
2712
2713 if (!hasNull && parentCode < tcFirstMakerNoteIFD)
2714 {
2715
2716 char message [256];
2717
2718 sprintf (message,
2719 "%s %s is not NULL terminated",
2720 LookupParentCode (parentCode),
2721 LookupTagCode (parentCode, tagCode));
2722
2723 ReportWarning (message);
2724
2725 }
2726
2727 }
2728
2729 #else
2730
2731 (void) parentCode; // Unused
2732 (void) tagCode; // Unused
2733
2734 #endif
2735
2736 }
2737
2738 // Medata working group - Allow UTF-8
2739
2740 s.Set_UTF8_or_System (buffer);
2741
2742 if (trimBlanks)
2743 {
2744
2745 s.TrimTrailingBlanks ();
2746
2747 }
2748
2749 }
2750
2751 /*****************************************************************************/
2752
ParseDualStringTag(dng_stream & stream,uint32 parentCode,uint32 tagCode,uint32 tagCount,dng_string & s1,dng_string & s2)2753 void ParseDualStringTag (dng_stream &stream,
2754 uint32 parentCode,
2755 uint32 tagCode,
2756 uint32 tagCount,
2757 dng_string &s1,
2758 dng_string &s2)
2759 {
2760
2761 if (tagCount == 0 ||
2762 tagCount == 0xFFFFFFFF)
2763 {
2764
2765 s1.Clear ();
2766 s2.Clear ();
2767
2768 return;
2769
2770 }
2771
2772 dng_memory_data temp_buffer (tagCount + 1);
2773
2774 char *buffer = temp_buffer.Buffer_char ();
2775
2776 stream.Get (buffer, tagCount);
2777
2778 // Make sure the string is null terminated.
2779
2780 if (buffer [tagCount - 1] != 0)
2781 {
2782
2783 buffer [tagCount] = 0;
2784
2785 #if qDNGValidate
2786
2787 {
2788
2789 uint32 nullCount = 0;
2790
2791 for (uint32 j = 0; j < tagCount; j++)
2792 {
2793
2794 if (buffer [j] == 0)
2795 {
2796
2797 nullCount++;
2798
2799 }
2800
2801 }
2802
2803 if (nullCount < 2 && parentCode < tcFirstMakerNoteIFD)
2804 {
2805
2806 char message [256];
2807
2808 sprintf (message,
2809 "%s %s is not NULL terminated",
2810 LookupParentCode (parentCode),
2811 LookupTagCode (parentCode, tagCode));
2812
2813 ReportWarning (message);
2814
2815 }
2816
2817 }
2818
2819 #else
2820
2821 (void) parentCode; // Unused
2822 (void) tagCode; // Unused
2823
2824 #endif
2825
2826 }
2827
2828 // Medata working group - Allow UTF-8
2829
2830 s1.Set_UTF8_or_System (buffer);
2831
2832 s2.Set_ASCII (NULL);
2833
2834 for (uint32 j = 1; j < tagCount - 1; j++)
2835 {
2836
2837 if (buffer [j - 1] != 0 &&
2838 buffer [j ] == 0)
2839 {
2840
2841 // Medata working group - Allow UTF-8
2842
2843 s2.Set_UTF8_or_System (buffer + j + 1);
2844
2845 break;
2846
2847 }
2848
2849 }
2850
2851 s1.TrimTrailingBlanks ();
2852 s2.TrimTrailingBlanks ();
2853
2854 }
2855
2856 /*****************************************************************************/
2857
ParseEncodedStringTag(dng_stream & stream,uint32 parentCode,uint32 tagCode,uint32 tagCount,dng_string & s)2858 void ParseEncodedStringTag (dng_stream &stream,
2859 uint32 parentCode,
2860 uint32 tagCode,
2861 uint32 tagCount,
2862 dng_string &s)
2863 {
2864
2865 if (tagCount < 8)
2866 {
2867
2868 #if qDNGValidate
2869
2870 {
2871
2872 char message [256];
2873
2874 sprintf (message,
2875 "%s %s has unexpected count (%u)",
2876 LookupParentCode (parentCode),
2877 LookupTagCode (parentCode, tagCode),
2878 (unsigned) tagCount);
2879
2880 ReportWarning (message);
2881
2882 }
2883
2884 #else
2885
2886 (void) parentCode; // Unused
2887 (void) tagCode; // Unused
2888
2889 #endif
2890
2891 s.Clear ();
2892
2893 return;
2894
2895 }
2896
2897 char label [8];
2898
2899 stream.Get (label, 8);
2900
2901 // Sometimes lowercase is used by mistake. Accept this, but issue
2902 // warning.
2903
2904 {
2905
2906 bool hadLower = false;
2907
2908 for (uint32 j = 0; j < 8; j++)
2909 {
2910
2911 if (label [j] >= 'a' && label [j] <= 'z')
2912 {
2913
2914 label [j] = 'A' + (label [j] - 'a');
2915
2916 hadLower = true;
2917
2918 }
2919
2920 }
2921
2922 #if qDNGValidate
2923
2924 if (hadLower)
2925 {
2926
2927 char message [256];
2928
2929 sprintf (message,
2930 "%s %s text encoding label not all uppercase",
2931 LookupParentCode (parentCode),
2932 LookupTagCode (parentCode, tagCode));
2933
2934 ReportWarning (message);
2935
2936 }
2937
2938 #endif
2939
2940 }
2941
2942 if (memcmp (label, "UNICODE\000", 8) == 0)
2943 {
2944
2945 uint32 uChars = (tagCount - 8) >> 1;
2946
2947 dng_memory_data temp_buffer ((uChars + 1) * 2);
2948
2949 uint16 *buffer = temp_buffer.Buffer_uint16 ();
2950
2951 for (uint32 j = 0; j < uChars; j++)
2952 {
2953
2954 buffer [j] = stream.Get_uint16 ();
2955
2956 }
2957
2958 buffer [uChars] = 0;
2959
2960 #if qDNGValidate
2961
2962 {
2963
2964 // If the writer used UTF-8 rather than UTF-16, and padded
2965 // the string with blanks, then there will be lots of 0x2020
2966 // (unicode dagger symbol) characters in the string.
2967
2968 uint32 count2020 = 0;
2969
2970 for (uint32 k = 0; buffer [k] != 0; k++)
2971 {
2972
2973 if (buffer [k] == 0x2020)
2974 {
2975
2976 count2020++;
2977
2978 }
2979
2980 }
2981
2982 if (count2020 > 1)
2983 {
2984
2985 char message [256];
2986
2987 sprintf (message,
2988 "%s %s text appears to be UTF-8 rather than UTF-16",
2989 LookupParentCode (parentCode),
2990 LookupTagCode (parentCode, tagCode));
2991
2992 ReportWarning (message);
2993
2994 }
2995
2996 }
2997
2998 #endif
2999
3000 s.Set_UTF16 (buffer);
3001
3002 }
3003
3004 else
3005 {
3006
3007 uint32 aChars = tagCount - 8;
3008
3009 dng_memory_data temp_buffer (aChars + 1);
3010
3011 char *buffer = temp_buffer.Buffer_char ();
3012
3013 stream.Get (buffer, aChars);
3014
3015 buffer [aChars] = 0;
3016
3017 enum dng_encoding
3018 {
3019 dng_encoding_ascii,
3020 dng_encoding_jis_x208_1990,
3021 dng_encoding_unknown
3022 };
3023
3024 dng_encoding encoding = dng_encoding_unknown;
3025
3026 if (memcmp (label, "ASCII\000\000\000", 8) == 0)
3027 {
3028
3029 encoding = dng_encoding_ascii;
3030
3031 }
3032
3033 else if (memcmp (label, "JIS\000\000\000\000\000\000", 8) == 0)
3034 {
3035
3036 encoding = dng_encoding_jis_x208_1990;
3037
3038 }
3039
3040 else
3041 {
3042
3043 // Some Nikon D1 files have UserComment tags with zero encoding bits and
3044 // garbage text values. So don't try to parse tags with unknown text
3045 // encoding unless all the characters are printing ASCII.
3046
3047 #if qDNGValidate
3048
3049 if (memcmp (label, "\000\000\000\000\000\000\000\000\000", 8) == 0)
3050 {
3051
3052 // Many camera makes store null tags with all zero encoding, so
3053 // don't report a warning message for null strings.
3054
3055 if (buffer [0] != 0)
3056 {
3057
3058 char message [256];
3059
3060 sprintf (message,
3061 "%s %s has unknown encoding",
3062 LookupParentCode (parentCode),
3063 LookupTagCode (parentCode, tagCode));
3064
3065 ReportWarning (message);
3066
3067 }
3068
3069 }
3070
3071 else
3072 {
3073
3074 char message [256];
3075
3076 sprintf (message,
3077 "%s %s has unexpected text encoding",
3078 LookupParentCode (parentCode),
3079 LookupTagCode (parentCode, tagCode));
3080
3081 ReportWarning (message);
3082
3083 }
3084
3085 #endif
3086
3087 }
3088
3089 // If text encoding was unknown, and the text is anything
3090 // other than pure ASCII, then ignore it.
3091
3092 if (encoding == dng_encoding_unknown)
3093 {
3094
3095 encoding = dng_encoding_ascii;
3096
3097 for (uint32 i = 0; i < aChars && buffer [i] != 0; i++)
3098 {
3099
3100 if (buffer [i] < ' ' ||
3101 buffer [i] > '~')
3102 {
3103
3104 buffer [0] = 0;
3105
3106 break;
3107
3108 }
3109
3110 }
3111
3112 }
3113
3114 switch (encoding)
3115 {
3116
3117 case dng_encoding_ascii:
3118 {
3119
3120 // Medata working group - allow UTF-8 for ASCII tags.
3121
3122 s.Set_UTF8_or_System (buffer);
3123
3124 break;
3125
3126 }
3127
3128 case dng_encoding_jis_x208_1990:
3129 {
3130 s.Set_JIS_X208_1990 (buffer);
3131 break;
3132 }
3133
3134 case dng_encoding_unknown:
3135 {
3136 s.Set_SystemEncoding (buffer);
3137 break;
3138 }
3139
3140 default:
3141 break;
3142
3143 }
3144
3145 #if qDNGValidate
3146
3147 {
3148
3149 if (encoding == dng_encoding_ascii && !s.IsASCII ())
3150 {
3151
3152 char message [256];
3153
3154 sprintf (message,
3155 "%s %s has non-ASCII characters",
3156 LookupParentCode (parentCode),
3157 LookupTagCode (parentCode, tagCode));
3158
3159 ReportWarning (message);
3160
3161 }
3162
3163 }
3164
3165 #endif
3166
3167 }
3168
3169 s.TrimTrailingBlanks ();
3170
3171 }
3172
3173 /*****************************************************************************/
3174
ParseMatrixTag(dng_stream & stream,uint32 parentCode,uint32 tagCode,uint32 tagType,uint32 tagCount,uint32 rows,uint32 cols,dng_matrix & m)3175 bool ParseMatrixTag (dng_stream &stream,
3176 uint32 parentCode,
3177 uint32 tagCode,
3178 uint32 tagType,
3179 uint32 tagCount,
3180 uint32 rows,
3181 uint32 cols,
3182 dng_matrix &m)
3183 {
3184
3185 if (CheckTagCount (parentCode, tagCode, tagCount, rows * cols))
3186 {
3187
3188 dng_matrix temp (rows, cols);
3189
3190 for (uint32 row = 0; row < rows; row++)
3191 for (uint32 col = 0; col < cols; col++)
3192 {
3193
3194 temp [row] [col] = stream.TagValue_real64 (tagType);
3195
3196 }
3197
3198 m = temp;
3199
3200 return true;
3201
3202 }
3203
3204 return false;
3205
3206 }
3207
3208 /*****************************************************************************/
3209
ParseVectorTag(dng_stream & stream,uint32 parentCode,uint32 tagCode,uint32 tagType,uint32 tagCount,uint32 count,dng_vector & v)3210 bool ParseVectorTag (dng_stream &stream,
3211 uint32 parentCode,
3212 uint32 tagCode,
3213 uint32 tagType,
3214 uint32 tagCount,
3215 uint32 count,
3216 dng_vector &v)
3217 {
3218
3219 if (CheckTagCount (parentCode, tagCode, tagCount, count))
3220 {
3221
3222 dng_vector temp (count);
3223
3224 for (uint32 index = 0; index < count; index++)
3225 {
3226
3227 temp [index] = stream.TagValue_real64 (tagType);
3228
3229 }
3230
3231 v = temp;
3232
3233 return true;
3234
3235 }
3236
3237 return false;
3238
3239 }
3240
3241 /*****************************************************************************/
3242
ParseDateTimeTag(dng_stream & stream,uint32 parentCode,uint32 tagCode,uint32 tagType,uint32 tagCount,dng_date_time & dt)3243 bool ParseDateTimeTag (dng_stream &stream,
3244 uint32 parentCode,
3245 uint32 tagCode,
3246 uint32 tagType,
3247 uint32 tagCount,
3248 dng_date_time &dt)
3249 {
3250
3251 if (!CheckTagType (parentCode, tagCode, tagType, ttAscii))
3252 {
3253 return false;
3254 }
3255
3256 // Kludge: Some versions of PaintShop Pro write these fields
3257 // with a length of 21 rather than 20. Otherwise they are
3258 // correctly formated. So relax this test and allow these
3259 // these longer than standard tags to be parsed.
3260
3261 (void) CheckTagCount (parentCode, tagCode, tagCount, 20);
3262
3263 if (tagCount < 20)
3264 {
3265 return false;
3266 }
3267
3268 char s [21];
3269
3270 stream.Get (s, 20);
3271
3272 s [20] = 0;
3273
3274 // See if this is a valid date/time string.
3275
3276 if (dt.Parse (s))
3277 {
3278 return true;
3279 }
3280
3281 // Accept strings that contain only blanks, colons, and zeros as
3282 // valid "null" dates.
3283
3284 dt = dng_date_time ();
3285
3286 for (uint32 index = 0; index < 21; index++)
3287 {
3288
3289 char c = s [index];
3290
3291 if (c == 0)
3292 {
3293 return true;
3294 }
3295
3296 if (c != ' ' && c != ':' && c != '0')
3297 {
3298
3299 #if qDNGValidate
3300
3301 {
3302
3303 char message [256];
3304
3305 sprintf (message,
3306 "%s %s is not a valid date/time",
3307 LookupParentCode (parentCode),
3308 LookupTagCode (parentCode, tagCode));
3309
3310 ReportWarning (message);
3311
3312 }
3313
3314 #endif
3315
3316 return false;
3317
3318 }
3319
3320 }
3321
3322 return false;
3323
3324 }
3325
3326 /*****************************************************************************/
3327