1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "heif_stream.h"
17 #include "heif_constant.h"
18 #include "securec.h"
19
20 #include <sstream>
21
22 const uint8_t BUFFER_INDEX_FOUR = 4;
23 const uint8_t BUFFER_INDEX_FIVE = 5;
24 const uint8_t BUFFER_INDEX_SIX = 6;
25 const uint8_t BUFFER_INDEX_SEVEN = 7;
26
27 namespace OHOS {
28 namespace ImagePlugin {
HeifBufferInputStream(const uint8_t * data,size_t size,bool needCopy)29 HeifBufferInputStream::HeifBufferInputStream(const uint8_t *data, size_t size, bool needCopy)
30 : length_(size), pos_(0), copied_(needCopy)
31 {
32 if (copied_) {
33 auto *copiedData = new uint8_t[length_];
34 memcpy_s(copiedData, length_, data, length_);
35 data_ = copiedData;
36 } else {
37 data_ = data;
38 }
39 }
40
~HeifBufferInputStream()41 HeifBufferInputStream::~HeifBufferInputStream()
42 {
43 if (copied_) {
44 delete[] data_;
45 }
46 }
47
Tell() const48 int64_t HeifBufferInputStream::Tell() const
49 {
50 return pos_;
51 }
52
CheckSize(size_t target_size,int64_t end)53 bool HeifBufferInputStream::CheckSize(size_t target_size, int64_t end)
54 {
55 auto posAfterRead = Tell() + static_cast<int64_t>(target_size);
56 return (end < 0 || posAfterRead <= end) && static_cast<size_t>(posAfterRead) <= length_;
57 }
58
Read(void * data,size_t size)59 bool HeifBufferInputStream::Read(void *data, size_t size)
60 {
61 auto end_pos = static_cast<size_t>(pos_) + size;
62 if (static_cast<size_t>(end_pos) > length_) {
63 return false;
64 }
65
66 if (memcpy_s(data, size, &data_[pos_], size) != EOK) {
67 return false;
68 }
69 pos_ = pos_ + static_cast<int64_t>(size);
70
71 return true;
72 }
73
Seek(int64_t position)74 bool HeifBufferInputStream::Seek(int64_t position)
75 {
76 if (static_cast<size_t>(position) > length_ || position < 0)
77 return false;
78
79 pos_ = position;
80 return true;
81 }
82
HeifStreamReader(std::shared_ptr<HeifInputStream> stream,int64_t start,size_t length)83 HeifStreamReader::HeifStreamReader(std::shared_ptr<HeifInputStream> stream, int64_t start, size_t length)
84 : inputStream_(std::move(stream)), start_(start)
85 {
86 end_ = start_ + static_cast<int64_t>(length);
87 }
88
Read8()89 uint8_t HeifStreamReader::Read8()
90 {
91 if (!CheckSize(UINT8_BYTES_NUM)) {
92 return 0;
93 }
94 uint8_t buf;
95 auto stream = GetStream();
96 bool success = stream->Read(&buf, UINT8_BYTES_NUM);
97 if (!success) {
98 SetError(true);
99 return 0;
100 }
101 return buf;
102 }
103
Read16()104 uint16_t HeifStreamReader::Read16()
105 {
106 if (!CheckSize(UINT16_BYTES_NUM)) {
107 return 0;
108 }
109 uint8_t buf[UINT16_BYTES_NUM];
110 auto stream = GetStream();
111 bool success = stream->Read(buf, UINT16_BYTES_NUM);
112 if (!success) {
113 SetError(true);
114 return 0;
115 }
116 return static_cast<uint16_t>((buf[BUFFER_INDEX_ZERO] << ONE_BYTE_SHIFT) | (buf[BUFFER_INDEX_ONE]));
117 }
118
Read32()119 uint32_t HeifStreamReader::Read32()
120 {
121 if (!CheckSize(UINT32_BYTES_NUM)) {
122 return 0;
123 }
124 uint8_t buf[UINT32_BYTES_NUM];
125 auto stream = GetStream();
126 bool success = stream->Read(buf, UINT32_BYTES_NUM);
127 if (!success) {
128 SetError(true);
129 return 0;
130 }
131 return static_cast<uint32_t>((buf[BUFFER_INDEX_ZERO] << THREE_BYTES_SHIFT) |
132 (buf[BUFFER_INDEX_ONE] << TWO_BYTES_SHIFT) |
133 (buf[BUFFER_INDEX_TWO] << ONE_BYTE_SHIFT) |
134 (buf[BUFFER_INDEX_THREE]));
135 }
136
Read64()137 uint64_t HeifStreamReader::Read64()
138 {
139 if (!CheckSize(UINT64_BYTES_NUM)) {
140 return 0;
141 }
142 uint8_t buf[UINT64_BYTES_NUM];
143 auto stream = GetStream();
144 bool success = stream->Read(buf, UINT64_BYTES_NUM);
145 if (!success) {
146 SetError(true);
147 return 0;
148 }
149 return static_cast<uint64_t>(((uint64_t)buf[BUFFER_INDEX_ZERO] << SEVEN_BYTES_SHIFT) |
150 ((uint64_t)buf[BUFFER_INDEX_ONE] << SIX_BYTES_SHIFT) |
151 ((uint64_t)buf[BUFFER_INDEX_TWO] << FIVE_BYTES_SHIFT) |
152 ((uint64_t)buf[BUFFER_INDEX_THREE] << FOUR_BYTES_SHIFT) |
153 ((uint64_t)buf[BUFFER_INDEX_FOUR] << THREE_BYTES_SHIFT) |
154 ((uint64_t)buf[BUFFER_INDEX_FIVE] << TWO_BYTES_SHIFT) |
155 ((uint64_t)buf[BUFFER_INDEX_SIX] << ONE_BYTE_SHIFT) |
156 ((uint64_t)buf[BUFFER_INDEX_SEVEN]));
157 }
158
ReadData(uint8_t * data,size_t size)159 bool HeifStreamReader::ReadData(uint8_t *data, size_t size)
160 {
161 if (!CheckSize(size)) {
162 return false;
163 }
164 bool res = GetStream()->Read(data, size);
165 if (!res) {
166 SetError(true);
167 }
168 return res;
169 }
170
ReadString()171 std::string HeifStreamReader::ReadString()
172 {
173 if (IsAtEnd()) {
174 return {};
175 }
176 std::stringstream strStream;
177 auto stream = GetStream();
178 char strChar = UINT8_BYTES_NUM;
179 while (strChar != 0) {
180 if (!CheckSize(UINT8_BYTES_NUM)) {
181 return {};
182 }
183 bool res = stream->Read(&strChar, UINT8_BYTES_NUM);
184 if (!res) {
185 SetError(true);
186 return {};
187 }
188 if (strChar != 0) {
189 strStream << strChar;
190 }
191 }
192 return strStream.str();
193 }
194
CheckSize(size_t size)195 bool HeifStreamReader::CheckSize(size_t size)
196 {
197 bool res = inputStream_->CheckSize(size, end_);
198 if (!res) {
199 SetError(true);
200 }
201 return res;
202 }
203
CheckSize(size_t size)204 void HeifStreamWriter::CheckSize(size_t size)
205 {
206 size_t posAfterMove = position_ + size;
207 if (posAfterMove > data_.size()) {
208 data_.resize(posAfterMove);
209 }
210 }
211
Write8(uint8_t value)212 void HeifStreamWriter::Write8(uint8_t value)
213 {
214 if (position_ == data_.size()) {
215 data_.push_back(value);
216 position_++;
217 } else {
218 data_[position_++] = value;
219 }
220 }
221
Write16(uint16_t value)222 void HeifStreamWriter::Write16(uint16_t value)
223 {
224 CheckSize(UINT16_BYTES_NUM);
225 data_[position_++] = uint8_t((value >> ONE_BYTE_SHIFT) & 0xFF);
226 data_[position_++] = uint8_t(value & 0xFF);
227 }
228
Write32(uint32_t value)229 void HeifStreamWriter::Write32(uint32_t value)
230 {
231 CheckSize(UINT32_BYTES_NUM);
232 data_[position_++] = uint8_t((value >> THREE_BYTES_SHIFT) & 0xFF);
233 data_[position_++] = uint8_t((value >> TWO_BYTES_SHIFT) & 0xFF);
234 data_[position_++] = uint8_t((value >> ONE_BYTE_SHIFT) & 0xFF);
235 data_[position_++] = uint8_t(value & 0xFF);
236 }
237
Write64(uint64_t value)238 void HeifStreamWriter::Write64(uint64_t value)
239 {
240 CheckSize(UINT64_BYTES_NUM);
241 data_[position_++] = uint8_t((value >> SEVEN_BYTES_SHIFT) & 0xFF);
242 data_[position_++] = uint8_t((value >> SIX_BYTES_SHIFT) & 0xFF);
243 data_[position_++] = uint8_t((value >> FIVE_BYTES_SHIFT) & 0xFF);
244 data_[position_++] = uint8_t((value >> FOUR_BYTES_SHIFT) & 0xFF);
245 data_[position_++] = uint8_t((value >> THREE_BYTES_SHIFT) & 0xFF);
246 data_[position_++] = uint8_t((value >> TWO_BYTES_SHIFT) & 0xFF);
247 data_[position_++] = uint8_t((value >> ONE_BYTE_SHIFT) & 0xFF);
248 data_[position_++] = uint8_t(value & 0xFF);
249 }
250
Write(int size,uint64_t value)251 void HeifStreamWriter::Write(int size, uint64_t value)
252 {
253 switch (size) {
254 case UINT8_BYTES_NUM: {
255 Write8((uint8_t) value);
256 break;
257 }
258 case UINT16_BYTES_NUM: {
259 Write16((uint16_t) value);
260 break;
261 }
262 case UINT32_BYTES_NUM: {
263 Write32((uint32_t) value);
264 break;
265 }
266 case UINT64_BYTES_NUM:
267 Write64((uint64_t) value);
268 break;
269 default:
270 break;
271 }
272 }
273
Write(const std::string & str)274 void HeifStreamWriter::Write(const std::string &str)
275 {
276 CheckSize(str.size() + UINT8_BYTES_NUM);
277 for (char ch : str) {
278 data_[position_++] = ch;
279 }
280 data_[position_++] = 0;
281 }
282
Write(const std::vector<uint8_t> & data)283 void HeifStreamWriter::Write(const std::vector<uint8_t> &data)
284 {
285 CheckSize(data.size());
286 if (EOK != memcpy_s(data_.data() + position_, data_.size() - position_, data.data(), data.size())) {
287 return;
288 }
289 position_ += data.size();
290 }
291
Skip(size_t skipSize)292 void HeifStreamWriter::Skip(size_t skipSize)
293 {
294 CheckSize(skipSize);
295 position_ += skipSize;
296 }
297
Insert(size_t insertSize)298 void HeifStreamWriter::Insert(size_t insertSize)
299 {
300 if (insertSize == 0) {
301 return;
302 }
303 size_t sizeToMove = data_.size() - position_;
304 void *pCurrent = data_.data() + position_;
305 void *pAfterMove = reinterpret_cast<uint8_t*>(pCurrent) + insertSize;
306 data_.resize(data_.size() + insertSize);
307 if (EOK != memmove_s(pAfterMove, sizeToMove, pCurrent, sizeToMove)) {
308 return;
309 }
310 }
311 } // namespace ImagePlugin
312 } // namespace OHOS
313