libopenraw
rafcontainer.cpp
1/* -*- tab-width:4; c-basic-offset:4 indent-tabs-mode:t -*- */
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
34namespace OpenRaw {
35namespace Internals {
36
37RafContainer::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
55const std::string & RafContainer::getModel()
56{
57 if(!m_read) {
58 _readHeader();
59 }
60 return m_model;
61}
62
63IfdFileContainer * 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
78JfifContainer * 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
93RafMetaContainer * 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
108bool 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 auto result = readUInt32(m_file);
128 if (result.empty()) {
129 return false;
130 }
131 m_version = result.value();
132
133 m_file->seek(20, SEEK_CUR);
134
135 result = readUInt32(m_file);
136 if (result.empty()) {
137 return false;
138 }
139 m_offsetDirectory.jpegOffset = result.value();
140 result = readUInt32(m_file);
141 if (result.empty()) {
142 return false;
143 }
144 m_offsetDirectory.jpegLength = result.value();
145 result = readUInt32(m_file);
146 if (result.empty()) {
147 return false;
148 }
149 m_offsetDirectory.metaOffset = result.value();
150 result = readUInt32(m_file);
151 if (result.empty()) {
152 return false;
153 }
154 m_offsetDirectory.metaLength = result.value();
155 result = readUInt32(m_file);
156 if (result.empty()) {
157 return false;
158 }
159 m_offsetDirectory.cfaOffset = result.value();
160 result = readUInt32(m_file);
161 if (result.empty()) {
162 return false;
163 }
164 m_offsetDirectory.cfaLength = result.value();
165
166 return true;
167}
168
169}
170}
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition arwfile.cpp:30