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 - Backup RAW data.
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::backupRaw(DNGWriterHost& host,
0026                                   AutoPtr<dng_negative>& negative)
0027 {
0028     if (backupOriginalRawFile)
0029     {
0030         qCDebug(DIGIKAM_GENERAL_LOG) << "DNGWriter: Backup Original RAW file (" << inputInfo.size() << " bytes)";
0031 
0032         QFileInfo originalFileInfo(parent->inputFile());
0033 
0034         QFile originalFile(originalFileInfo.absoluteFilePath());
0035 
0036         if (!originalFile.open(QIODevice::ReadOnly))
0037         {
0038             qCCritical(DIGIKAM_GENERAL_LOG) << "DNGWriter: Cannot open original RAW file to backup in DNG. Aborted...";
0039 
0040             return PROCESS_FAILED;
0041         }
0042 
0043         QDataStream originalDataStream(&originalFile);
0044 
0045         quint32 forkLength = originalFileInfo.size();
0046         quint32 forkBlocks = (quint32)floor((forkLength + 65535.0) / 65536.0);
0047 
0048         QVector<quint32> offsets;
0049         quint32 offset     = (2 + forkBlocks) * sizeof(quint32);
0050         offsets.push_back(offset);
0051 
0052         QByteArray originalDataBlock;
0053         originalDataBlock.resize(CHUNK);
0054 
0055         QTemporaryFile compressedFile;
0056 
0057         if (!compressedFile.open())
0058         {
0059             qCCritical(DIGIKAM_GENERAL_LOG) << "DNGWriter: Cannot open temporary file to write Zipped Raw data. Aborted...";
0060 
0061             return PROCESS_FAILED;
0062         }
0063 
0064         QDataStream compressedDataStream(&compressedFile);
0065 
0066         for (quint32 block = 0 ; block < forkBlocks ; ++block)
0067         {
0068             int originalBlockLength = originalDataStream.readRawData(originalDataBlock.data(), CHUNK);
0069 
0070             QByteArray compressedDataBlock = qCompress((const uchar*)originalDataBlock.data(), originalBlockLength, -1);
0071             compressedDataBlock.remove(0, 4);   // removes qCompress own header
0072             qCDebug(DIGIKAM_GENERAL_LOG) << "DNGWriter: compressed data block " << originalBlockLength << " -> " << compressedDataBlock.size();
0073 
0074             offset += compressedDataBlock.size();
0075             offsets.push_back(offset);
0076 
0077             compressedDataStream.writeRawData(compressedDataBlock.data(), compressedDataBlock.size());
0078         }
0079 
0080         dng_memory_allocator memalloc2(gDefaultDNGMemoryAllocator);
0081         dng_memory_stream tempDataStream(memalloc2);
0082         tempDataStream.SetBigEndian(true);
0083         tempDataStream.Put_uint32(forkLength);
0084 
0085         for (qint32 idx = 0 ; idx < offsets.size() ; ++idx)
0086         {
0087             tempDataStream.Put_uint32(offsets[idx]);
0088         }
0089 
0090         QByteArray compressedData;
0091         compressedData.resize(compressedFile.size());
0092         compressedFile.seek(0);
0093         compressedDataStream.readRawData(compressedData.data(), compressedData.size());
0094         tempDataStream.Put(compressedData.data(), compressedData.size());
0095 
0096         compressedFile.remove();
0097         originalFile.close();
0098 
0099         tempDataStream.Put_uint32(0);
0100         tempDataStream.Put_uint32(0);
0101         tempDataStream.Put_uint32(0);
0102         tempDataStream.Put_uint32(0);
0103         tempDataStream.Put_uint32(0);
0104         tempDataStream.Put_uint32(0);
0105         tempDataStream.Put_uint32(0);
0106 
0107         AutoPtr<dng_memory_block> block(host.Allocate(tempDataStream.Length()));
0108         tempDataStream.SetReadPosition(0);
0109         tempDataStream.Get(block->Buffer(), tempDataStream.Length());
0110 
0111         dng_md5_printer md5;
0112         md5.Process(block->Buffer(), block->LogicalSize());
0113         negative->SetOriginalRawFileData(block);
0114         negative->SetOriginalRawFileDigest(md5.Result());
0115         negative->ValidateOriginalRawFileDigest();
0116     }
0117 
0118     if (cancel)
0119     {
0120         return PROCESS_CANCELED;
0121     }
0122 
0123     return PROCESS_CONTINUE;
0124 }
0125 
0126 } // namespace Digikam