1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "gfx_utils/file.h" 17a3e0fd82Sopenharmony_ci#include "gfx_utils/mem_api.h" 18a3e0fd82Sopenharmony_ci#include "imgdecode/file_img_decoder.h" 19a3e0fd82Sopenharmony_ci#include "imgdecode/image_load.h" 20a3e0fd82Sopenharmony_ci 21a3e0fd82Sopenharmony_cinamespace OHOS { 22a3e0fd82Sopenharmony_ciFileImgDecoder& FileImgDecoder::GetInstance() 23a3e0fd82Sopenharmony_ci{ 24a3e0fd82Sopenharmony_ci static FileImgDecoder instance; 25a3e0fd82Sopenharmony_ci return instance; 26a3e0fd82Sopenharmony_ci} 27a3e0fd82Sopenharmony_ci 28a3e0fd82Sopenharmony_ciRetCode FileImgDecoder::Open(ImgResDsc& dsc) 29a3e0fd82Sopenharmony_ci{ 30a3e0fd82Sopenharmony_ci#ifdef _WIN32 31a3e0fd82Sopenharmony_ci int32_t fd = open(dsc.path, O_RDONLY | O_BINARY); 32a3e0fd82Sopenharmony_ci#else 33a3e0fd82Sopenharmony_ci int32_t fd = open(dsc.path, O_RDONLY); 34a3e0fd82Sopenharmony_ci#endif 35a3e0fd82Sopenharmony_ci if (fd == -1) { 36a3e0fd82Sopenharmony_ci return RetCode::FAIL; 37a3e0fd82Sopenharmony_ci } 38a3e0fd82Sopenharmony_ci dsc.fd = fd; 39a3e0fd82Sopenharmony_ci 40a3e0fd82Sopenharmony_ci dsc.imgInfo.data = nullptr; 41a3e0fd82Sopenharmony_ci dsc.inCache_ = false; 42a3e0fd82Sopenharmony_ci uint8_t colorMode = dsc.imgInfo.header.colorMode; 43a3e0fd82Sopenharmony_ci if (IsImgValidMode(colorMode)) { 44a3e0fd82Sopenharmony_ci return RetCode::OK; 45a3e0fd82Sopenharmony_ci } else { 46a3e0fd82Sopenharmony_ci return RetCode::FAIL; 47a3e0fd82Sopenharmony_ci } 48a3e0fd82Sopenharmony_ci} 49a3e0fd82Sopenharmony_ci 50a3e0fd82Sopenharmony_ciRetCode FileImgDecoder::Close(ImgResDsc& dsc) 51a3e0fd82Sopenharmony_ci{ 52a3e0fd82Sopenharmony_ci if (dsc.imgInfo.data != nullptr) { 53a3e0fd82Sopenharmony_ci ImageCacheFree(dsc.imgInfo); 54a3e0fd82Sopenharmony_ci dsc.imgInfo.data = nullptr; 55a3e0fd82Sopenharmony_ci } 56a3e0fd82Sopenharmony_ci if (dsc.fd && (dsc.fd != -1)) { 57a3e0fd82Sopenharmony_ci close(dsc.fd); 58a3e0fd82Sopenharmony_ci dsc.fd = -1; 59a3e0fd82Sopenharmony_ci } 60a3e0fd82Sopenharmony_ci 61a3e0fd82Sopenharmony_ci return RetCode::OK; 62a3e0fd82Sopenharmony_ci} 63a3e0fd82Sopenharmony_ci 64a3e0fd82Sopenharmony_ciRetCode FileImgDecoder::GetHeader(ImgResDsc& dsc) 65a3e0fd82Sopenharmony_ci{ 66a3e0fd82Sopenharmony_ci int32_t fd; 67a3e0fd82Sopenharmony_ci int32_t readCount; 68a3e0fd82Sopenharmony_ci#ifdef _WIN32 69a3e0fd82Sopenharmony_ci fd = open(dsc.path, O_BINARY); 70a3e0fd82Sopenharmony_ci#else 71a3e0fd82Sopenharmony_ci fd = open(dsc.path, O_RDONLY); 72a3e0fd82Sopenharmony_ci#endif 73a3e0fd82Sopenharmony_ci if (fd == -1) { 74a3e0fd82Sopenharmony_ci return RetCode::FAIL; 75a3e0fd82Sopenharmony_ci } 76a3e0fd82Sopenharmony_ci 77a3e0fd82Sopenharmony_ci readCount = read(fd, &dsc.imgInfo.header, sizeof(ImageHeader)); 78a3e0fd82Sopenharmony_ci close(fd); 79a3e0fd82Sopenharmony_ci dsc.fd = -1; 80a3e0fd82Sopenharmony_ci if (readCount != sizeof(ImageHeader)) { 81a3e0fd82Sopenharmony_ci dsc.imgInfo.header.width = 0; 82a3e0fd82Sopenharmony_ci dsc.imgInfo.header.height = 0; 83a3e0fd82Sopenharmony_ci dsc.imgInfo.header.colorMode = UNKNOWN; 84a3e0fd82Sopenharmony_ci return RetCode::FAIL; 85a3e0fd82Sopenharmony_ci } 86a3e0fd82Sopenharmony_ci 87a3e0fd82Sopenharmony_ci return RetCode::OK; 88a3e0fd82Sopenharmony_ci} 89a3e0fd82Sopenharmony_ci 90a3e0fd82Sopenharmony_ciRetCode FileImgDecoder::ReadLine(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf) 91a3e0fd82Sopenharmony_ci{ 92a3e0fd82Sopenharmony_ci if (IsImgValidMode(dsc.imgInfo.header.colorMode)) { 93a3e0fd82Sopenharmony_ci return ReadLineTrueColor(dsc, start, len, buf); 94a3e0fd82Sopenharmony_ci } 95a3e0fd82Sopenharmony_ci return RetCode::FAIL; 96a3e0fd82Sopenharmony_ci} 97a3e0fd82Sopenharmony_ci 98a3e0fd82Sopenharmony_ciRetCode FileImgDecoder::ReadToCache(ImgResDsc& dsc) 99a3e0fd82Sopenharmony_ci{ 100a3e0fd82Sopenharmony_ci struct stat info; 101a3e0fd82Sopenharmony_ci if (!dsc.inCache_) { 102a3e0fd82Sopenharmony_ci lseek(dsc.fd, 0, SEEK_SET); 103a3e0fd82Sopenharmony_ci int32_t readCount = read(dsc.fd, &dsc.imgInfo.header, sizeof(ImageHeader)); 104a3e0fd82Sopenharmony_ci if (readCount != sizeof(ImageHeader)) { 105a3e0fd82Sopenharmony_ci return RetCode::FAIL; 106a3e0fd82Sopenharmony_ci } 107a3e0fd82Sopenharmony_ci 108a3e0fd82Sopenharmony_ci int32_t ret = fstat(dsc.fd, &info); 109a3e0fd82Sopenharmony_ci if (ret != 0) { 110a3e0fd82Sopenharmony_ci return RetCode::FAIL; 111a3e0fd82Sopenharmony_ci } 112a3e0fd82Sopenharmony_ci uint32_t pxCount = info.st_size - readCount; 113a3e0fd82Sopenharmony_ci if (dsc.imgInfo.data != nullptr) { 114a3e0fd82Sopenharmony_ci ImageCacheFree(dsc.imgInfo); 115a3e0fd82Sopenharmony_ci dsc.imgInfo.data = nullptr; 116a3e0fd82Sopenharmony_ci } 117a3e0fd82Sopenharmony_ci 118a3e0fd82Sopenharmony_ci bool readSuccess = false; 119a3e0fd82Sopenharmony_ci if (dsc.imgInfo.header.compressMode != COMPRESS_MODE_NONE) { 120a3e0fd82Sopenharmony_ci readSuccess = ImageLoad::GetImageInfo(dsc.fd, pxCount, dsc.imgInfo); 121a3e0fd82Sopenharmony_ci } else { 122a3e0fd82Sopenharmony_ci dsc.imgInfo.dataSize = pxCount; 123a3e0fd82Sopenharmony_ci dsc.imgInfo.data = reinterpret_cast<uint8_t*>(ImageCacheMalloc(dsc.imgInfo)); 124a3e0fd82Sopenharmony_ci if (dsc.imgInfo.data == nullptr) { 125a3e0fd82Sopenharmony_ci return RetCode::OK; 126a3e0fd82Sopenharmony_ci } 127a3e0fd82Sopenharmony_ci uint8_t* tmp = const_cast<uint8_t*>(dsc.imgInfo.data); 128a3e0fd82Sopenharmony_ci readSuccess = (static_cast<int32_t>(pxCount) == read(dsc.fd, reinterpret_cast<void*>(tmp), pxCount)); 129a3e0fd82Sopenharmony_ci } 130a3e0fd82Sopenharmony_ci if (!readSuccess) { 131a3e0fd82Sopenharmony_ci ImageCacheFree(dsc.imgInfo); 132a3e0fd82Sopenharmony_ci dsc.imgInfo.data = nullptr; 133a3e0fd82Sopenharmony_ci dsc.imgInfo.dataSize = 0; 134a3e0fd82Sopenharmony_ci close(dsc.fd); 135a3e0fd82Sopenharmony_ci dsc.fd = -1; 136a3e0fd82Sopenharmony_ci return RetCode::OK; 137a3e0fd82Sopenharmony_ci } 138a3e0fd82Sopenharmony_ci dsc.inCache_ = true; 139a3e0fd82Sopenharmony_ci close(dsc.fd); 140a3e0fd82Sopenharmony_ci dsc.fd = -1; 141a3e0fd82Sopenharmony_ci } 142a3e0fd82Sopenharmony_ci 143a3e0fd82Sopenharmony_ci return RetCode::OK; 144a3e0fd82Sopenharmony_ci} 145a3e0fd82Sopenharmony_ci 146a3e0fd82Sopenharmony_ciRetCode FileImgDecoder::ReadLineTrueColor(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf) 147a3e0fd82Sopenharmony_ci{ 148a3e0fd82Sopenharmony_ci uint8_t pxSizeInBit = DrawUtils::GetPxSizeByColorMode(dsc.imgInfo.header.colorMode); 149a3e0fd82Sopenharmony_ci off_t res; 150a3e0fd82Sopenharmony_ci 151a3e0fd82Sopenharmony_ci uint32_t pos = ((start.y * dsc.imgInfo.header.width + start.x) * pxSizeInBit) >> BYTE_TO_BIT_SHIFT; 152a3e0fd82Sopenharmony_ci pos += sizeof(ImageHeader); /* Skip the header */ 153a3e0fd82Sopenharmony_ci res = lseek(dsc.fd, pos, SEEK_SET); 154a3e0fd82Sopenharmony_ci if (res == -1) { 155a3e0fd82Sopenharmony_ci return RetCode::FAIL; 156a3e0fd82Sopenharmony_ci } 157a3e0fd82Sopenharmony_ci uint32_t btr = len * (pxSizeInBit >> BYTE_TO_BIT_SHIFT); 158a3e0fd82Sopenharmony_ci int32_t br = read(dsc.fd, buf, btr); 159a3e0fd82Sopenharmony_ci if ((br == -1) || (btr != static_cast<uint32_t>(br))) { 160a3e0fd82Sopenharmony_ci return RetCode::FAIL; 161a3e0fd82Sopenharmony_ci } 162a3e0fd82Sopenharmony_ci 163a3e0fd82Sopenharmony_ci return RetCode::OK; 164a3e0fd82Sopenharmony_ci} 165a3e0fd82Sopenharmony_ci} // namespace OHOS 166