ifddir.cpp

00001 /*
00002  * libopenraw - ifddir.cpp
00003  *
00004  * Copyright (C) 2006 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 <libopenraw/types.h>
00023 
00024 #include "debug.h"
00025 #include "exception.h"
00026 #include "ifd.h"
00027 #include "io/stream.h"
00028 #include "ifdfilecontainer.h"
00029 #include "ifddir.h"
00030 
00031 using namespace Debug;
00032 
00033 namespace OpenRaw {
00034 
00035     namespace Internals {
00036 
00037         IFDDir::IFDDir(off_t _offset, IFDFileContainer & _container)
00038             : m_offset(_offset), m_container(_container), 
00039                 m_entries()
00040         {
00041             
00042         }
00043 
00044         IFDDir::~IFDDir()
00045         {
00046 
00047         }
00048 
00049         bool IFDDir::load()
00050         {
00051             Trace(DEBUG1) << "IFDDir::load() m_offset =" << m_offset << "\n";
00052             int16_t numEntries = 0;
00053             IO::Stream *file = m_container.file();
00054             m_entries.clear();
00055             file->seek(m_offset, SEEK_SET);
00056             m_container.readInt16(file, numEntries);
00057 
00058             Trace(DEBUG1) << "num =" << numEntries << "\n";
00059 
00060             for(int16_t i = 0; i < numEntries; i++) {
00061                 int16_t id;
00062                 int16_t type;
00063                 int32_t count;
00064                 uint32_t data;
00065                 m_container.readInt16(file, id);
00066                 m_container.readInt16(file, type);
00067                 m_container.readInt32(file, count);
00068                 file->read(&data, 4);
00069                 IFDEntry::Ref entry(new IFDEntry(id, type, 
00070                                                                                  count, data, m_container));
00071                 Trace(DEBUG1) << "adding elem for " << id << "\n";
00072                 m_entries[id] = entry;
00073             }
00074 
00075             return true;
00076         }
00077 
00078         IFDEntry::Ref IFDDir::getEntry(int id)
00079         {
00080             return m_entries[id];
00081         }
00082 
00083 
00084         bool IFDDir::getIntegerValue(int id, uint32_t &v)
00085         {
00086             bool success = false;
00087             IFDEntry::Ref e = getEntry(id);
00088             if (e != NULL) {
00089                 try {
00090                     switch(e->type())
00091                     {
00092                     case IFD::EXIF_FORMAT_LONG:
00093                         v = e->getLong();
00094                         success = true;
00095                         break;
00096                     case IFD::EXIF_FORMAT_SHORT:
00097                         v = e->getShort();
00098                         success = true;
00099                         break;
00100                     default:
00101                         break;
00102                     }
00103                 }
00104                 catch(std::exception & e) {
00105                     Trace(ERROR) << "Exception raised " << e.what() 
00106                                              << " fetch integer value for " << id << "\n";
00107                 }
00108             }
00109             return success;
00110         }
00111 
00112 
00113         bool IFDDir::getLongValue(int id, uint32_t &v)
00114         {
00115             bool success = false;
00116             IFDEntry::Ref e = getEntry(id);
00117             if (e != NULL) {
00118                 try {
00119                     v = e->getLong();
00120                     success = true;
00121                 }
00122                 catch(std::exception & e) {
00123                     Trace(ERROR) << "Exception raised " << e.what() 
00124                                              << " fetch long value for " << id << "\n";
00125                 }
00126             }
00127             return success;
00128         }
00129 
00130 
00131         bool IFDDir::getShortValue(int id, uint16_t &v)
00132         {
00133             bool success = false;
00134             IFDEntry::Ref e = getEntry(id);
00135             if (e != NULL) {
00136                 try {
00137                     v = e->getShort();
00138                     success = true;
00139                 }
00140                 catch(std::exception & e) {
00141                     Trace(ERROR) << "Exception raised " << e.what() 
00142                                              << " fetch long value for " << id << "\n";
00143                 }
00144             }
00145             return success;
00146         }
00147 
00148         off_t IFDDir::nextIFD()
00149         {
00150             int16_t numEntries;
00151             IO::Stream *file = m_container.file();
00152 
00153             if(m_entries.size() == 0) {
00154                 file->seek(m_offset, SEEK_SET);
00155                 m_container.readInt16(file, numEntries);
00156                 Trace(DEBUG1) << "numEntries =" << numEntries 
00157                                     << " shifting " << (numEntries * 12) + 2
00158                                     << "bytes\n";
00159             }
00160             else {
00161                 numEntries = m_entries.size();
00162             }
00163 
00164             file->seek(m_offset + (numEntries * 12) + 2, SEEK_SET);
00165             int32_t next;
00166             m_container.readInt32(file, next);
00167             return next;
00168         }
00169         
00173         IFDDir::Ref IFDDir::getSubIFD()
00174         {
00175             bool success;
00176             uint32_t offset = 0;
00177             success = getLongValue(IFD::EXIF_TAG_SUB_IFDS, offset);
00178             if (success) {
00179                 Ref ref(new IFDDir(offset, m_container));
00180             }
00181             return Ref(static_cast<IFDDir*>(NULL));
00182         }
00183 
00187         IFDDir::Ref IFDDir::getExifIFD()
00188         {
00189             bool success;
00190             uint32_t offset = 0;
00191             success = getLongValue(IFD::EXIF_TAG_EXIF_IFD_POINTER, offset);
00192             if (success) {
00193                 Ref ref(new IFDDir(offset, m_container));
00194             }
00195             return Ref(static_cast<IFDDir*>(NULL));
00196         }
00197 
00198     }
00199 }
00200 

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