|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
* libopenraw - crwfile.cpp
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* Copyright (C) 2006-2017 Hubert Figuière
|
|
rpm-build |
d2b433 |
* Copyright (c) 2008 Novell, Inc.
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* This library is free software: you can redistribute it and/or
|
|
rpm-build |
d2b433 |
* modify it under the terms of the GNU Lesser General Public License
|
|
rpm-build |
d2b433 |
* as published by the Free Software Foundation, either version 3 of
|
|
rpm-build |
d2b433 |
* the License, or (at your option) any later version.
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
d2b433 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
d2b433 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
d2b433 |
* Lesser General Public License for more details.
|
|
rpm-build |
d2b433 |
*
|
|
rpm-build |
d2b433 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
d2b433 |
* License along with this library. If not, see
|
|
rpm-build |
d2b433 |
* <http://www.gnu.org/licenses/>.
|
|
rpm-build |
d2b433 |
*/
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#include <fcntl.h>
|
|
rpm-build |
d2b433 |
#include <stddef.h>
|
|
rpm-build |
d2b433 |
#include <cstdint>
|
|
rpm-build |
d2b433 |
#include <algorithm>
|
|
rpm-build |
d2b433 |
#include <functional>
|
|
rpm-build |
d2b433 |
#include <memory>
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#include <libopenraw/debug.h>
|
|
rpm-build |
d2b433 |
#include <libopenraw/metadata.h>
|
|
rpm-build |
d2b433 |
#include <libopenraw/cameraids.h>
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#include "rawdata.hpp"
|
|
rpm-build |
d2b433 |
#include "metavalue.hpp"
|
|
rpm-build |
d2b433 |
#include "cfapattern.hpp"
|
|
rpm-build |
d2b433 |
#include "rawfile.hpp"
|
|
rpm-build |
d2b433 |
#include "trace.hpp"
|
|
rpm-build |
d2b433 |
#include "io/streamclone.hpp"
|
|
rpm-build |
d2b433 |
#include "io/memstream.hpp"
|
|
rpm-build |
d2b433 |
#include "crwfile.hpp"
|
|
rpm-build |
d2b433 |
#include "ciffcontainer.hpp"
|
|
rpm-build |
d2b433 |
#include "jfifcontainer.hpp"
|
|
rpm-build |
d2b433 |
#include "crwdecompressor.hpp"
|
|
rpm-build |
d2b433 |
#include "rawfile_private.hpp"
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
using namespace Debug;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
namespace OpenRaw {
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
namespace Internals {
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
using namespace CIFF;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
#define OR_MAKE_CANON_TYPEID(camid) \
|
|
rpm-build |
d2b433 |
OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,camid)
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
/* taken from dcraw, by default */
|
|
rpm-build |
d2b433 |
static const BuiltinColourMatrix s_matrices[] = {
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D30), 0, 0,
|
|
rpm-build |
d2b433 |
{ 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D60), 0, 0xfa0,
|
|
rpm-build |
d2b433 |
{ 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_10D), 0, 0xfa0,
|
|
rpm-build |
d2b433 |
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_300D), 0, 0xfa0,
|
|
rpm-build |
d2b433 |
{ 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
|
|
rpm-build |
d2b433 |
// { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1), 0, 0,
|
|
rpm-build |
d2b433 |
// { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G2), 0, 0,
|
|
rpm-build |
d2b433 |
{ 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3), 0, 0,
|
|
rpm-build |
d2b433 |
{ 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5), 0, 0,
|
|
rpm-build |
d2b433 |
{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G6), 0, 0,
|
|
rpm-build |
d2b433 |
{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
|
|
rpm-build |
d2b433 |
{ OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_PRO1), 0, 0,
|
|
rpm-build |
d2b433 |
{ 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
|
|
rpm-build |
d2b433 |
{ 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
|
|
rpm-build |
d2b433 |
};
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
const RawFile::camera_ids_t CRWFile::s_def[] = {
|
|
rpm-build |
d2b433 |
{ "Canon EOS D30" , OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D30) },
|
|
rpm-build |
d2b433 |
{ "Canon EOS D60" , OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D60) },
|
|
rpm-build |
d2b433 |
{ "Canon EOS 10D" , OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_10D) },
|
|
rpm-build |
d2b433 |
{ "Canon EOS 300D DIGITAL", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_300D) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot G1", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot G2", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G2) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot G3", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot G5", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot G6", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G6) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot G7", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G7) },
|
|
rpm-build |
d2b433 |
{ "Canon PowerShot Pro1", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_PRO1) },
|
|
rpm-build |
d2b433 |
{ 0, 0 }
|
|
rpm-build |
d2b433 |
};
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
RawFile *CRWFile::factory(const IO::Stream::Ptr &s)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
return new CRWFile(s);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
CRWFile::CRWFile(const IO::Stream::Ptr &s)
|
|
rpm-build |
d2b433 |
: RawFile(OR_RAWFILE_TYPE_CRW),
|
|
rpm-build |
d2b433 |
m_io(s),
|
|
rpm-build |
d2b433 |
m_container(new CIFFContainer(m_io)),
|
|
rpm-build |
d2b433 |
m_x(0), m_y(0)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
_setIdMap(s_def);
|
|
rpm-build |
d2b433 |
_setMatrices(s_matrices);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
CRWFile::~CRWFile()
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
delete m_container;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
::or_error CRWFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
::or_error err = OR_ERROR_NOT_FOUND;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
Heap::Ref heap = m_container->heap();
|
|
rpm-build |
d2b433 |
if(!heap) {
|
|
rpm-build |
d2b433 |
// this is not a CIFF file.
|
|
rpm-build |
d2b433 |
return err;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
const RecordEntry::List & records = heap->records();
|
|
rpm-build |
d2b433 |
RecordEntry::List::const_iterator iter;
|
|
rpm-build |
d2b433 |
iter = std::find_if(records.cbegin(), records.cend(), std::bind(
|
|
rpm-build |
d2b433 |
&RecordEntry::isA, std::placeholders::_1,
|
|
rpm-build |
d2b433 |
static_cast<uint16_t>(TAG_JPEGIMAGE)));
|
|
rpm-build |
d2b433 |
if (iter != records.end()) {
|
|
rpm-build |
d2b433 |
LOGDBG2("JPEG @%u\n", (*iter).offset);
|
|
rpm-build |
d2b433 |
m_x = m_y = 0;
|
|
rpm-build |
d2b433 |
uint32_t offset = heap->offset() + (*iter).offset;
|
|
rpm-build |
d2b433 |
IO::StreamClone::Ptr s(new IO::StreamClone(m_io, offset));
|
|
rpm-build |
d2b433 |
std::unique_ptr<JfifContainer> jfif(new JfifContainer(s, 0));
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
jfif->getDimensions(m_x, m_y);
|
|
rpm-build |
d2b433 |
LOGDBG1("JPEG dimensions x=%d y=%d\n", m_x, m_y);
|
|
rpm-build |
d2b433 |
uint32_t dim = std::max(m_x,m_y);
|
|
rpm-build |
d2b433 |
_addThumbnail(dim, ThumbDesc(m_x, m_y, OR_DATA_TYPE_JPEG, offset, (*iter).length));
|
|
rpm-build |
d2b433 |
list.push_back(dim);
|
|
rpm-build |
d2b433 |
err = OR_ERROR_NONE;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
return err;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
RawContainer* CRWFile::getContainer() const
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
return m_container;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
::or_error CRWFile::_getRawData(RawData & data, uint32_t options)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
::or_error err = OR_ERROR_NOT_FOUND;
|
|
rpm-build |
d2b433 |
Heap::Ref props = m_container->getImageProps();
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if(!props) {
|
|
rpm-build |
d2b433 |
return OR_ERROR_NOT_FOUND;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
const ImageSpec * img_spec = m_container->getImageSpec();
|
|
rpm-build |
d2b433 |
uint32_t x, y;
|
|
rpm-build |
d2b433 |
x = y = 0;
|
|
rpm-build |
d2b433 |
if(img_spec) {
|
|
rpm-build |
d2b433 |
x = img_spec->imageWidth;
|
|
rpm-build |
d2b433 |
y = img_spec->imageHeight;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
// locate decoder table
|
|
rpm-build |
d2b433 |
const CIFF::RecordEntry::List & propsRecs = props->records();
|
|
rpm-build |
d2b433 |
auto iter = std::find_if(propsRecs.cbegin(), propsRecs.cend(), std::bind(
|
|
rpm-build |
d2b433 |
&RecordEntry::isA, std::placeholders::_1,
|
|
rpm-build |
d2b433 |
static_cast<uint16_t>(TAG_EXIFINFORMATION)));
|
|
rpm-build |
d2b433 |
if (iter == propsRecs.end()) {
|
|
rpm-build |
d2b433 |
LOGERR("Couldn't find the Exif information.\n");
|
|
rpm-build |
d2b433 |
return OR_ERROR_NOT_FOUND;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
Heap exifProps(iter->offset + props->offset(), iter->length, m_container);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
const RecordEntry::List & exifPropsRecs = exifProps.records();
|
|
rpm-build |
d2b433 |
iter = std::find_if(exifPropsRecs.cbegin(), exifPropsRecs.cend(),
|
|
rpm-build |
d2b433 |
std::bind(
|
|
rpm-build |
d2b433 |
&RecordEntry::isA, std::placeholders::_1,
|
|
rpm-build |
d2b433 |
static_cast<uint16_t>(TAG_DECODERTABLE)));
|
|
rpm-build |
d2b433 |
if (iter == exifPropsRecs.end()) {
|
|
rpm-build |
d2b433 |
LOGERR("Couldn't find the decoder table.\n");
|
|
rpm-build |
d2b433 |
return err;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
LOGDBG2("length = %d\n", iter->length);
|
|
rpm-build |
d2b433 |
LOGDBG2("offset = %ld\n", exifProps.offset() + iter->offset);
|
|
rpm-build |
d2b433 |
auto file = m_container->file();
|
|
rpm-build |
d2b433 |
file->seek(exifProps.offset() + iter->offset, SEEK_SET);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
auto result = m_container->readUInt32(file);
|
|
rpm-build |
d2b433 |
if(result.empty()) {
|
|
rpm-build |
d2b433 |
LOGERR("Couldn't find decoder table\n");
|
|
rpm-build |
d2b433 |
return OR_ERROR_NOT_FOUND;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
uint32_t decoderTable = result.unwrap();
|
|
rpm-build |
d2b433 |
LOGDBG2("decoder table = %u\n", decoderTable);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
// locate the CFA info
|
|
rpm-build |
d2b433 |
iter = std::find_if(exifPropsRecs.cbegin(), exifPropsRecs.cend(), std::bind(
|
|
rpm-build |
d2b433 |
&RecordEntry::isA, std::placeholders::_1,
|
|
rpm-build |
d2b433 |
static_cast<uint16_t>(TAG_SENSORINFO)));
|
|
rpm-build |
d2b433 |
if (iter == exifPropsRecs.end()) {
|
|
rpm-build |
d2b433 |
LOGERR("Couldn't find the sensor info.\n");
|
|
rpm-build |
d2b433 |
return err;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
LOGDBG2("length = %u\n", iter->length);
|
|
rpm-build |
d2b433 |
LOGDBG2("offset = %ld\n", exifProps.offset() + iter->offset);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
// go figure what the +2 is. looks like it is the byte #
|
|
rpm-build |
d2b433 |
file->seek(exifProps.offset() + iter->offset + 2, SEEK_SET);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
auto cfa_x = m_container->readUInt16(file);
|
|
rpm-build |
d2b433 |
auto cfa_y = m_container->readUInt16(file);
|
|
rpm-build |
d2b433 |
if(cfa_x.empty() || cfa_y.empty()) {
|
|
rpm-build |
d2b433 |
LOGERR("Couldn't find the sensor size.\n");
|
|
rpm-build |
d2b433 |
return OR_ERROR_NOT_FOUND;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
const CIFF::RecordEntry *entry = m_container->getRawDataRecord();
|
|
rpm-build |
d2b433 |
if (entry) {
|
|
rpm-build |
d2b433 |
CIFF::Heap::Ref heap = m_container->heap();
|
|
rpm-build |
d2b433 |
LOGDBG2("RAW @%ld\n", heap->offset() + entry->offset);
|
|
rpm-build |
d2b433 |
size_t byte_size = entry->length;
|
|
rpm-build |
d2b433 |
void *buf = data.allocData(byte_size);
|
|
rpm-build |
d2b433 |
size_t real_size = entry->fetchData(heap.get(), buf, byte_size);
|
|
rpm-build |
d2b433 |
if (real_size != byte_size) {
|
|
rpm-build |
d2b433 |
LOGWARN("wrong size\n");
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
data.setDimensions(x, y);
|
|
rpm-build |
d2b433 |
data.setCfaPatternType(OR_CFA_PATTERN_RGGB);
|
|
rpm-build |
d2b433 |
data.setDataType(OR_DATA_TYPE_COMPRESSED_RAW);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
// decompress if we need
|
|
rpm-build |
d2b433 |
if((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
|
|
rpm-build |
d2b433 |
std::unique_ptr<IO::Stream> s(new IO::MemStream(data.data(),
|
|
rpm-build |
d2b433 |
data.size()));
|
|
rpm-build |
d2b433 |
s->open(); // TODO check success
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
CrwDecompressor decomp(s.get(), m_container);
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
decomp.setOutputDimensions(cfa_x.unwrap(), cfa_y.unwrap());
|
|
rpm-build |
d2b433 |
decomp.setDecoderTable(decoderTable);
|
|
rpm-build |
d2b433 |
RawDataPtr dData = decomp.decompress();
|
|
rpm-build |
d2b433 |
if (dData) {
|
|
rpm-build |
d2b433 |
LOGDBG1("Out size is %dx%d\n", dData->width(), dData->height());
|
|
rpm-build |
d2b433 |
dData->setCfaPatternType(data.cfaPattern()->patternType());
|
|
rpm-build |
d2b433 |
data.swap(*dData);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
err = OR_ERROR_NONE;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
return err;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
MetaValue *CRWFile::_getMetaValue(int32_t meta_index)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
MetaValue * val = NULL;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
switch(META_INDEX_MASKOUT(meta_index)) {
|
|
rpm-build |
d2b433 |
case META_NS_TIFF:
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
uint32_t index = META_NS_MASKOUT(meta_index);
|
|
rpm-build |
d2b433 |
switch(index) {
|
|
rpm-build |
d2b433 |
case EXIF_TAG_ORIENTATION:
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
const ImageSpec * img_spec = m_container->getImageSpec();
|
|
rpm-build |
d2b433 |
if(img_spec) {
|
|
rpm-build |
d2b433 |
val = new MetaValue(static_cast<uint32_t>(
|
|
rpm-build |
d2b433 |
img_spec->exifOrientation()));
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
case EXIF_TAG_MAKE:
|
|
rpm-build |
d2b433 |
case EXIF_TAG_MODEL:
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
if (index == EXIF_TAG_MAKE && !m_make.empty()) {
|
|
rpm-build |
d2b433 |
val = new MetaValue(m_make);
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
if (index == EXIF_TAG_MODEL && !m_model.empty()) {
|
|
rpm-build |
d2b433 |
val = new MetaValue(m_model);
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
CIFF::Heap::Ref heap = m_container->getCameraProps();
|
|
rpm-build |
d2b433 |
if(heap) {
|
|
rpm-build |
d2b433 |
auto propsRecs = heap->records();
|
|
rpm-build |
d2b433 |
auto iter
|
|
rpm-build |
d2b433 |
= std::find_if(propsRecs.cbegin(), propsRecs.cend(),
|
|
rpm-build |
d2b433 |
[](const CIFF::RecordEntry &e){
|
|
rpm-build |
d2b433 |
return e.isA(static_cast<uint16_t>(CIFF::TAG_RAWMAKEMODEL));
|
|
rpm-build |
d2b433 |
});
|
|
rpm-build |
d2b433 |
if (iter == propsRecs.end()) {
|
|
rpm-build |
d2b433 |
LOGERR("Couldn't find the image info.\n");
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
else {
|
|
rpm-build |
d2b433 |
char buf[256];
|
|
rpm-build |
d2b433 |
size_t sz = iter->length;
|
|
rpm-build |
d2b433 |
if(sz > 256) {
|
|
rpm-build |
d2b433 |
sz = 256;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
/*size_t sz2 = */iter->fetchData(heap.get(),
|
|
rpm-build |
d2b433 |
(void*)buf, sz);
|
|
rpm-build |
d2b433 |
const char *p = buf;
|
|
rpm-build |
d2b433 |
while(*p) {
|
|
rpm-build |
d2b433 |
p++;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
m_make = std::string(buf, p - buf);
|
|
rpm-build |
d2b433 |
p++;
|
|
rpm-build |
d2b433 |
m_model = p;
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
if (index == EXIF_TAG_MODEL) {
|
|
rpm-build |
d2b433 |
val = new MetaValue(m_model);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
else if (index == EXIF_TAG_MAKE) {
|
|
rpm-build |
d2b433 |
val = new MetaValue(m_make);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
LOGDBG1("Make %s\n", m_make.c_str());
|
|
rpm-build |
d2b433 |
LOGDBG1("Model %s\n", m_model.c_str());
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
case META_NS_EXIF:
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
default:
|
|
rpm-build |
d2b433 |
LOGERR("Unknown Meta Namespace\n");
|
|
rpm-build |
d2b433 |
break;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
return val;
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
void CRWFile::_identifyId()
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
std::string model;
|
|
rpm-build |
d2b433 |
std::string make;
|
|
rpm-build |
d2b433 |
try {
|
|
rpm-build |
d2b433 |
MetaValue * v = _getMetaValue(META_NS_TIFF | EXIF_TAG_MODEL);
|
|
rpm-build |
d2b433 |
if(v) {
|
|
rpm-build |
d2b433 |
model = v->getString(0);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
delete v;
|
|
rpm-build |
d2b433 |
v = _getMetaValue(META_NS_TIFF | EXIF_TAG_MAKE);
|
|
rpm-build |
d2b433 |
if(v) {
|
|
rpm-build |
d2b433 |
make = v->getString(0);
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
delete v;
|
|
rpm-build |
d2b433 |
_setTypeId(_typeIdFromModel(make, model));
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
catch(...)
|
|
rpm-build |
d2b433 |
{
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
}
|
|
rpm-build |
d2b433 |
|
|
rpm-build |
d2b433 |
/*
|
|
rpm-build |
d2b433 |
Local Variables:
|
|
rpm-build |
d2b433 |
mode:c++
|
|
rpm-build |
d2b433 |
c-file-style:"stroustrup"
|
|
rpm-build |
d2b433 |
c-file-offsets:((innamespace . 0))
|
|
rpm-build |
d2b433 |
indent-tabs-mode:nil
|
|
rpm-build |
d2b433 |
fill-column:80
|
|
rpm-build |
d2b433 |
End:
|
|
rpm-build |
d2b433 |
*/
|