1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong DID Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "codec_jpeg_helper.h" 17094332d3Sopenharmony_ci#include <ashmem.h> 18094332d3Sopenharmony_ci#include <cerrno> 19094332d3Sopenharmony_ci#include <cstring> 20094332d3Sopenharmony_ci#include <securec.h> 21094332d3Sopenharmony_ci#include "hdf_log.h" 22094332d3Sopenharmony_ci 23094332d3Sopenharmony_cistatic int8_t UnZigZagTable[64] = { 24094332d3Sopenharmony_ci 0, 1, 5, 6, 14, 15, 27, 28, 25094332d3Sopenharmony_ci 2, 4, 7, 13, 16, 26, 29, 42, 26094332d3Sopenharmony_ci 3, 8, 12, 17, 25, 30, 41, 43, 27094332d3Sopenharmony_ci 9, 11, 18, 24, 31, 40, 44, 53, 28094332d3Sopenharmony_ci 10, 19, 23, 32, 39, 45, 52, 54, 29094332d3Sopenharmony_ci 20, 22, 33, 38, 46, 51, 55, 60, 30094332d3Sopenharmony_ci 21, 34, 37, 47, 50, 56, 59, 61, 31094332d3Sopenharmony_ci 35, 36, 48, 49, 57, 58, 62, 63}; 32094332d3Sopenharmony_ci 33094332d3Sopenharmony_ciusing namespace OHOS::HDI::Codec::Image::V2_0; 34094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t fd) 35094332d3Sopenharmony_ci{ 36094332d3Sopenharmony_ci HDF_LOGI("enter"); 37094332d3Sopenharmony_ci int32_t curPos = 0; 38094332d3Sopenharmony_ci // SOI 39094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffd8); 40094332d3Sopenharmony_ci if (curPos < 0) { 41094332d3Sopenharmony_ci HDF_LOGE("assemble SOI error"); 42094332d3Sopenharmony_ci return -1; 43094332d3Sopenharmony_ci } 44094332d3Sopenharmony_ci 45094332d3Sopenharmony_ci // DQT 46094332d3Sopenharmony_ci curPos = JpegDqtAssemble(decInfo, buffer, curPos); 47094332d3Sopenharmony_ci if (curPos < 0) { 48094332d3Sopenharmony_ci HDF_LOGE("assemble DQT error"); 49094332d3Sopenharmony_ci return -1; 50094332d3Sopenharmony_ci } 51094332d3Sopenharmony_ci 52094332d3Sopenharmony_ci // DHT 53094332d3Sopenharmony_ci curPos = JpegDhtAssemble(decInfo, buffer, curPos); 54094332d3Sopenharmony_ci if (curPos < 0) { 55094332d3Sopenharmony_ci HDF_LOGE("assemble DHT error"); 56094332d3Sopenharmony_ci return -1; 57094332d3Sopenharmony_ci } 58094332d3Sopenharmony_ci // DRI 59094332d3Sopenharmony_ci curPos = JpegDriAssemble(decInfo, buffer, curPos); 60094332d3Sopenharmony_ci if (curPos < 0) { 61094332d3Sopenharmony_ci HDF_LOGE("assemble DRI error"); 62094332d3Sopenharmony_ci return -1; 63094332d3Sopenharmony_ci } 64094332d3Sopenharmony_ci 65094332d3Sopenharmony_ci // SOF 66094332d3Sopenharmony_ci curPos = JpegSofAssemble(decInfo, buffer, curPos); 67094332d3Sopenharmony_ci if (curPos < 0) { 68094332d3Sopenharmony_ci HDF_LOGE("assemble SOF error"); 69094332d3Sopenharmony_ci return -1; 70094332d3Sopenharmony_ci } 71094332d3Sopenharmony_ci // SOS 72094332d3Sopenharmony_ci curPos = JpegSosAssemble(decInfo, buffer, curPos); 73094332d3Sopenharmony_ci if (curPos < 0) { 74094332d3Sopenharmony_ci HDF_LOGE("assemble SOS error"); 75094332d3Sopenharmony_ci return -1; 76094332d3Sopenharmony_ci } 77094332d3Sopenharmony_ci // DATA 78094332d3Sopenharmony_ci curPos = JpegDataAssemble(buffer, curPos, fd); 79094332d3Sopenharmony_ci if (curPos < 0) { 80094332d3Sopenharmony_ci HDF_LOGE("assemble CompressedData error"); 81094332d3Sopenharmony_ci return -1; 82094332d3Sopenharmony_ci } 83094332d3Sopenharmony_ci // EOI 84094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffd9); 85094332d3Sopenharmony_ci if (curPos < 0) { 86094332d3Sopenharmony_ci HDF_LOGE("assemble EOI error"); 87094332d3Sopenharmony_ci return -1; 88094332d3Sopenharmony_ci } 89094332d3Sopenharmony_ci return curPos; 90094332d3Sopenharmony_ci} 91094332d3Sopenharmony_ci 92094332d3Sopenharmony_cibool CodecJpegHelper::DessambleJpeg(int8_t *buffer, size_t bufferLen, struct CodecJpegDecInfo &decInfo, 93094332d3Sopenharmony_ci std::unique_ptr<int8_t[]> &compressBuffer, uint32_t &comBufLen, uint32_t &dataStart) 94094332d3Sopenharmony_ci{ 95094332d3Sopenharmony_ci HDF_LOGI("enter"); 96094332d3Sopenharmony_ci int8_t *start = buffer; 97094332d3Sopenharmony_ci const int8_t *end = buffer + bufferLen; 98094332d3Sopenharmony_ci while (start < end) { 99094332d3Sopenharmony_ci JpegMarker marker = (JpegMarker)FindMarker(start); 100094332d3Sopenharmony_ci start += 2; // 2: marker len 101094332d3Sopenharmony_ci switch (marker) { 102094332d3Sopenharmony_ci case SOI: 103094332d3Sopenharmony_ci case EOI: 104094332d3Sopenharmony_ci break; 105094332d3Sopenharmony_ci case SOF0: 106094332d3Sopenharmony_ci start += DessambleSof(start, decInfo); 107094332d3Sopenharmony_ci break; 108094332d3Sopenharmony_ci case DHT: 109094332d3Sopenharmony_ci start += DessambleDht(start, decInfo); 110094332d3Sopenharmony_ci break; 111094332d3Sopenharmony_ci case SOS: { 112094332d3Sopenharmony_ci start += DessambleSos(start, decInfo); 113094332d3Sopenharmony_ci dataStart = start - buffer; 114094332d3Sopenharmony_ci // compressed data start 115094332d3Sopenharmony_ci auto len = DessambleCompressData(start, compressBuffer, comBufLen); 116094332d3Sopenharmony_ci if (len < 0) { 117094332d3Sopenharmony_ci HDF_LOGE("copy compressed data error"); 118094332d3Sopenharmony_ci return false; 119094332d3Sopenharmony_ci } 120094332d3Sopenharmony_ci start += len; 121094332d3Sopenharmony_ci break; 122094332d3Sopenharmony_ci } 123094332d3Sopenharmony_ci 124094332d3Sopenharmony_ci case DQT: 125094332d3Sopenharmony_ci start += DessambleDqt(start, decInfo); 126094332d3Sopenharmony_ci break; 127094332d3Sopenharmony_ci case DRI: { 128094332d3Sopenharmony_ci start += 2; // 2: marker len 129094332d3Sopenharmony_ci decInfo.restartInterval = GetInt16(start); 130094332d3Sopenharmony_ci start += 2; // 2: interval len 131094332d3Sopenharmony_ci break; 132094332d3Sopenharmony_ci } 133094332d3Sopenharmony_ci default: { 134094332d3Sopenharmony_ci short len = GetInt16(start); 135094332d3Sopenharmony_ci start += len; 136094332d3Sopenharmony_ci HDF_LOGW("skip marker[%{public}x], len[%{public}d]", marker, len); 137094332d3Sopenharmony_ci break; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci } 140094332d3Sopenharmony_ci } 141094332d3Sopenharmony_ci return true; 142094332d3Sopenharmony_ci} 143094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegDqtAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos) 144094332d3Sopenharmony_ci{ 145094332d3Sopenharmony_ci HDF_LOGI("enter. curPos = %{public}d", curPos); 146094332d3Sopenharmony_ci // flag 147094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffdb); 148094332d3Sopenharmony_ci if (curPos < 0) { 149094332d3Sopenharmony_ci HDF_LOGE("assemble DQT flag error"); 150094332d3Sopenharmony_ci return curPos; 151094332d3Sopenharmony_ci } 152094332d3Sopenharmony_ci 153094332d3Sopenharmony_ci // skip len first 154094332d3Sopenharmony_ci int32_t lenPos = curPos; 155094332d3Sopenharmony_ci curPos += 2; // 2: marker len 156094332d3Sopenharmony_ci 157094332d3Sopenharmony_ci // data 158094332d3Sopenharmony_ci for (size_t i = 0; i < decInfo.quantTbl.size(); i++) { 159094332d3Sopenharmony_ci if (!decInfo.quantTbl[i].tableFlag) { 160094332d3Sopenharmony_ci break; 161094332d3Sopenharmony_ci } 162094332d3Sopenharmony_ci uint8_t index = 0; // precision 1:16bit, 0: 8bit, deault:1 163094332d3Sopenharmony_ci index = (index << 4) | i; // precision << 4 | tableid 164094332d3Sopenharmony_ci curPos = PutInt8(buffer, curPos, index); 165094332d3Sopenharmony_ci if (curPos < 0) { 166094332d3Sopenharmony_ci HDF_LOGE("assemble precision and tableid error"); 167094332d3Sopenharmony_ci return curPos; 168094332d3Sopenharmony_ci } 169094332d3Sopenharmony_ci 170094332d3Sopenharmony_ci for (size_t j = 0; j < decInfo.quantTbl[i].quantVal.size(); j++) { 171094332d3Sopenharmony_ci HDF_LOGI("decInfo.quantTbl[%{public}zu].quantVal[%{public}zu] = %{public}d", i, j, 172094332d3Sopenharmony_ci decInfo.quantTbl[i].quantVal[j]); 173094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, decInfo.quantTbl[i].quantVal[j]); 174094332d3Sopenharmony_ci } 175094332d3Sopenharmony_ci } 176094332d3Sopenharmony_ci int16_t bufferLen = static_cast<int16_t>(curPos - lenPos); 177094332d3Sopenharmony_ci auto ret = PutInt16(buffer, lenPos, bufferLen); 178094332d3Sopenharmony_ci if (ret < 0) { 179094332d3Sopenharmony_ci HDF_LOGE("assemble len error"); 180094332d3Sopenharmony_ci return ret; 181094332d3Sopenharmony_ci } 182094332d3Sopenharmony_ci return curPos; 183094332d3Sopenharmony_ci} 184094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegDriAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos) 185094332d3Sopenharmony_ci{ 186094332d3Sopenharmony_ci HDF_LOGI("enter, restartInterval = %{public}d curPos = %{public}d", decInfo.restartInterval, curPos); 187094332d3Sopenharmony_ci if (decInfo.restartInterval <= 0) { 188094332d3Sopenharmony_ci return curPos; 189094332d3Sopenharmony_ci } 190094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffdd); 191094332d3Sopenharmony_ci if (curPos < 0) { 192094332d3Sopenharmony_ci HDF_LOGE("assemble DRI flag error"); 193094332d3Sopenharmony_ci return curPos; 194094332d3Sopenharmony_ci } 195094332d3Sopenharmony_ci 196094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 4); // 4: dri data len( marker len included) 197094332d3Sopenharmony_ci if (curPos < 0) { 198094332d3Sopenharmony_ci HDF_LOGE("assemble DRI len error"); 199094332d3Sopenharmony_ci return curPos; 200094332d3Sopenharmony_ci } 201094332d3Sopenharmony_ci 202094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, decInfo.restartInterval); 203094332d3Sopenharmony_ci if (curPos < 0) { 204094332d3Sopenharmony_ci HDF_LOGE("assemble dri value error"); 205094332d3Sopenharmony_ci return curPos; 206094332d3Sopenharmony_ci } 207094332d3Sopenharmony_ci return curPos; 208094332d3Sopenharmony_ci} 209094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegDhtAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos) 210094332d3Sopenharmony_ci{ 211094332d3Sopenharmony_ci HDF_LOGI("enter. curPos = %{public}d", curPos); 212094332d3Sopenharmony_ci curPos = JpegDhtAssemble(decInfo.dcHuffTbl, buffer, curPos); 213094332d3Sopenharmony_ci if (curPos < 0) { 214094332d3Sopenharmony_ci HDF_LOGE("assemble dc hufman error"); 215094332d3Sopenharmony_ci return curPos; 216094332d3Sopenharmony_ci } 217094332d3Sopenharmony_ci 218094332d3Sopenharmony_ci curPos = JpegDhtAssemble(decInfo.acHuffTbl, buffer, curPos, false); 219094332d3Sopenharmony_ci if (curPos < 0) { 220094332d3Sopenharmony_ci HDF_LOGE("assemble ac hufman error"); 221094332d3Sopenharmony_ci } 222094332d3Sopenharmony_ci return curPos; 223094332d3Sopenharmony_ci} 224094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegDhtAssemble(const std::vector<CodecJpegHuffTable> &table, int8_t *buffer, int32_t curPos, 225094332d3Sopenharmony_ci bool dc) 226094332d3Sopenharmony_ci{ 227094332d3Sopenharmony_ci HDF_LOGI("enter. curPos = %{public}d", curPos); 228094332d3Sopenharmony_ci // DC Hufman 229094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffc4); 230094332d3Sopenharmony_ci if (curPos < 0) { 231094332d3Sopenharmony_ci HDF_LOGE("assemble hufman flag error"); 232094332d3Sopenharmony_ci return curPos; 233094332d3Sopenharmony_ci } 234094332d3Sopenharmony_ci // skip len 235094332d3Sopenharmony_ci int32_t lenPos = curPos; 236094332d3Sopenharmony_ci curPos += 2; // 2: marker len 237094332d3Sopenharmony_ci for (size_t i = 0; i < table.size(); i++) { 238094332d3Sopenharmony_ci if (!table[i].tableFlag) { 239094332d3Sopenharmony_ci break; 240094332d3Sopenharmony_ci } 241094332d3Sopenharmony_ci uint8_t type = 0; // type 0:DC, 1:AC 242094332d3Sopenharmony_ci if (!dc) { 243094332d3Sopenharmony_ci type = 1; 244094332d3Sopenharmony_ci } 245094332d3Sopenharmony_ci type = (type << 4) | i; // type << 4 | tableid 246094332d3Sopenharmony_ci curPos = PutInt8(buffer, curPos, type); 247094332d3Sopenharmony_ci if (curPos < 0) { 248094332d3Sopenharmony_ci HDF_LOGE("assemble tableid and dc/ac error"); 249094332d3Sopenharmony_ci return curPos; 250094332d3Sopenharmony_ci } 251094332d3Sopenharmony_ci // bits 252094332d3Sopenharmony_ci auto ret = memcpy_s(buffer + curPos, table[i].bits.size(), table[i].bits.data(), table[i].bits.size()); 253094332d3Sopenharmony_ci if (ret != EOK) { 254094332d3Sopenharmony_ci char buf[MAX_BUFFER_LEN] = {0}; 255094332d3Sopenharmony_ci strerror_r(errno, buf, sizeof(buf)); 256094332d3Sopenharmony_ci HDF_LOGE("assemble bits error ret = %{public}s", buf); 257094332d3Sopenharmony_ci return ret; 258094332d3Sopenharmony_ci } 259094332d3Sopenharmony_ci curPos += table[i].bits.size(); 260094332d3Sopenharmony_ci // val 261094332d3Sopenharmony_ci ret = memcpy_s(buffer + curPos, table[i].huffVal.size(), table[i].huffVal.data(), table[i].huffVal.size()); 262094332d3Sopenharmony_ci if (ret != EOK) { 263094332d3Sopenharmony_ci HDF_LOGE("assemble huffVal error, ret = %{public}d", ret); 264094332d3Sopenharmony_ci return ret; 265094332d3Sopenharmony_ci } 266094332d3Sopenharmony_ci curPos += table[i].huffVal.size(); 267094332d3Sopenharmony_ci } 268094332d3Sopenharmony_ci int16_t bufferLen = static_cast<int16_t>(curPos - lenPos); 269094332d3Sopenharmony_ci auto ret = PutInt16(buffer, lenPos, bufferLen); 270094332d3Sopenharmony_ci if (ret < 0) { 271094332d3Sopenharmony_ci HDF_LOGE("assemble len error"); 272094332d3Sopenharmony_ci return ret; 273094332d3Sopenharmony_ci } 274094332d3Sopenharmony_ci return curPos; 275094332d3Sopenharmony_ci} 276094332d3Sopenharmony_ci 277094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegSofAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos) 278094332d3Sopenharmony_ci{ 279094332d3Sopenharmony_ci HDF_LOGI("enter. curPos = %{public}d", curPos); 280094332d3Sopenharmony_ci // flag 281094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffc0); 282094332d3Sopenharmony_ci if (curPos < 0) { 283094332d3Sopenharmony_ci HDF_LOGE("assemble SOF flag error"); 284094332d3Sopenharmony_ci return curPos; 285094332d3Sopenharmony_ci } 286094332d3Sopenharmony_ci 287094332d3Sopenharmony_ci int16_t len = decInfo.numComponents * 3 + 8; // * rgb channel + other data 288094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, len); 289094332d3Sopenharmony_ci if (curPos < 0) { 290094332d3Sopenharmony_ci HDF_LOGE("assemble SOF len error"); 291094332d3Sopenharmony_ci return curPos; 292094332d3Sopenharmony_ci } 293094332d3Sopenharmony_ci 294094332d3Sopenharmony_ci int8_t precision = decInfo.dataPrecision & 0xFF; 295094332d3Sopenharmony_ci curPos = PutInt8(buffer, curPos, precision); 296094332d3Sopenharmony_ci if (curPos < 0) { 297094332d3Sopenharmony_ci HDF_LOGE("assemble SOF precision error"); 298094332d3Sopenharmony_ci return curPos; 299094332d3Sopenharmony_ci } 300094332d3Sopenharmony_ci 301094332d3Sopenharmony_ci // width 302094332d3Sopenharmony_ci int16_t width = decInfo.imageHeight & 0xFFFF; 303094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, width); 304094332d3Sopenharmony_ci if (curPos < 0) { 305094332d3Sopenharmony_ci HDF_LOGE("assemble SOF width error"); 306094332d3Sopenharmony_ci return curPos; 307094332d3Sopenharmony_ci } 308094332d3Sopenharmony_ci 309094332d3Sopenharmony_ci // height 310094332d3Sopenharmony_ci int16_t height = decInfo.imageWidth & 0xFFFF; 311094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, height); 312094332d3Sopenharmony_ci if (curPos < 0) { 313094332d3Sopenharmony_ci HDF_LOGE("assemble SOF width error"); 314094332d3Sopenharmony_ci return curPos; 315094332d3Sopenharmony_ci } 316094332d3Sopenharmony_ci // components 317094332d3Sopenharmony_ci int8_t components = decInfo.numComponents & 0xFF; 318094332d3Sopenharmony_ci curPos = PutInt8(buffer, curPos, components); 319094332d3Sopenharmony_ci if (curPos < 0) { 320094332d3Sopenharmony_ci HDF_LOGE("assemble SOF components error"); 321094332d3Sopenharmony_ci return curPos; 322094332d3Sopenharmony_ci } 323094332d3Sopenharmony_ci for (size_t i = 0; i < decInfo.compInfo.size(); i++) { 324094332d3Sopenharmony_ci int8_t componentId = decInfo.compInfo[i].componentId; 325094332d3Sopenharmony_ci // byte offset 326094332d3Sopenharmony_ci int8_t sampFactor = ((decInfo.compInfo[i].hSampFactor & 0xFF) << 4) | (decInfo.compInfo[i].vSampFactor & 0xFF); 327094332d3Sopenharmony_ci int8_t quantity = decInfo.compInfo[i].quantTableNo; 328094332d3Sopenharmony_ci int8_t bufferValue[] = {componentId, sampFactor, quantity}; 329094332d3Sopenharmony_ci auto ret = memcpy_s(buffer + curPos, sizeof(bufferValue), bufferValue, sizeof(bufferValue)); 330094332d3Sopenharmony_ci if (ret != EOK) { 331094332d3Sopenharmony_ci HDF_LOGE("assemble component error, ret = %{public}d", ret); 332094332d3Sopenharmony_ci return ret; 333094332d3Sopenharmony_ci } 334094332d3Sopenharmony_ci curPos += sizeof(bufferValue); 335094332d3Sopenharmony_ci } 336094332d3Sopenharmony_ci return curPos; 337094332d3Sopenharmony_ci} 338094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegSosAssemble(const struct CodecJpegDecInfo &decInfo, int8_t *buffer, int32_t curPos) 339094332d3Sopenharmony_ci{ 340094332d3Sopenharmony_ci HDF_LOGI("enter. curPos = %{public}d", curPos); 341094332d3Sopenharmony_ci // flag 342094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, 0xffda); 343094332d3Sopenharmony_ci if (curPos < 0) { 344094332d3Sopenharmony_ci HDF_LOGE("assemble SOS flag error"); 345094332d3Sopenharmony_ci return curPos; 346094332d3Sopenharmony_ci } 347094332d3Sopenharmony_ci 348094332d3Sopenharmony_ci int16_t len = decInfo.numComponents * 2 + 6; // * rgb table length + other data 349094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, len); 350094332d3Sopenharmony_ci if (curPos < 0) { 351094332d3Sopenharmony_ci HDF_LOGE("assemble SOS len error"); 352094332d3Sopenharmony_ci return curPos; 353094332d3Sopenharmony_ci } 354094332d3Sopenharmony_ci 355094332d3Sopenharmony_ci int8_t components = decInfo.numComponents & 0xFF; 356094332d3Sopenharmony_ci curPos = PutInt8(buffer, curPos, components); 357094332d3Sopenharmony_ci if (curPos < 0) { 358094332d3Sopenharmony_ci HDF_LOGE("assemble SOS components error"); 359094332d3Sopenharmony_ci return curPos; 360094332d3Sopenharmony_ci } 361094332d3Sopenharmony_ci 362094332d3Sopenharmony_ci for (size_t i = 0; i < decInfo.compInfo.size(); i++) { 363094332d3Sopenharmony_ci int8_t componentId = decInfo.compInfo[i].componentId; 364094332d3Sopenharmony_ci int8_t indexNo = ((decInfo.compInfo[i].dcTableNo & 0xFF) << 4) | (decInfo.compInfo[i].acTableNo & 0xFF); 365094332d3Sopenharmony_ci int16_t value = ((componentId << 8) | indexNo) & 0xffff; 366094332d3Sopenharmony_ci curPos = PutInt16(buffer, curPos, value); 367094332d3Sopenharmony_ci if (curPos < 0) { 368094332d3Sopenharmony_ci HDF_LOGE("assemble SOS component value error"); 369094332d3Sopenharmony_ci return curPos; 370094332d3Sopenharmony_ci } 371094332d3Sopenharmony_ci } 372094332d3Sopenharmony_ci int8_t dataStart[] = {0x00, 0x3F, 0x00}; 373094332d3Sopenharmony_ci auto ret = memcpy_s(buffer + curPos, sizeof(dataStart), dataStart, sizeof(dataStart)); 374094332d3Sopenharmony_ci if (ret != EOK) { 375094332d3Sopenharmony_ci HDF_LOGE("assemble SOS data flag error, ret = %{public}d", ret); 376094332d3Sopenharmony_ci return ret; 377094332d3Sopenharmony_ci } 378094332d3Sopenharmony_ci curPos += sizeof(dataStart); 379094332d3Sopenharmony_ci return curPos; 380094332d3Sopenharmony_ci} 381094332d3Sopenharmony_ciint32_t CodecJpegHelper::JpegDataAssemble(int8_t *buffer, int32_t curPos, int32_t fd) 382094332d3Sopenharmony_ci{ 383094332d3Sopenharmony_ci HDF_LOGI("enter. curPos = %{public}d", curPos); 384094332d3Sopenharmony_ci int32_t size = OHOS::AshmemGetSize(fd); 385094332d3Sopenharmony_ci HDF_LOGI("get size %{public}d from fd %{public}d", size, fd); 386094332d3Sopenharmony_ci OHOS::Ashmem mem(fd, size); 387094332d3Sopenharmony_ci // check ret value 388094332d3Sopenharmony_ci mem.MapReadOnlyAshmem(); 389094332d3Sopenharmony_ci auto addr = const_cast<void *>(mem.ReadFromAshmem(0, 0)); 390094332d3Sopenharmony_ci auto ret = memcpy_s(buffer + curPos, size, addr, size); 391094332d3Sopenharmony_ci if (ret != EOK) { 392094332d3Sopenharmony_ci HDF_LOGE("assemble compressed data error, ret = %{public}d", ret); 393094332d3Sopenharmony_ci mem.UnmapAshmem(); 394094332d3Sopenharmony_ci if (ret > 0) { 395094332d3Sopenharmony_ci return -ret; 396094332d3Sopenharmony_ci } 397094332d3Sopenharmony_ci return ret; 398094332d3Sopenharmony_ci } 399094332d3Sopenharmony_ci mem.UnmapAshmem(); 400094332d3Sopenharmony_ci mem.CloseAshmem(); 401094332d3Sopenharmony_ci curPos += size; 402094332d3Sopenharmony_ci return curPos; 403094332d3Sopenharmony_ci} 404094332d3Sopenharmony_ci 405094332d3Sopenharmony_ciint32_t CodecJpegHelper::DessambleSof(int8_t *buffer, struct CodecJpegDecInfo &decInfo) 406094332d3Sopenharmony_ci{ 407094332d3Sopenharmony_ci HDF_LOGI("dessamble SOI"); 408094332d3Sopenharmony_ci // len 409094332d3Sopenharmony_ci int32_t len = GetInt16(buffer); 410094332d3Sopenharmony_ci buffer += 2; // 2: marker len 411094332d3Sopenharmony_ci // precision 412094332d3Sopenharmony_ci decInfo.dataPrecision = GetInt8(buffer); 413094332d3Sopenharmony_ci buffer++; 414094332d3Sopenharmony_ci // height 415094332d3Sopenharmony_ci decInfo.imageHeight = GetInt16(buffer); 416094332d3Sopenharmony_ci buffer += 2; // 2: height len 417094332d3Sopenharmony_ci // width 418094332d3Sopenharmony_ci decInfo.imageWidth = GetInt16(buffer); 419094332d3Sopenharmony_ci buffer += 2; // 2: width len 420094332d3Sopenharmony_ci 421094332d3Sopenharmony_ci decInfo.numComponents = GetInt8(buffer); 422094332d3Sopenharmony_ci buffer++; 423094332d3Sopenharmony_ci 424094332d3Sopenharmony_ci HDF_LOGI("image width[%{public}d],height[%{public}d],components[%{public}d]", decInfo.imageWidth, 425094332d3Sopenharmony_ci decInfo.imageHeight, decInfo.numComponents); 426094332d3Sopenharmony_ci for (size_t i = 0; i < decInfo.numComponents; i++) { 427094332d3Sopenharmony_ci CodecJpegCompInfo comInfo; 428094332d3Sopenharmony_ci 429094332d3Sopenharmony_ci comInfo.infoFlag = true; 430094332d3Sopenharmony_ci comInfo.componentId = GetInt8(buffer); 431094332d3Sopenharmony_ci buffer++; 432094332d3Sopenharmony_ci 433094332d3Sopenharmony_ci int8_t sampFactor = GetInt8(buffer); 434094332d3Sopenharmony_ci buffer++; 435094332d3Sopenharmony_ci comInfo.hSampFactor = (sampFactor >> 4) & 0xFF; // 4: hsampfactor offset 436094332d3Sopenharmony_ci comInfo.vSampFactor = sampFactor & 0x0F; 437094332d3Sopenharmony_ci 438094332d3Sopenharmony_ci comInfo.quantTableNo = GetInt8(buffer); 439094332d3Sopenharmony_ci buffer++; 440094332d3Sopenharmony_ci decInfo.compInfo.push_back(std::move(comInfo)); 441094332d3Sopenharmony_ci HDF_LOGI("componentId[%{public}d],hSampFactor[%{public}d],vSampFactor[%{public}d],quantTableNo[%{public}d]", 442094332d3Sopenharmony_ci comInfo.componentId, comInfo.hSampFactor, comInfo.vSampFactor, comInfo.quantTableNo); 443094332d3Sopenharmony_ci } 444094332d3Sopenharmony_ci return len; 445094332d3Sopenharmony_ci} 446094332d3Sopenharmony_ciint32_t CodecJpegHelper::DessambleSos(int8_t *buffer, struct CodecJpegDecInfo &decInfo) 447094332d3Sopenharmony_ci{ 448094332d3Sopenharmony_ci HDF_LOGI("dessamble SOS"); 449094332d3Sopenharmony_ci int32_t len = GetInt16(buffer); 450094332d3Sopenharmony_ci buffer += 2; // 2:marker len 451094332d3Sopenharmony_ci 452094332d3Sopenharmony_ci int32_t components = GetInt8(buffer); 453094332d3Sopenharmony_ci buffer++; 454094332d3Sopenharmony_ci 455094332d3Sopenharmony_ci for (int32_t i = 0; i < components; i++) { 456094332d3Sopenharmony_ci decInfo.compInfo[i].infoFlag = true; 457094332d3Sopenharmony_ci 458094332d3Sopenharmony_ci int32_t componentId = GetInt8(buffer); 459094332d3Sopenharmony_ci (void)componentId; 460094332d3Sopenharmony_ci buffer++; 461094332d3Sopenharmony_ci // index not used 462094332d3Sopenharmony_ci auto data = GetInt8(buffer); 463094332d3Sopenharmony_ci buffer++; 464094332d3Sopenharmony_ci decInfo.compInfo[i].dcTableNo = (data >> 4) & 0x0F; // 4: dctable offset 465094332d3Sopenharmony_ci decInfo.compInfo[i].acTableNo = data & 0x0F; 466094332d3Sopenharmony_ci HDF_LOGI("componentId[%{public}d],dcTableNo[%{public}d],acTableNo[%{public}d]", componentId, 467094332d3Sopenharmony_ci decInfo.compInfo[i].dcTableNo, decInfo.compInfo[i].acTableNo); 468094332d3Sopenharmony_ci } 469094332d3Sopenharmony_ci buffer += 3; // skip 0x003F00 470094332d3Sopenharmony_ci return len; 471094332d3Sopenharmony_ci} 472094332d3Sopenharmony_ciint32_t CodecJpegHelper::DessambleCompressData(int8_t *buffer, std::unique_ptr<int8_t[]> &compressBuffer, 473094332d3Sopenharmony_ci uint32_t &comBufLen) 474094332d3Sopenharmony_ci{ 475094332d3Sopenharmony_ci int8_t *dataStart = buffer; 476094332d3Sopenharmony_ci do { 477094332d3Sopenharmony_ci int32_t v = GetInt8(buffer); 478094332d3Sopenharmony_ci buffer++; 479094332d3Sopenharmony_ci if (v != 0xff) { 480094332d3Sopenharmony_ci continue; 481094332d3Sopenharmony_ci } 482094332d3Sopenharmony_ci v = GetInt8(buffer); 483094332d3Sopenharmony_ci buffer++; 484094332d3Sopenharmony_ci if (v != 0xd9) { 485094332d3Sopenharmony_ci continue; 486094332d3Sopenharmony_ci } 487094332d3Sopenharmony_ci buffer -= 2; // 2: marker len 488094332d3Sopenharmony_ci break; 489094332d3Sopenharmony_ci } while (1); 490094332d3Sopenharmony_ci comBufLen = (int32_t)(buffer - dataStart) + 1; 491094332d3Sopenharmony_ci compressBuffer = std::make_unique<int8_t[]>(comBufLen); 492094332d3Sopenharmony_ci auto ret = memcpy_s(compressBuffer.get(), comBufLen, dataStart, comBufLen); 493094332d3Sopenharmony_ci if (ret != EOK) { 494094332d3Sopenharmony_ci HDF_LOGE("copy compressed data error, dataLen %{public}d, ret %{public}d", comBufLen, ret); 495094332d3Sopenharmony_ci compressBuffer = nullptr; 496094332d3Sopenharmony_ci return ret; 497094332d3Sopenharmony_ci } 498094332d3Sopenharmony_ci return comBufLen; 499094332d3Sopenharmony_ci} 500094332d3Sopenharmony_ciint32_t CodecJpegHelper::DessambleDqt(int8_t *buffer, struct CodecJpegDecInfo &decInfo) 501094332d3Sopenharmony_ci{ 502094332d3Sopenharmony_ci HDF_LOGI("dessamble DQT"); 503094332d3Sopenharmony_ci int8_t *bufferOri = buffer; 504094332d3Sopenharmony_ci int32_t len = GetInt16(buffer); 505094332d3Sopenharmony_ci buffer += 2; // 2: marker len 506094332d3Sopenharmony_ci // maybe has more dqt table 507094332d3Sopenharmony_ci while ((buffer - bufferOri) < len) { 508094332d3Sopenharmony_ci auto data = GetInt8(buffer); 509094332d3Sopenharmony_ci buffer++; 510094332d3Sopenharmony_ci int32_t tableId = data & 0x000f; 511094332d3Sopenharmony_ci (void)tableId; 512094332d3Sopenharmony_ci int32_t size = 64; 513094332d3Sopenharmony_ci CodecJpegQuantTable table; 514094332d3Sopenharmony_ci table.tableFlag = true; 515094332d3Sopenharmony_ci table.quantVal.resize(size); 516094332d3Sopenharmony_ci std::vector<uint16_t> mtx; 517094332d3Sopenharmony_ci HDF_LOGI("tableid[%{public}d]", tableId); 518094332d3Sopenharmony_ci for (int32_t i = 0; i < size; i++) { 519094332d3Sopenharmony_ci if (((data >> 4) & 0x0f) == 1) { // 4: low 4 bits, 1: for 16 bits 520094332d3Sopenharmony_ci mtx.push_back(static_cast<int16_t>(GetInt16(buffer))); 521094332d3Sopenharmony_ci buffer += 2; // 2: data offset 522094332d3Sopenharmony_ci } else { 523094332d3Sopenharmony_ci mtx.push_back(static_cast<int8_t>(GetInt8(buffer))); 524094332d3Sopenharmony_ci buffer += 1; // 1: data offset 525094332d3Sopenharmony_ci } 526094332d3Sopenharmony_ci } 527094332d3Sopenharmony_ci // unzigzag quant table 528094332d3Sopenharmony_ci for (int32_t i = 0; i < size; i++) { 529094332d3Sopenharmony_ci table.quantVal[i] = mtx[UnZigZagTable[i]]; 530094332d3Sopenharmony_ci } 531094332d3Sopenharmony_ci decInfo.quantTbl.push_back(std::move(table)); 532094332d3Sopenharmony_ci } 533094332d3Sopenharmony_ci return len; 534094332d3Sopenharmony_ci} 535094332d3Sopenharmony_ciint32_t CodecJpegHelper::DessambleDht(int8_t *buffer, struct CodecJpegDecInfo &decInfo) 536094332d3Sopenharmony_ci{ 537094332d3Sopenharmony_ci HDF_LOGI("dessamble DHT"); 538094332d3Sopenharmony_ci int8_t *bufferOri = buffer; 539094332d3Sopenharmony_ci int32_t len = GetInt16(buffer); 540094332d3Sopenharmony_ci buffer += 2; // 2: marker len 541094332d3Sopenharmony_ci // 可能存在多个表在同一个dht marker 中 542094332d3Sopenharmony_ci while ((buffer - bufferOri) < len) { 543094332d3Sopenharmony_ci auto data = GetInt8(buffer); 544094332d3Sopenharmony_ci buffer++; 545094332d3Sopenharmony_ci int32_t tableId = data & 0x000f; 546094332d3Sopenharmony_ci (void)tableId; 547094332d3Sopenharmony_ci int32_t acOrDc = (data >> 4) & 0x0f; // 0:DC, 1:AC, 4: ac/dc data offset 548094332d3Sopenharmony_ci CodecJpegHuffTable table; 549094332d3Sopenharmony_ci table.tableFlag = true; 550094332d3Sopenharmony_ci int32_t num = 0; 551094332d3Sopenharmony_ci for (size_t i = 0; i < 16; i++) { // 16: Data size 552094332d3Sopenharmony_ci auto data = GetInt8(buffer); 553094332d3Sopenharmony_ci buffer++; 554094332d3Sopenharmony_ci table.bits.push_back(data); 555094332d3Sopenharmony_ci num += data & 0x00ff; 556094332d3Sopenharmony_ci } 557094332d3Sopenharmony_ci HDF_LOGI("tableid[%{public}d], acOrDc[%{public}d], num[%{public}d]", tableId, acOrDc, num); 558094332d3Sopenharmony_ci // val 559094332d3Sopenharmony_ci for (int32_t i = 0; i < num; i++) { 560094332d3Sopenharmony_ci table.huffVal.push_back(*buffer++); 561094332d3Sopenharmony_ci } 562094332d3Sopenharmony_ci if (acOrDc == 1) { 563094332d3Sopenharmony_ci decInfo.acHuffTbl.push_back(std::move(table)); 564094332d3Sopenharmony_ci } else { 565094332d3Sopenharmony_ci decInfo.dcHuffTbl.push_back(std::move(table)); 566094332d3Sopenharmony_ci } 567094332d3Sopenharmony_ci } 568094332d3Sopenharmony_ci return len; 569094332d3Sopenharmony_ci} 570094332d3Sopenharmony_ci 571094332d3Sopenharmony_ciint32_t CodecJpegHelper::FindMarker(int8_t *start) 572094332d3Sopenharmony_ci{ 573094332d3Sopenharmony_ci int32_t marker = GetInt16(start); 574094332d3Sopenharmony_ci return marker; 575094332d3Sopenharmony_ci} 576094332d3Sopenharmony_ci 577094332d3Sopenharmony_ciint32_t CodecJpegHelper::PutInt16(int8_t *buffer, int32_t curPos, int16_t value) 578094332d3Sopenharmony_ci{ 579094332d3Sopenharmony_ci int8_t data[] = {value >> 8, value & 0xFF}; 580094332d3Sopenharmony_ci auto ret = memcpy_s(buffer + curPos, sizeof(data), data, sizeof(data)); 581094332d3Sopenharmony_ci if (ret != EOK) { 582094332d3Sopenharmony_ci HDF_LOGE("memcpy ret err %{public}d", ret); 583094332d3Sopenharmony_ci return -1; 584094332d3Sopenharmony_ci } 585094332d3Sopenharmony_ci return curPos + sizeof(data); 586094332d3Sopenharmony_ci} 587094332d3Sopenharmony_ci 588094332d3Sopenharmony_ciint32_t CodecJpegHelper::PutInt8(int8_t *buffer, int32_t curPos, int8_t value) 589094332d3Sopenharmony_ci{ 590094332d3Sopenharmony_ci auto ret = memcpy_s(buffer + curPos, sizeof(value), &value, sizeof(value)); 591094332d3Sopenharmony_ci if (ret != EOK) { 592094332d3Sopenharmony_ci HDF_LOGE("memcpy ret err %{public}d", ret); 593094332d3Sopenharmony_ci return -1; 594094332d3Sopenharmony_ci } 595094332d3Sopenharmony_ci return curPos + sizeof(value); 596094332d3Sopenharmony_ci} 597094332d3Sopenharmony_ci 598094332d3Sopenharmony_ciint32_t CodecJpegHelper::GetInt8(int8_t *buffer) 599094332d3Sopenharmony_ci{ 600094332d3Sopenharmony_ci return buffer[0] & 0x00ff; 601094332d3Sopenharmony_ci} 602094332d3Sopenharmony_ci 603094332d3Sopenharmony_ciint32_t CodecJpegHelper::GetInt16(int8_t *buffer) 604094332d3Sopenharmony_ci{ 605094332d3Sopenharmony_ci return ((buffer[0] << 8) & 0x00ff00) | (buffer[1] & 0x00ff); // 8:data offset 606094332d3Sopenharmony_ci} 607