/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "gfx_utils/file.h" #include "gfx_utils/mem_api.h" #include "imgdecode/file_img_decoder.h" #include "imgdecode/image_load.h" namespace OHOS { FileImgDecoder& FileImgDecoder::GetInstance() { static FileImgDecoder instance; return instance; } RetCode FileImgDecoder::Open(ImgResDsc& dsc) { #ifdef _WIN32 int32_t fd = open(dsc.path, O_RDONLY | O_BINARY); #else int32_t fd = open(dsc.path, O_RDONLY); #endif if (fd == -1) { return RetCode::FAIL; } dsc.fd = fd; dsc.imgInfo.data = nullptr; dsc.inCache_ = false; uint8_t colorMode = dsc.imgInfo.header.colorMode; if (IsImgValidMode(colorMode)) { return RetCode::OK; } else { return RetCode::FAIL; } } RetCode FileImgDecoder::Close(ImgResDsc& dsc) { if (dsc.imgInfo.data != nullptr) { ImageCacheFree(dsc.imgInfo); dsc.imgInfo.data = nullptr; } if (dsc.fd && (dsc.fd != -1)) { close(dsc.fd); dsc.fd = -1; } return RetCode::OK; } RetCode FileImgDecoder::GetHeader(ImgResDsc& dsc) { int32_t fd; int32_t readCount; #ifdef _WIN32 fd = open(dsc.path, O_BINARY); #else fd = open(dsc.path, O_RDONLY); #endif if (fd == -1) { return RetCode::FAIL; } readCount = read(fd, &dsc.imgInfo.header, sizeof(ImageHeader)); close(fd); dsc.fd = -1; if (readCount != sizeof(ImageHeader)) { dsc.imgInfo.header.width = 0; dsc.imgInfo.header.height = 0; dsc.imgInfo.header.colorMode = UNKNOWN; return RetCode::FAIL; } return RetCode::OK; } RetCode FileImgDecoder::ReadLine(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf) { if (IsImgValidMode(dsc.imgInfo.header.colorMode)) { return ReadLineTrueColor(dsc, start, len, buf); } return RetCode::FAIL; } RetCode FileImgDecoder::ReadToCache(ImgResDsc& dsc) { struct stat info; if (!dsc.inCache_) { lseek(dsc.fd, 0, SEEK_SET); int32_t readCount = read(dsc.fd, &dsc.imgInfo.header, sizeof(ImageHeader)); if (readCount != sizeof(ImageHeader)) { return RetCode::FAIL; } int32_t ret = fstat(dsc.fd, &info); if (ret != 0) { return RetCode::FAIL; } uint32_t pxCount = info.st_size - readCount; if (dsc.imgInfo.data != nullptr) { ImageCacheFree(dsc.imgInfo); dsc.imgInfo.data = nullptr; } bool readSuccess = false; if (dsc.imgInfo.header.compressMode != COMPRESS_MODE_NONE) { readSuccess = ImageLoad::GetImageInfo(dsc.fd, pxCount, dsc.imgInfo); } else { dsc.imgInfo.dataSize = pxCount; dsc.imgInfo.data = reinterpret_cast(ImageCacheMalloc(dsc.imgInfo)); if (dsc.imgInfo.data == nullptr) { return RetCode::OK; } uint8_t* tmp = const_cast(dsc.imgInfo.data); readSuccess = (static_cast(pxCount) == read(dsc.fd, reinterpret_cast(tmp), pxCount)); } if (!readSuccess) { ImageCacheFree(dsc.imgInfo); dsc.imgInfo.data = nullptr; dsc.imgInfo.dataSize = 0; close(dsc.fd); dsc.fd = -1; return RetCode::OK; } dsc.inCache_ = true; close(dsc.fd); dsc.fd = -1; } return RetCode::OK; } RetCode FileImgDecoder::ReadLineTrueColor(ImgResDsc& dsc, const Point& start, int16_t len, uint8_t* buf) { uint8_t pxSizeInBit = DrawUtils::GetPxSizeByColorMode(dsc.imgInfo.header.colorMode); off_t res; uint32_t pos = ((start.y * dsc.imgInfo.header.width + start.x) * pxSizeInBit) >> BYTE_TO_BIT_SHIFT; pos += sizeof(ImageHeader); /* Skip the header */ res = lseek(dsc.fd, pos, SEEK_SET); if (res == -1) { return RetCode::FAIL; } uint32_t btr = len * (pxSizeInBit >> BYTE_TO_BIT_SHIFT); int32_t br = read(dsc.fd, buf, btr); if ((br == -1) || (btr != static_cast(br))) { return RetCode::FAIL; } return RetCode::OK; } } // namespace OHOS