From 9285a78f2a39129caa2fc7cea51119f4c496d40f Mon Sep 17 00:00:00 2001 From: seungho Date: Tue, 4 May 2021 18:02:29 +0900 Subject: [PATCH] Make non-animated webp file can be loaded. - Make webp file that has wrong file extension can be loaded as a single image with image-visual. - Make webp file that hasn't animated option can be loaded with animated-image-visual without duplicated loading. Change-Id: Idab5ed59d3bb06e87dd6028a39b41b8ea0986371 Signed-off-by: seungho --- dali/internal/imaging/common/image-loader.cpp | 4 + dali/internal/imaging/common/loader-webp.cpp | 240 ++++++++++++++++++++++++++ dali/internal/imaging/common/loader-webp.h | 64 +++++++ dali/internal/imaging/common/webp-loading.cpp | 196 +++++++++++---------- dali/internal/imaging/file.list | 1 + 5 files changed, 410 insertions(+), 95 deletions(-) create mode 100644 dali/internal/imaging/common/loader-webp.cpp create mode 100644 dali/internal/imaging/common/loader-webp.h diff --git a/dali/internal/imaging/common/image-loader.cpp b/dali/internal/imaging/common/image-loader.cpp index f0ace20..dbf492c 100644 --- a/dali/internal/imaging/common/image-loader.cpp +++ b/dali/internal/imaging/common/image-loader.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ enum FileFormats FORMAT_JPEG, FORMAT_BMP, FORMAT_GIF, + FORMAT_WEBP, FORMAT_KTX, FORMAT_ASTC, FORMAT_ICO, @@ -82,6 +84,7 @@ const Dali::ImageLoader::BitmapLoader BITMAP_LOADER_LOOKUP_TABLE[FORMAT_TOTAL_CO {Jpeg::MAGIC_BYTE_1, Jpeg::MAGIC_BYTE_2, LoadBitmapFromJpeg, LoadJpegHeader, Bitmap::BITMAP_2D_PACKED_PIXELS}, {Bmp::MAGIC_BYTE_1, Bmp::MAGIC_BYTE_2, LoadBitmapFromBmp, LoadBmpHeader, Bitmap::BITMAP_2D_PACKED_PIXELS}, {Gif::MAGIC_BYTE_1, Gif::MAGIC_BYTE_2, LoadBitmapFromGif, LoadGifHeader, Bitmap::BITMAP_2D_PACKED_PIXELS}, + {Webp::MAGIC_BYTE_1, Webp::MAGIC_BYTE_2, LoadBitmapFromWebp, LoadWebpHeader, Bitmap::BITMAP_2D_PACKED_PIXELS}, {Ktx::MAGIC_BYTE_1, Ktx::MAGIC_BYTE_2, LoadBitmapFromKtx, LoadKtxHeader, Bitmap::BITMAP_COMPRESSED }, {Astc::MAGIC_BYTE_1, Astc::MAGIC_BYTE_2, LoadBitmapFromAstc, LoadAstcHeader, Bitmap::BITMAP_COMPRESSED }, {Ico::MAGIC_BYTE_1, Ico::MAGIC_BYTE_2, LoadBitmapFromIco, LoadIcoHeader, Bitmap::BITMAP_2D_PACKED_PIXELS}, @@ -107,6 +110,7 @@ const FormatExtension FORMAT_EXTENSIONS[] = {".jpg", FORMAT_JPEG}, {".bmp", FORMAT_BMP }, {".gif", FORMAT_GIF }, + {".webp", FORMAT_WEBP }, {".ktx", FORMAT_KTX }, {".astc", FORMAT_ASTC}, {".ico", FORMAT_ICO }, diff --git a/dali/internal/imaging/common/loader-webp.cpp b/dali/internal/imaging/common/loader-webp.cpp new file mode 100644 index 0000000..37404dd --- /dev/null +++ b/dali/internal/imaging/common/loader-webp.cpp @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2021 Samsung Electronics 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 + +// EXTERNAL INCLUDES +#ifdef DALI_WEBP_AVAILABLE +#include +#include + +#if WEBP_DEMUX_ABI_VERSION > 0x0101 +#define DALI_ANIMATED_WEBP_ENABLED 1 +#endif +#endif +#include +#include +#include +#include + +typedef unsigned char WebPByteType; + +namespace Dali +{ +namespace TizenPlatform +{ +#ifdef DALI_ANIMATED_WEBP_ENABLED +bool ReadWebPInformation(FILE* const fp, WebPData& webPData) +{ + if(fp == NULL) + { + return false; + } + + if(fseek(fp, 0, SEEK_END) <= -1) + { + return false; + } + WebPDataInit(&webPData); + webPData.size = ftell(fp); + + if((!fseek(fp, 0, SEEK_SET))) + { + unsigned char* WebPDataBuffer; + WebPDataBuffer = reinterpret_cast(malloc(sizeof(WebPByteType) * webPData.size)); + webPData.size = fread(WebPDataBuffer, sizeof(WebPByteType), webPData.size, fp); + webPData.bytes = WebPDataBuffer; + } + else + { + return false; + } + return true; +} + +void ReleaseResource(WebPData& webPData, WebPAnimDecoder* webPAnimDecoder) +{ + free((void*)webPData.bytes); + webPData.bytes = nullptr; + WebPDataInit(&webPData); + if(webPAnimDecoder) + { + WebPAnimDecoderDelete(webPAnimDecoder); + } +} + +#endif + +bool LoadWebpHeader(const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height) +{ + FILE* const fp = input.file; + if(fp == NULL) + { + return false; + } + + if(fseek(fp, 0, SEEK_END) <= -1) + { + return false; + } + + // If the image is non-animated webp +#ifdef DALI_WEBP_AVAILABLE + size_t webPSize = ftell(fp); + if((!fseek(fp, 0, SEEK_SET))) + { + std::vector encodedImage; + encodedImage.resize(webPSize, 0); + size_t readCount = fread(&encodedImage[0], sizeof(uint8_t), encodedImage.size(), fp); + if(readCount != encodedImage.size()) + { + return false; + } + int32_t imageWidth, imageHeight; + if(WebPGetInfo(&encodedImage[0], encodedImage.size(), &imageWidth, &imageHeight)) + { + width = static_cast(imageWidth); + height = static_cast(imageHeight); + return true; + } + } +#endif + + // If the image is animated webp +#ifdef DALI_ANIMATED_WEBP_ENABLED + WebPData webPData; + WebPAnimDecoder* webPAnimDecoder; + WebPAnimInfo webPAnimInfo; + if(ReadWebPInformation(fp, webPData)) + { + WebPAnimDecoderOptions webPAnimDecoderOptions; + WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions); + webPAnimDecoderOptions.color_mode = MODE_RGBA; + webPAnimDecoder = WebPAnimDecoderNew(&webPData, &webPAnimDecoderOptions); + if(webPAnimDecoder != nullptr) + { + WebPAnimDecoderGetInfo(webPAnimDecoder, &webPAnimInfo); + width = webPAnimInfo.canvas_width; + height = webPAnimInfo.canvas_height; + return true; + } + } + ReleaseResource(webPData, webPAnimDecoder); +#endif + DALI_LOG_ERROR("WebP file open failed.\n"); + return false; +} + +bool LoadBitmapFromWebp(const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap) +{ + FILE* const fp = input.file; + if(fp == NULL) + { + return false; + } + + if(fseek(fp, 0, SEEK_END) <= -1) + { + return false; + } + + // If the image is non-animated webp +#ifdef DALI_WEBP_AVAILABLE + size_t webPSize = ftell(fp); + if((!fseek(fp, 0, SEEK_SET))) + { + std::vector encodedImage; + encodedImage.resize(webPSize, 0); + size_t readCount = fread(&encodedImage[0], sizeof(uint8_t), encodedImage.size(), fp); + if(readCount != encodedImage.size()) + { + DALI_LOG_ERROR("WebP image loading failed.\n"); + return false; + } + + int32_t width, height; + if(!WebPGetInfo(&encodedImage[0], encodedImage.size(), &width, &height)) + { + DALI_LOG_ERROR("Cannot retrieve WebP image size information.\n"); + return false; + } + + WebPBitstreamFeatures features; + if(VP8_STATUS_NOT_ENOUGH_DATA == WebPGetFeatures(&encodedImage[0], encodedImage.size(), &features)) + { + DALI_LOG_ERROR("Cannot retrieve WebP image features.\n"); + return false; + } + + uint32_t channelNumber = (features.has_alpha) ? 4 : 3; + Pixel::Format pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888; + bitmap = Dali::Devel::PixelBuffer::New(width, height, pixelFormat); + uint8_t* frameBuffer = nullptr; + if(channelNumber == 4) + { + frameBuffer = WebPDecodeRGBA(&encodedImage[0], encodedImage.size(), &width, &height); + } + else + { + frameBuffer = WebPDecodeRGB(&encodedImage[0], encodedImage.size(), &width, &height); + } + + if(frameBuffer != nullptr) + { + const int32_t bufferSize = width * height * sizeof(uint8_t) * channelNumber; + memcpy(bitmap.GetBuffer(), frameBuffer, bufferSize); + free((void*)frameBuffer); + return true; + } + } +#endif + + // If the image is animated webp +#ifdef DALI_ANIMATED_WEBP_ENABLED + WebPData webPData; + WebPAnimDecoder* webPAnimDecoder; + WebPAnimInfo webPAnimInfo; + if(ReadWebPInformation(fp, webPData)) + { + WebPAnimDecoderOptions webPAnimDecoderOptions; + WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions); + webPAnimDecoderOptions.color_mode = MODE_RGBA; + webPAnimDecoder = WebPAnimDecoderNew(&webPData, &webPAnimDecoderOptions); + if(webPAnimDecoder != nullptr) + { + uint8_t* frameBuffer; + int timestamp; + WebPAnimDecoderGetInfo(webPAnimDecoder, &webPAnimInfo); + WebPAnimDecoderReset(webPAnimDecoder); + WebPAnimDecoderGetNext(webPAnimDecoder, &frameBuffer, ×tamp); + + bitmap = Dali::Devel::PixelBuffer::New(webPAnimInfo.canvas_width, webPAnimInfo.canvas_height, Dali::Pixel::RGBA8888); + const int32_t bufferSize = webPAnimInfo.canvas_width * webPAnimInfo.canvas_height * sizeof(uint32_t); + memcpy(bitmap.GetBuffer(), frameBuffer, bufferSize); + return true; + } + } + ReleaseResource(webPData, webPAnimDecoder); +#endif + + DALI_LOG_ERROR("WebP image loading failed.\n"); + return false; +} + +} // namespace TizenPlatform + +} // namespace Dali diff --git a/dali/internal/imaging/common/loader-webp.h b/dali/internal/imaging/common/loader-webp.h new file mode 100644 index 0000000..55d3278 --- /dev/null +++ b/dali/internal/imaging/common/loader-webp.h @@ -0,0 +1,64 @@ +#ifndef DALI_TIZEN_PLATFORM_LOADER_WEBP_H +#define DALI_TIZEN_PLATFORM_LOADER_WEBP_H + +/* + * Copyright (c) 2021 Samsung Electronics 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 +#include + +namespace Dali +{ +namespace Devel +{ +class PixelBuffer; +} + +namespace TizenPlatform +{ +class ResourceLoadingClient; + +namespace Webp +{ +const unsigned char MAGIC_BYTE_1 = 0x52; +const unsigned char MAGIC_BYTE_2 = 0x49; +} // namespace Webp + +/** + * Loads the header of a Webp file and fills in the width and height appropriately. + * @param[in] input Information about the input image (including file pointer) + * @param[out] width Is set with the width of the image + * @param[out] height Is set with the height of the image + * @return true if the file's header was read successully, false otherwise + */ +bool LoadWebpHeader(const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height); + +/** + * Loads the bitmap from a Webp file. This function checks the header first + * and if it is not a Webp file, then it returns straight away. + * @note For animated Webps, only the first image is displayed + * @param[in] input Information about the input image (including file pointer) + * @param[out] bitmap The bitmap class where the decoded image will be stored + * @return true if file decoded successfully, false otherwise + */ +bool LoadBitmapFromWebp(const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap); + +} // namespace TizenPlatform + +} // namespace Dali + +#endif // DALI_TIZEN_PLATFORM_LOADER_WEBP_H diff --git a/dali/internal/imaging/common/webp-loading.cpp b/dali/internal/imaging/common/webp-loading.cpp index 7e4511c..dc758fa 100644 --- a/dali/internal/imaging/common/webp-loading.cpp +++ b/dali/internal/imaging/common/webp-loading.cpp @@ -24,7 +24,7 @@ #include #if WEBP_DEMUX_ABI_VERSION > 0x0101 -#define DALI_WEBP_ENABLED 1 +#define DALI_ANIMATED_WEBP_ENABLED 1 #endif #endif @@ -40,6 +40,9 @@ #include #include +// INTERNAL INCLUDES +#include + typedef unsigned char WebPByteType; namespace Dali @@ -63,34 +66,56 @@ struct WebPLoading::Impl public: Impl(const std::string& url, bool isLocalResource) : mUrl(url), - mLoadSucceeded(true), - mMutex() + mFrameCount(1u), + mMutex(), + mBuffer(nullptr), + mBufferSize(0u), + mImageSize(), + mLoadSucceeded(true) { -#ifdef DALI_WEBP_ENABLED + // mFrameCount will be 1 if the input image is non-animated image or animated image with single frame. if(ReadWebPInformation(isLocalResource)) { +#ifdef DALI_ANIMATED_WEBP_ENABLED + WebPDataInit(&mWebPData); + mWebPData.size = mBufferSize; + mWebPData.bytes = mBuffer; WebPAnimDecoderOptions webPAnimDecoderOptions; WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions); webPAnimDecoderOptions.color_mode = MODE_RGBA; mWebPAnimDecoder = WebPAnimDecoderNew(&mWebPData, &webPAnimDecoderOptions); WebPAnimDecoderGetInfo(mWebPAnimDecoder, &mWebPAnimInfo); mTimeStamp.assign(mWebPAnimInfo.frame_count, 0); + mFrameCount = mWebPAnimInfo.frame_count; + mImageSize = ImageDimensions(mWebPAnimInfo.canvas_width, mWebPAnimInfo.canvas_height); +#elif DALI_WEBP_AVAILABLE + int32_t imageWidth, imageHeight; + if(WebPGetInfo(mBuffer, mBufferSize, &imageWidth, &imageHeight)) + { + mImageSize = ImageDimensions(imageWidth, imageHeight); + } +#endif +#ifndef DALI_WEBP_AVAILABLE + // If the system doesn't support webp, loading will be failed. + mFrameCount = 0u; + mLoadSucceeded = false; +#endif } else { + mFrameCount = 0u; mLoadSucceeded = false; + DALI_LOG_ERROR("Image loading failed for: \"%s\".\n", mUrl.c_str()); } -#endif } bool ReadWebPInformation(bool isLocalResource) { -#ifdef DALI_WEBP_ENABLED - WebPDataInit(&mWebPData); + FILE* fp = nullptr; if(isLocalResource) { Internal::Platform::FileReader fileReader(mUrl); - FILE* fp = fileReader.GetFile(); + fp = fileReader.GetFile(); if(fp == NULL) { return false; @@ -101,17 +126,12 @@ public: return false; } - mWebPData.size = ftell(fp); - if((!fseek(fp, 0, SEEK_SET))) - { - unsigned char* WebPDataBuffer; - WebPDataBuffer = reinterpret_cast(malloc(sizeof(WebPByteType) * mWebPData.size)); - mWebPData.size = fread(WebPDataBuffer, sizeof(WebPByteType), mWebPData.size, fp); - mWebPData.bytes = WebPDataBuffer; - } - else + mBufferSize = ftell(fp); + if(!fseek(fp, 0, SEEK_SET)) { - return false; + mBuffer = reinterpret_cast(malloc(sizeof(WebPByteType) * mBufferSize)); + mBufferSize = fread(mBuffer, sizeof(WebPByteType), mBufferSize, fp); + return true; } } else @@ -124,37 +144,25 @@ public: succeeded = TizenPlatform::Network::DownloadRemoteFileIntoMemory(mUrl, dataBuffer, dataSize, MAXIMUM_DOWNLOAD_IMAGE_SIZE); if(succeeded) { - size_t blobSize = dataBuffer.Size(); - if(blobSize > 0U) + mBufferSize = dataBuffer.Size(); + if(mBufferSize > 0U) { // Open a file handle on the memory buffer: - Dali::Internal::Platform::FileReader fileReader(dataBuffer, blobSize); - FILE* const fp = fileReader.GetFile(); - if(NULL != fp) + Internal::Platform::FileReader fileReader(dataBuffer, mBufferSize); + fp = fileReader.GetFile(); + if(fp != nullptr) { - if((!fseek(fp, 0, SEEK_SET))) + if(!fseek(fp, 0, SEEK_SET)) { - unsigned char* WebPDataBuffer; - WebPDataBuffer = reinterpret_cast(malloc(sizeof(WebPByteType) * blobSize)); - mWebPData.size = fread(WebPDataBuffer, sizeof(WebPByteType), mWebPData.size, fp); - mWebPData.bytes = WebPDataBuffer; + mBuffer = reinterpret_cast(malloc(sizeof(WebPByteType) * mBufferSize)); + mBufferSize = fread(mBuffer, sizeof(WebPByteType), mBufferSize, fp); + return true; } - else - { - DALI_LOG_ERROR("Error seeking within file\n"); - } - } - else - { - DALI_LOG_ERROR("Error reading file\n"); } } } } - return true; -#else return false; -#endif } // Moveable but not copyable @@ -166,10 +174,9 @@ public: ~Impl() { -#ifdef DALI_WEBP_ENABLED +#ifdef DALI_ANIMATED_WEBP_ENABLED if(&mWebPData != NULL) { - free((void*)mWebPData.bytes); mWebPData.bytes = nullptr; WebPDataInit(&mWebPData); } @@ -178,15 +185,22 @@ public: WebPAnimDecoderDelete(mWebPAnimDecoder); } #endif + free((void*)mBuffer); + mBuffer = nullptr; } std::string mUrl; std::vector mTimeStamp; uint32_t mLoadingFrame{0}; - bool mLoadSucceeded; + uint32_t mFrameCount; Mutex mMutex; + // For the case the system doesn't support DALI_ANIMATED_WEBP_ENABLED + unsigned char* mBuffer; + uint32_t mBufferSize; + ImageDimensions mImageSize; + bool mLoadSucceeded; -#ifdef DALI_WEBP_ENABLED +#ifdef DALI_ANIMATED_WEBP_ENABLED WebPData mWebPData{0}; WebPAnimDecoder* mWebPAnimDecoder{nullptr}; WebPAnimInfo mWebPAnimInfo{0}; @@ -195,7 +209,7 @@ public: AnimatedImageLoadingPtr WebPLoading::New(const std::string& url, bool isLocalResource) { -#ifndef DALI_WEBP_ENABLED +#ifndef DALI_ANIMATED_WEBP_ENABLED DALI_LOG_ERROR("The system does not support Animated WebP format.\n"); #endif return AnimatedImageLoadingPtr(new WebPLoading(url, isLocalResource)); @@ -213,64 +227,64 @@ WebPLoading::~WebPLoading() bool WebPLoading::LoadNextNFrames(uint32_t frameStartIndex, int count, std::vector& pixelData) { -#ifdef DALI_WEBP_ENABLED - Mutex::ScopedLock lock(mImpl->mMutex); - if(frameStartIndex >= mImpl->mWebPAnimInfo.frame_count || !mImpl->mLoadSucceeded) + for(int i = 0; i < count; ++i) { - return false; + Dali::Devel::PixelBuffer pixelBuffer = LoadFrame((frameStartIndex + i) % mImpl->mFrameCount); + Dali::PixelData imageData = Devel::PixelBuffer::Convert(pixelBuffer); + pixelData.push_back(imageData); } - - DALI_LOG_INFO(gWebPLoadingLogFilter, Debug::Concise, "LoadNextNFrames( frameStartIndex:%d, count:%d )\n", frameStartIndex, count); - - if(mImpl->mLoadingFrame > frameStartIndex) + if(pixelData.size() != static_cast(count)) { - mImpl->mLoadingFrame = 0; - WebPAnimDecoderReset(mImpl->mWebPAnimDecoder); + return false; } + return true; +} - for(; mImpl->mLoadingFrame < frameStartIndex; ++mImpl->mLoadingFrame) - { - uint8_t* frameBuffer; - int timestamp; - WebPAnimDecoderGetNext(mImpl->mWebPAnimDecoder, &frameBuffer, ×tamp); - mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp; - } +Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex) +{ + Dali::Devel::PixelBuffer pixelBuffer; - for(int i = 0; i < count; ++i) + // WebPDecodeRGBA is faster than to use demux API for loading non-animated image. + // If frame count is 1, use WebPDecodeRGBA api. +#ifdef DALI_WEBP_AVAILABLE + if(mImpl->mFrameCount == 1) { - const int bufferSize = mImpl->mWebPAnimInfo.canvas_width * mImpl->mWebPAnimInfo.canvas_height * sizeof(uint32_t); - uint8_t* frameBuffer; - int timestamp; - WebPAnimDecoderGetNext(mImpl->mWebPAnimDecoder, &frameBuffer, ×tamp); + int32_t width, height; + if(!WebPGetInfo(mImpl->mBuffer, mImpl->mBufferSize, &width, &height)) + { + return pixelBuffer; + } - auto pixelBuffer = new uint8_t[bufferSize]; - memcpy(pixelBuffer, frameBuffer, bufferSize); - mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp; + WebPBitstreamFeatures features; + if(VP8_STATUS_NOT_ENOUGH_DATA == WebPGetFeatures(mImpl->mBuffer, mImpl->mBufferSize, &features)) + { + return pixelBuffer; + } - if(pixelBuffer) + uint32_t channelNumber = (features.has_alpha) ? 4 : 3; + Pixel::Format pixelFormat = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888; + pixelBuffer = Dali::Devel::PixelBuffer::New(width, height, pixelFormat); + uint8_t* frameBuffer = nullptr; + if(channelNumber == 4) + { + frameBuffer = WebPDecodeRGBA(mImpl->mBuffer, mImpl->mBufferSize, &width, &height); + } + else { - pixelData.push_back(Dali::PixelData::New(pixelBuffer, bufferSize, mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height, Dali::Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY)); + frameBuffer = WebPDecodeRGB(mImpl->mBuffer, mImpl->mBufferSize, &width, &height); } - mImpl->mLoadingFrame++; - if(mImpl->mLoadingFrame >= mImpl->mWebPAnimInfo.frame_count) + if(frameBuffer != nullptr) { - mImpl->mLoadingFrame = 0; - WebPAnimDecoderReset(mImpl->mWebPAnimDecoder); + const int32_t imageBufferSize = width * height * sizeof(uint8_t) * channelNumber; + memcpy(pixelBuffer.GetBuffer(), frameBuffer, imageBufferSize); + free((void*)frameBuffer); + return pixelBuffer; } } - - return true; -#else - return false; #endif -} -Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex) -{ - Dali::Devel::PixelBuffer pixelBuffer; - -#ifdef DALI_WEBP_ENABLED +#ifdef DALI_ANIMATED_WEBP_ENABLED Mutex::ScopedLock lock(mImpl->mMutex); if(frameIndex >= mImpl->mWebPAnimInfo.frame_count || !mImpl->mLoadSucceeded) { @@ -314,20 +328,12 @@ Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex) ImageDimensions WebPLoading::GetImageSize() const { -#ifdef DALI_WEBP_ENABLED - return ImageDimensions(mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height); -#else - return ImageDimensions(); -#endif + return mImpl->mImageSize; } uint32_t WebPLoading::GetImageCount() const { -#ifdef DALI_WEBP_ENABLED - return mImpl->mWebPAnimInfo.frame_count; -#else - return 0u; -#endif + return mImpl->mFrameCount; } uint32_t WebPLoading::GetFrameInterval(uint32_t frameIndex) const diff --git a/dali/internal/imaging/file.list b/dali/internal/imaging/file.list index b5f0894..4dcda76 100644 --- a/dali/internal/imaging/file.list +++ b/dali/internal/imaging/file.list @@ -17,6 +17,7 @@ SET( adaptor_imaging_common_src_files ${adaptor_imaging_dir}/common/loader-ktx.cpp ${adaptor_imaging_dir}/common/loader-png.cpp ${adaptor_imaging_dir}/common/loader-wbmp.cpp + ${adaptor_imaging_dir}/common/loader-webp.cpp ${adaptor_imaging_dir}/common/pixel-manipulation.cpp ${adaptor_imaging_dir}/common/gif-loading.cpp ${adaptor_imaging_dir}/common/webp-loading.cpp -- 2.7.4