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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 { // *iter == tsize
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             // no size found, let's fail gracefuly
00218             Trace(DEBUG1) << "no size found\n";
00219             ret = OR_ERROR_NOT_FOUND;
00220         }
00221 
00222         return ret;
00223     }
00224 
00225 }
00226 
00227 

Generated on Sat Jan 27 11:36:13 2007 for libopenraw by  doxygen 1.4.7