libopenraw
rafmetacontainer.cpp
1/* -*- tab-width:4; c-basic-offset:4 -*- */
2/*
3 * libopenraw - rafcontainer.cpp
4 *
5 * Copyright (C) 2011-2017 Hubert Figuière
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 <stdlib.h>
23
24#include <cstdint>
25#include <string>
26#include <utility>
27
28#include "trace.hpp"
29#include "metavalue.hpp"
30#include "rafmetacontainer.hpp"
31#include "io/stream.hpp"
32
33namespace OpenRaw {
34namespace Internals {
35
36RafMetaValue::RafMetaValue(uint16_t tag, uint16_t size, const MetaValue & v)
37 : m_tag(tag)
38 , m_size(size)
39 , m_value(v)
40{
41}
42
43RafMetaValue::~RafMetaValue()
44{
45}
46
47RafMetaContainer::RafMetaContainer(const IO::Stream::Ptr &_file)
48 : RawContainer(_file, 0)
49 , m_count(0)
50{
51 setEndian(ENDIAN_BIG);
52}
53
54uint32_t RafMetaContainer::count()
55{
56 if(m_count == 0) {
57 _read();
58 }
59 return m_count;
60}
61
62RafMetaValue::Ref RafMetaContainer::getValue(uint16_t tag)
63{
64 if(m_tags.empty()) {
65 _read();
66 }
67 std::map<uint16_t, RafMetaValue::Ref>::const_iterator iter = m_tags.find(tag);
68 if(iter != m_tags.end()) {
69 return iter->second;
70 }
71 return RafMetaValue::Ref();
72}
73
74void RafMetaContainer::_read()
75{
76 auto result = readUInt32(m_file);
77 if (result.empty()) {
78 LOGERR("Couldn't read RAF meta count\n");
79 return;
80 }
81 m_count = result.value();
82
83 for(uint32_t i = 0; i < m_count; i++) {
84 auto result16 = readUInt16(m_file);
85 if (result16.empty()) {
86 return;
87 }
88 uint16_t tag = result16.value();
89
90 result16 = readUInt16(m_file);
91 if (result16.empty()) {
92 return;
93 }
94 uint16_t sz = result16.value();
95
96 MetaValue::value_t v;
97 if (sz == 4) {
98 auto result32 = readUInt32(m_file);
99 if (result32) {
100 v = MetaValue::value_t(result32.value());
101 }
102 } else {
103 char *content;
104 content = (char*)calloc(1, sz + 1);
105 content[sz] = 0;
106 m_file->read(content, sz);
107 v = MetaValue::value_t(std::string(content));
108 free(content);
109 }
110
111 RafMetaValue::Ref value = std::make_shared<RafMetaValue>(tag, sz, MetaValue(v));
112 m_tags.insert(std::make_pair(tag, value));
113 }
114}
115
116}
117}
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30