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