diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000000000000000000000000000000000000..6e4add213eb67b38b6c95b40a551472e54c39a84 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,19 @@ +*.tgz filter=lfs diff=lfs merge=lfs -text +*.trp filter=lfs diff=lfs merge=lfs -text +*.apk filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.asm filter=lfs diff=lfs merge=lfs -text +*.8svn filter=lfs diff=lfs merge=lfs -text +*.9svn filter=lfs diff=lfs merge=lfs -text +*.dylib filter=lfs diff=lfs merge=lfs -text +*.exe filter=lfs diff=lfs merge=lfs -text +*.a filter=lfs diff=lfs merge=lfs -text +*.so filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.dll filter=lfs diff=lfs merge=lfs -text +*.dat filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.bz filter=lfs diff=lfs merge=lfs -text +*.gif filter=lfs diff=lfs merge=lfs -text diff --git a/frameworks/innerkitsimpl/common/src/pixel_map.cpp b/frameworks/innerkitsimpl/common/src/pixel_map.cpp index a537f99f8db6ee7a73ad3b7dd485db946eec442d..e5d3b905041b854966830e36abbd551331edee82 100644 --- a/frameworks/innerkitsimpl/common/src/pixel_map.cpp +++ b/frameworks/innerkitsimpl/common/src/pixel_map.cpp @@ -22,10 +22,8 @@ #include "media_errors.h" #include "pixel_convert_adapter.h" #include "pixel_map_utils.h" -#include "pixel_map_parcel.h" #include "post_proc.h" #include "parcel.h" -#include "ipc_file_descriptor.h" #ifndef _WIN32 #include "securec.h" #else @@ -35,6 +33,7 @@ #if !defined(_WIN32) && !defined(_APPLE) #include #include "ashmem.h" +#include "ipc_file_descriptor.h" #endif namespace OHOS { @@ -48,6 +47,9 @@ constexpr uint8_t BGRA_ALPHA_INDEX = 3; constexpr uint8_t BGRA_BYTES = 4; constexpr uint8_t PER_PIXEL_LEN = 1; +constexpr uint8_t FILL_NUMBER = 3; +constexpr uint8_t ALIGN_NUMBER = 4; + PixelMap::~PixelMap() { FreePixelMap(); @@ -111,12 +113,14 @@ void PixelMap::SetPixelsAddr(void *addr, void *context, uint32_t size, Allocator unique_ptr PixelMap::Create(const uint32_t *colors, uint32_t colorLength, const InitializationOptions &opts) { + HiLog::Info(LABEL, "PixelMap::Create1 enter"); return Create(colors, colorLength, 0, opts.size.width, opts); } unique_ptr PixelMap::Create(const uint32_t *colors, uint32_t colorLength, int32_t offset, int32_t stride, const InitializationOptions &opts) { + HiLog::Info(LABEL, "PixelMap::Create2 enter"); if (!CheckParams(colors, colorLength, offset, stride, opts)) { return nullptr; } @@ -194,6 +198,7 @@ bool PixelMap::CheckParams(const uint32_t *colors, uint32_t colorLength, int32_t unique_ptr PixelMap::Create(const InitializationOptions &opts) { + HiLog::Info(LABEL, "PixelMap::Create3 enter"); unique_ptr dstPixelMap = make_unique(); if (dstPixelMap == nullptr) { HiLog::Error(LABEL, "create pixelMap pointer fail"); @@ -209,6 +214,10 @@ unique_ptr PixelMap::Create(const InitializationOptions &opts) return nullptr; } uint32_t bufferSize = dstPixelMap->GetByteCount(); + if (bufferSize <= 0) { + HiLog::Error(LABEL, "calloc parameter bufferSize:[%{public}d] error.", bufferSize); + return nullptr; + } uint8_t *dstPixels = static_cast(calloc(bufferSize, 1)); if (dstPixels == nullptr) { HiLog::Error(LABEL, "allocate memory size %{public}u fail", bufferSize); @@ -245,12 +254,14 @@ void PixelMap::UpdatePixelsAlpha(const AlphaType &alphaType, const PixelFormat & unique_ptr PixelMap::Create(PixelMap &source, const InitializationOptions &opts) { + HiLog::Info(LABEL, "PixelMap::Create4 enter"); Rect rect; return Create(source, rect, opts); } unique_ptr PixelMap::Create(PixelMap &source, const Rect &srcRect, const InitializationOptions &opts) { + HiLog::Info(LABEL, "PixelMap::Create5 enter"); ImageInfo srcImageInfo; source.GetImageInfo(srcImageInfo); PostProc postProc; @@ -305,6 +316,10 @@ bool PixelMap::SourceCropAndConvert(PixelMap &source, const ImageInfo &srcImageI const Rect &srcRect, PixelMap &dstPixelMap) { uint32_t bufferSize = dstPixelMap.GetByteCount(); + if (bufferSize <= 0) { + HiLog::Error(LABEL, "malloc parameter bufferSize:[%{public}d] error.", bufferSize); + return false; + } void *dstPixels = malloc(bufferSize); if (dstPixels == nullptr) { HiLog::Error(LABEL, "allocate memory size %{public}u fail", bufferSize); @@ -365,10 +380,14 @@ void PixelMap::InitDstImageInfo(const InitializationOptions &opts, const ImageIn bool PixelMap::CopyPixelMap(PixelMap &source, PixelMap &dstPixelMap) { uint32_t bufferSize = source.GetByteCount(); - if (bufferSize == 0 || source.GetPixels() == nullptr) { + if (source.GetPixels() == nullptr) { HiLog::Error(LABEL, "source pixelMap data invalid"); return false; } + if (bufferSize <= 0) { + HiLog::Error(LABEL, "malloc parameter bufferSize:[%{public}d] error.", bufferSize); + return false; + } uint8_t *dstPixels = static_cast(malloc(bufferSize)); if (dstPixels == nullptr) { HiLog::Error(LABEL, "allocate memory size %{public}u fail", bufferSize); @@ -466,7 +485,7 @@ uint32_t PixelMap::SetImageInfo(ImageInfo &info, bool isReused) return ERR_IMAGE_TOO_LARGE; } if (info.pixelFormat == PixelFormat::ALPHA_8) { - rowDataSize_ = pixelBytes_ * ((info.size.width + 3) / 4 * 4); + rowDataSize_ = pixelBytes_ * ((info.size.width + FILL_NUMBER) / ALIGN_NUMBER * ALIGN_NUMBER); HiLog::Info(LABEL, "ALPHA_8 rowDataSize_ %{public}d.", rowDataSize_); } else { rowDataSize_ = pixelBytes_ * info.size.width; @@ -639,6 +658,7 @@ int32_t PixelMap::GetRowBytes() int32_t PixelMap::GetByteCount() { + HiLog::Debug(LABEL, "GetByteCount"); return rowDataSize_ * imageInfo_.size.height; } @@ -705,15 +725,18 @@ uint8_t PixelMap::GetARGB32ColorB(uint32_t color) bool PixelMap::IsSameImage(const PixelMap &other) { if (data_ == nullptr || other.data_ == nullptr) { + HiLog::Error(LABEL, "IsSameImage data_ is nullptr."); return false; } if (imageInfo_.size.width != other.imageInfo_.size.width || imageInfo_.size.height != other.imageInfo_.size.height || imageInfo_.pixelFormat != other.imageInfo_.pixelFormat || imageInfo_.alphaType != other.imageInfo_.alphaType) { + HiLog::Error(LABEL, "IsSameImage imageInfo check not OK."); return false; } uint64_t size = static_cast(rowDataSize_) * imageInfo_.size.height; if (memcmp(data_, other.data_, size) != 0) { + HiLog::Error(LABEL, "IsSameImage mmemcmp check not OK."); return false; } return true; @@ -1011,7 +1034,139 @@ void *PixelMap::GetFd() const return context_; } -bool PixelMap::WriteFileDescriptor(Parcel &data, int fd) const +void PixelMap::ReleaseMemory(AllocatorType allocType, void *addr, void *context, uint32_t size) +{ + if (allocType == AllocatorType::SHARE_MEM_ALLOC) { +#if !defined(_WIN32) && !defined(_APPLE) + int *fd = static_cast(context); + if (addr != nullptr) { + ::munmap(addr, size); + } + if (fd != nullptr) { + ::close(*fd); + delete fd; + } +#endif + } else if (allocType == AllocatorType::HEAP_ALLOC) { + if (addr != nullptr) { + free(addr); + addr = nullptr; + } + } +} + +bool PixelMap::WriteImageData(Parcel &parcel, size_t size) const +{ + const uint8_t *data = data_; + if (data == nullptr) { + HiLog::Error(LABEL, "write to parcel failed, pixel memory is null."); + return false; + } + if (data == nullptr || size > MAX_IMAGEDATA_SIZE) { + return false; + } + + if (!parcel.WriteInt32(size)) { + return false; + } + if (size <= MIN_IMAGEDATA_SIZE) { + return parcel.WriteUnpadBuffer(data, size); + } +#if !defined(_WIN32) && !defined(_APPLE) + int fd = AshmemCreate("Parcel ImageData", size); + HiLog::Info(LABEL, "AshmemCreate:[%{public}d].", fd); + if (fd < 0) { + return false; + } + + int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE); + HiLog::Info(LABEL, "AshmemSetProt:[%{public}d].", result); + if (result < 0) { + return false; + } + void *ptr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + if (ptr == MAP_FAILED) { + return false; + } + HiLog::Info(LABEL, "mmap success"); + + if (memcpy_s(ptr, size, data, size) != EOK) { + ::munmap(ptr, size); + HiLog::Error(LABEL, "WriteImageData memcpy_s error"); + return false; + } + + if (!WriteFileDescriptor(parcel, fd)) { + ::munmap(ptr, size); + HiLog::Error(LABEL, "WriteImageData WriteFileDescriptor error"); + return false; + } + HiLog::Debug(LABEL, "WriteImageData WriteFileDescriptor success"); + HiLog::Debug(LABEL, "WriteImageData End"); +#endif + return true; +} + +uint8_t *PixelMap::ReadImageData(Parcel &parcel, int32_t bufferSize) +{ + uint8_t *base = nullptr; + int fd = -1; + + if (static_cast(bufferSize) <= MIN_IMAGEDATA_SIZE) { + const uint8_t *ptr = parcel.ReadUnpadBuffer(bufferSize); + if (bufferSize <= 0) { + HiLog::Error(LABEL, "malloc parameter bufferSize:[%{public}d] error.", bufferSize); + return nullptr; + } + base = static_cast(malloc(bufferSize)); + if (base == nullptr) { + HiLog::Error(LABEL, "alloc output pixel memory size:[%{public}d] error.", bufferSize); + return nullptr; + } + if (memcpy_s(base, bufferSize, ptr, bufferSize) != 0) { + free(base); + base = nullptr; + HiLog::Error(LABEL, "memcpy pixel data size:[%{public}d] error.", bufferSize); + return nullptr; + } + } else { +#if !defined(_WIN32) && !defined(_APPLE) + fd = ReadFileDescriptor(parcel); + if (fd < 0) { + HiLog::Error(LABEL, "read fd :[%{public}d] error", fd); + return nullptr; + } + void *ptr = ::mmap(nullptr, bufferSize, PROT_READ, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + // do not close fd here. fd will be closed in FileDescriptor, ::close(fd) + HiLog::Error(LABEL, "mmap error"); + return nullptr; + } + if (bufferSize <= 0) { + HiLog::Error(LABEL, "malloc parameter bufferSize:[%{public}d] error.", bufferSize); + return nullptr; + } + base = static_cast(malloc(bufferSize)); + if (base == nullptr) { + HiLog::Error(LABEL, "alloc output pixel memory size:[%{public}d] error.", bufferSize); + return nullptr; + } + if (memcpy_s(base, bufferSize, ptr, bufferSize) != 0) { + free(base); + base = nullptr; + HiLog::Error(LABEL, "memcpy pixel data size:[%{public}d] error.", bufferSize); + return nullptr; + } + + ReleaseMemory(AllocatorType::SHARE_MEM_ALLOC, ptr, &fd, bufferSize); +#endif + } + + return base; +} + +bool PixelMap::WriteFileDescriptor(Parcel &parcel, int fd) { if (fd < 0) { return false; @@ -1021,12 +1176,12 @@ bool PixelMap::WriteFileDescriptor(Parcel &data, int fd) const return false; } sptr descriptor = new IPCFileDescriptor(dupFd); - return data.WriteObject(descriptor); + return parcel.WriteObject(descriptor); } -int PixelMap::ReadFileDescriptor(Parcel &data) +int PixelMap::ReadFileDescriptor(Parcel &parcel) { - sptr descriptor = data.ReadObject(); + sptr descriptor = parcel.ReadObject(); if (descriptor == nullptr) { return -1; } @@ -1037,66 +1192,70 @@ int PixelMap::ReadFileDescriptor(Parcel &data) return dup(fd); } -bool PixelMap::Marshalling(Parcel &data) const +bool PixelMap::WriteImageInfo(Parcel &parcel) const { - int32_t PIXEL_MAP_INFO_MAX_LENGTH = 128; - int32_t bufferSize = rowDataSize_ * imageInfo_.size.height; - - if (static_cast(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH) > data.GetDataCapacity() && - !data.SetDataCapacity(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH)) { - HiLog::Error(LABEL, "set parcel max capacity:[%{public}d] failed.", bufferSize + PIXEL_MAP_INFO_MAX_LENGTH); + if (!parcel.WriteInt32(imageInfo_.size.width)) { + HiLog::Error(LABEL, "write image info width:[%{public}d] to parcel failed.", imageInfo_.size.width); return false; } - if (!data.WriteInt32(imageInfo_.size.width)) { - HiLog::Error(LABEL, "write pixel map width:[%{public}d] to parcel failed.", imageInfo_.size.width); + if (!parcel.WriteInt32(imageInfo_.size.height)) { + HiLog::Error(LABEL, "write image info height:[%{public}d] to parcel failed.", imageInfo_.size.height); return false; } - if (!data.WriteInt32(imageInfo_.size.height)) { - HiLog::Error(LABEL, "write pixel map height:[%{public}d] to parcel failed.", imageInfo_.size.height); + if (!parcel.WriteInt32(static_cast(imageInfo_.pixelFormat))) { + HiLog::Error(LABEL, "write image info pixel format:[%{public}d] to parcel failed.", imageInfo_.pixelFormat); return false; } - if (!data.WriteInt32(static_cast(imageInfo_.pixelFormat))) { - HiLog::Error(LABEL, "write pixel map pixel format:[%{public}d] to parcel failed.", imageInfo_.pixelFormat); + if (!parcel.WriteInt32(static_cast(imageInfo_.colorSpace))) { + HiLog::Error(LABEL, "write image info color space:[%{public}d] to parcel failed.", imageInfo_.colorSpace); return false; } - if (!data.WriteInt32(static_cast(imageInfo_.colorSpace))) { - HiLog::Error(LABEL, "write pixel map color space:[%{public}d] to parcel failed.", imageInfo_.colorSpace); + if (!parcel.WriteInt32(static_cast(imageInfo_.alphaType))) { + HiLog::Error(LABEL, "write image info alpha type:[%{public}d] to parcel failed.", imageInfo_.alphaType); return false; } - if (!data.WriteInt32(static_cast(imageInfo_.alphaType))) { - HiLog::Error(LABEL, "write pixel map alpha type:[%{public}d] to parcel failed.", imageInfo_.alphaType); + if (!parcel.WriteInt32(imageInfo_.baseDensity)) { + HiLog::Error(LABEL, "write image info base density:[%{public}d] to parcel failed.", imageInfo_.baseDensity); return false; } - if (!data.WriteInt32(imageInfo_.baseDensity)) { - HiLog::Error(LABEL, "write pixel map base density:[%{public}d] to parcel failed.", imageInfo_.baseDensity); + return true; +} + +bool PixelMap::Marshalling(Parcel &parcel) const +{ + int32_t PIXEL_MAP_INFO_MAX_LENGTH = 128; + int32_t bufferSize = rowDataSize_ * imageInfo_.size.height; + if (static_cast(bufferSize) <= MIN_IMAGEDATA_SIZE && + static_cast(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH) > parcel.GetDataCapacity() && + !parcel.SetDataCapacity(bufferSize + PIXEL_MAP_INFO_MAX_LENGTH)) { + HiLog::Error(LABEL, "set parcel max capacity:[%{public}d] failed.", bufferSize + PIXEL_MAP_INFO_MAX_LENGTH); return false; } - if (!data.WriteInt32(bufferSize)) { - HiLog::Error(LABEL, "write pixel map buffer size:[%{public}d] to parcel failed.", bufferSize); + if (!WriteImageInfo(parcel)) { + HiLog::Error(LABEL, "write image info to parcel failed."); return false; } - if (!data.WriteInt32(static_cast(allocatorType_))) { + + if (!parcel.WriteInt32(static_cast(allocatorType_))) { HiLog::Error(LABEL, "write pixel map allocator type:[%{public}d] to parcel failed.", allocatorType_); return false; } if (allocatorType_ == AllocatorType::SHARE_MEM_ALLOC) { +#if !defined(_WIN32) && !defined(_APPLE) int *fd = static_cast(context_); if (*fd < 0) { HiLog::Error(LABEL, "write pixel map failed, fd < 0."); return false; } - if (!WriteFileDescriptor(data, *fd)) { + + if (!WriteFileDescriptor(parcel, *fd)) { HiLog::Error(LABEL, "write pixel map fd:[%{public}d] to parcel failed.", *fd); return false; } +#endif } else { - const uint8_t *addr = data_; - if (addr == nullptr) { - HiLog::Error(LABEL, "write to parcel failed, pixel memory is null."); - return false; - } - if (!data.WriteBuffer(addr, bufferSize)) { + if (!WriteImageData(parcel, bufferSize)) { HiLog::Error(LABEL, "write pixel map buffer to parcel failed."); return false; } @@ -1104,32 +1263,46 @@ bool PixelMap::Marshalling(Parcel &data) const return true; } -PixelMap *PixelMap::Unmarshalling(Parcel &data) +bool PixelMap::ReadImageInfo(Parcel &parcel, ImageInfo &imgInfo) +{ + imgInfo.size.width = parcel.ReadInt32(); + HiLog::Debug(LABEL, "read pixel map width:[%{public}d] to parcel.", imgInfo.size.width); + imgInfo.size.height = parcel.ReadInt32(); + HiLog::Debug(LABEL, "read pixel map height:[%{public}d] to parcel.", imgInfo.size.height); + imgInfo.pixelFormat = static_cast(parcel.ReadInt32()); + HiLog::Debug(LABEL, "read pixel map pixelFormat:[%{public}d] to parcel.", imgInfo.pixelFormat); + imgInfo.colorSpace = static_cast(parcel.ReadInt32()); + HiLog::Debug(LABEL, "read pixel map colorSpace:[%{public}d] to parcel.", imgInfo.colorSpace); + imgInfo.alphaType = static_cast(parcel.ReadInt32()); + HiLog::Debug(LABEL, "read pixel map alphaType:[%{public}d] to parcel.", imgInfo.alphaType); + imgInfo.baseDensity = parcel.ReadInt32(); + return true; +} + +PixelMap *PixelMap::Unmarshalling(Parcel &parcel) { PixelMap *pixelMap = new PixelMap(); if (pixelMap == nullptr) { - HiLog::Error(LABEL, "create pixelmap pointer fail"); return nullptr; } ImageInfo imgInfo; - imgInfo.size.width = data.ReadInt32(); - imgInfo.size.height = data.ReadInt32(); - imgInfo.pixelFormat = static_cast(data.ReadInt32()); - imgInfo.colorSpace = static_cast(data.ReadInt32()); - imgInfo.alphaType = static_cast(data.ReadInt32()); - imgInfo.baseDensity = data.ReadInt32(); - int32_t bufferSize = data.ReadInt32(); - AllocatorType allocType = static_cast(data.ReadInt32()); + if (!pixelMap->ReadImageInfo(parcel, imgInfo)) { + HiLog::Error(LABEL, "read imageInfo fail"); + return nullptr; + } + + AllocatorType allocType = static_cast(parcel.ReadInt32()); + int32_t bufferSize = parcel.ReadInt32(); uint8_t *base = nullptr; void *context = nullptr; if (allocType == AllocatorType::SHARE_MEM_ALLOC) { - int fd = ReadFileDescriptor(data); +#if !defined(_WIN32) && !defined(_APPLE) + int fd = ReadFileDescriptor(parcel); if (fd < 0) { HiLog::Error(LABEL, "fd < 0"); return nullptr; } - HiLog::Debug(LABEL, "ReadFileDescriptor fd %{public}d.", fd); void* ptr = ::mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { ::close(fd); @@ -1138,49 +1311,24 @@ PixelMap *PixelMap::Unmarshalling(Parcel &data) } context = new int32_t(); if (context == nullptr) { - HiLog::Error(LABEL, "alloc context error."); ::munmap(ptr, bufferSize); ::close(fd); return nullptr; } *static_cast(context) = fd; base = static_cast(ptr); +#endif } else { - const uint8_t *addr = data.ReadBuffer(bufferSize); - if (addr == nullptr) { - HiLog::Error(LABEL, "read buffer from parcel failed, read buffer addr is null"); - return nullptr; - } - base = static_cast(malloc(bufferSize)); + base = ReadImageData(parcel, bufferSize); if (base == nullptr) { - HiLog::Error(LABEL, "alloc output pixel memory size:[%{public}d] error.", bufferSize); - return nullptr; - } - if (memcpy_s(base, bufferSize, addr, bufferSize) != 0) { - free(base); - base = nullptr; - HiLog::Error(LABEL, "memcpy pixel data size:[%{public}d] error.", bufferSize); + HiLog::Error(LABEL, "get pixel memory size:[%{public}d] error.", bufferSize); return nullptr; } } uint32_t ret = pixelMap->SetImageInfo(imgInfo); if (ret != SUCCESS) { - if (allocType == AllocatorType::SHARE_MEM_ALLOC) { - int *fd = static_cast(context); - if (base != nullptr) { - ::munmap(base, bufferSize); - } - if (fd != nullptr) { - ::close(*fd); - delete fd; - } - } else if (allocType == AllocatorType::HEAP_ALLOC) { - if (base != nullptr) { - free(base); - base = nullptr; - } - } + ReleaseMemory(allocType, base, context, bufferSize); HiLog::Error(LABEL, "create pixel map from parcel failed, set image info error."); return nullptr; } diff --git a/frameworks/innerkitsimpl/test/unittest/image_pixel_map_test.cpp b/frameworks/innerkitsimpl/test/unittest/image_pixel_map_test.cpp index c9906841482da40260ca97717113a36540ed7166..cbd34f6fd14f0c6196eeeda87563b77ea6c9b445 100644 --- a/frameworks/innerkitsimpl/test/unittest/image_pixel_map_test.cpp +++ b/frameworks/innerkitsimpl/test/unittest/image_pixel_map_test.cpp @@ -27,6 +27,8 @@ static constexpr int32_t PIXEL_MAP_TEST_HEIGHT = 3; static constexpr int32_t PIXEL_MAP_RGB565_BYTE = 2; static constexpr int32_t PIXEL_MAP_RGB888_BYTE = 3; static constexpr int32_t PIXEL_MAP_ARGB8888_BYTE = 4; +constexpr int32_t PIXEL_MAP_BIG_TEST_WIDTH = 4 * 1024; +constexpr int32_t PIXEL_MAP_BIG_TEST_HEIGHT = 3 * 100; class ImagePixelMapTest : public testing::Test { public: @@ -48,7 +50,13 @@ public: int32_t rowDataSize = pixelMapWidth; uint32_t bufferSize = rowDataSize * pixelMapHeight; + if (bufferSize <= 0) { + return nullptr; + } void *buffer = malloc(bufferSize); + if (buffer == nullptr) { + return nullptr; + } char *ch = (char *)buffer; for (unsigned int i = 0; i < bufferSize; i++) { *(ch++) = (char)i; @@ -58,6 +66,36 @@ public: return pixelMap; } + + std::unique_ptr ConstructBigPixmap() + { + int32_t pixelMapWidth = PIXEL_MAP_BIG_TEST_WIDTH; + int32_t pixelMapHeight = PIXEL_MAP_BIG_TEST_HEIGHT; + std::unique_ptr pixelMap = std::make_unique(); + ImageInfo info; + info.size.width = pixelMapWidth; + info.size.height = pixelMapHeight; + info.pixelFormat = PixelFormat::RGB_888; + info.colorSpace = ColorSpace::SRGB; + pixelMap->SetImageInfo(info); + + int32_t bufferSize = pixelMap->GetByteCount(); + if (bufferSize <= 0) { + return nullptr; + } + std::unique_ptr buffer = malloc(bufferSize); + if (buffer == nullptr) { + return nullptr; + } + char *ch = (char *)buffer; + for (int32_t i = 0; i < bufferSize; i++) { + *(ch++) = 'a'; + } + + pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr); + + return pixelMap; + } /** * @tc.name: ImagePixelMap001 * @tc.desc: ALPHA_8 pixel format pixel map operation @@ -469,22 +507,16 @@ HWTEST_F(ImagePixelMapTest, ImagePixelMap011, TestSize.Level3) GTEST_LOG_(INFO) << "ImagePixelMapTest: ImagePixelMap011 start"; Parcel data; - std::unique_ptr pixelmap1 = ConstructPixmap(); - bool ret = pixelmap1.get()->Marshalling(data); - EXPECT_EQ(true, ret); PixelMap *pixelmap2 = PixelMap::Unmarshalling(data); - EXPECT_EQ(pixelmap1->GetHeight(), pixelmap2->GetHeight()); EXPECT_EQ(pixelmap1->GetWidth(), pixelmap2->GetWidth()); EXPECT_EQ(pixelmap1->GetPixelFormat(), pixelmap2->GetPixelFormat()); EXPECT_EQ(pixelmap1->GetColorSpace(), pixelmap2->GetColorSpace()); - EXPECT_EQ(true, pixelmap1->IsSameImage(*pixelmap2)); - GTEST_LOG_(INFO) << "ImagePixelMapTest: ImagePixelMap011 end"; } /** @@ -513,5 +545,40 @@ HWTEST_F(ImagePixelMapTest, ImagePixelMap012, TestSize.Level3) EXPECT_EQ(newPixelMap, nullptr); GTEST_LOG_(INFO) << "ImagePixelMapTest: ImagePixelMap012 end"; } + + +/** +* @tc.name: ImagePixelMap013 +* @tc.desc: test CreateFromParcel +* @tc.type: FUNC +* @tc.require: AR000FTAMO +*/ +HWTEST_F(ImagePixelMapTest, ImagePixelMap013, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImagePixelMapTest: ImagePixelMap013 start"; + + Parcel data; + std::unique_ptr pixelmap1 = ConstructBigPixmap(); + EXPECT_NE(pixelmap1, nullptr); + GTEST_LOG_(INFO) << "ImagePixelMap013 ConstructPixmap success"; + bool ret = pixelmap1.get()->Marshalling(data); + GTEST_LOG_(INFO) << "ImagePixelMap013 Marshalling success"; + EXPECT_EQ(true, ret); + + PixelMap *pixelmap2 = PixelMap::Unmarshalling(data); + GTEST_LOG_(INFO) << "ImagePixelMap013 Unmarshalling success"; + GTEST_LOG_(INFO) << "ImagePixelMap013 pixelmap1 GetHeight :" << pixelmap1->GetHeight(); + GTEST_LOG_(INFO) << "ImagePixelMap013 pixelmap2 GetHeight :" << pixelmap2->GetHeight(); + EXPECT_EQ(pixelmap1->GetHeight(), pixelmap2->GetHeight()); + GTEST_LOG_(INFO) << "ImagePixelMap013 GetHeight success"; + EXPECT_EQ(pixelmap1->GetWidth(), pixelmap2->GetWidth()); + GTEST_LOG_(INFO) << "ImagePixelMap013 GetWidth success"; + EXPECT_EQ(pixelmap1->GetPixelFormat(), pixelmap2->GetPixelFormat()); + GTEST_LOG_(INFO) << "ImagePixelMap013 GetPixelFormat success"; + EXPECT_EQ(pixelmap1->GetColorSpace(), pixelmap2->GetColorSpace()); + GTEST_LOG_(INFO) << "ImagePixelMap013 GetColorSpace success"; + EXPECT_EQ(true, pixelmap1->IsSameImage(*pixelmap2)); + GTEST_LOG_(INFO) << "ImagePixelMapTest: ImagePixelMap013 end"; +} } // namespace Multimedia } // namespace OHOS \ No newline at end of file diff --git a/frameworks/kits/js/common/pixel_map_napi.cpp b/frameworks/kits/js/common/pixel_map_napi.cpp index 7eb75e2a1c71be51fe6c4981f20217271f56919f..3aa4d78609fb042f0bd4f8846ca83a024af426ce 100644 --- a/frameworks/kits/js/common/pixel_map_napi.cpp +++ b/frameworks/kits/js/common/pixel_map_napi.cpp @@ -454,16 +454,11 @@ napi_value PixelMapNapi::CreatePixelMap(napi_env env, napi_callback_info info) IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar); - //we are static method! - //thisVar is nullptr here + // we are static method! + // this Var is nullptr here IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info")); - //IMG_NAPI_CHECK_RET_D(argCount >= 2, nullptr, HiLog::Error(LABEL, "CreatePixelMap args count mismatch %{public}d", argCount)); std::unique_ptr asyncContext = std::make_unique(); -// status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->nConstructor)); - -// IMG_NAPI_CHECK_RET_D(IMG_IS_READY(status, asyncContext->nConstructor), -// nullptr, HiLog::Error(LABEL, "fail to unwrap context")); status = napi_get_arraybuffer_info(env, argValue[0], &(asyncContext->colorsBuffer), &(asyncContext->colorsBufferSize)); @@ -483,7 +478,7 @@ napi_value PixelMapNapi::CreatePixelMap(napi_env env, napi_callback_info info) napi_get_undefined(env, &result); } - IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap", + IMG_CREATE_CREATE_ASYNC_WORK(env, status, "CreatePixelMap", CreatePixelMapExec, CreatePixelMapComplete, asyncContext, asyncContext->work); IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), @@ -556,7 +551,6 @@ napi_value PixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info inf IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar); IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info")); - //IMG_NAPI_CHECK_RET_D(argCount >= 1, nullptr, HiLog::Error(LABEL, "ReadPixelsToBuffer args count mismatch %{public}d", argCount)); std::unique_ptr asyncContext = std::make_unique(); status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->nConstructor)); @@ -585,7 +579,7 @@ napi_value PixelMapNapi::ReadPixelsToBuffer(napi_env env, napi_callback_info inf napi_get_undefined(env, &result); } - IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsToBuffer", + IMG_CREATE_CREATE_ASYNC_WORK(env, status, "ReadPixelsToBuffer", [](napi_env env, void *data) { auto context = static_cast(data); @@ -615,7 +609,6 @@ napi_value PixelMapNapi::ReadPixels(napi_env env, napi_callback_info info) IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar); IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info")); - //IMG_NAPI_CHECK_RET_D(argCount >= 1, nullptr, HiLog::Error(LABEL, "ReadPixels args count mismatch %{public}d", argCount)); std::unique_ptr asyncContext = std::make_unique(); status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->nConstructor)); @@ -671,7 +664,6 @@ napi_value PixelMapNapi::WritePixels(napi_env env, napi_callback_info info) IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar); IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info")); - //IMG_NAPI_CHECK_RET_D(argCount >= 1, nullptr, HiLog::Error(LABEL, "WritePixels args count mismatch %{public}d", argCount)); std::unique_ptr asyncContext = std::make_unique(); status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->nConstructor)); @@ -728,7 +720,6 @@ napi_value PixelMapNapi::WriteBufferToPixels(napi_env env, napi_callback_info in IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar); IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info")); - //IMG_NAPI_CHECK_RET_D(argCount >= 1, nullptr, HiLog::Error(LABEL, "WriteBufferToPixels args count mismatch %{public}d", argCount)); std::unique_ptr asyncContext = std::make_unique(); status = napi_unwrap(env, thisVar, reinterpret_cast(&asyncContext->nConstructor)); diff --git a/interfaces/innerkits/include/pixel_map.h b/interfaces/innerkits/include/pixel_map.h index 68a5a44b8b4bdb13abd023aec94a59b48f117717..eccacc2abca823a60e819d5427f49adcd4852b7a 100644 --- a/interfaces/innerkits/include/pixel_map.h +++ b/interfaces/innerkits/include/pixel_map.h @@ -120,6 +120,8 @@ public: NATIVEEXPORT bool Marshalling(Parcel &data) const override; NATIVEEXPORT static PixelMap *Unmarshalling(Parcel &data); private: + static constexpr size_t MAX_IMAGEDATA_SIZE = 128 * 1024 * 1024; // 128M + static constexpr size_t MIN_IMAGEDATA_SIZE = 32 * 1024; // 32k friend class ImageSource; static bool ALPHA8ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount); static bool RGB565ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out, uint32_t outCount); @@ -162,8 +164,14 @@ private: ? false : true; } - bool WriteFileDescriptor(Parcel &data, int fd) const; - static int ReadFileDescriptor(Parcel &data); + + static void ReleaseMemory(AllocatorType allocType, void *addr, void *context, uint32_t size); + bool WriteImageData(Parcel &parcel, size_t size) const; + static uint8_t *ReadImageData(Parcel &parcel, int32_t size); + static int ReadFileDescriptor(Parcel &parcel); + static bool WriteFileDescriptor(Parcel &parcel, int fd); + bool ReadImageInfo(Parcel &parcel, ImageInfo &imgInfo); + bool WriteImageInfo(Parcel &parcel) const; uint8_t *data_ = nullptr; // this info SHOULD be the final info for decoded pixelmap, not the original image info diff --git a/plugins/common/libs/BUILD.gn b/plugins/common/libs/BUILD.gn index 3e705a6be24c459cafafad3d11bd085f699d0d6c..9f45b2280c50ebe399529eebaef99beeb7253710 100644 --- a/plugins/common/libs/BUILD.gn +++ b/plugins/common/libs/BUILD.gn @@ -40,6 +40,8 @@ group("multimediaplugin") { # "image/libheifplugin:heifplugin", # "image/libheifplugin:heifpluginmetadata", + "image/libbmpplugin:bmpplugin", + "image/libbmpplugin:bmppluginmetadata", "image/libjpegplugin:jpegplugin", "image/libjpegplugin:jpegpluginmetadata", "image/libpngplugin:pngplugin", diff --git a/plugins/common/libs/image/formatagentplugin/src/plugin_export.cpp b/plugins/common/libs/image/formatagentplugin/src/plugin_export.cpp index 9b80719096b3d936164f74d970e6c3da43fbeb9b..ad8b053cea655349eb34638aaed20cbd24572321 100644 --- a/plugins/common/libs/image/formatagentplugin/src/plugin_export.cpp +++ b/plugins/common/libs/image/formatagentplugin/src/plugin_export.cpp @@ -27,7 +27,9 @@ #include "wbmp_format_agent.h" // plugin package name same as metadata. -PLUGIN_EXPORT_REGISTER_PACKAGE("LibImageFormatAgent") +namespace { + const std::string PACKAGE_NAME = ("LibImageFormatAgent"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN @@ -41,14 +43,35 @@ PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::RawFormatAgent) PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::WbmpFormatAgent) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibImageFormatAgent" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin. PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} \ No newline at end of file diff --git a/plugins/common/libs/image/libbmpplugin/BUILD.gn b/plugins/common/libs/image/libbmpplugin/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4bbdceeff66d7389ad81b36ebf047c7cdaa9ceec --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/BUILD.gn @@ -0,0 +1,94 @@ +# Copyright (C) 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. + +import("//build/ohos.gni") +import("//foundation/multimedia/image_standard/ide/image_decode_config.gni") + +ohos_shared_library("bmpplugin") { + sources = [ + "//foundation/multimedia/image_standard/plugins/common/libs/image/libbmpplugin/src/bmp_decoder.cpp", + "//foundation/multimedia/image_standard/plugins/common/libs/image/libbmpplugin/src/bmp_stream.cpp", + "//foundation/multimedia/image_standard/plugins/common/libs/image/libbmpplugin/src/plugin_export.cpp", + ] + + include_dirs = [ + "//foundation/multimedia/utils/include", + "//foundation/multimedia/image_standard/plugins/manager/include", + "//foundation/multimedia/image_standard/plugins/manager/include/image", + "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase", + "//foundation/multimedia/image_standard/plugins/common/libs/image/libbmpplugin/include", + "//foundation/multimedia/image_standard/interfaces/innerkits/include", + "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include", + "//third_party/flutter/skia/include/core", + "//third_party/flutter/skia/include/codec", + "//third_party/flutter/skia", + ] + if (use_mingw_win) { + defines = image_decode_windows_defines + include_dirs += [ + "//foundation/multimedia/image_standard/mock/native/include", + "//foundation/multimedia/image_standard/mock/native/include/secure", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/win", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config", + ] + deps = [ + "//foundation/ace/ace_engine/build/third_party/flutter/skia:ace_skia_core", + "//foundation/graphic/ide/libs/skia:skia", + "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils_static", + "//foundation/multimedia/image_standard/mock/native:log_mock_static", + "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static", + ] + + #libs = [ "//foundation/multimedia/image/libskia.lib" ] + } else if (use_clang_mac) { + defines = image_decode_mac_defines + include_dirs += [ + "//foundation/multimedia/image_standard/mock/native/include", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/mac", + "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config", + "//utils/native/base/include", + ] + deps = [ + "//foundation/graphic/ide/libs/skia:skia", + "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils_static", + "//foundation/multimedia/image_standard/mock/native:log_mock_static", + "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static", + "//utils/native/base:utilsecurec", + ] + } else { + include_dirs += [ "//utils/native/base/include" ] + deps = [ + "//foundation/ace/ace_engine/build/third_party/flutter/skia:ace_skia_ohos", + "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils", + "//foundation/multimedia/image_standard/plugins/manager:pluginmanager", + "//utils/native/base:utils", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + + #aosp_deps = [ "shared_library:libhwui" ] + } + subsystem_name = "multimedia" + part_name = "multimedia_image_standard" +} + +ohos_prebuilt_etc("bmppluginmetadata") { + source = "bmpplugin.pluginmeta" + relative_install_dir = "multimediaplugin/image" + subsystem_name = "multimedia" + part_name = "multimedia_image_standard" +} diff --git a/plugins/common/libs/image/libbmpplugin/bmpplugin.pluginmeta b/plugins/common/libs/image/libbmpplugin/bmpplugin.pluginmeta new file mode 100644 index 0000000000000000000000000000000000000000..0ffc1cac68e8343cc6bf4f6ad4c875cfb288428b --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/bmpplugin.pluginmeta @@ -0,0 +1,25 @@ +{ + "packageName":"LibBmpPlugin", + "version":"1.0.0.0", + "targetVersion":"1.0.0.0", + "libraryPath":"libbmpplugin.z.so", + "classes": [ + { + "className":"OHOS::ImagePlugin::BmpDecoder", + "services": [ + { + "interfaceID":2, + "serviceType":0 + } + ], + "priority":100, + "capabilities": [ + { + "name":"encodeFormat", + "type":"string", + "value": "image/bmp" + } + ] + } + ] +} diff --git a/plugins/common/libs/image/libbmpplugin/include/bmp_decoder.h b/plugins/common/libs/image/libbmpplugin/include/bmp_decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..af5798c23fb699f757ce89e42863dea68d526ba3 --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/include/bmp_decoder.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 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. + */ + +#ifndef BMP_DECODER_H +#define BMP_DECODER_H + +#include +#include +#include "SkCodec.h" +#include "abs_image_decoder.h" +#include "bmp_stream.h" +#include "hilog/log.h" +#include "log_tags.h" +#include "plugin_class_base.h" + +namespace OHOS { +namespace ImagePlugin { +enum class BmpDecodingState : int32_t { + UNDECIDED = 0, + SOURCE_INITED = 1, + BASE_INFO_PARSED = 2, + IMAGE_DECODING = 3, + IMAGE_ERROR = 4, + IMAGE_DECODED = 5 +}; + +class BmpDecoder : public AbsImageDecoder, public OHOS::MultimediaPlugin::PluginClassBase { +public: + BmpDecoder() = default; + virtual ~BmpDecoder() override {}; + void SetSource(InputDataStream &sourceStream) override; + void Reset() override; + uint32_t SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) override; + uint32_t Decode(uint32_t index, DecodeContext &context) override; + uint32_t GetImageSize(uint32_t index, PlSize &size) override; + uint32_t PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) override; + +private: + DISALLOW_COPY_AND_MOVE(BmpDecoder); + bool DecodeHeader(); + PlAlphaType ConvertToAlphaType(SkAlphaType alphaType); + SkColorType ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat); + uint32_t SetContextPixelsBuffer(uint64_t byteCount, DecodeContext &context); + uint32_t SetShareMemBuffer(uint64_t byteCount, DecodeContext &context); + InputDataStream *stream_ = nullptr; + std::unique_ptr codec_ = nullptr; + SkImageInfo info_; + SkColorType desireColor_ = kUnknown_SkColorType; + BmpDecodingState state_ = BmpDecodingState::UNDECIDED; +}; +} // namespace ImagePlugin +} // namespace OHOS + +#endif // BMP_DECODER_H diff --git a/plugins/common/libs/image/libbmpplugin/include/bmp_stream.h b/plugins/common/libs/image/libbmpplugin/include/bmp_stream.h new file mode 100644 index 0000000000000000000000000000000000000000..7502cabbbb87c4fcfa6587d3929cf45fb89b49cd --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/include/bmp_stream.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 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. + */ + +#ifndef BMP_STREAM_H +#define BMP_STREAM_H + +#include +#include +#include "SkStream.h" +#include "hilog/log.h" +#include "input_data_stream.h" +#include "log_tags.h" +#include "nocopyable.h" + +namespace OHOS { +namespace ImagePlugin { +class BmpStream : public SkStream { +public: + BmpStream() = default; + explicit BmpStream(InputDataStream *stream); + virtual ~BmpStream() override {}; + /** + * Reads or skips size number of bytes. + * if buffer is null, skip size bytes, return how many bytes skipped. + * else copy size bytes into buffer, return how many bytes copied. + */ + size_t read(void *buffer, size_t size) override; + /** + * Peeks size number of bytes. + */ + size_t peek(void *buffer, size_t size) const override; + /** + * Returns true when all the bytes in the stream have been read. + */ + bool isAtEnd() const override; + +private: + DISALLOW_COPY_AND_MOVE(BmpStream); + ImagePlugin::InputDataStream *inputStream_ = nullptr; +}; +} // namespace ImagePlugin +} // namespace OHOS + +#endif // BMP_STREAM_H diff --git a/plugins/common/libs/image/libbmpplugin/src/bmp_decoder.cpp b/plugins/common/libs/image/libbmpplugin/src/bmp_decoder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dbcc6913a60d0890963da728f3886915e4238cd5 --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/src/bmp_decoder.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (C) 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 "bmp_decoder.h" +#include "image_utils.h" +#include "media_errors.h" +#include "securec.h" + +namespace OHOS { +namespace ImagePlugin { +using namespace OHOS::HiviewDFX; +using namespace Media; +using namespace std; +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "BmpDecoder" }; +namespace { +constexpr uint32_t BMP_IMAGE_NUM = 1; +} + +void BmpDecoder::SetSource(InputDataStream &sourceStream) +{ + stream_ = &sourceStream; + state_ = BmpDecodingState::SOURCE_INITED; +} + +void BmpDecoder::Reset() +{ + if (stream_ != nullptr) { + stream_->Seek(0); + } + codec_.release(); + info_.reset(); + desireColor_ = kUnknown_SkColorType; +} + +uint32_t BmpDecoder::GetImageSize(uint32_t index, PlSize &size) +{ + if (index >= BMP_IMAGE_NUM) { + HiLog::Error(LABEL, "GetImageSize failed, invalid index:%{public}u, range:%{public}u", index, BMP_IMAGE_NUM); + return ERR_IMAGE_INVALID_PARAMETER; + } + if (state_ < BmpDecodingState::SOURCE_INITED) { + HiLog::Error(LABEL, "GetImageSize failed, invalid state:%{public}d", state_); + return ERR_MEDIA_INVALID_OPERATION; + } + if (state_ >= BmpDecodingState::BASE_INFO_PARSED) { + size.width = info_.width(); + size.height = info_.height(); + return SUCCESS; + } + if (!DecodeHeader()) { + HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_); + return ERR_IMAGE_DECODE_HEAD_ABNORMAL; + } + size.width = info_.width(); + size.height = info_.height(); + state_ = BmpDecodingState::BASE_INFO_PARSED; + return SUCCESS; +} + +uint32_t BmpDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) +{ + if (index >= BMP_IMAGE_NUM) { + HiLog::Error(LABEL, "SetDecodeOptions failed, invalid index:%{public}u, range:%{public}u", index, + BMP_IMAGE_NUM); + return ERR_IMAGE_INVALID_PARAMETER; + } + if (state_ < BmpDecodingState::SOURCE_INITED) { + HiLog::Error(LABEL, "SetDecodeOptions failed, invalid state %{public}d", state_); + return ERR_MEDIA_INVALID_OPERATION; + } + if (state_ >= BmpDecodingState::IMAGE_DECODING) { + Reset(); + state_ = BmpDecodingState::SOURCE_INITED; + } + if (state_ < BmpDecodingState::BASE_INFO_PARSED) { + if (!DecodeHeader()) { + HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_); + return ERR_IMAGE_DECODE_HEAD_ABNORMAL; + } + state_ = BmpDecodingState::BASE_INFO_PARSED; + } + PlPixelFormat desiredFormat = opts.desiredPixelFormat; + desireColor_ = ConvertToColorType(desiredFormat, info.pixelFormat); + info.size.width = info_.width(); + info.size.height = info_.height(); + info.alphaType = ConvertToAlphaType(info_.alphaType()); + state_ = BmpDecodingState::IMAGE_DECODING; + return SUCCESS; +} + +uint32_t BmpDecoder::SetShareMemBuffer(uint64_t byteCount, DecodeContext &context) +{ + int fd = AshmemCreate("BMP RawData", byteCount); + if (fd < 0) { + return ERR_SHAMEM_DATA_ABNORMAL; + } + int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE); + if (result < 0) { + ::close(fd); + return ERR_SHAMEM_DATA_ABNORMAL; + } + void* ptr = ::mmap(nullptr, byteCount, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + ::close(fd); + return ERR_SHAMEM_DATA_ABNORMAL; + } + context.pixelsBuffer.buffer = ptr; + void *fdBuffer = new int32_t(); + if (fdBuffer == nullptr) { + ::munmap(ptr, byteCount); + ::close(fd); + context.pixelsBuffer.buffer = nullptr; + return ERR_SHAMEM_DATA_ABNORMAL; + } + *static_cast(fdBuffer) = fd; + context.pixelsBuffer.context = fdBuffer; + context.pixelsBuffer.bufferSize = byteCount; + context.allocatorType = AllocatorType::SHARE_MEM_ALLOC; + context.freeFunc = nullptr; + return SUCCESS; +} + +uint32_t BmpDecoder::SetContextPixelsBuffer(uint64_t byteCount, DecodeContext &context) +{ + if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) { +#if !defined(_WIN32) && !defined(_APPLE) + uint32_t res = SetShareMemBuffer(byteCount, context); + if (res != SUCCESS) { + return res; + } +#endif + } else { + if (byteCount <= 0) { + HiLog::Error(LABEL, "Decode failed, byteCount is invalid value"); + return ERR_MEDIA_INVALID_VALUE; + } + void *outputBuffer = malloc(byteCount); + if (outputBuffer == nullptr) { + HiLog::Error(LABEL, "Decode failed, alloc output buffer size:[%{public}llu] error", + static_cast(byteCount)); + return ERR_IMAGE_MALLOC_ABNORMAL; + } +#ifdef _WIN32 + memset(outputBuffer, 0, byteCount); +#else + if (memset_s(outputBuffer, byteCount, 0, byteCount) != EOK) { + HiLog::Error(LABEL, "Decode failed, memset buffer failed"); + free(outputBuffer); + outputBuffer = nullptr; + return ERR_IMAGE_DECODE_FAILED; + } +#endif + context.pixelsBuffer.buffer = outputBuffer; + context.pixelsBuffer.bufferSize = byteCount; + context.pixelsBuffer.context = nullptr; + context.allocatorType = AllocatorType::HEAP_ALLOC; + context.freeFunc = nullptr; + } + return SUCCESS; +} + +uint32_t BmpDecoder::Decode(uint32_t index, DecodeContext &context) +{ + if (index >= BMP_IMAGE_NUM) { + HiLog::Error(LABEL, "Decode failed, invalid index:%{public}u, range:%{public}u", index, BMP_IMAGE_NUM); + return ERR_IMAGE_INVALID_PARAMETER; + } + if (codec_ == nullptr) { + HiLog::Error(LABEL, "Decode failed, codec is null"); + return ERR_IMAGE_DECODE_FAILED; + } + if (state_ != BmpDecodingState::IMAGE_DECODING) { + HiLog::Error(LABEL, "Decode failed, invalid state %{public}d", state_); + return ERR_MEDIA_INVALID_OPERATION; + } + + SkImageInfo dstInfo = info_.makeColorType(desireColor_); + if (ImageUtils::CheckMulOverflow(dstInfo.width(), dstInfo.height(), dstInfo.bytesPerPixel())) { + HiLog::Error(LABEL, "Decode failed, width:%{public}d, height:%{public}d is too large", + dstInfo.width(), dstInfo.height()); + return ERR_IMAGE_DECODE_FAILED; + } + if (context.pixelsBuffer.buffer == nullptr) { + uint64_t byteCount = static_cast(dstInfo.height()) * dstInfo.width() * dstInfo.bytesPerPixel(); + uint32_t res = SetContextPixelsBuffer(byteCount, context); + if (res != SUCCESS) { + return res; + } + } + uint8_t *dstBuffer = static_cast(context.pixelsBuffer.buffer); + size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel(); + SkCodec::Result ret = codec_->getPixels(dstInfo, dstBuffer, rowBytes); + if (ret != SkCodec::kSuccess) { + HiLog::Error(LABEL, "Decode failed, get pixels failed, ret=%{public}d", ret); + state_ = BmpDecodingState::IMAGE_ERROR; + return ERR_IMAGE_DECODE_ABNORMAL; + } + state_ = BmpDecodingState::IMAGE_DECODED; + return SUCCESS; +} + +uint32_t BmpDecoder::PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) +{ + // currently not support increment decode + return ERR_IMAGE_DATA_UNSUPPORT; +} + +bool BmpDecoder::DecodeHeader() +{ + codec_ = SkCodec::MakeFromStream(make_unique(stream_)); + if (codec_ == nullptr) { + HiLog::Error(LABEL, "create codec from stream failed"); + return false; + } + info_ = codec_->getInfo(); + return true; +} + +PlAlphaType BmpDecoder::ConvertToAlphaType(SkAlphaType alphaType) +{ + switch (alphaType) { + case kOpaque_SkAlphaType: + return PlAlphaType::IMAGE_ALPHA_TYPE_OPAQUE; + case kPremul_SkAlphaType: + return PlAlphaType::IMAGE_ALPHA_TYPE_PREMUL; + case kUnpremul_SkAlphaType: + return PlAlphaType::IMAGE_ALPHA_TYPE_UNPREMUL; + default: + HiLog::Error(LABEL, "known alpha type:%{public}d", alphaType); + break; + } + return PlAlphaType::IMAGE_ALPHA_TYPE_UNKNOWN; +} + +SkColorType BmpDecoder::ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat) +{ + switch (format) { + case PlPixelFormat::UNKNOWN: + case PlPixelFormat::RGBA_8888: { + outputFormat = PlPixelFormat::RGBA_8888; + return kRGBA_8888_SkColorType; + } + case PlPixelFormat::BGRA_8888: { + outputFormat = PlPixelFormat::BGRA_8888; + return kBGRA_8888_SkColorType; + } + case PlPixelFormat::ALPHA_8: { + SkColorType colorType = info_.colorType(); + if (colorType == kAlpha_8_SkColorType || (colorType == kGray_8_SkColorType && info_.isOpaque())) { + outputFormat = PlPixelFormat::ALPHA_8; + return kAlpha_8_SkColorType; + } + break; + } + case PlPixelFormat::RGB_565: { + if (info_.isOpaque()) { + outputFormat = PlPixelFormat::RGB_565; + return kRGB_565_SkColorType; + } + break; + } + default: { + break; + } + } + HiLog::Debug(LABEL, "unsupported convert to format:%{public}d, set default RGBA", format); + outputFormat = PlPixelFormat::RGBA_8888; + return kRGBA_8888_SkColorType; +} +} // namespace ImagePlugin +} // namespace OHOS \ No newline at end of file diff --git a/plugins/common/libs/image/libbmpplugin/src/bmp_stream.cpp b/plugins/common/libs/image/libbmpplugin/src/bmp_stream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6694bce8bed4098442a5bbe0b21624db89f8214e --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/src/bmp_stream.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 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 "bmp_stream.h" + +namespace OHOS { +namespace ImagePlugin { +using namespace OHOS::HiviewDFX; +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "BmpStream" }; +BmpStream::BmpStream(InputDataStream *stream) : inputStream_(stream) {} + +size_t BmpStream::read(void *buffer, size_t size) +{ + if (inputStream_ == nullptr) { + HiLog::Error(LABEL, "read failed, inputStream_ is null"); + return 0; + } + if (buffer == nullptr) { + size_t curPosition = static_cast(inputStream_->Tell()); + if (!inputStream_->Seek(curPosition + size)) { + HiLog::Error(LABEL, "read failed, curpositon=%{public}zu, skip size=%{public}zu", curPosition, size); + return 0; + } + return size; + } + uint32_t desireSize = static_cast(size); + uint32_t bufferSize = desireSize; + uint32_t readSize = desireSize; + if (!inputStream_->Read(desireSize, static_cast(buffer), bufferSize, readSize)) { + HiLog::Error(LABEL, "read failed, desire read size=%{public}u", desireSize); + return 0; + } + return readSize; +} + +size_t BmpStream::peek(void *buffer, size_t size) const +{ + if (inputStream_ == nullptr) { + HiLog::Error(LABEL, "peek failed, inputStream_ is null"); + return 0; + } + if (buffer == nullptr) { + HiLog::Error(LABEL, "peek failed, output buffer is null"); + return 0; + } + uint32_t desireSize = static_cast(size); + uint32_t bufferSize = desireSize; + uint32_t readSize = desireSize; + if (!inputStream_->Peek(desireSize, static_cast(buffer), bufferSize, readSize)) { + HiLog::Error(LABEL, "peek failed, desire peek size=%{public}u", desireSize); + return 0; + } + return readSize; +} + +bool BmpStream::isAtEnd() const +{ + if (inputStream_ == nullptr) { + HiLog::Error(LABEL, "get stream status failed, inputStream_ is null."); + return false; + } + size_t size = inputStream_->GetStreamSize(); + return (inputStream_->Tell() == size); +} +} // namespace ImagePlugin +} // namespace OHOS diff --git a/plugins/common/libs/image/libbmpplugin/src/plugin_export.cpp b/plugins/common/libs/image/libbmpplugin/src/plugin_export.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f96396f0675824766ebac4192570ce767b010b7e --- /dev/null +++ b/plugins/common/libs/image/libbmpplugin/src/plugin_export.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 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 "plugin_export.h" +#include "bmp_decoder.h" +#include "hilog/log.h" +#include "log_tags.h" +#include "plugin_utils.h" + +// plugin package name same as metadata. +namespace { + const std::string PACKAGE_NAME = ("LibBmpPlugin"); +} + +// register implement classes of this plugin. +PLUGIN_EXPORT_REGISTER_CLASS_BEGIN +PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::BmpDecoder) +PLUGIN_EXPORT_REGISTER_CLASS_END + +using std::string; +using namespace OHOS::HiviewDFX; + +static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibBmpPlugin" }; + +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) + +// define the external interface of this plugin. +PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() +PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} \ No newline at end of file diff --git a/plugins/common/libs/image/libgifplugin/src/plugin_export.cpp b/plugins/common/libs/image/libgifplugin/src/plugin_export.cpp index 549b117b51dcfaf7e3598595d4965fbc20826cfb..bce66c2cc2d3a5a7f20f72aa6db6be6eb3efa73b 100644 --- a/plugins/common/libs/image/libgifplugin/src/plugin_export.cpp +++ b/plugins/common/libs/image/libgifplugin/src/plugin_export.cpp @@ -20,21 +20,44 @@ #include "gif_decoder.h" // plugin package name same as metadata. -PLUGIN_EXPORT_REGISTER_PACKAGE("LibGifPlugin") +namespace { + const std::string PACKAGE_NAME = ("LibGifPlugin"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::GifDecoder) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibGifPlugin" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin. PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} diff --git a/plugins/common/libs/image/libheifplugin/src/plugin_export.cpp b/plugins/common/libs/image/libheifplugin/src/plugin_export.cpp index 9e32a21647bb65b5d7dbcd841ceba6e218665f25..b18be40a5c6ef679ccce86e2e1d47b9344c5b172 100644 --- a/plugins/common/libs/image/libheifplugin/src/plugin_export.cpp +++ b/plugins/common/libs/image/libheifplugin/src/plugin_export.cpp @@ -20,21 +20,44 @@ #include "plugin_utils.h" // plugin package name same as metadata. -PLUGIN_EXPORT_REGISTER_PACKAGE("LibHeifPlugin") +namespace { + const std::string PACKAGE_NAME = ("LibHeifPlugin"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::HeifDecoder) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibHeifPlugin" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin. PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} diff --git a/plugins/common/libs/image/libjpegplugin/BUILD.gn b/plugins/common/libs/image/libjpegplugin/BUILD.gn index 593d55dbec497da7bbcf3601f7b3ce4533c712a3..71aca4ffbcc35756ca4e1a0f58ddc336dff79a2c 100644 --- a/plugins/common/libs/image/libjpegplugin/BUILD.gn +++ b/plugins/common/libs/image/libjpegplugin/BUILD.gn @@ -41,25 +41,25 @@ ohos_shared_library("jpegplugin") { include_dirs += [ "//foundation/multimedia/image_standard/mock/native/include", - "//third_party/libjpeg", + "//third_party/flutter/skia/third_party/libjpeg-turbo", ] deps = [ + "//foundation/ace/ace_engine/build/third_party/flutter/libjpeg:ace_libjpeg", "//foundation/multimedia/image_standard/interfaces/innerkits:image_static", "//foundation/multimedia/image_standard/mock/native:utils_mock_static", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static", - "//third_party/libjpeg:libjpeg_static", ] } else if (use_clang_mac) { defines = image_decode_mac_defines include_dirs += [ "//foundation/multimedia/image_standard/mock/native/include", - "//third_party/libjpeg", + "//third_party/flutter/skia/third_party/libjpeg-turbo", ] deps = [ + "//foundation/ace/ace_engine/build/third_party/flutter/libjpeg:ace_libjpeg", "//foundation/multimedia/image_standard/interfaces/innerkits:image_static", "//foundation/multimedia/image_standard/mock/native:utils_mock_static", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static", - "//third_party/libjpeg:libjpeg_static", ] } else { defines = [ "DUAL_ADAPTER" ] @@ -67,16 +67,17 @@ ohos_shared_library("jpegplugin") { include_dirs += [ "//utils/native/base/include" ] sources += [ "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/jpeg_encoder.cpp" ] deps = [ + #"//third_party/flutter/skia/third_party/libjpeg-turbo:libjpeg", + "//foundation/ace/ace_engine/build/third_party/flutter/libjpeg:ace_libjpeg", "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager", - "//third_party/libjpeg:libjpeg_static", "//utils/native/base:utils", ] if (DUAL_ADAPTER) { } else { - deps += [ "//third_party/libjpeg:libjpeg_static" ] - include_dirs += [ "//third_party/libjpeg" ] + deps += [ "//foundation/ace/ace_engine/build/third_party/flutter/libjpeg:ace_libjpeg" ] + include_dirs += [ "//third_party/flutter/skia/third_party/libjpeg-turbo" ] } external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/plugins/common/libs/image/libjpegplugin/src/plugin_export.cpp b/plugins/common/libs/image/libjpegplugin/src/plugin_export.cpp index bac59e55efc0c4cdc6a798d37d3519e95d1bf400..fd9a7c498cddc457284af2e4311494d8e0ae5432 100644 --- a/plugins/common/libs/image/libjpegplugin/src/plugin_export.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/plugin_export.cpp @@ -21,7 +21,9 @@ #include "log_tags.h" // plugin package name same as metadata. -PLUGIN_EXPORT_REGISTER_PACKAGE("LibJpegPlugin") +namespace { + const std::string PACKAGE_NAME = ("LibJpegPlugin"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN @@ -31,14 +33,35 @@ PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::JpegEncoder) #endif PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibJpegPlugin" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin. PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} diff --git a/plugins/common/libs/image/libpngplugin/src/plugin_export.cpp b/plugins/common/libs/image/libpngplugin/src/plugin_export.cpp index d9409b28016c273666949a6ad31ab311b4ee5f81..1be1a31d8f23ac23bc0d53b89cb5d1047075ea9f 100644 --- a/plugins/common/libs/image/libpngplugin/src/plugin_export.cpp +++ b/plugins/common/libs/image/libpngplugin/src/plugin_export.cpp @@ -20,21 +20,44 @@ #include "png_decoder.h" // plugin package name same as metadata. -PLUGIN_EXPORT_REGISTER_PACKAGE("LibPngPlugin") +namespace { + const std::string PACKAGE_NAME = ("LibPngPlugin"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::PngDecoder) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibPngPlugin" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin. PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} diff --git a/plugins/common/libs/image/libwebpplugin/src/plugin_export.cpp b/plugins/common/libs/image/libwebpplugin/src/plugin_export.cpp index 57159092550d828ecae9a57a24a77465a97aa433..92950d6e2d804b3cb8161b54512e1cfdc117fb26 100644 --- a/plugins/common/libs/image/libwebpplugin/src/plugin_export.cpp +++ b/plugins/common/libs/image/libwebpplugin/src/plugin_export.cpp @@ -20,21 +20,44 @@ #include "webp_decoder.h" // plugin package name same as metadata. -PLUGIN_EXPORT_REGISTER_PACKAGE("LibWebpPlugin") +namespace { + const std::string PACKAGE_NAME = ("LibWebpPlugin"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::WebpDecoder) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibWebpPlugin" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin. PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} diff --git a/plugins/manager/include/pluginbase/plugin_utils.h b/plugins/manager/include/pluginbase/plugin_utils.h index 790d3bcb1ed3200146b2c42d51bc7438b987ea7b..d356da374b76f312b434715675bfff327e37458b 100644 --- a/plugins/manager/include/pluginbase/plugin_utils.h +++ b/plugins/manager/include/pluginbase/plugin_utils.h @@ -38,7 +38,9 @@ using PluginObjectCreatorFunc = OHOS::MultimediaPlugin::PluginClassBase *(*)(); // --------- a set of code fragments that helps define a simple plugin_export.cpp file ---------- #define PLUGIN_EXPORT_REGISTER_PACKAGE(packageName) \ -static const std::string PACKAGE_NAME = (packageName); +namespace { \ + const std::string PACKAGE_NAME = (packageName); \ +} #define PLUGIN_EXPORT_REGISTER_CLASS_BEGIN \ using ImplClassMap = std::map; \ diff --git a/plugins/manager/test/unittest/common/plugin_example/plugin_example2/plugin_export.cpp b/plugins/manager/test/unittest/common/plugin_example/plugin_example2/plugin_export.cpp index 761ae7c4d2ef68fc211abd501abd3cb22beff792..9bab70dcfaecac0b34b6e1e7df5cde7508ec3fb6 100644 --- a/plugins/manager/test/unittest/common/plugin_example/plugin_example2/plugin_export.cpp +++ b/plugins/manager/test/unittest/common/plugin_example/plugin_example2/plugin_export.cpp @@ -22,7 +22,9 @@ // this file shows how to easily write the plugin_export.cpp file using the code elements provided by plugin_utils.h. // but sometimes you may need to write this file directly, see plugin_example1. -PLUGIN_EXPORT_REGISTER_PACKAGE("plugin_example2") +namespace { + const std::string PACKAGE_NAME = ("plugin_example2"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN @@ -30,15 +32,36 @@ PLUGIN_EXPORT_REGISTER_CLASS(OHOS::PluginExample::LabelDetector2) PLUGIN_EXPORT_REGISTER_CLASS(OHOS::PluginExample::CloudLabelDetector2) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "plugin_example2" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +} diff --git a/plugins/manager/test/unittest/common/plugin_example/plugin_example3/plugin_export.cpp b/plugins/manager/test/unittest/common/plugin_example/plugin_example3/plugin_export.cpp index 0205a53f35a04c67e0e6abb71db0867f90493e40..9220362649264af63e58ac7e58a773efa0c5cefc 100644 --- a/plugins/manager/test/unittest/common/plugin_example/plugin_example3/plugin_export.cpp +++ b/plugins/manager/test/unittest/common/plugin_example/plugin_example3/plugin_export.cpp @@ -22,7 +22,9 @@ // this file shows how to easily write the plugin_export.cpp file using the code elements provided by plugin_utils.h. // but sometimes you may need to write this file directly, see plugin_example1. -PLUGIN_EXPORT_REGISTER_PACKAGE("plugin_example3") +namespace { + const std::string PACKAGE_NAME = ("plugin_example3"); +} // register implement classes of this plugin. PLUGIN_EXPORT_REGISTER_CLASS_BEGIN @@ -30,15 +32,36 @@ PLUGIN_EXPORT_REGISTER_CLASS(OHOS::PluginExample::LabelDetector3) PLUGIN_EXPORT_REGISTER_CLASS(OHOS::PluginExample::CloudLabelDetector3) PLUGIN_EXPORT_REGISTER_CLASS_END +using std::string; using namespace OHOS::HiviewDFX; static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "plugin_example3" }; -#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__); -#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__); +#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__) +#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__) // define the external interface of this plugin PLUGIN_EXPORT_DEFAULT_EXTERNAL_START() PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP() -// PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE() +OHOS::MultimediaPlugin::PluginClassBase *PluginExternalCreate(const string &className) +{ + HiLog::Debug(LABEL, "PluginExternalCreate: create object for package: %{public}s, class: %{public}s.", + PACKAGE_NAME.c_str(), className.c_str()); + + auto iter = implClassMap.find(className); + if (iter == implClassMap.end()) { + HiLog::Error(LABEL, "PluginExternalCreate: failed to find class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + auto creator = iter->second; + if (creator == nullptr) { + HiLog::Error(LABEL, "PluginExternalCreate: null creator for class: %{public}s, in package: %{public}s.", + className.c_str(), PACKAGE_NAME.c_str()); + return nullptr; + } + + return creator(); +}