/* * libopenraw - dngfile.cpp * * Copyright (C) 2006-2017 Hubert Figuière * Copyright (C) 2008 Novell, Inc. * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include #include #include #include #include "rawdata.hpp" #include "trace.hpp" #include "io/memstream.hpp" #include "jfifcontainer.hpp" #include "ljpegdecompressor.hpp" #include "ifd.hpp" #include "ifddir.hpp" #include "ifdentry.hpp" #include "dngfile.hpp" using namespace Debug; namespace OpenRaw { namespace Internals { const IfdFile::camera_ids_t DngFile::s_def[] = { { "PENTAX K10D ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K10D_DNG) }, { "PENTAX Q ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_Q_DNG) }, { "PENTAX K200D ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K200D_DNG) }, { "PENTAX Q10 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_Q10_DNG) }, { "PENTAX Q7 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_Q7_DNG) }, { "PENTAX QS-1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_QS1_DNG) }, { "PENTAX K-x ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_KX_DNG) }, { "PENTAX K-r ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_KR_DNG) }, { "PENTAX K-01 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K01_DNG) }, { "PENTAX K-1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K1_DNG) }, { "PENTAX K-30 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K30_DNG) }, { "PENTAX K-5 II s ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K5_IIS_DNG) }, { "PENTAX K-50 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K50_DNG) }, { "PENTAX K-500 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K500_DNG) }, { "PENTAX K-3 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K3_DNG) }, { "PENTAX K-3 II ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K3_II_DNG) }, { "PENTAX K-70 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_K70_DNG) }, { "PENTAX K-S1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_KS1_DNG) }, { "PENTAX KP ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_KP_DNG) }, { "PENTAX MX-1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX, OR_TYPEID_PENTAX_MX1_DNG) }, { "R9 - Digital Back DMR", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_DMR) }, { "M8 Digital Camera", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_M8) }, { "M9 Digital Camera", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_M9) }, { "M Monochrom", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_M_MONOCHROM) }, { "LEICA M (Typ 240)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_M_TYP240) }, { "LEICA M10", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_M10) }, { "LEICA X1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_X1) }, { "LEICA X2", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_X2) }, { "Leica S2", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_S2) }, { "LEICA X VARIO (Typ 107)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_X_VARIO) }, { "LEICA X (Typ 113)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_X_TYP113) }, { "LEICA SL (Typ 601)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_SL_TYP601) }, { "LEICA T (Typ 701)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_T_TYP701) }, { "LEICA Q (Typ 116)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, OR_TYPEID_LEICA_Q_TYP116) }, { "GR DIGITAL 2 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH, OR_TYPEID_RICOH_GR2) }, { "GR ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH, OR_TYPEID_RICOH_GR) }, { "GXR ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH, OR_TYPEID_RICOH_GXR) }, { "GXR A16 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH, OR_TYPEID_RICOH_GXR_A16) }, { "SAMSUNG GX10 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SAMSUNG, OR_TYPEID_SAMSUNG_GX10) }, { "Pro 815 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SAMSUNG, OR_TYPEID_SAMSUNG_PRO815) }, { "M1", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_XIAOYI, OR_TYPEID_XIAOYI_M1) }, { "iPhone 6s Plus", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_APPLE, OR_TYPEID_APPLE_IPHONE_6SPLUS) }, { "iPhone 7 Plus", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_APPLE, OR_TYPEID_APPLE_IPHONE_7PLUS) }, { 0, OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_ADOBE, OR_TYPEID_ADOBE_DNG_GENERIC) } }; RawFile *DngFile::factory(const IO::Stream::Ptr &s) { return new DngFile(s); } DngFile::DngFile(const IO::Stream::Ptr &s) : TiffEpFile(s, OR_RAWFILE_TYPE_DNG) { _setIdMap(s_def); } DngFile::~DngFile() { } ::or_error DngFile::_getRawData(RawData & data, uint32_t options) { ::or_error ret = OR_ERROR_NONE; const IfdDir::Ref & _cfaIfd = cfaIfd(); LOGDBG1("_getRawData()\n"); if (!_cfaIfd) { LOGDBG1("cfaIfd is NULL: not found\n"); return OR_ERROR_NOT_FOUND; } ret = _getRawDataFromDir(data, _cfaIfd); if(ret != OR_ERROR_NONE) { LOGERR("couldn't find raw data\n"); return ret; } auto result = _cfaIfd->getValue(IFD::EXIF_TAG_COMPRESSION); if (result.ok() && (result.unwrap() == IFD::COMPRESS_LJPEG)) { // if the option is not set, decompress if ((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) { IO::Stream::Ptr s( std::make_shared(data.data(), data.size())); s->open(); // TODO check success std::unique_ptr jfif(new JfifContainer(s, 0)); LJpegDecompressor decomp(s.get(), jfif.get()); RawDataPtr dData = decomp.decompress(); if (dData) { dData->setCfaPattern(data.cfaPattern()); data.swap(*dData); } } } else { data.setDataType(OR_DATA_TYPE_RAW); } uint32_t crop_x, crop_y, crop_w, crop_h; IfdEntry::Ref e = _cfaIfd->getEntry(IFD::DNG_TAG_DEFAULT_CROP_ORIGIN); if(e) { crop_x = e->getIntegerArrayItem(0); crop_y = e->getIntegerArrayItem(1); } else { crop_x = crop_y = 0; } e = _cfaIfd->getEntry(IFD::DNG_TAG_DEFAULT_CROP_SIZE); if(e) { crop_w = e->getIntegerArrayItem(0); crop_h = e->getIntegerArrayItem(1); } else { crop_w = data.width(); crop_h = data.height(); } data.setRoi(crop_x, crop_y, crop_w, crop_h); return ret; } void DngFile::_identifyId() { TiffEpFile::_identifyId(); // XXX what if the DNG file match the non DNG? // XXX maybe we should hint of the type in the camera ID table if (OR_GET_FILE_TYPEID_CAMERA(_typeId()) == 0) { const IfdDir::Ref & _mainIfd = mainIfd(); auto uniqueCameraModel = _mainIfd->getValue(IFD::DNG_TAG_UNIQUE_CAMERA_MODEL); if (uniqueCameraModel.ok()) { // set a generic DNG type if we found a // unique camera model _setTypeId( OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_ADOBE, OR_TYPEID_ADOBE_DNG_GENERIC)); } } } } } /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)) indent-tabs-mode:nil fill-column:80 End: */