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