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
00029 #include "debug.h"
00030
00031 #include <libopenraw++/rawfile.h>
00032 #include <libopenraw++/thumbnail.h>
00033
00034 #include "cr2file.h"
00035 #include "neffile.h"
00036 #include "orffile.h"
00037 #include "arwfile.h"
00038 #include "peffile.h"
00039 #include "crwfile.h"
00040 #include "dngfile.h"
00041
00042 #include "rawfilefactory.h"
00043
00044 using std::string;
00045 using namespace Debug;
00046
00047 namespace OpenRaw {
00048
00049 using Internals::RawFileFactory;
00050
00051 void init(void)
00052 {
00053 static RawFileFactory fctcr2(OR_RAWFILE_TYPE_CR2,
00054 &Internals::CR2File::factory,
00055 "cr2");
00056 static RawFileFactory fctnef(OR_RAWFILE_TYPE_NEF,
00057 &Internals::NEFFile::factory,
00058 "nef");
00059 static RawFileFactory fctarw(OR_RAWFILE_TYPE_ARW,
00060 &Internals::ARWFile::factory,
00061 "arw");
00062 static RawFileFactory fctorf(OR_RAWFILE_TYPE_ORF,
00063 &Internals::ORFFile::factory,
00064 "orf");
00065 static RawFileFactory fctdng(OR_RAWFILE_TYPE_DNG,
00066 &Internals::DNGFile::factory,
00067 "dng");
00068 static RawFileFactory fctpef(OR_RAWFILE_TYPE_PEF,
00069 &Internals::PEFFile::factory,
00070 "pef");
00071 static RawFileFactory fctcrw(OR_RAWFILE_TYPE_CRW,
00072 &Internals::CRWFile::factory,
00073 "crw");
00074 }
00075
00076 class RawFile::Private
00077 {
00078 public:
00079 Private(std::string f, Type t)
00080 : m_filename(f),
00081 m_type(t),
00082 m_sizes()
00083 {
00084 }
00085
00087 std::string m_filename;
00089 Type m_type;
00091 std::vector<uint32_t> m_sizes;
00092 };
00093
00094
00095
00096 RawFile *RawFile::newRawFile(const char*_filename, RawFile::Type _typeHint)
00097 {
00098 init();
00099
00100 Type type;
00101 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
00102 type = identify(_filename);
00103 }
00104 else {
00105 type = _typeHint;
00106 }
00107 Trace(DEBUG1) << "factory size " << RawFileFactory::table().size() << "\n";
00108 RawFileFactory::Table::iterator iter = RawFileFactory::table().find(type);
00109 if (iter == RawFileFactory::table().end()) {
00110 Trace(WARNING) << "factory not found\n";
00111 return NULL;
00112 }
00113 if (iter->second == NULL) {
00114 Trace(WARNING) << "factory is NULL\n";
00115 return NULL;
00116 }
00117 return (*(iter->second))(_filename);
00118 }
00119
00120
00121 RawFile::Type RawFile::identify(const char*_filename)
00122 {
00123 const char *e = ::strrchr(_filename, '.');
00124 if (e == NULL) {
00125 Trace(DEBUG1) << "Extension not found\n";
00126 return OR_RAWFILE_TYPE_UNKNOWN;
00127 }
00128 std::string extension(e + 1);
00129 if (extension.length() > 3) {
00130 return OR_RAWFILE_TYPE_UNKNOWN;
00131 }
00132
00133 boost::to_lower(extension);
00134
00135 RawFileFactory::Extensions & extensions = RawFileFactory::extensions();
00136 RawFileFactory::Extensions::iterator iter = extensions.find(extension);
00137 if (iter == extensions.end())
00138 {
00139 return OR_RAWFILE_TYPE_UNKNOWN;
00140 }
00141 return iter->second;
00142 }
00143
00144
00145 RawFile::RawFile(const char * _filename, RawFile::Type _type)
00146 : d(new Private(_filename, _type))
00147 {
00148
00149 }
00150
00151
00152 RawFile::~RawFile()
00153 {
00154 delete d;
00155 }
00156
00157
00158 RawFile::Type RawFile::type() const
00159 {
00160 return d->m_type;
00161 }
00162
00163 const std::vector<uint32_t> & RawFile::listThumbnailSizes(void)
00164 {
00165 if (d->m_sizes.size() == 0) {
00166 Trace(DEBUG1) << "_enumThumbnailSizes init\n";
00167 bool ret = _enumThumbnailSizes(d->m_sizes);
00168 if (!ret) {
00169 Trace(DEBUG1) << "_enumThumbnailSizes failed\n";
00170 }
00171 }
00172 return d->m_sizes;
00173 }
00174
00175
00176 ::or_error RawFile::getThumbnail(uint32_t tsize, Thumbnail & thumbnail)
00177 {
00178 ::or_error ret = OR_ERROR_NOT_FOUND;
00179 uint32_t smallest_bigger = 0xffffffff;
00180 uint32_t biggest_smaller = 0;
00181 uint32_t found_size = 0;
00182
00183 Trace(DEBUG1) << "requested size " << tsize << "\n";
00184
00185 const std::vector<uint32_t> & sizes(listThumbnailSizes());
00186
00187 std::vector<uint32_t>::const_iterator iter;
00188
00189 for (iter = sizes.begin(); iter != sizes.end(); ++iter) {
00190 Trace(DEBUG1) << "current iter is " << *iter << "\n";
00191 if (*iter < tsize) {
00192 if (*iter > biggest_smaller) {
00193 biggest_smaller = *iter;
00194 }
00195 }
00196 else if(*iter > tsize) {
00197 if(*iter < smallest_bigger) {
00198 smallest_bigger = *iter;
00199 }
00200 }
00201 else {
00202 found_size = tsize;
00203 break;
00204 }
00205 }
00206
00207 if (found_size == 0) {
00208 found_size = (smallest_bigger != 0xffffffff ?
00209 smallest_bigger : biggest_smaller);
00210 }
00211
00212 if (found_size != 0) {
00213 Trace(DEBUG1) << "size " << found_size << " found\n";
00214 ret = _getThumbnail(found_size, thumbnail);
00215 }
00216 else {
00217
00218 Trace(DEBUG1) << "no size found\n";
00219 ret = OR_ERROR_NOT_FOUND;
00220 }
00221
00222 return ret;
00223 }
00224
00225 }
00226
00227