rawfile.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cstring>
00023 #include <cassert>
00024 #include <map>
00025 #include <string>
00026
00027 #include <boost/algorithm/string.hpp>
00028 #include <boost/bind.hpp>
00029 #include <boost/checked_delete.hpp>
00030
00031 #include "debug.h"
00032
00033 #include <libopenraw/metadata.h>
00034 #include <libopenraw++/rawfile.h>
00035 #include <libopenraw++/thumbnail.h>
00036
00037 #include "cr2file.h"
00038 #include "neffile.h"
00039 #include "orffile.h"
00040 #include "arwfile.h"
00041 #include "peffile.h"
00042 #include "crwfile.h"
00043 #include "erffile.h"
00044 #include "dngfile.h"
00045 #include "mrwfile.h"
00046 #include "metavalue.h"
00047 #include "exception.h"
00048
00049 #include "rawfilefactory.h"
00050
00051 using std::string;
00052 using namespace Debug;
00053
00054 namespace OpenRaw {
00055
00056 using Internals::RawFileFactory;
00057
00058 void init(void)
00059 {
00060 static RawFileFactory fctcr2(OR_RAWFILE_TYPE_CR2,
00061 &Internals::CR2File::factory,
00062 "cr2");
00063 static RawFileFactory fctnef(OR_RAWFILE_TYPE_NEF,
00064 &Internals::NEFFile::factory,
00065 "nef");
00066 static RawFileFactory fctarw(OR_RAWFILE_TYPE_ARW,
00067 &Internals::ARWFile::factory,
00068 "arw");
00069 static RawFileFactory fctorf(OR_RAWFILE_TYPE_ORF,
00070 &Internals::ORFFile::factory,
00071 "orf");
00072 static RawFileFactory fctdng(OR_RAWFILE_TYPE_DNG,
00073 &Internals::DNGFile::factory,
00074 "dng");
00075 static RawFileFactory fctpef(OR_RAWFILE_TYPE_PEF,
00076 &Internals::PEFFile::factory,
00077 "pef");
00078 static RawFileFactory fctcrw(OR_RAWFILE_TYPE_CRW,
00079 &Internals::CRWFile::factory,
00080 "crw");
00081 static RawFileFactory fcterf(OR_RAWFILE_TYPE_ERF,
00082 &Internals::ERFFile::factory,
00083 "erf");
00084 static RawFileFactory fctmrw(OR_RAWFILE_TYPE_MRW,
00085 &Internals::MRWFile::factory,
00086 "mrw");
00087 }
00088
00089 class RawFile::Private
00090 {
00091 public:
00092 Private(std::string f, Type t)
00093 : m_filename(f),
00094 m_type(t),
00095 m_sizes()
00096 {
00097 }
00098 ~Private()
00099 {
00100 std::map<int32_t, MetaValue*>::iterator iter;
00101 for(iter = m_metadata.begin();
00102 iter != m_metadata.end(); ++iter)
00103 {
00104 if(iter->second) {
00105 delete iter->second;
00106 }
00107 }
00108 }
00110 std::string m_filename;
00112 Type m_type;
00114 std::vector<uint32_t> m_sizes;
00115 std::map<int32_t, MetaValue*> m_metadata;
00116 };
00117
00118
00119
00120 RawFile *RawFile::newRawFile(const char*_filename, RawFile::Type _typeHint)
00121 {
00122 init();
00123
00124 Type type;
00125 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
00126 type = identify(_filename);
00127 }
00128 else {
00129 type = _typeHint;
00130 }
00131 Trace(DEBUG1) << "factory size " << RawFileFactory::table().size() << "\n";
00132 RawFileFactory::Table::iterator iter = RawFileFactory::table().find(type);
00133 if (iter == RawFileFactory::table().end()) {
00134 Trace(WARNING) << "factory not found\n";
00135 return NULL;
00136 }
00137 if (iter->second == NULL) {
00138 Trace(WARNING) << "factory is NULL\n";
00139 return NULL;
00140 }
00141 return (*(iter->second))(_filename);
00142 }
00143
00144
00145 RawFile::Type RawFile::identify(const char*_filename)
00146 {
00147 const char *e = ::strrchr(_filename, '.');
00148 if (e == NULL) {
00149 Trace(DEBUG1) << "Extension not found\n";
00150 return OR_RAWFILE_TYPE_UNKNOWN;
00151 }
00152 std::string extension(e + 1);
00153 if (extension.length() > 3) {
00154 return OR_RAWFILE_TYPE_UNKNOWN;
00155 }
00156
00157 boost::to_lower(extension);
00158
00159 RawFileFactory::Extensions & extensions = RawFileFactory::extensions();
00160 RawFileFactory::Extensions::iterator iter = extensions.find(extension);
00161 if (iter == extensions.end())
00162 {
00163 return OR_RAWFILE_TYPE_UNKNOWN;
00164 }
00165 return iter->second;
00166 }
00167
00168
00169 RawFile::RawFile(const char * _filename, RawFile::Type _type)
00170 : d(new Private(_filename, _type))
00171 {
00172
00173 }
00174
00175
00176 RawFile::~RawFile()
00177 {
00178 delete d;
00179 }
00180
00181
00182 RawFile::Type RawFile::type() const
00183 {
00184 return d->m_type;
00185 }
00186
00187 const std::vector<uint32_t> & RawFile::listThumbnailSizes(void)
00188 {
00189 if (d->m_sizes.size() == 0) {
00190 Trace(DEBUG1) << "_enumThumbnailSizes init\n";
00191 bool ret = _enumThumbnailSizes(d->m_sizes);
00192 if (!ret) {
00193 Trace(DEBUG1) << "_enumThumbnailSizes failed\n";
00194 }
00195 }
00196 return d->m_sizes;
00197 }
00198
00199
00200 ::or_error RawFile::getThumbnail(uint32_t tsize, Thumbnail & thumbnail)
00201 {
00202 ::or_error ret = OR_ERROR_NOT_FOUND;
00203 uint32_t smallest_bigger = 0xffffffff;
00204 uint32_t biggest_smaller = 0;
00205 uint32_t found_size = 0;
00206
00207 Trace(DEBUG1) << "requested size " << tsize << "\n";
00208
00209 const std::vector<uint32_t> & sizes(listThumbnailSizes());
00210
00211 std::vector<uint32_t>::const_iterator iter;
00212
00213 for (iter = sizes.begin(); iter != sizes.end(); ++iter) {
00214 Trace(DEBUG1) << "current iter is " << *iter << "\n";
00215 if (*iter < tsize) {
00216 if (*iter > biggest_smaller) {
00217 biggest_smaller = *iter;
00218 }
00219 }
00220 else if(*iter > tsize) {
00221 if(*iter < smallest_bigger) {
00222 smallest_bigger = *iter;
00223 }
00224 }
00225 else {
00226 found_size = tsize;
00227 break;
00228 }
00229 }
00230
00231 if (found_size == 0) {
00232 found_size = (smallest_bigger != 0xffffffff ?
00233 smallest_bigger : biggest_smaller);
00234 }
00235
00236 if (found_size != 0) {
00237 Trace(DEBUG1) << "size " << found_size << " found\n";
00238 ret = _getThumbnail(found_size, thumbnail);
00239 }
00240 else {
00241
00242 Trace(DEBUG1) << "no size found\n";
00243 ret = OR_ERROR_NOT_FOUND;
00244 }
00245
00246 return ret;
00247 }
00248
00249
00250 ::or_error RawFile::getRawData(RawData & rawdata, uint32_t options)
00251 {
00252 Trace(DEBUG1) << "getRawData()\n";
00253 ::or_error ret = _getRawData(rawdata, options);
00254 return ret;
00255 }
00256
00257
00258 int32_t RawFile::getOrientation()
00259 {
00260 int32_t idx = 0;
00261 const MetaValue * value = getMetaValue(META_NS_TIFF
00262 | EXIF_TAG_ORIENTATION);
00263 if(value == NULL) {
00264 return 0;
00265 }
00266 try {
00267 idx = value->getInteger();
00268 }
00269 catch(const Internals::BadTypeException & e) {
00270 Trace(DEBUG1) << "wrong type - " << e.what() << "\n";
00271 }
00272 return idx;
00273 }
00274
00275 const MetaValue *RawFile::getMetaValue(int32_t meta_index)
00276 {
00277 MetaValue *val = NULL;
00278 std::map<int32_t, MetaValue*>::iterator iter = d->m_metadata.find(meta_index);
00279 if(iter == d->m_metadata.end()) {
00280 val = _getMetaValue(meta_index);
00281 if(val != NULL) {
00282 d->m_metadata[meta_index] = val;
00283 }
00284 }
00285 else {
00286 val = iter->second;
00287 }
00288 return val;
00289 }
00290
00291 }
00292
00293