File indexing completed on 2025-01-05 03:56:02
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 0008 * 0009 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "dngwriter_p.h" 0016 0017 // C++ includes 0018 0019 #include <cstdio> 0020 0021 // Qt includes 0022 0023 #include <QFile> 0024 0025 // KDE includes 0026 0027 #include "digikam_debug.h" 0028 0029 // Local includes 0030 0031 #include "dngwriter.h" 0032 #include "dngwriterhost.h" 0033 0034 namespace Digikam 0035 { 0036 0037 DNGWriter::Private::Private(DNGWriter* const dd) 0038 : parent (dd), 0039 bayerPattern(Unknown), 0040 filter (0), 0041 metaLoaded (false), 0042 activeWidth (0), 0043 activeHeight(0), 0044 outputHeight(0), 0045 outputWidth (0), 0046 width (0), 0047 height (0), 0048 exif (nullptr) 0049 { 0050 reset(); 0051 } 0052 0053 DNGWriter::Private::~Private() 0054 { 0055 } 0056 0057 void DNGWriter::Private::reset() 0058 { 0059 cancel = false; 0060 jpegLossLessCompression = true; 0061 updateFileDate = false; 0062 backupOriginalRawFile = false; 0063 previewMode = DNGWriter::FULL_SIZE; 0064 } 0065 0066 void DNGWriter::Private::cleanup() 0067 { 0068 if (::remove(QFile::encodeName(outputFile).constData()) != 0) 0069 { 0070 qCDebug(DIGIKAM_GENERAL_LOG) << "Cannot remove " << outputFile; 0071 } 0072 } 0073 0074 dng_date_time DNGWriter::Private::dngDateTime(const QDateTime& qDT) const 0075 { 0076 dng_date_time dngDT; 0077 dngDT.fYear = qDT.date().year(); 0078 dngDT.fMonth = qDT.date().month(); 0079 dngDT.fDay = qDT.date().day(); 0080 dngDT.fHour = qDT.time().hour(); 0081 dngDT.fMinute = qDT.time().minute(); 0082 dngDT.fSecond = qDT.time().second(); 0083 0084 return dngDT; 0085 } 0086 0087 bool DNGWriter::Private::fujiRotate(QByteArray& rawData, DRawInfo& identify) const 0088 { 0089 QByteArray tmpData(rawData); 0090 int height = identify.outputSize.height(); 0091 int width = identify.outputSize.width(); 0092 unsigned short* tmp = reinterpret_cast<unsigned short*>(tmpData.data()); 0093 unsigned short* output = reinterpret_cast<unsigned short*>(rawData.data()); 0094 0095 for (int row = 0 ; row < height ; ++row) 0096 { 0097 for (int col = 0 ; col < width ; ++col) 0098 { 0099 output[col * height + row] = tmp[row * width + col]; 0100 } 0101 } 0102 0103 identify.orientation = DRawInfo::ORIENTATION_Mirror90CCW; 0104 identify.outputSize = QSize(height, width); 0105 0106 // TODO: rotate margins 0107 0108 return true; 0109 } 0110 0111 QString DNGWriter::Private::dngErrorCodeToString(int errorCode) const 0112 { 0113 switch (errorCode) 0114 { 0115 default: 0116 case 100000: return QLatin1String("Unknown error"); 0117 0118 case 100003: return QLatin1String("Processing stopped by user (or host application) request"); 0119 0120 case 100004: return QLatin1String("Necessary host functionality is not present"); 0121 0122 case 100005: return QLatin1String("Out of memory"); 0123 0124 case 100006: return QLatin1String("File format is not valid"); 0125 0126 case 100007: return QLatin1String("Matrix has wrong shape, is badly conditioned, or similar problem"); 0127 0128 case 100008: return QLatin1String("Could not open file"); 0129 0130 case 100009: return QLatin1String("Error reading file"); 0131 0132 case 100010: return QLatin1String("Error writing file"); 0133 0134 case 100011: return QLatin1String("Unexpected end of file"); 0135 0136 case 100012: return QLatin1String("File is damaged in some way"); 0137 0138 case 100013: return QLatin1String("Image is too big to save as DNG"); 0139 0140 case 100014: return QLatin1String("Image is too big to save as TIFF"); 0141 0142 case 100015: return QLatin1String("DNG version is unsupported"); 0143 } 0144 } 0145 0146 QString DNGWriter::Private::dngBayerPatternToString(int pattern) const 0147 { 0148 switch (pattern) 0149 { 0150 case LinearRaw: 0151 { 0152 return QLatin1String("Bayer Linear Raw Pattern Mosaic"); 0153 } 0154 0155 case Standard: 0156 { 0157 return QLatin1String("Bayer Standard Pattern Mosaic"); 0158 } 0159 0160 case Fuji: 0161 { 0162 return QLatin1String("Bayer Fuji Pattern Mosaic"); 0163 } 0164 0165 case Fuji6x6: 0166 { 0167 return QLatin1String("Bayer Fuji 6x6 Pattern Mosaic"); 0168 } 0169 0170 case FourColor: 0171 { 0172 return QLatin1String("Bayer Four Color Pattern Mosaic"); 0173 } 0174 0175 default: // Unknown 0176 { 0177 return QLatin1String("Bayer Unknown Pattern Mosaic"); 0178 } 0179 } 0180 } 0181 0182 int DNGWriter::Private::debugExtractedRAWData(const QByteArray& rawData) 0183 { 0184 QString rawdataFilePath(inputInfo.completeBaseName() + QLatin1String(".dat")); 0185 QFileInfo rawdataInfo(rawdataFilePath); 0186 0187 QFile rawdataFile(rawdataFilePath); 0188 0189 if (!rawdataFile.open(QIODevice::WriteOnly)) 0190 { 0191 qCDebug(DIGIKAM_GENERAL_LOG) << "DNGWriter: Cannot open file to write RAW data. Aborted..." ; 0192 return PROCESS_FAILED; 0193 } 0194 0195 QDataStream rawdataStream(&rawdataFile); 0196 rawdataStream.writeRawData(rawData.data(), rawData.size()); 0197 rawdataFile.close(); 0198 0199 return PROCESS_CONTINUE; 0200 } 0201 0202 } // namespace Digikam