libopenraw
rafcontainer.cpp
1 /* -*- tab-width:4; c-basic-offset:4 -*- */
2 /*
3  * libopenraw - rafcontainer.cpp
4  *
5  * Copyright (C) 2011-2016 Hubert Figuiere
6  *
7  * This library is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <fcntl.h>
23 #include <string.h>
24 #include <memory>
25 
26 #include "rafcontainer.hpp"
27 #include "raffile.hpp"
28 #include "jfifcontainer.hpp"
29 #include "ifdfilecontainer.hpp"
30 #include "rafmetacontainer.hpp"
31 #include "io/stream.hpp"
32 #include "io/streamclone.hpp"
33 
34 namespace OpenRaw {
35 namespace Internals {
36 
37 RafContainer::RafContainer(const IO::Stream::Ptr &_file)
38  : RawContainer(_file, 0)
39  , m_read(false)
40  , m_version(0)
41  , m_jpegPreview(nullptr)
42  , m_cfaContainer(nullptr)
43  , m_metaContainer(nullptr)
44 {
45  memset((void*)&m_offsetDirectory, 0, sizeof(m_offsetDirectory));
46 }
47 
49 {
50  delete m_jpegPreview;
51  delete m_cfaContainer;
52  delete m_metaContainer;
53 }
54 
55 const std::string & RafContainer::getModel()
56 {
57  if(!m_read) {
58  _readHeader();
59  }
60  return m_model;
61 }
62 
63 IfdFileContainer * RafContainer::getCfaContainer()
64 {
65  if(!m_cfaContainer) {
66  if(!m_read) {
67  _readHeader();
68  }
69  if(m_offsetDirectory.cfaOffset && m_offsetDirectory.cfaLength) {
70  m_cfaContainer = new IfdFileContainer(
71  std::make_shared<IO::StreamClone>(
72  m_file, m_offsetDirectory.cfaOffset), 0);
73  }
74  }
75  return m_cfaContainer;
76 }
77 
78 JfifContainer * RafContainer::getJpegPreview()
79 {
80  if(!m_jpegPreview) {
81  if(!m_read) {
82  _readHeader();
83  }
84  if(m_offsetDirectory.jpegOffset && m_offsetDirectory.jpegLength) {
85  m_jpegPreview = new JfifContainer(
86  std::make_shared<IO::StreamClone>(
87  m_file, m_offsetDirectory.jpegOffset), 0);
88  }
89  }
90  return m_jpegPreview;
91 }
92 
93 RafMetaContainer * RafContainer::getMetaContainer()
94 {
95  if(!m_metaContainer) {
96  if(!m_read) {
97  _readHeader();
98  }
99  if(m_offsetDirectory.metaOffset && m_offsetDirectory.metaLength) {
100  m_metaContainer = new RafMetaContainer(
101  std::make_shared<IO::StreamClone>(
102  m_file, m_offsetDirectory.metaOffset));
103  }
104  }
105  return m_metaContainer;
106 }
107 
108 bool RafContainer::_readHeader()
109 {
110  char magic[29];
111  char model[33];
112  magic[28] = 0;
113  model[32] = 0;
114  m_read = true;
115 
116  m_file->read(magic, 28);
117 
118  if(strncmp(magic, RAF_MAGIC, RAF_MAGIC_LEN) != 0) {
119  // not a RAF file
120  return false;
121  }
122 
123  setEndian(ENDIAN_BIG);
124 
125  m_file->read(model, 32);
126  m_model = model;
127  readUInt32(m_file, m_version);
128  m_file->seek(20, SEEK_CUR);
129  readUInt32(m_file, m_offsetDirectory.jpegOffset);
130  readUInt32(m_file, m_offsetDirectory.jpegLength);
131  readUInt32(m_file, m_offsetDirectory.metaOffset);
132  readUInt32(m_file, m_offsetDirectory.metaLength);
133  readUInt32(m_file, m_offsetDirectory.cfaOffset);
134  readUInt32(m_file, m_offsetDirectory.cfaLength);
135 
136  return true;
137 }
138 
139 }
140 }
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
Definition: arwfile.cpp:30