1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong DID 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 #include "codec_jpeg_helper.h"
16 #include <ashmem.h>
17 #include <cerrno>
18 #include <cinttypes>
19 #include <cstring>
20 #include <memory>
21 #include <securec.h>
22 #include "codec_log_wrapper.h"
23 namespace OHOS {
24 namespace VDI {
25 namespace JPEG {
JpegAssemble(const struct CodecJpegDecInfo & decInfo,int8_t * buffer,int32_t fd)26 int32_t CodecJpegHelper::JpegAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t fd)
27 {
28 CODEC_LOGI("enter");
29 int32_t curPos = 0;
30 // SOI
31 curPos = PutInt16(buffer, curPos, 0xffd8);
32 if (curPos < 0) {
33 CODEC_LOGE("assemble SOI error");
34 return -1;
35 }
36
37 // DQT
38 curPos = JpegDqtAssemble(decInfo, buffer, curPos);
39 if (curPos < 0) {
40 CODEC_LOGE("assemble DQT error");
41 return -1;
42 }
43
44 // DHT
45 curPos = JpegDhtAssemble(decInfo, buffer, curPos);
46 if (curPos < 0) {
47 CODEC_LOGE("assemble DHT error");
48 return -1;
49 }
50 // DRI
51 curPos = JpegDriAssemble(decInfo, buffer, curPos);
52 if (curPos < 0) {
53 CODEC_LOGE("assemble DRI error");
54 return -1;
55 }
56
57 // SOF
58 curPos = JpegSofAssemble(decInfo, buffer, curPos);
59 if (curPos < 0) {
60 CODEC_LOGE("assemble SOF error");
61 return -1;
62 }
63 // SOS
64 curPos = JpegSosAssemble(decInfo, buffer, curPos);
65 if (curPos < 0) {
66 CODEC_LOGE("assemble SOS error");
67 return -1;
68 }
69 // DATA
70 curPos = JpegDataAssemble(buffer, curPos, fd);
71 if (curPos < 0) {
72 CODEC_LOGE("assemble CompressedData error");
73 return -1;
74 }
75 // EOI
76 curPos = PutInt16(buffer, curPos, 0xffd9);
77 if (curPos < 0) {
78 CODEC_LOGE("assemble EOI error");
79 return -1;
80 }
81 return curPos;
82 }
83
DessambleJpeg(int8_t * buffer,size_t bufferLen,struct CodecJpegDecInfo & decInfo,std::unique_ptr<int8_t[]> & compressBuffer,int32_t & comBufLen)84 bool CodecJpegHelper::DessambleJpeg(int8_t *buffer, size_t bufferLen, struct CodecJpegDecInfo &decInfo,
85 std::unique_ptr<int8_t[]> &compressBuffer, int32_t &comBufLen)
86 {
87 CODEC_LOGI("enter");
88 int8_t *start = buffer;
89 const int8_t *end = buffer + bufferLen;
90 while (start < end) {
91 JpegMarker marker = (JpegMarker)FindMarker(start);
92 start += 2; // 2: marker len
93 switch (marker) {
94 case SOI:
95 case EOI:
96 break;
97 case SOF0:
98 start += DessambleSof(start, decInfo);
99 break;
100 case DHT:
101 start += DessambleDht(start, decInfo);
102 break;
103 case SOS: {
104 start += DessambleSos(start, decInfo);
105 // compressed data start
106 auto len = DessambleCompressData(start, compressBuffer, comBufLen);
107 if (len < 0) {
108 CODEC_LOGE("copy compressed data error");
109 return false;
110 }
111 start += len;
112 break;
113 }
114
115 case DQT:
116 start += DessambleDqt(start, decInfo);
117 break;
118 case DRI: {
119 start += 2; // 2: marker len
120 decInfo.restartInterval = GetInt16(start);
121 start += 2; // 2: interval len
122 break;
123 }
124 default: {
125 short len = GetInt16(start);
126 start += len;
127 CODEC_LOGW("skip marker[%{public}x], len[%{public}d]", marker, len);
128 break;
129 }
130 }
131 }
132 return true;
133 }
JpegDqtAssemble(const struct CodecJpegDecInfo & decInfo,int8_t * buffer,int32_t curPos)134 int32_t CodecJpegHelper::JpegDqtAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos)
135 {
136 CODEC_LOGI("enter. curPos = %{public}d, quantTbl.size= %{public}zu", curPos, decInfo.quantTbl.size());
137 // flag
138 curPos = PutInt16(buffer, curPos, 0xffdb);
139 if (curPos < 0) {
140 CODEC_LOGE("assemble DQT flag error");
141 return curPos;
142 }
143
144 // skip len first
145 int32_t lenPos = curPos;
146 curPos += 2; // 2: marker len
147
148 // data
149 for (size_t i = 0; i < decInfo.quantTbl.size(); i++) {
150 if (!decInfo.quantTbl[i].tableFlag) {
151 break;
152 }
153 uint8_t index = 0; // precision 1: 16bit, 0: 8bit, deault:0
154 if (decInfo.quantTbl[i].quantVal.size() == 64) { // 64: quant table length
155 index = 1;
156 }
157 index = (index << 4) | i; // precision << 4 | tableid
158 curPos = PutInt8(buffer, curPos, index);
159 if (curPos < 0) {
160 CODEC_LOGE("assemble precision and tableid error");
161 return curPos;
162 }
163
164 for (size_t j = 0; j < decInfo.quantTbl[i].quantVal.size(); j++) {
165 #ifdef JPEG_DEBUG
166 CODEC_LOGD("decInfo.quantTbl[%{public}d].quantVal[%{public}d] = %{public}d", i, j,
167 decInfo.quantTbl[i].quantVal[j]);
168 #endif
169 curPos = PutInt16(buffer, curPos, decInfo.quantTbl[i].quantVal[j]);
170 }
171 }
172 int16_t bufferLen = static_cast<int16_t>(curPos - lenPos);
173 auto ret = PutInt16(buffer, lenPos, bufferLen);
174 if (ret < 0) {
175 CODEC_LOGE("assemble len error");
176 return ret;
177 }
178 return curPos;
179 }
JpegDriAssemble(const struct CodecJpegDecInfo & decInfo,int8_t * buffer,int32_t curPos)180 int32_t CodecJpegHelper::JpegDriAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos)
181 {
182 CODEC_LOGI("enter, restartInterval = %{public}d curPos = %{public}d", decInfo.restartInterval, curPos);
183 if (decInfo.restartInterval <= 0) {
184 return curPos;
185 }
186 curPos = PutInt16(buffer, curPos, 0xffdd);
187 if (curPos < 0) {
188 CODEC_LOGE("assemble DRI flag error");
189 return curPos;
190 }
191
192 curPos = PutInt16(buffer, curPos, 4); // 4: dri data len( marker len included)
193 if (curPos < 0) {
194 CODEC_LOGE("assemble DRI len error");
195 return curPos;
196 }
197
198 curPos = PutInt16(buffer, curPos, decInfo.restartInterval);
199 if (curPos < 0) {
200 CODEC_LOGE("assemble dri value error");
201 return curPos;
202 }
203 return curPos;
204 }
JpegDhtAssemble(const struct CodecJpegDecInfo & decInfo,int8_t * buffer,int32_t curPos)205 int32_t CodecJpegHelper::JpegDhtAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos)
206 {
207 CODEC_LOGI("enter. curPos = %{public}d", curPos);
208 curPos = JpegDhtAssemble(decInfo.dcHuffTbl, buffer, curPos);
209 if (curPos < 0) {
210 CODEC_LOGE("assemble dc hufman error");
211 return curPos;
212 }
213
214 curPos = JpegDhtAssemble(decInfo.acHuffTbl, buffer, curPos, false);
215 if (curPos < 0) {
216 CODEC_LOGE("assemble ac hufman error");
217 }
218 return curPos;
219 }
JpegDhtAssemble(const std::vector<CodecJpegHuffTable> & table,int8_t * buffer,int32_t curPos,bool dc)220 int32_t CodecJpegHelper::JpegDhtAssemble(
221 const std::vector<CodecJpegHuffTable> &table, int8_t *buffer, int32_t curPos, bool dc)
222 {
223 CODEC_LOGI("enter. curPos = %{public}d, table.size() = %{public}zu", curPos, table.size());
224 // DC Hufman
225 curPos = PutInt16(buffer, curPos, 0xffc4);
226 if (curPos < 0) {
227 CODEC_LOGE("assemble hufman flag error");
228 return curPos;
229 }
230 // skip len
231 int32_t lenPos = curPos;
232 curPos += 2; // 2: marker len
233 for (size_t i = 0; i < table.size(); i++) {
234 if (!table[i].tableFlag) {
235 break;
236 }
237 uint8_t type = 0; // type 0:DC, 1:AC
238 if (!dc) {
239 type = 1;
240 }
241 type = (type << 4) | i; // type << 4 | tableid
242 curPos = PutInt8(buffer, curPos, type);
243 if (curPos < 0) {
244 CODEC_LOGE("assemble tableid and dc/ac error");
245 return curPos;
246 }
247 // bits
248 auto ret = memcpy_s(buffer + curPos, table[i].bits.size(), table[i].bits.data(), table[i].bits.size());
249 if (ret != EOK) {
250 char buf[MAX_BUFFER_LEN] = {0};
251 strerror_r(errno, buf, sizeof(buf));
252 CODEC_LOGE("assemble bits error ret = %{public}s", buf);
253 return ret;
254 }
255 curPos += table[i].bits.size();
256 // val
257 ret = memcpy_s(buffer + curPos, table[i].huffVal.size(), table[i].huffVal.data(), table[i].huffVal.size());
258 if (ret != EOK) {
259 CODEC_LOGE("assemble huffVal error, ret = %{public}d", ret);
260 return ret;
261 }
262 curPos += table[i].huffVal.size();
263 }
264 int16_t bufferLen = static_cast<int16_t>(curPos - lenPos);
265 auto ret = PutInt16(buffer, lenPos, bufferLen);
266 if (ret < 0) {
267 CODEC_LOGE("assemble len error");
268 return ret;
269 }
270 return curPos;
271 }
272
JpegSofAssemble(const struct CodecJpegDecInfo & decInfo,int8_t * buffer,int32_t curPos)273 int32_t CodecJpegHelper::JpegSofAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos)
274 {
275 CODEC_LOGI("enter. curPos = %{public}d", curPos);
276 // flag
277 curPos = PutInt16(buffer, curPos, 0xffc0);
278 if (curPos < 0) {
279 CODEC_LOGE("assemble SOF flag error");
280 return curPos;
281 }
282
283 int16_t len = decInfo.numComponents * 3 + 8;
284 curPos = PutInt16(buffer, curPos, len);
285 if (curPos < 0) {
286 CODEC_LOGE("assemble SOF len error");
287 return curPos;
288 }
289
290 int8_t precision = decInfo.dataPrecision & 0xFF;
291 curPos = PutInt8(buffer, curPos, precision);
292 if (curPos < 0) {
293 CODEC_LOGE("assemble SOF precision error");
294 return curPos;
295 }
296
297 // width
298 int16_t width = decInfo.imageHeight & 0xFFFF;
299 curPos = PutInt16(buffer, curPos, width);
300 if (curPos < 0) {
301 CODEC_LOGE("assemble SOF width error");
302 return curPos;
303 }
304
305 // height
306 int16_t height = decInfo.imageWidth & 0xFFFF;
307 curPos = PutInt16(buffer, curPos, height);
308 if (curPos < 0) {
309 CODEC_LOGE("assemble SOF width error");
310 return curPos;
311 }
312 // components
313 int8_t components = decInfo.numComponents & 0xFF;
314 curPos = PutInt8(buffer, curPos, components);
315 if (curPos < 0) {
316 CODEC_LOGE("assemble SOF components error");
317 return curPos;
318 }
319 for (size_t i = 0; i < decInfo.compInfo.size(); i++) {
320 int8_t componentId = decInfo.compInfo[i].componentId;
321 int8_t sampFactor = ((decInfo.compInfo[i].hSampFactor & 0xFF) << 4) | (decInfo.compInfo[i].vSampFactor & 0xFF);
322 int8_t quantity = decInfo.compInfo[i].quantTableNo;
323 int8_t bufferValue[] = {componentId, sampFactor, quantity};
324 auto ret = memcpy_s(buffer + curPos, sizeof(bufferValue), bufferValue, sizeof(bufferValue));
325 if (ret != EOK) {
326 CODEC_LOGE("assemble component error, ret = %{public}d", ret);
327 return ret;
328 }
329 curPos += sizeof(bufferValue);
330 }
331 return curPos;
332 }
JpegSosAssemble(const struct CodecJpegDecInfo & decInfo,int8_t * buffer,int32_t curPos)333 int32_t CodecJpegHelper::JpegSosAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos)
334 {
335 CODEC_LOGI("enter. curPos = %{public}d", curPos);
336 // flag
337 curPos = PutInt16(buffer, curPos, 0xffda);
338 if (curPos < 0) {
339 CODEC_LOGE("assemble SOS flag error");
340 return curPos;
341 }
342
343 int16_t len = decInfo.numComponents * 2 + 6;
344 curPos = PutInt16(buffer, curPos, len);
345 if (curPos < 0) {
346 CODEC_LOGE("assemble SOS len error");
347 return curPos;
348 }
349
350 int8_t components = decInfo.numComponents & 0xFF;
351 curPos = PutInt8(buffer, curPos, components);
352 if (curPos < 0) {
353 CODEC_LOGE("assemble SOS components error");
354 return curPos;
355 }
356
357 for (size_t i = 0; i < decInfo.compInfo.size(); i++) {
358 int8_t componentId = decInfo.compInfo[i].componentId;
359 int8_t indexNo = ((decInfo.compInfo[i].dcTableNo & 0xFF) << 4) | (decInfo.compInfo[i].acTableNo & 0xFF);
360 int16_t value = ((componentId << 8) | indexNo) & 0xffff;
361 curPos = PutInt16(buffer, curPos, value);
362 if (curPos < 0) {
363 CODEC_LOGE("assemble SOS component value error");
364 return curPos;
365 }
366 }
367 int8_t dataStart[] = {0x00, 0x3F, 0x00};
368 auto ret = memcpy_s(buffer + curPos, sizeof(dataStart), dataStart, sizeof(dataStart));
369 if (ret != EOK) {
370 CODEC_LOGE("assemble SOS data flag error, ret = %{public}d", ret);
371 return ret;
372 }
373 curPos += sizeof(dataStart);
374 return curPos;
375 }
JpegDataAssemble(int8_t * buffer,int32_t curPos,int32_t fd)376 int32_t CodecJpegHelper::JpegDataAssemble(int8_t *buffer, int32_t curPos, int32_t fd)
377 {
378 CODEC_LOGI("enter. curPos = %{public}d", curPos);
379 int32_t size = OHOS::AshmemGetSize(fd);
380 OHOS::Ashmem mem(fd, size);
381 // check ret value
382 mem.MapReadOnlyAshmem();
383 auto addr = const_cast<void *>(mem.ReadFromAshmem(0, 0));
384 auto ret = memcpy_s(buffer + curPos, size, addr, size);
385 if (ret != EOK) {
386 CODEC_LOGE("assemble compressed data error, ret = %{public}d", ret);
387 mem.UnmapAshmem();
388 if (ret > 0) {
389 return -ret;
390 }
391 return ret;
392 }
393 mem.UnmapAshmem();
394 mem.CloseAshmem();
395 curPos += size;
396 return curPos;
397 }
398
DessambleSof(int8_t * buffer,struct CodecJpegDecInfo & decInfo)399 int32_t CodecJpegHelper::DessambleSof(int8_t *buffer, struct CodecJpegDecInfo &decInfo)
400 {
401 CODEC_LOGI("dessamble SOI");
402 // len
403 int32_t len = GetInt16(buffer);
404 buffer += 2; // 2: marker len
405 // precision
406 decInfo.dataPrecision = GetInt8(buffer);
407 buffer++;
408 // height
409 decInfo.imageHeight = GetInt16(buffer);
410 buffer += 2; // 2: height len
411 // width
412 decInfo.imageWidth = GetInt16(buffer);
413 buffer += 2; // 2: width len
414
415 decInfo.numComponents = GetInt8(buffer);
416 buffer++;
417
418 #ifdef JPEG_DEBUG
419 CODEC_LOGD("image width[%{public}d],height[%{public}d],components[%{public}d]", decInfo.imageWidth,
420 decInfo.imageHeight, decInfo.numComponents);
421 #endif
422 for (size_t i = 0; i < decInfo.numComponents; i++) {
423 CodecJpegCompInfo comInfo;
424
425 comInfo.infoFlag = true;
426 comInfo.componentId = GetInt8(buffer);
427 buffer++;
428
429 int8_t sampFactor = GetInt8(buffer);
430 buffer++;
431 comInfo.hSampFactor = (sampFactor >> 4) & 0xFF; // 4: hsampfactor offset
432 comInfo.vSampFactor = sampFactor & 0x0F;
433
434 comInfo.quantTableNo = GetInt8(buffer);
435 buffer++;
436 decInfo.compInfo.push_back(std::move(comInfo));
437 #ifdef JPEG_DEBUG
438 CODEC_LOGD("componentId[%{public}d],hSampFactor[%{public}d],vSampFactor[%{public}d],quantTableNo[%{public}d]",
439 comInfo.componentId, comInfo.hSampFactor, comInfo.vSampFactor, comInfo.quantTableNo);
440 #endif
441 }
442 return len;
443 }
DessambleSos(int8_t * buffer,struct CodecJpegDecInfo & decInfo)444 int32_t CodecJpegHelper::DessambleSos(int8_t *buffer, struct CodecJpegDecInfo &decInfo)
445 {
446 CODEC_LOGI("dessamble SOS");
447 int32_t len = GetInt16(buffer);
448 buffer += 2; // 2:marker len
449
450 int32_t components = GetInt8(buffer);
451 buffer++;
452
453 for (int32_t i = 0; i < components; i++) {
454 decInfo.compInfo[i].infoFlag = true;
455
456 int32_t componentId = GetInt8(buffer);
457 (void)componentId;
458 buffer++;
459 // index not used
460 auto data = GetInt8(buffer);
461 buffer++;
462 decInfo.compInfo[i].dcTableNo = (data >> 4) & 0x0F; // 4: dctable offset
463 decInfo.compInfo[i].acTableNo = data & 0x0F;
464 #ifdef JPEG_DEBUG
465 CODEC_LOGD("componentId[%{public}d],dcTableNo[%{public}d],acTableNo[%{public}d]", componentId,
466 decInfo.compInfo[i].dcTableNo, decInfo.compInfo[i].acTableNo);
467 #endif
468 }
469 buffer += 3; // skip 0x003F00
470 return len;
471 }
DessambleCompressData(int8_t * buffer,std::unique_ptr<int8_t[]> & compressBuffer,int32_t & comBufLen)472 int32_t CodecJpegHelper::DessambleCompressData(
473 int8_t *buffer, std::unique_ptr<int8_t[]> &compressBuffer, int32_t &comBufLen)
474 {
475 int8_t *dataStart = buffer;
476 int32_t v = 0xff;
477 do {
478 v = GetInt8(buffer);
479 buffer++;
480 if (v != 0xff) {
481 continue;
482 }
483 v = GetInt8(buffer);
484 buffer++;
485 if (v != 0xd9) {
486 continue;
487 }
488 buffer -= 2; // 2: marker len
489 break;
490 } while (1);
491 comBufLen = (int32_t)(buffer - dataStart);
492 compressBuffer = std::make_unique<int8_t[]>(comBufLen);
493 auto ret = memcpy_s(compressBuffer.get(), comBufLen, dataStart, comBufLen);
494 if (ret != EOK) {
495 CODEC_LOGE("copy compressed data error, dataLen %{public}d, ret %{public}d", comBufLen, ret);
496 compressBuffer = nullptr;
497 return ret;
498 }
499 return comBufLen;
500 }
DessambleDqt(int8_t * buffer,struct CodecJpegDecInfo & decInfo)501 int32_t CodecJpegHelper::DessambleDqt(int8_t *buffer, struct CodecJpegDecInfo &decInfo)
502 {
503 CODEC_LOGI("dessamble DQT");
504 int8_t *bufferOri = buffer;
505 int32_t len = GetInt16(buffer);
506 buffer += 2; // 2: marker len
507 // maybe has more dqt table
508 while ((buffer - bufferOri) < len) {
509 auto data = GetInt8(buffer);
510 buffer++;
511 int32_t tableId = data & 0x000f;
512 (void)tableId;
513 int32_t dqtbufferSize = 64; // dqt base size
514 if (((data >> 4) & 0x0f) == 1) { // 4: low 4 bits, 1: for 16 bits
515 dqtbufferSize *= 2; // 2: 16bits has double size
516 }
517 CodecJpegQuantTable table;
518 table.tableFlag = true;
519 #ifdef JPEG_DEBUG
520 CODEC_LOGD("tableid[%{public}d]", tableId);
521 #endif
522 for (int32_t i = 0; i < dqtbufferSize / 2; i++) { // 2: 16bits has double size
523 table.quantVal.push_back(static_cast<int16_t>(GetInt16(buffer)));
524 buffer += 2; // 2: data offset
525 }
526 decInfo.quantTbl.push_back(std::move(table));
527 }
528 return len;
529 }
DessambleDht(int8_t * buffer,struct CodecJpegDecInfo & decInfo)530 int32_t CodecJpegHelper::DessambleDht(int8_t *buffer, struct CodecJpegDecInfo &decInfo)
531 {
532 CODEC_LOGI("dessamble DHT");
533 int8_t *bufferOri = buffer;
534 int32_t len = GetInt16(buffer);
535 buffer += 2; // 2: marker len
536 // 可能存在多个表在同一个dht marker 中
537 while ((buffer - bufferOri) < len) {
538 auto data = GetInt8(buffer);
539 buffer++;
540 int32_t tableId = data & 0x000f;
541 (void)tableId;
542 int32_t acOrDc = (data >> 4) & 0x0f; // 0:DC, 1:AC, 4: ac/dc data offset
543 CodecJpegHuffTable table;
544 table.tableFlag = true;
545 int32_t num = 0;
546 for (size_t i = 0; i < 16; i++) { // 16: Data size
547 auto data = GetInt8(buffer);
548 buffer++;
549 table.bits.push_back(data);
550 num += data & 0x00ff;
551 }
552 #ifdef JPEG_DEBUG
553 CODEC_LOGD("tableid[%{public}d], acOrDc[%{public}d], num[%{public}d]", tableId, acOrDc, num);
554 #endif
555 // val
556 for (int32_t i = 0; i < num; i++) {
557 table.huffVal.push_back(*buffer++);
558 }
559 if (acOrDc == 1) {
560 decInfo.acHuffTbl.push_back(std::move(table));
561 } else {
562 decInfo.dcHuffTbl.push_back(std::move(table));
563 }
564 }
565 return len;
566 }
567
FindMarker(int8_t * start)568 int32_t CodecJpegHelper::FindMarker(int8_t *start)
569 {
570 int32_t marker = GetInt16(start);
571 return marker;
572 }
573
PutInt16(int8_t * buffer,int32_t curPos,int16_t value)574 int32_t CodecJpegHelper::PutInt16(int8_t *buffer, int32_t curPos, int16_t value)
575 {
576 int8_t data[] = {value >> 8, value & 0xFF};
577 auto ret = memcpy_s(buffer + curPos, sizeof(data), data, sizeof(data));
578 if (ret != EOK) {
579 CODEC_LOGE("memcpy ret err %{public}d", ret);
580 return -1;
581 }
582 return curPos + sizeof(data);
583 }
584
PutInt8(int8_t * buffer,int32_t curPos,int8_t value)585 int32_t CodecJpegHelper::PutInt8(int8_t *buffer, int32_t curPos, int8_t value)
586 {
587 auto ret = memcpy_s(buffer + curPos, sizeof(value), &value, sizeof(value));
588 if (ret != EOK) {
589 CODEC_LOGE("memcpy ret err %{public}d", ret);
590 return -1;
591 }
592 return curPos + sizeof(value);
593 }
594
GetInt8(int8_t * buffer)595 int32_t CodecJpegHelper::GetInt8(int8_t *buffer)
596 {
597 return buffer[0] & 0x00ff;
598 }
599
GetInt16(int8_t * buffer)600 int32_t CodecJpegHelper::GetInt16(int8_t *buffer)
601 {
602 return ((buffer[0] << 8) & 0x00ff00) | (buffer[1] & 0x00ff); // 8:data offset
603 }
604 } // namespace JPEG
605 } // namespace VDI
606 } // namespace OHOS