File indexing completed on 2025-01-05 03:56:01

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2008-09-25
0007  * Description : a tool to convert RAW file to DNG - Exif Metadata storage.
0008  *
0009  * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2010-2011 by Jens Mueller <tschenser at gmx dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "dngwriter_p.h"
0017 
0018 // Local includes
0019 
0020 #include "dngwriterhost.h"
0021 
0022 namespace Digikam
0023 {
0024 
0025 int DNGWriter::Private::storeExif(DNGWriterHost& /*host*/,
0026                                   AutoPtr<dng_negative>& negative,
0027                                   DRawInfo* const identify,
0028                                   DRawInfo* const /*identifyMake*/,
0029                                   DMetadata* const meta)
0030 {
0031     // Self-write text information.
0032 
0033     exif->fModel.Set_ASCII(identify->model.toLatin1().constData());
0034     exif->fMake.Set_ASCII(identify->make.toLatin1().constData());
0035     exif->fSoftware.Set_ASCII(QString::fromLatin1("digiKam %1").arg(digiKamVersion()).toLatin1().constData());
0036     exif->fExifVersion = DNG_CHAR4('0', '2', '3', '0');
0037 
0038     // Self-Write CFAPattern (section G) manually from mosaic info container.
0039 
0040     const dng_mosaic_info* mosaicInfo = negative->GetMosaicInfo();
0041 
0042     if (mosaicInfo)
0043     {
0044         exif->fCFARepeatPatternCols = mosaicInfo->fCFAPatternSize.v;
0045         exif->fCFARepeatPatternRows = mosaicInfo->fCFAPatternSize.h;
0046 
0047         for (uint16 c = 0 ; c < exif->fCFARepeatPatternCols ; ++c)
0048         {
0049             for (uint16 r = 0 ; r < exif->fCFARepeatPatternRows ; ++r)
0050             {
0051                 exif->fCFAPattern[r][c] = mosaicInfo->fCFAPattern[c][r];
0052             }
0053         }
0054     }
0055 
0056     // Write information with Exiv2
0057 
0058     metaLoaded = meta->load(parent->inputFile());
0059 
0060     if (metaLoaded)
0061     {
0062         qCDebug(DIGIKAM_GENERAL_LOG) << "DNGWriter: Updating Exif metadata to DNG Negative";
0063 
0064         QString  str;
0065         long int num, den;
0066         long     val;
0067 
0068         fileDate                 = meta->getItemDateTime();
0069 
0070         // Time from original shot
0071 
0072         orgDateTimeInfo.SetDateTime(dngDateTime(meta->getItemDateTime()));
0073         exif->fDateTimeOriginal  = orgDateTimeInfo;
0074 
0075         dng_date_time_info digiDateTimeInfo;
0076         digiDateTimeInfo.SetDateTime(dngDateTime(meta->getDigitizationDateTime(true)));
0077         exif->fDateTimeDigitized = digiDateTimeInfo;
0078 
0079         negative->UpdateDateTime(orgDateTimeInfo);
0080 
0081         // String Tags
0082 
0083         str = meta->getExifTagString("Exif.Image.Make");
0084         if (!str.isEmpty()) exif->fMake.Set_ASCII(str.trimmed().toLatin1().constData());
0085 
0086         str = meta->getExifTagString("Exif.Image.Model");
0087         if (!str.isEmpty()) exif->fModel.Set_ASCII(str.trimmed().toLatin1().constData());
0088 
0089         str = meta->getExifTagString("Exif.Image.Software");
0090         if (!str.isEmpty()) exif->fSoftware.Set_ASCII(str.trimmed().toLatin1().constData());
0091 
0092         str = meta->getExifTagString("Exif.Image.ImageDescription");
0093         if (!str.isEmpty()) exif->fImageDescription.Set_ASCII(str.trimmed().toLatin1().constData());
0094 
0095         str = meta->getExifTagString("Exif.Image.Artist");
0096         if (!str.isEmpty()) exif->fArtist.Set_ASCII(str.trimmed().toLatin1().constData());
0097 
0098         str = meta->getExifTagString("Exif.Image.Copyright");
0099         if (!str.isEmpty()) exif->fCopyright.Set_ASCII(str.trimmed().toLatin1().constData());
0100 
0101         str = meta->getExifTagString("Exif.Photo.UserComment");
0102         if (!str.isEmpty()) exif->fUserComment.Set_ASCII(str.trimmed().toLatin1().constData());
0103 
0104         str = meta->getExifTagString("Exif.Image.CameraSerialNumber");
0105         if (!str.isEmpty()) exif->fCameraSerialNumber.Set_ASCII(str.trimmed().toLatin1().constData());
0106 
0107         str = meta->getExifTagString("Exif.GPSInfo.GPSLatitudeRef");
0108         if (!str.isEmpty()) exif->fGPSLatitudeRef.Set_ASCII(str.trimmed().toLatin1().constData());
0109 
0110         str = meta->getExifTagString("Exif.GPSInfo.GPSLongitudeRef");
0111         if (!str.isEmpty()) exif->fGPSLongitudeRef.Set_ASCII(str.trimmed().toLatin1().constData());
0112 
0113         str = meta->getExifTagString("Exif.GPSInfo.GPSSatellites");
0114         if (!str.isEmpty()) exif->fGPSSatellites.Set_ASCII(str.trimmed().toLatin1().constData());
0115 
0116         str = meta->getExifTagString("Exif.GPSInfo.GPSStatus");
0117         if (!str.isEmpty()) exif->fGPSStatus.Set_ASCII(str.trimmed().toLatin1().constData());
0118 
0119         str = meta->getExifTagString("Exif.GPSInfo.GPSMeasureMode");
0120         if (!str.isEmpty()) exif->fGPSMeasureMode.Set_ASCII(str.trimmed().toLatin1().constData());
0121 
0122         str = meta->getExifTagString("Exif.GPSInfo.GPSSpeedRef");
0123         if (!str.isEmpty()) exif->fGPSSpeedRef.Set_ASCII(str.trimmed().toLatin1().constData());
0124 
0125         str = meta->getExifTagString("Exif.GPSInfo.GPSTrackRef");
0126         if (!str.isEmpty()) exif->fGPSTrackRef.Set_ASCII(str.trimmed().toLatin1().constData());
0127 
0128         str = meta->getExifTagString("Exif.GPSInfo.GPSSpeedRef");
0129         if (!str.isEmpty()) exif->fGPSSpeedRef.Set_ASCII(str.trimmed().toLatin1().constData());
0130 
0131         str = meta->getExifTagString("Exif.GPSInfo.GPSImgDirectionRef");
0132         if (!str.isEmpty()) exif->fGPSSpeedRef.Set_ASCII(str.trimmed().toLatin1().constData());
0133 
0134         str = meta->getExifTagString("Exif.GPSInfo.GPSMapDatum");
0135         if (!str.isEmpty()) exif->fGPSMapDatum.Set_ASCII(str.trimmed().toLatin1().constData());
0136 
0137         str = meta->getExifTagString("Exif.GPSInfo.GPSDestLatitudeRef");
0138         if (!str.isEmpty()) exif->fGPSDestLatitudeRef.Set_ASCII(str.trimmed().toLatin1().constData());
0139 
0140         str = meta->getExifTagString("Exif.GPSInfo.GPSDestLongitudeRef");
0141         if (!str.isEmpty()) exif->fGPSDestLongitudeRef.Set_ASCII(str.trimmed().toLatin1().constData());
0142 
0143         str = meta->getExifTagString("Exif.GPSInfo.GPSDestBearingRef");
0144         if (!str.isEmpty()) exif->fGPSDestBearingRef.Set_ASCII(str.trimmed().toLatin1().constData());
0145 
0146         str = meta->getExifTagString("Exif.GPSInfo.GPSDestDistanceRef");
0147         if (!str.isEmpty()) exif->fGPSDestDistanceRef.Set_ASCII(str.trimmed().toLatin1().constData());
0148 
0149         str = meta->getExifTagString("Exif.GPSInfo.GPSProcessingMethod");
0150         if (!str.isEmpty()) exif->fGPSProcessingMethod.Set_ASCII(str.trimmed().toLatin1().constData());
0151 
0152         str = meta->getExifTagString("Exif.GPSInfo.GPSAreaInformation");
0153         if (!str.isEmpty()) exif->fGPSAreaInformation.Set_ASCII(str.trimmed().toLatin1().constData());
0154 
0155         str = meta->getExifTagString("Exif.GPSInfo.GPSDateStamp");
0156         if (!str.isEmpty()) exif->fGPSDateStamp.Set_ASCII(str.trimmed().toLatin1().constData());
0157 
0158         // Rational Tags
0159 
0160         if (meta->getExifTagRational("Exif.Photo.ExposureTime", num, den))          exif->fExposureTime             = dng_urational(num, den);
0161         if (meta->getExifTagRational("Exif.Photo.FNumber", num, den))               exif->fFNumber                  = dng_urational(num, den);
0162         if (meta->getExifTagRational("Exif.Photo.ShutterSpeedValue", num, den))     exif->fShutterSpeedValue        = dng_srational(num, den);
0163         if (meta->getExifTagRational("Exif.Photo.ApertureValue", num, den))         exif->fApertureValue            = dng_urational(num, den);
0164         if (meta->getExifTagRational("Exif.Photo.BrightnessValue", num, den))       exif->fBrightnessValue          = dng_srational(num, den);
0165         if (meta->getExifTagRational("Exif.Photo.ExposureBiasValue", num, den))     exif->fExposureBiasValue        = dng_srational(num, den);
0166         if (meta->getExifTagRational("Exif.Photo.MaxApertureValue", num, den))      exif->fMaxApertureValue         = dng_urational(num, den);
0167         if (meta->getExifTagRational("Exif.Photo.FocalLength", num, den))           exif->fFocalLength              = dng_urational(num, den);
0168         if (meta->getExifTagRational("Exif.Photo.DigitalZoomRatio", num, den))      exif->fDigitalZoomRatio         = dng_urational(num, den);
0169         if (meta->getExifTagRational("Exif.Photo.SubjectDistance", num, den))       exif->fSubjectDistance          = dng_urational(num, den);
0170         if (meta->getExifTagRational("Exif.Image.BatteryLevel", num, den))          exif->fBatteryLevelR            = dng_urational(num, den);
0171         if (meta->getExifTagRational("Exif.Photo.FocalPlaneXResolution", num, den)) exif->fFocalPlaneXResolution    = dng_urational(num, den);
0172         if (meta->getExifTagRational("Exif.Photo.FocalPlaneYResolution", num, den)) exif->fFocalPlaneYResolution    = dng_urational(num, den);
0173         if (meta->getExifTagRational("Exif.GPSInfo.GPSAltitude", num, den))         exif->fGPSAltitude              = dng_urational(num, den);
0174         if (meta->getExifTagRational("Exif.GPSInfo.GPSDOP", num, den))              exif->fGPSDOP                   = dng_urational(num, den);
0175         if (meta->getExifTagRational("Exif.GPSInfo.GPSSpeed", num, den))            exif->fGPSSpeed                 = dng_urational(num, den);
0176         if (meta->getExifTagRational("Exif.GPSInfo.GPSTrack", num, den))            exif->fGPSTrack                 = dng_urational(num, den);
0177         if (meta->getExifTagRational("Exif.GPSInfo.GPSImgDirection", num, den))     exif->fGPSImgDirection          = dng_urational(num, den);
0178         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestBearing", num, den))      exif->fGPSDestBearing           = dng_urational(num, den);
0179         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestDistance", num, den))     exif->fGPSDestDistance          = dng_urational(num, den);
0180         if (meta->getExifTagRational("Exif.GPSInfo.GPSLatitude", num, den, 0))      exif->fGPSLatitude[0]           = dng_urational(num, den);
0181         if (meta->getExifTagRational("Exif.GPSInfo.GPSLatitude", num, den, 1))      exif->fGPSLatitude[1]           = dng_urational(num, den);
0182         if (meta->getExifTagRational("Exif.GPSInfo.GPSLatitude", num, den, 2))      exif->fGPSLatitude[2]           = dng_urational(num, den);
0183         if (meta->getExifTagRational("Exif.GPSInfo.GPSLongitude", num, den, 0))     exif->fGPSLongitude[0]          = dng_urational(num, den);
0184         if (meta->getExifTagRational("Exif.GPSInfo.GPSLongitude", num, den, 1))     exif->fGPSLongitude[1]          = dng_urational(num, den);
0185         if (meta->getExifTagRational("Exif.GPSInfo.GPSLongitude", num, den, 2))     exif->fGPSLongitude[2]          = dng_urational(num, den);
0186         if (meta->getExifTagRational("Exif.GPSInfo.GPSTimeStamp", num, den, 0))     exif->fGPSTimeStamp[0]          = dng_urational(num, den);
0187         if (meta->getExifTagRational("Exif.GPSInfo.GPSTimeStamp", num, den, 1))     exif->fGPSTimeStamp[1]          = dng_urational(num, den);
0188         if (meta->getExifTagRational("Exif.GPSInfo.GPSTimeStamp", num, den, 2))     exif->fGPSTimeStamp[2]          = dng_urational(num, den);
0189         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestLatitude", num, den, 0))  exif->fGPSDestLatitude[0]       = dng_urational(num, den);
0190         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestLatitude", num, den, 1))  exif->fGPSDestLatitude[1]       = dng_urational(num, den);
0191         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestLatitude", num, den, 2))  exif->fGPSDestLatitude[2]       = dng_urational(num, den);
0192         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestLongitude", num, den, 0)) exif->fGPSDestLongitude[0]      = dng_urational(num, den);
0193         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestLongitude", num, den, 1)) exif->fGPSDestLongitude[1]      = dng_urational(num, den);
0194         if (meta->getExifTagRational("Exif.GPSInfo.GPSDestLongitude", num, den, 2)) exif->fGPSDestLongitude[2]      = dng_urational(num, den);
0195 
0196         // Integer Tags
0197 
0198         if (meta->getExifTagLong("Exif.Photo.ExposureProgram", val))                exif->fExposureProgram          = (uint32)val;
0199         if (meta->getExifTagLong("Exif.Photo.ISOSpeedRatings", val))                exif->fISOSpeedRatings[0]       = (uint32)val;
0200         if (meta->getExifTagLong("Exif.Photo.MeteringMode", val))                   exif->fMeteringMode             = (uint32)val;
0201         if (meta->getExifTagLong("Exif.Photo.LightSource", val))                    exif->fLightSource              = (uint32)val;
0202         if (meta->getExifTagLong("Exif.Photo.Flash", val))                          exif->fFlash                    = (uint32)val;
0203         if (meta->getExifTagLong("Exif.Photo.SensingMethod", val))                  exif->fSensingMethod            = (uint32)val;
0204         if (meta->getExifTagLong("Exif.Photo.FileSource", val))                     exif->fFileSource               = (uint32)val;
0205         if (meta->getExifTagLong("Exif.Photo.SceneType", val))                      exif->fSceneType                = (uint32)val;
0206         if (meta->getExifTagLong("Exif.Photo.CustomRendered", val))                 exif->fCustomRendered           = (uint32)val;
0207         if (meta->getExifTagLong("Exif.Photo.ExposureMode", val))                   exif->fExposureMode             = (uint32)val;
0208         if (meta->getExifTagLong("Exif.Photo.WhiteBalance", val))                   exif->fWhiteBalance             = (uint32)val;
0209         if (meta->getExifTagLong("Exif.Photo.SceneCaptureType", val))               exif->fSceneCaptureType         = (uint32)val;
0210         if (meta->getExifTagLong("Exif.Photo.GainControl", val))                    exif->fGainControl              = (uint32)val;
0211         if (meta->getExifTagLong("Exif.Photo.Contrast", val))                       exif->fContrast                 = (uint32)val;
0212         if (meta->getExifTagLong("Exif.Photo.Saturation", val))                     exif->fSaturation               = (uint32)val;
0213         if (meta->getExifTagLong("Exif.Photo.Sharpness", val))                      exif->fSharpness                = (uint32)val;
0214         if (meta->getExifTagLong("Exif.Photo.SubjectDistanceRange", val))           exif->fSubjectDistanceRange     = (uint32)val;
0215         if (meta->getExifTagLong("Exif.Photo.FocalLengthIn35mmFilm", val))          exif->fFocalLengthIn35mmFilm    = (uint32)val;
0216         if (meta->getExifTagLong("Exif.Photo.ComponentsConfiguration", val))        exif->fComponentsConfiguration  = (uint32)val;
0217         if (meta->getExifTagLong("Exif.Photo.PixelXDimension", val))                exif->fPixelXDimension          = (uint32)val;
0218         if (meta->getExifTagLong("Exif.Photo.PixelYDimension", val))                exif->fPixelYDimension          = (uint32)val;
0219         if (meta->getExifTagLong("Exif.Photo.FocalPlaneResolutionUnit", val))       exif->fFocalPlaneResolutionUnit = (uint32)val;
0220         if (meta->getExifTagLong("Exif.GPSInfo.GPSAltitudeRef", val))               exif->fGPSAltitudeRef           = (uint32)val;
0221         if (meta->getExifTagLong("Exif.GPSInfo.GPSDifferential", val))              exif->fGPSDifferential          = (uint32)val;
0222 
0223         long gpsVer1        = 0;
0224         long gpsVer2        = 0;
0225         long gpsVer3        = 0;
0226         long gpsVer4        = 0;
0227         meta->getExifTagLong("Exif.GPSInfo.GPSVersionID", gpsVer1, 0);
0228         meta->getExifTagLong("Exif.GPSInfo.GPSVersionID", gpsVer2, 1);
0229         meta->getExifTagLong("Exif.GPSInfo.GPSVersionID", gpsVer3, 2);
0230         meta->getExifTagLong("Exif.GPSInfo.GPSVersionID", gpsVer4, 3);
0231 
0232         long gpsVer         = 0;
0233         gpsVer             += gpsVer1 << 24;
0234         gpsVer             += gpsVer2 << 16;
0235         gpsVer             += gpsVer3 <<  8;
0236         gpsVer             += gpsVer4;
0237         exif->fGPSVersionID = (uint32)gpsVer;
0238     }
0239 
0240     if (cancel)
0241     {
0242         return PROCESS_CANCELED;
0243     }
0244 
0245     return PROCESS_CONTINUE;
0246 }
0247 
0248 } // namespace Digikam