libopenraw
orffile.cpp
00001 /*
00002  * libopenraw - orffile.cpp
00003  *
00004  * Copyright (C) 2006, 2008, 2010 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 License
00008  * as published by the Free Software Foundation, either version 3 of
00009  * 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, see
00018  * <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 #include <libopenraw++/thumbnail.h>
00022 #include <libopenraw++/rawdata.h>
00023 
00024 #include "trace.h"
00025 #include "orffile.h"
00026 #include "ifd.h"
00027 #include "ifddir.h"
00028 #include "ifdentry.h"
00029 #include "orfcontainer.h"
00030 #include "io/file.h"
00031 
00032 using namespace Debug;
00033 
00034 namespace OpenRaw {
00035 namespace Internals {
00036 
00037         const struct IFDFile::camera_ids_t OrfFile::s_def[] = {
00038             { "E-1             ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00039                                                        OR_TYPEID_OLYMPUS_E1) },
00040             { "E-10        "    , OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00041                                                   OR_TYPEID_OLYMPUS_E10) },
00042             { "E-3             ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00043                                                       OR_TYPEID_OLYMPUS_E3) },
00044             { "E-300           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00045                                                       OR_TYPEID_OLYMPUS_E300) },
00046             { "E-330           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00047                                                       OR_TYPEID_OLYMPUS_E330) },
00048             { "E-400           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00049                                                       OR_TYPEID_OLYMPUS_E400) },
00050             { "E-410           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00051                                                       OR_TYPEID_OLYMPUS_E410) },
00052             { "E-500           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00053                                                       OR_TYPEID_OLYMPUS_E500) },
00054             { "E-510           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00055                                                       OR_TYPEID_OLYMPUS_E510) },
00056             { "SP350"           , OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00057                                                       OR_TYPEID_OLYMPUS_SP350) },
00058             { "SP500UZ"         , OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00059                                                       OR_TYPEID_OLYMPUS_SP500) },
00060             { "SP510UZ"         , OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00061                                                       OR_TYPEID_OLYMPUS_SP510) },
00062             { "SP550UZ                ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00063                                                       OR_TYPEID_OLYMPUS_SP550) },
00064             { "E-P1            ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00065                                                       OR_TYPEID_OLYMPUS_EP1) },
00066             { "E-620           ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_OLYMPUS, 
00067                                                       OR_TYPEID_OLYMPUS_E620) },
00068             { 0, 0 }
00069         };
00070 
00071         RawFile *OrfFile::factory(IO::Stream *s)
00072         {
00073             return new OrfFile(s);
00074         }
00075 
00076 
00077         OrfFile::OrfFile(IO::Stream *s)
00078             : IFDFile(s, OR_RAWFILE_TYPE_ORF, false)
00079         {
00080             _setIdMap(s_def);
00081             m_container = new OrfContainer(m_io, 0);
00082         }
00083         
00084         OrfFile::~OrfFile()
00085         {
00086         }
00087 
00088         IFDDir::Ref  OrfFile::_locateCfaIfd()
00089         {
00090             // in ORF the CFA IFD is the main IFD
00091             if(!m_mainIfd) {
00092                 m_mainIfd = _locateMainIfd();
00093             }
00094             return m_mainIfd;
00095         }
00096 
00097 
00098         IFDDir::Ref  OrfFile::_locateMainIfd()
00099         {
00100             return m_container->setDirectory(0);
00101         }
00102 
00103 
00104         
00105         ::or_error OrfFile::_getRawData(RawData & data, uint32_t options)
00106         {
00107             ::or_error err;
00108             if(!m_cfaIfd) {
00109                 m_cfaIfd = _locateCfaIfd();
00110             }
00111             err = _getRawDataFromDir(data, m_cfaIfd);
00112             if(err == OR_ERROR_NONE) {
00113                 // ORF files seems to be marked as uncompressed even if they are.
00114                 uint32_t x = data.x();
00115                 uint32_t y = data.y();
00116                 uint16_t compression = 0;
00117                 if(data.size() < x * y * 2) {
00118                     compression = 65535;
00119                     data.setCompression(65535);
00120                     data.setDataType(OR_DATA_TYPE_COMPRESSED_CFA);
00121                 }
00122                 else {
00123                     compression = data.compression();
00124                 }
00125                 switch(compression) {
00126                 case 65535:
00127                     if((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
00128                         // TODO decompress
00129                     }
00130                     break;
00131                 default:
00132                     break;
00133                 }
00134             }
00135             return err;
00136         }
00137 
00138 }
00139 }
00140