25 #include "ciffcontainer.hpp" 28 using namespace Debug;
39 auto file = container->file();
40 file->seek(offset, SEEK_SET);
42 ret = container->
readUInt32(file, imageHeight);
43 ret = container->
readUInt32(file, pixelAspectRatio);
44 ret = container->
readInt32(file, rotationAngle);
45 ret = container->
readUInt32(file, componentBitDepth);
46 ret = container->
readUInt32(file, colorBitDepth);
51 int32_t ImageSpec::exifOrientation()
const 53 int32_t orientation = 0;
54 switch(rotationAngle) {
71 RecordEntry::RecordEntry()
72 : typeCode(0), length(0), offset(0)
79 auto file = container->file();
86 size_t RecordEntry::fetchData(
Heap* heap,
void* buf,
size_t size)
const 89 offset + heap->
offset(), size);
96 m_container(_container),
99 Debug::Trace(DEBUG2) <<
"Heap @ " << start <<
" length = " 103 std::vector<RecordEntry> & Heap::records()
105 if (m_records.size() == 0) {
112 bool Heap::_loadRecords()
114 auto file = m_container->file();
115 file->seek(m_start + m_length - 4, SEEK_SET);
116 int32_t record_offset;
117 bool ret = m_container->
readInt32(file, record_offset);
123 file->seek(m_start + record_offset, SEEK_SET);
124 ret = m_container->
readInt16(file, numRecords);
126 Trace(DEBUG1) <<
"read failed: " << ret <<
"\n";
128 Trace(DEBUG2) <<
"numRecords " << numRecords <<
"\n";
130 m_records.reserve(numRecords);
131 for (i = 0; i < numRecords; i++) {
133 m_records.back().readFrom(m_container);
150 endian = RawContainer::ENDIAN_NULL;
152 auto file = container->file();
153 int s = file->read(byteOrder, 2);
155 if((byteOrder[0] ==
'I') && (byteOrder[1] ==
'I')) {
158 else if((byteOrder[0] ==
'M') && (byteOrder[1] ==
'M')) {
161 container->setEndian(endian);
162 ret = container->
readUInt32(file, headerLength);
164 ret = (file->read(type, 4) == 4);
167 ret = (file->read(subType, 4) == 4);
178 CIFFContainer::CIFFContainer(
const IO::Stream::Ptr &_file)
182 m_hasImageSpec(
false)
184 m_endian = _readHeader();
187 CIFFContainer::~CIFFContainer()
191 CIFF::Heap::Ref CIFFContainer::heap()
193 if (m_heap ==
nullptr) {
199 bool CIFFContainer::_loadHeap()
205 if (m_endian != ENDIAN_NULL) {
206 off_t heapLength = m_file->filesize() - m_hdr.headerLength;
208 Trace(DEBUG1) <<
"heap len " << heapLength <<
"\n";
209 m_heap = std::make_shared<CIFF::Heap>(m_hdr.headerLength,
215 Trace(DEBUG1) <<
"Unknown endian\n";
224 EndianType _endian = ENDIAN_NULL;
225 m_hdr.readFrom(
this);
226 if ((::strncmp(m_hdr.type,
"HEAP", 4) == 0)
227 && (::strncmp(m_hdr.subType,
"CCDR", 4) == 0)) {
228 _endian = m_hdr.endian;
233 CIFF::Heap::Ref CIFFContainer::getImageProps()
237 return CIFF::Heap::Ref();
240 auto & records = m_heap->records();
243 auto iter = std::find_if(records.cbegin(), records.cend(),
245 return e.isA(static_cast<uint16_t>(CIFF::TAG_IMAGEPROPS));
247 if (iter == records.end()) {
248 Trace(ERROR) <<
"Couldn't find the image properties.\n";
249 return CIFF::Heap::Ref();
252 m_imageprops = std::make_shared<CIFF::Heap>(
253 iter->offset + m_heap->offset(), iter->length,
this);
260 if(!m_hasImageSpec) {
261 CIFF::Heap::Ref props = getImageProps();
266 auto & propsRecs = props->records();
267 auto iter = std::find_if(propsRecs.cbegin(), propsRecs.cend(),
269 return e.isA(static_cast<uint16_t>(CIFF::TAG_IMAGEINFO));
271 if (iter == propsRecs.end()) {
272 Trace(ERROR) <<
"Couldn't find the image info.\n";
275 m_imagespec.readFrom(iter->offset + props->offset(),
this);
276 m_hasImageSpec =
true;
281 const CIFF::Heap::Ref CIFFContainer::getCameraProps()
284 CIFF::Heap::Ref props = getImageProps();
287 return CIFF::Heap::Ref();
289 auto & propsRecs = props->records();
290 auto iter = std::find_if(propsRecs.cbegin(), propsRecs.cend(),
292 return e.isA(static_cast<uint16_t>(CIFF::TAG_CAMERAOBJECT));
294 if (iter == propsRecs.end()) {
295 Trace(ERROR) <<
"Couldn't find the camera props.\n";
296 return CIFF::Heap::Ref();
298 m_cameraprops = std::make_shared<CIFF::Heap>(
299 iter->offset + props->offset(), iter->length,
this);
301 return m_cameraprops;
309 auto & records = m_heap->records();
311 auto iter = std::find_if(records.cbegin(), records.cend(),
313 return e.isA(static_cast<uint16_t>(CIFF::TAG_RAWIMAGEDATA));
316 if (iter != records.end()) {
size_t fetchData(void *buf, off_t offset, size_t buf_size)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
bool readUInt32(const IO::Stream::Ptr &f, uint32_t &v)
bool readUInt16(const IO::Stream::Ptr &f, uint16_t &v)
bool readInt32(const IO::Stream::Ptr &f, int32_t &v)
bool readInt16(const IO::Stream::Ptr &f, int16_t &v)