rawfile.cpp

00001 /*
00002  * libopenraw - rawfile.cpp
00003  *
00004  * Copyright (C) 2006-2007 Hubert Figuiere
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
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 { // *iter == tsize
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             // no size found, let's fail gracefuly
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 

Generated on Tue Jun 17 11:47:26 2008 for libopenraw by  doxygen 1.5.6