Support Asynchronous Loading of Animated Image 46/237346/11
authorSeungho, Baek <sbsh.baek@samsung.com>
Mon, 29 Jun 2020 09:24:29 +0000 (18:24 +0900)
committerSeungho, Baek <sbsh.baek@samsung.com>
Fri, 3 Jul 2020 02:09:03 +0000 (11:09 +0900)
Change-Id: Ic896aff6252bc495227c355b7036ae6dd126b42d
Signed-off-by: Seungho, Baek <sbsh.baek@samsung.com>
dali/devel-api/adaptor-framework/animated-image-loading.cpp
dali/devel-api/adaptor-framework/animated-image-loading.h
dali/internal/accessibility/tizen-wayland/atspi/dbus.h
dali/internal/imaging/common/animated-image-loading-impl.h
dali/internal/imaging/common/gif-loading.cpp
dali/internal/imaging/common/gif-loading.h
dali/internal/imaging/common/webp-loading.cpp
dali/internal/imaging/common/webp-loading.h

index f2a9afa..1f6dc03 100644 (file)
@@ -32,7 +32,6 @@ AnimatedImageLoading::AnimatedImageLoading()
 
 AnimatedImageLoading AnimatedImageLoading::New( const std::string& url, bool isLocalResource )
 {
-
   const std::size_t urlSize = url.length();
 
   Internal::Adaptor::AnimatedImageLoadingPtr internal = NULL;
@@ -68,6 +67,11 @@ bool AnimatedImageLoading::LoadNextNFrames( uint32_t frameStartIndex, int count,
   return GetImplementation( *this ).LoadNextNFrames( frameStartIndex, count, pixelData );
 }
 
+Dali::Devel::PixelBuffer AnimatedImageLoading::LoadFrame( uint32_t frameIndex )
+{
+  return GetImplementation( *this ).LoadFrame( frameIndex );
+}
+
 ImageDimensions AnimatedImageLoading::GetImageSize() const
 {
   return GetImplementation( *this ).GetImageSize();
@@ -83,6 +87,11 @@ uint32_t AnimatedImageLoading::GetFrameInterval( uint32_t frameIndex ) const
   return GetImplementation( *this ).GetFrameInterval( frameIndex );
 }
 
+std::string AnimatedImageLoading::GetUrl() const
+{
+  return GetImplementation( *this ).GetUrl();
+}
+
 AnimatedImageLoading::AnimatedImageLoading( Internal::Adaptor::AnimatedImageLoading* internal )
 : BaseHandle( internal )
 {
index 7c0a69b..ecc2488 100644 (file)
@@ -25,6 +25,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/dali-adaptor-common.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 
 namespace Dali
 {
@@ -113,6 +114,16 @@ public:
    */
   bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector<Dali::PixelData>& pixelData );
 
+   /**
+   * @brief Load a frame of the animated image.
+   *
+   * @note This function will load the entire animated image into memory if not already loaded.
+   * @param[in] frameIndex The frame index to load.
+   * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
+   */
+
+  Dali::Devel::PixelBuffer LoadFrame( uint32_t frameIndex );
+
   /**
    * @brief Get the size of a animated image.
    *
@@ -134,6 +145,13 @@ public:
    */
   uint32_t GetFrameInterval( uint32_t frameIndex ) const;
 
+  /**
+   * @brief Get the animated image file URL
+   *
+   * @return The URL string of the animated image file
+   */
+  std::string GetUrl() const;
+
 public: // Not intended for application developers
   /// @cond internal
   /**
index e3176a3..f9be4e0 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
 
 /*
- * Copyright 2019  Samsung Electronics Co., Ltd
+ * Copyright 2020  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.
@@ -2232,8 +2232,8 @@ namespace DBus
   /**
    * @brief Class representing client's end of DBUS connection
    *
-   * Allows calling (synchronous and asynchronos) methods on selected interface
-   * Allows (synchronous and asynchronos) setting / getting properties.
+   * Allows calling (synchronous and asynchronous) methods on selected interface
+   * Allows (synchronous and asynchronous) setting / getting properties.
    * Allows registering signals.
    */
   class DBusClient
@@ -2756,8 +2756,8 @@ namespace DBus
   /**
    * @brief Class representing server's end of DBUS connection
    *
-   * Allows listening (synchronously and asynchronosly) on methods on selected interface
-   * Allows listening (synchronously and asynchronosly) on setting / getting properties.
+   * Allows listening (synchronously and asynchronously) on methods on selected interface
+   * Allows listening (synchronously and asynchronously) on setting / getting properties.
    * Allows emiting signals.
    */
   class DBusServer
index 759eb09..87f8c18 100644 (file)
@@ -74,6 +74,11 @@ public:
   virtual bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector<Dali::PixelData>& pixelData ) = 0;
 
   /**
+   * @copydoc Dali::AnimatedImageLoading::LoadFrame()
+   */
+  virtual Dali::Devel::PixelBuffer LoadFrame( uint32_t frameIndex ) = 0;
+
+  /**
    * @copydoc Dali::AnimatedImageLoading::GetImageSize()
    */
   virtual ImageDimensions GetImageSize() const = 0;
@@ -87,6 +92,11 @@ public:
    * @copydoc Dali::AnimatedImageLoading::LoadFrameDelays()
    */
   virtual uint32_t GetFrameInterval( uint32_t frameIndex ) const = 0;
+
+  /**
+   * @copydoc Dali::AnimatedImageLoading::GetUrl()
+   */
+  virtual std::string GetUrl() const = 0;
 };
 
 } // namespace Adaptor
index 187d91c..a6793f2 100644 (file)
@@ -1284,6 +1284,25 @@ bool GifLoading::LoadNextNFrames( uint32_t frameStartIndex, int count, std::vect
   return ret;
 }
 
+Dali::Devel::PixelBuffer GifLoading::LoadFrame( uint32_t frameIndex )
+{
+  int error;
+  Dali::Devel::PixelBuffer pixelBuffer;
+
+  DALI_LOG_INFO( gGifLoadingLogFilter, Debug::Concise, "LoadFrame( frameIndex:%d )\n", frameIndex );
+
+  pixelBuffer = Dali::Devel::PixelBuffer::New( mImpl->imageProperties.w, mImpl->imageProperties.h, Dali::Pixel::RGBA8888 );
+
+  mImpl->loaderInfo.animated.currentFrame = 1 + ( frameIndex % mImpl->loaderInfo.animated.frameCount );
+  ReadNextFrame( mImpl->loaderInfo, mImpl->imageProperties, pixelBuffer.GetBuffer(), &error );
+
+  if( error != 0 )
+  {
+    pixelBuffer = Dali::Devel::PixelBuffer();
+  }
+  return pixelBuffer;
+}
+
 ImageDimensions GifLoading::GetImageSize() const
 {
   return ImageDimensions( mImpl->imageProperties.w, mImpl->imageProperties.h );
@@ -1299,6 +1318,11 @@ uint32_t GifLoading::GetFrameInterval( uint32_t frameIndex ) const
   return mImpl->loaderInfo.animated.frames[frameIndex].info.delay * 10;
 }
 
+std::string GifLoading::GetUrl() const
+{
+  return mImpl->mUrl;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 4ee7565..c53fcde 100644 (file)
@@ -83,6 +83,16 @@ public:
    */
   bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector<Dali::PixelData>& pixelData ) override;
 
+   /**
+   * @brief Load the next Frame of the animated image.
+   *
+   * @note This function will load the entire animated image into memory if not already loaded.
+   * @param[in] frameIndex The frame counter to load. Will usually be the next frame.
+   * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
+   */
+
+  Dali::Devel::PixelBuffer LoadFrame( uint32_t frameIndex ) override;
+
   /**
    * @brief Get the size of a gif image.
    *
@@ -104,6 +114,13 @@ public:
    */
   uint32_t GetFrameInterval( uint32_t frameIndex ) const override;
 
+  /**
+   * @brief Get the animated image file URL
+   *
+   * @return The URL string of the animated image file
+   */
+  std::string GetUrl() const override;
+
 private:
   struct Impl;
   Impl* mImpl;
index d3031fa..db9a48f 100644 (file)
@@ -263,6 +263,50 @@ bool WebPLoading::LoadNextNFrames( uint32_t frameStartIndex, int count, std::vec
 #endif
 }
 
+Dali::Devel::PixelBuffer WebPLoading::LoadFrame( uint32_t frameIndex )
+{
+  Dali::Devel::PixelBuffer pixelBuffer;
+#ifdef DALI_WEBP_ENABLED
+  if( frameIndex  >= mImpl->mWebPAnimInfo.frame_count )
+  {
+    return pixelBuffer;
+  }
+
+  DALI_LOG_INFO( gWebPLoadingLogFilter, Debug::Concise, "LoadNextNFrames( frameIndex:%d )\n", frameIndex );
+
+  if( mImpl->mLoadingFrame > frameIndex  )
+  {
+    mImpl->mLoadingFrame = 0;
+    WebPAnimDecoderReset( mImpl->mWebPAnimDecoder );
+  }
+
+  for( ; mImpl->mLoadingFrame < frameIndex ; ++mImpl->mLoadingFrame )
+  {
+    uint8_t* frameBuffer;
+    int timestamp;
+    WebPAnimDecoderGetNext( mImpl->mWebPAnimDecoder, &frameBuffer, &timestamp );
+    mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp;
+  }
+
+  const int bufferSize = mImpl->mWebPAnimInfo.canvas_width * mImpl->mWebPAnimInfo.canvas_height * sizeof( uint32_t );
+  uint8_t* frameBuffer;
+  int timestamp;
+  WebPAnimDecoderGetNext( mImpl->mWebPAnimDecoder, &frameBuffer, &timestamp );
+
+  pixelBuffer = Dali::Devel::PixelBuffer::New( mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height, Dali::Pixel::RGBA8888 );
+  memcpy( pixelBuffer.GetBuffer(), frameBuffer, bufferSize );
+  mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp;
+
+  mImpl->mLoadingFrame++;
+  if( mImpl->mLoadingFrame >= mImpl->mWebPAnimInfo.frame_count )
+  {
+    mImpl->mLoadingFrame = 0;
+    WebPAnimDecoderReset( mImpl->mWebPAnimDecoder );
+  }
+#endif
+  return pixelBuffer;
+}
+
 ImageDimensions WebPLoading::GetImageSize() const
 {
 #ifdef DALI_WEBP_ENABLED
@@ -297,6 +341,11 @@ uint32_t WebPLoading::GetFrameInterval( uint32_t frameIndex ) const
   }
 }
 
+std::string WebPLoading::GetUrl() const
+{
+  return mImpl->mUrl;
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 01bd4e3..430cf53 100644 (file)
@@ -86,6 +86,16 @@ public:
    */
   bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector<Dali::PixelData>& pixelData ) override;
 
+   /**
+   * @brief Load the next Frame of the animated image.
+   *
+   * @note This function will load the entire animated image into memory if not already loaded.
+   * @param[in] frameIndex The frame counter to load. Will usually be the next frame.
+   * @return Dali::Devel::PixelBuffer The loaded PixelBuffer. If loading is fail, return empty handle.
+   */
+
+  Dali::Devel::PixelBuffer LoadFrame( uint32_t frameIndex ) override;
+
   /**
    * @brief Get the size of a webp image.
    *
@@ -107,6 +117,8 @@ public:
    */
   uint32_t GetFrameInterval( uint32_t frameIndex ) const override;
 
+  std::string GetUrl() const override;
+
 private:
   struct Impl;
   Impl* mImpl;