Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / common / loader-webp.cpp
index e388712..25a24d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
  *
  */
 
+// HEADER
 #include <dali/internal/imaging/common/loader-webp.h>
 
-// EXTERNAL INCLUDES
-#ifdef DALI_WEBP_AVAILABLE
-#include <webp/decode.h>
-#include <webp/demux.h>
-
-#if WEBP_DEMUX_ABI_VERSION > 0x0101
-#define DALI_ANIMATED_WEBP_ENABLED 1
-#endif
-#endif
+// INTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
-#include <dali/integration-api/debug.h>
-#include <cstring>
-#include <memory>
-
-typedef unsigned char WebPByteType;
+#include <dali/internal/imaging/common/webp-loading.h>
 
 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<WebPByteType*>(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)
+namespace
 {
-  free((void*)webPData.bytes);
-  webPData.bytes = nullptr;
-  WebPDataInit(&webPData);
-  if(webPAnimDecoder)
-  {
-    WebPAnimDecoderDelete(webPAnimDecoder);
-  }
+constexpr uint32_t FIRST_FRAME_INDEX = 0u;
 }
 
-#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<uint8_t> 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<uint32_t>(imageWidth);
-      height = static_cast<uint32_t>(imageHeight);
-      return true;
-    }
-  }
-#endif
-
-  // If the image is animated webp
-#ifdef DALI_ANIMATED_WEBP_ENABLED
-  WebPData         webPData;
-  WebPAnimDecoder* webPAnimDecoder = nullptr;
-  WebPAnimInfo     webPAnimInfo;
-  if(ReadWebPInformation(fp, webPData))
+  FILE* const                fp          = input.file;
+  Dali::AnimatedImageLoading webPLoading = Dali::AnimatedImageLoading(Dali::Internal::Adaptor::WebPLoading::New(fp).Get());
+  if(webPLoading)
   {
-    WebPAnimDecoderOptions webPAnimDecoderOptions;
-    WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions);
-    webPAnimDecoderOptions.color_mode = MODE_RGBA;
-    webPAnimDecoder                   = WebPAnimDecoderNew(&webPData, &webPAnimDecoderOptions);
-    if(webPAnimDecoder != nullptr)
+    ImageDimensions imageSize = webPLoading.GetImageSize();
+    if(webPLoading.HasLoadingSucceeded())
     {
-      WebPAnimDecoderGetInfo(webPAnimDecoder, &webPAnimInfo);
-      width  = webPAnimInfo.canvas_width;
-      height = webPAnimInfo.canvas_height;
+      width  = imageSize.GetWidth();
+      height = imageSize.GetHeight();
       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<uint8_t> 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 = nullptr;
-  WebPAnimInfo     webPAnimInfo;
-  if(ReadWebPInformation(fp, webPData))
+  FILE* const                fp          = input.file;
+  Dali::AnimatedImageLoading webPLoading = Dali::AnimatedImageLoading(Dali::Internal::Adaptor::WebPLoading::New(fp).Get());
+  if(webPLoading)
   {
-    WebPAnimDecoderOptions webPAnimDecoderOptions;
-    WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions);
-    webPAnimDecoderOptions.color_mode = MODE_RGBA;
-    webPAnimDecoder                   = WebPAnimDecoderNew(&webPData, &webPAnimDecoderOptions);
-    if(webPAnimDecoder != nullptr)
+    Dali::Devel::PixelBuffer pixelBuffer = webPLoading.LoadFrame(FIRST_FRAME_INDEX);
+    if(pixelBuffer)
     {
-      uint8_t* frameBuffer;
-      int      timestamp;
-      WebPAnimDecoderGetInfo(webPAnimDecoder, &webPAnimInfo);
-      WebPAnimDecoderReset(webPAnimDecoder);
-      WebPAnimDecoderGetNext(webPAnimDecoder, &frameBuffer, &timestamp);
-
-      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);
+      bitmap = pixelBuffer;
       return true;
     }
   }
-  ReleaseResource(webPData, webPAnimDecoder);
-#endif
-
-  DALI_LOG_ERROR("WebP image loading failed.\n");
   return false;
 }