28 #include <boost/algorithm/string.hpp>
29 #include <boost/bind.hpp>
30 #include <boost/scoped_ptr.hpp>
31 #include <boost/checked_delete.hpp>
35 #include <libopenraw/metadata.h>
36 #include <libopenraw++/rawfile.h>
37 #include <libopenraw++/rawdata.h>
38 #include <libopenraw++/thumbnail.h>
41 #include "io/memstream.h"
51 #include "metavalue.h"
52 #include "exception.h"
55 #include "rawfilefactory.h"
58 using namespace Debug;
62 using Internals::RawFileFactory;
66 static RawFileFactory fctcr2(OR_RAWFILE_TYPE_CR2,
67 boost::bind(&Internals::Cr2File::factory, _1),
69 static RawFileFactory fctnef(OR_RAWFILE_TYPE_NEF,
70 boost::bind(&Internals::NEFFile::factory, _1),
72 static RawFileFactory fctarw(OR_RAWFILE_TYPE_ARW,
73 boost::bind(&Internals::ARWFile::factory, _1),
75 static RawFileFactory fctorf(OR_RAWFILE_TYPE_ORF,
76 boost::bind(&Internals::OrfFile::factory, _1),
78 static RawFileFactory fctdng(OR_RAWFILE_TYPE_DNG,
79 boost::bind(&Internals::DNGFile::factory, _1),
81 static RawFileFactory fctpef(OR_RAWFILE_TYPE_PEF,
82 boost::bind(&Internals::PEFFile::factory, _1),
84 static RawFileFactory fctcrw(OR_RAWFILE_TYPE_CRW,
85 boost::bind(&Internals::CRWFile::factory, _1),
87 static RawFileFactory fcterf(OR_RAWFILE_TYPE_ERF,
88 boost::bind(&Internals::ERFFile::factory, _1),
90 static RawFileFactory fctmrw(OR_RAWFILE_TYPE_MRW,
91 boost::bind(&Internals::MRWFile::factory, _1),
100 m_type_id(OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NONE, OR_TYPEID_UNKNOWN)),
107 std::map<int32_t, MetaValue*>::iterator iter;
108 for(iter = m_metadata.begin();
109 iter != m_metadata.end(); ++iter)
122 std::map<int32_t, MetaValue*> m_metadata;
127 const char **RawFile::fileExtensions()
131 return RawFileFactory::fileExtensions();
135 RawFile *RawFile::newRawFile(
const char*_filename, RawFile::Type _typeHint)
140 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
141 type = identify(_filename);
146 Trace(DEBUG1) <<
"factory size " << RawFileFactory::table().size() <<
"\n";
147 RawFileFactory::Table::iterator iter = RawFileFactory::table().find(type);
148 if (iter == RawFileFactory::table().end()) {
149 Trace(WARNING) <<
"factory not found\n";
152 if (iter->second == NULL) {
153 Trace(WARNING) <<
"factory is NULL\n";
157 return iter->second(f);
160 RawFile *RawFile::newRawFileFromMemory(
const uint8_t *buffer,
162 RawFile::Type _typeHint)
166 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
167 ::or_error err = identifyBuffer(buffer, len, type);
168 if(err != OR_ERROR_NONE) {
169 Trace(ERROR) <<
"error identifying buffer\n";
176 RawFileFactory::Table::iterator iter = RawFileFactory::table().find(type);
177 if (iter == RawFileFactory::table().end()) {
178 Trace(WARNING) <<
"factory not found\n";
181 if (iter->second == NULL) {
182 Trace(WARNING) <<
"factory is NULL\n";
186 return iter->second(f);
190 RawFile::Type RawFile::identify(
const char*_filename)
192 const char *e = ::strrchr(_filename,
'.');
194 Trace(DEBUG1) <<
"Extension not found\n";
195 return OR_RAWFILE_TYPE_UNKNOWN;
197 std::string extension(e + 1);
198 if (extension.length() > 3) {
199 return OR_RAWFILE_TYPE_UNKNOWN;
202 boost::to_lower(extension);
204 RawFileFactory::Extensions & extensions = RawFileFactory::extensions();
205 RawFileFactory::Extensions::iterator iter = extensions.find(extension);
206 if (iter == extensions.end())
208 return OR_RAWFILE_TYPE_UNKNOWN;
213 ::or_error RawFile::identifyBuffer(
const uint8_t* buff,
size_t len,
214 RawFile::Type &_type)
216 _type = OR_RAWFILE_TYPE_UNKNOWN;
218 return OR_ERROR_BUF_TOO_SMALL;
220 if(memcmp(buff,
"\0MRM", 4) == 0) {
221 _type = OR_RAWFILE_TYPE_MRW;
222 return OR_ERROR_NONE;
224 if(memcmp(buff,
"II\x1a\0\0\0HEAPCCDR", 14) == 0) {
225 _type = OR_RAWFILE_TYPE_CRW;
226 return OR_ERROR_NONE;
228 if(memcmp(buff,
"IIRO", 4) == 0) {
229 _type = OR_RAWFILE_TYPE_ORF;
230 return OR_ERROR_NONE;
232 if((memcmp(buff,
"II\x2a\0", 4) == 0)
233 || (memcmp(buff,
"MM\0\x2a", 4) == 0)) {
236 if(memcmp(buff + 8,
"CR\x2", 3) == 0) {
237 _type = OR_RAWFILE_TYPE_CR2;
238 return OR_ERROR_NONE;
242 IO::Stream *s =
new IO::MemStream((
void*)buff, len);
243 boost::scoped_ptr<Internals::TiffEpFile> f(
new Internals::TiffEpFile(s, OR_RAWFILE_TYPE_TIFF));
246 const MetaValue *dng_version = f->getMetaValue(META_NS_TIFF | TIFF_TAG_DNG_VERSION);
248 Trace(DEBUG1) <<
"found DNG versions\n";
249 _type = OR_RAWFILE_TYPE_DNG;
250 return OR_ERROR_NONE;
253 const MetaValue *makev = f->getMetaValue(META_NS_TIFF | EXIF_TAG_MAKE);
255 std::string makes = makev->getString();
256 if(makes ==
"NIKON CORPORATION") {
257 _type = OR_RAWFILE_TYPE_NEF;
259 else if(makes ==
"SEIKO EPSON CORP."){
260 _type = OR_RAWFILE_TYPE_ERF;
262 else if(makes ==
"PENTAX Corporation ") {
263 _type = OR_RAWFILE_TYPE_PEF;
265 else if(makes ==
"SONY ") {
266 _type = OR_RAWFILE_TYPE_ARW;
268 else if(makes ==
"Canon") {
269 _type = OR_RAWFILE_TYPE_CR2;
275 return OR_ERROR_NONE;
312 Trace(DEBUG1) <<
"_enumThumbnailSizes init\n";
315 Trace(DEBUG1) <<
"_enumThumbnailSizes failed\n";
324 ::or_error ret = OR_ERROR_NOT_FOUND;
325 uint32_t smallest_bigger = 0xffffffff;
326 uint32_t biggest_smaller = 0;
327 uint32_t found_size = 0;
329 Trace(DEBUG1) <<
"requested size " << tsize <<
"\n";
333 std::vector<uint32_t>::const_iterator iter;
335 for (iter = sizes.begin(); iter != sizes.end(); ++iter) {
336 Trace(DEBUG1) <<
"current iter is " << *iter <<
"\n";
338 if (*iter > biggest_smaller) {
339 biggest_smaller = *iter;
342 else if(*iter > tsize) {
343 if(*iter < smallest_bigger) {
344 smallest_bigger = *iter;
353 if (found_size == 0) {
354 found_size = (smallest_bigger != 0xffffffff ?
355 smallest_bigger : biggest_smaller);
358 if (found_size != 0) {
359 Trace(DEBUG1) <<
"size " << found_size <<
" found\n";
364 Trace(DEBUG1) <<
"no size found\n";
365 ret = OR_ERROR_NOT_FOUND;
374 Trace(DEBUG1) <<
"getRawData()\n";
382 Trace(DEBUG1) <<
"options are " << options <<
"\n";
383 ::or_error ret =
getRawData(rawdata, options);
384 if(ret == OR_ERROR_NONE) {
385 if(rawdata.
dataType() != OR_DATA_TYPE_CFA) {
386 Trace(DEBUG1) <<
"wrong data type\n";
387 return OR_ERROR_INVALID_FORMAT;
390 or_cfa_pattern pattern;
392 pattern = rawdata.cfaPattern();
397 uint8_t *dst = (uint8_t *)bitmapdata.allocData(
sizeof(uint8_t) * 3 * x * y);
404 src = (uint16_t*)rawdata.data();
408 bimedian_demosaic(src, x, y, pattern, dst);
417 const MetaValue * value = getMetaValue(META_NS_TIFF
418 | EXIF_TAG_ORIENTATION);
423 idx = value->getInteger();
426 Trace(DEBUG1) <<
"wrong type - " << e.what() <<
"\n";
431 const MetaValue *RawFile::getMetaValue(int32_t meta_index)
434 std::map<int32_t, MetaValue*>::iterator iter = d->m_metadata.find(meta_index);
435 if(iter == d->m_metadata.end()) {
436 val = _getMetaValue(meta_index);
438 d->m_metadata[meta_index] = val;
448 RawFile::TypeId RawFile::_typeIdFromModel(
const std::string & model)
450 const struct camera_ids_t * p = d->m_cam_ids;
455 if(model == p->model) {
463 void RawFile::_setIdMap(
const camera_ids_t *map)
::or_error getThumbnail(uint32_t size, Thumbnail &thumbnail)
DataType dataType() const
::or_error getRawData(RawData &rawdata, uint32_t options)
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
virtual ::or_error _getRawData(RawData &data, uint32_t options)=0
void _setTypeId(TypeId _type_id)
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list)=0
virtual void setDimensions(uint32_t x, uint32_t y)
virtual ::or_error _getThumbnail(uint32_t size, Thumbnail &thumbnail)=0
const std::vector< uint32_t > & listThumbnailSizes(void)
void setDataType(DataType _type)
std::vector< uint32_t > m_sizes
base virtual class for IO