RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
Buffer.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5 Copyright (C) 2017 Axel Waggershauser
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
9 License as published by the Free Software Foundation; either
10 version 2 of 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, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#pragma once
23
24#include "rawspeedconfig.h"
25#include "adt/Array1DRef.h"
26#include "adt/Casts.h"
27#include "io/Endianness.h"
28#include "io/IOException.h"
29#include <cassert>
30#include <cstdint>
31#include <utility>
32
33#ifndef NDEBUG
34#include "AddressSanitizer.h"
35#endif
36
37namespace rawspeed {
38
39/*************************************************************************
40 * This is the buffer abstraction.
41 *
42 * It allows access to some piece of memory, typically a whole or part
43 * of a raw file. The underlying memory is never owned by the buffer.
44 * It intentionally supports only read/const access to the underlying memory.
45 *
46 *************************************************************************/
47class Buffer {
48public:
50
51protected:
52 const uint8_t* data = nullptr;
53
54private:
56
57public:
58 Buffer() = default;
59
60 // NOLINTNEXTLINE(google-explicit-constructor)
66
67 explicit Buffer(const uint8_t* data_, size_type size_)
68 : Buffer(Array1DRef(data_, implicit_cast<int>(size_))) {}
69
71 return {data, implicit_cast<int>(size)};
72 }
73
74 explicit operator Array1DRef<const uint8_t>() const {
75 return getAsArray1DRef();
76 }
77
78 [[nodiscard]] Buffer getSubView(size_type offset, size_type size_) const {
79 if (!isValid(offset, size_))
80 ThrowIOE("Buffer overflow: image file may be truncated");
81
82 return getAsArray1DRef().getCrop(offset, size_).getAsArray1DRef();
83 }
84
85 [[nodiscard]] Buffer getSubView(size_type offset) const {
86 if (!isValid(0, offset))
87 ThrowIOE("Buffer overflow: image file may be truncated");
88
89 size_type newSize = getSize() - offset;
90 return getSubView(offset, newSize);
91 }
92
93 // convenience getter for single bytes
94 uint8_t operator[](size_type offset) const {
95 return getAsArray1DRef()(offset);
96 }
97
98 // std begin/end iterators to allow for range loop
99 [[nodiscard]] const uint8_t* begin() const {
100 return getAsArray1DRef().begin();
101 }
102 [[nodiscard]] const uint8_t* end() const { return getAsArray1DRef().end(); }
103
104 // get memory of type T from byte offset 'offset + sizeof(T)*index' and swap
105 // byte order if required
106 template <typename T>
107 [[nodiscard]] T get(bool inNativeByteOrder, size_type offset,
108 size_type index = 0) const {
109 const Buffer buf =
110 getSubView(offset + (index * static_cast<size_type>(sizeof(T))),
111 static_cast<size_type>(sizeof(T)));
112 return getByteSwapped<T>(buf.begin(), !inNativeByteOrder);
113 }
114
115 [[nodiscard]] size_type RAWSPEED_READONLY getSize() const { return size; }
116
117 [[nodiscard]] bool isValid(size_type offset, size_type count = 1) const {
118 return static_cast<uint64_t>(offset) + count <=
119 static_cast<uint64_t>(getSize());
120 }
121};
122
123// WARNING: both buffers must belong to the same allocation, else this is UB!
124inline bool operator<(Buffer lhs, Buffer rhs) {
125 return std::pair(lhs.begin(), lhs.end()) < std::pair(rhs.begin(), rhs.end());
126}
127
128/*
129 * DataBuffer is a simple extension to Buffer. It knows about the byte order
130 * of its contents and can therefore provide save access to larger than
131 * byte sized data, like int, float, etc.
132 */
133class DataBuffer : public Buffer {
134 // FIXME: default should be Endianness::unknown !
135
137
138public:
139 DataBuffer() = default;
140
141 explicit DataBuffer(Buffer data_, Endianness endianness_)
142 : Buffer(data_), endianness(endianness_) {}
143
144 // get memory of type T from byte offset 'offset + sizeof(T)*index' and swap
145 // byte order if required
146 template <typename T>
147 [[nodiscard]] T get(size_type offset, size_type index = 0) const {
150
151 return Buffer::get<T>(getHostEndianness() == endianness, offset, index);
152 }
153
154 [[nodiscard]] Endianness getByteOrder() const { return endianness; }
155
157 std::swap(endianness, endianness_);
158 return endianness_;
159 }
160};
161
162} // namespace rawspeed
#define ThrowIOE(...)
Definition IOException.h:37
assert(dim.area() >=area)
CroppedArray1DRef< T > getCrop(int offset, int numElts) const
Definition Array1DRef.h:110
T * end() const
T * begin() const
Buffer()=default
DataBuffer()=default
Buffer(const uint8_t *data_, size_type size_)
Definition Buffer.h:67
Buffer()=default
Array1DRef< const uint8_t > getAsArray1DRef() const
Definition Buffer.h:70
Buffer getSubView(size_type offset, size_type size_) const
Definition Buffer.h:78
bool isValid(size_type offset, size_type count=1) const
Definition Buffer.h:117
Buffer(Array1DRef< const uint8_t > data_)
Definition Buffer.h:61
const uint8_t * begin() const
Definition Buffer.h:99
const uint8_t * end() const
Definition Buffer.h:102
T get(bool inNativeByteOrder, size_type offset, size_type index=0) const
Definition Buffer.h:107
size_type size
Definition Buffer.h:55
size_type RAWSPEED_READONLY getSize() const
Definition Buffer.h:115
Buffer getSubView(size_type offset) const
Definition Buffer.h:85
const uint8_t * data
Definition Buffer.h:52
uint32_t size_type
Definition Buffer.h:49
uint8_t operator[](size_type offset) const
Definition Buffer.h:94
Endianness getByteOrder() const
Definition Buffer.h:154
Endianness setByteOrder(Endianness endianness_)
Definition Buffer.h:156
DataBuffer(Buffer data_, Endianness endianness_)
Definition Buffer.h:141
Endianness endianness
Definition Buffer.h:136
T get(size_type offset, size_type index=0) const
Definition Buffer.h:147
bool operator<(const Range< T > &lhs, const Range< T > &rhs)
Definition Range.h:48
constexpr RAWSPEED_READNONE Ttgt implicit_cast(Tsrc value)
Definition Casts.h:32
int8_t getByteSwapped(int8_t v)
Definition Endianness.h:75
throw T(buf.data())
Endianness getHostEndianness()
Definition Endianness.h:51
void RAWSPEED_UNLIKELY_FUNCTION RAWSPEED_NOINLINE static char buf[bufSize]
static bool RegionIsPoisoned(const volatile void *addr, size_t size)