ciffcontainer.cpp

00001 /*
00002  * libopenraw - ciffcontainer.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 #include <cstring>
00022 #include <iostream>
00023 #include <boost/shared_ptr.hpp>
00024 
00025 #include <libopenraw/types.h>
00026 
00027 #include "io/file.h"
00028 #include "ciffcontainer.h"
00029 #include "debug.h"
00030 
00031 using namespace Debug;
00032 
00033 namespace OpenRaw {
00034     namespace Internals {
00035 
00036         namespace CIFF {
00037 
00038 
00039             RecordEntry::RecordEntry()
00040                 : typeCode(0), length(0), offset(0)
00041             {
00042             }
00043 
00044             bool RecordEntry::readFrom(CIFFContainer *container)
00045             {
00046                 bool ret;
00047                 IO::Stream *file = container->file();
00048                 ret = container->readUInt16(file, typeCode);
00049                 ret = container->readUInt32(file, length);
00050                 ret = container->readUInt32(file, offset);
00051                 return ret;
00052             }
00053 
00054             size_t RecordEntry::fetchData(Heap* heap, void* buf, size_t size)
00055             {
00056                 return heap->container()->fetchData(buf, 
00057                                                                                         offset + heap->offset(), size);
00058             }
00059 
00060 
00061             Heap::Heap(off_t start, off_t length, CIFFContainer * container)
00062                 : m_start(start),
00063                     m_length(length),
00064                     m_container(container),
00065                     m_records()
00066             {
00067             }
00068 
00069             std::vector<RecordEntry> & Heap::records()
00070             {
00071                 if (m_records.size() == 0) {
00072                     _loadRecords();
00073                 }
00074                 return m_records;
00075             }
00076 
00077 
00078             bool Heap::_loadRecords()
00079             {
00080                 IO::Stream *file = m_container->file();
00081                 file->seek(m_start + m_length - 4, SEEK_SET);
00082                 int32_t offset;
00083                 bool ret = m_container->readInt32(file, offset);
00084                     
00085                 if (ret) {
00086                     int16_t numRecords;
00087 
00088                     m_records.clear();
00089                     file->seek(m_start + offset, SEEK_SET);
00090                     ret = m_container->readInt16(file, numRecords);
00091                     if (!ret) 
00092                     {
00093                         Trace(DEBUG1) << "read failed: " << ret << "\n";
00094                     }
00095                     Trace(DEBUG2) << "numRecords " << numRecords << "\n";
00096                     int16_t i;
00097                     for (i = 0; i < numRecords; i++) {
00098                         m_records.push_back(RecordEntry());
00099                         m_records.back().readFrom(m_container);
00100                     }
00101                 }
00102                 return ret;
00103             }
00104 
00105 
00106 #if 0
00107             class OffsetTable {
00108                 uint16_t numRecords;/* the number tblArray elements */
00109                 RecordEntry tblArray[1];/* Array of the record entries */
00110             };
00111 #endif
00112 
00113 
00114             bool HeapFileHeader::readFrom(CIFFContainer *container)
00115             {
00116                 endian = RawContainer::ENDIAN_NULL;
00117                 bool ret = false;
00118                 IO::Stream *file = container->file();
00119                 int s = file->read(byteOrder, 2);
00120                 if (s == 2) {
00121                     if((byteOrder[0] == 'I') && (byteOrder[1] == 'I')) {
00122                         endian = RawContainer::ENDIAN_LITTLE;
00123                     }
00124                     else if((byteOrder[0] == 'M') && (byteOrder[1] == 'M')) {
00125                         endian = RawContainer::ENDIAN_BIG;
00126                     }
00127                     container->setEndian(endian);
00128                     ret = container->readUInt32(file, headerLength);
00129                     if (ret) {
00130                         ret = (file->read(type, 4) == 4);
00131                     }
00132                     if (ret) {
00133                         ret = (file->read(subType, 4) == 4);
00134                     }
00135                     if (ret) {
00136                         ret = container->readUInt32(file, version);
00137                     }
00138                 }
00139                 return ret;
00140             }
00141         }
00142         
00143         CIFFContainer::CIFFContainer(IO::Stream *file)
00144             : RawContainer(file, 0),
00145                 m_hdr(),
00146                 m_heap((CIFF::Heap*)NULL)
00147         {
00148             m_endian = _readHeader();
00149         }
00150 
00151         CIFFContainer::~CIFFContainer()
00152         {
00153         }
00154 
00155         CIFF::Heap::Ref CIFFContainer::heap()
00156         {
00157             if (m_heap == NULL) {
00158                 _loadHeap();
00159             }
00160             return m_heap;
00161         }
00162 
00163         bool CIFFContainer::_loadHeap()
00164         {
00165             bool ret = false;
00166             if (m_heap == NULL) {
00167                 if(m_endian != ENDIAN_NULL) {
00168                     off_t heapLength = m_file->filesize() - m_hdr.headerLength;
00169 
00170                     Trace(DEBUG1) << "heap len " << heapLength << "\n";
00171                     m_heap = CIFF::Heap::Ref(new CIFF::Heap(m_hdr.headerLength, 
00172                                                                                                     heapLength, this));
00173                     
00174                     ret = true;
00175                 }
00176                 else {
00177                     Trace(DEBUG1) << "Unknown endian\n";
00178                 }
00179             }
00180             return ret;
00181         }
00182 
00183 
00184         RawContainer::EndianType CIFFContainer::_readHeader()
00185         {
00186             EndianType endian = ENDIAN_NULL;
00187             m_hdr.readFrom(this);
00188             if ((::strncmp(m_hdr.type, "HEAP", 4) == 0)
00189                     && (::strncmp(m_hdr.subType, "CCDR", 4) == 0)) {
00190                 endian = m_hdr.endian;
00191             }
00192             return endian;
00193         }
00194 
00195     }
00196 }

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