Added PixelBuffer for image loading and operations. 26/134926/9
authorDavid Steele <david.steele@samsung.com>
Thu, 8 Jun 2017 18:13:03 +0000 (19:13 +0100)
committerDavid Steele <david.steele@samsung.com>
Mon, 26 Jun 2017 21:08:23 +0000 (21:08 +0000)
Moved alpha masking from PixelData in Core to stand-alone C methods
in Adaptor.

Change-Id: I7eede320fdbc00e067241a4228b7e99ad958fe04

24 files changed:
adaptors/common/bitmap-loader-impl.cpp [deleted file]
adaptors/common/bitmap-loader-impl.h [deleted file]
adaptors/common/file.list
adaptors/common/pixel-buffer-impl.cpp [new file with mode: 0644]
adaptors/common/pixel-buffer-impl.h [new file with mode: 0644]
adaptors/devel-api/adaptor-framework/bitmap-loader.cpp [deleted file]
adaptors/devel-api/adaptor-framework/bitmap-loader.h [deleted file]
adaptors/devel-api/adaptor-framework/image-loading.cpp
adaptors/devel-api/adaptor-framework/image-loading.h
adaptors/devel-api/adaptor-framework/pixel-buffer.cpp [new file with mode: 0644]
adaptors/devel-api/adaptor-framework/pixel-buffer.h [new file with mode: 0644]
adaptors/devel-api/file.list
automated-tests/execute.sh
automated-tests/src/dali-adaptor-internal/CMakeLists.txt
automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp [new file with mode: 0644]
automated-tests/src/dali-adaptor/CMakeLists.txt
automated-tests/src/dali-adaptor/utc-Dali-BitmapLoader.cpp [deleted file]
automated-tests/src/dali-adaptor/utc-Dali-ImageLoading.cpp
automated-tests/src/dali-adaptor/utc-Dali-PixelBuffer.cpp [new file with mode: 0644]
platform-abstractions/portable/alpha-mask.cpp [new file with mode: 0644]
platform-abstractions/portable/alpha-mask.h [new file with mode: 0644]
platform-abstractions/portable/pixel-manipulation.cpp [new file with mode: 0644]
platform-abstractions/portable/pixel-manipulation.h [new file with mode: 0644]
platform-abstractions/tizen/file.list

diff --git a/adaptors/common/bitmap-loader-impl.cpp b/adaptors/common/bitmap-loader-impl.cpp
deleted file mode 100644 (file)
index 9cef7ee..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2014 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.
- */
-
-// EXTERNAL INCLUDES
-#include <string>
-
-// INTERNAL INCLUDES
-#include "image-loading.h"
-#include "bitmap-loader-impl.h"
-
-namespace Dali
-{
-namespace Internal
-{
-
-IntrusivePtr<BitmapLoader> BitmapLoader::New(const std::string& url,
-                                             ImageDimensions size,
-                                             FittingMode::Type fittingMode,
-                                             SamplingMode::Type samplingMode,
-                                             bool orientationCorrection)
-{
-  IntrusivePtr<BitmapLoader> internal = new BitmapLoader( url, size, fittingMode, samplingMode, orientationCorrection );
-  return internal;
-}
-
-BitmapLoader::BitmapLoader(const std::string& url,
-                           ImageDimensions size,
-                           FittingMode::Type fittingMode,
-                           SamplingMode::Type samplingMode,
-                           bool orientationCorrection )
-: mPixelData(),
-  mUrl(url),
-  mSize( size ),
-  mFittingMode( fittingMode ),
-  mSamplingMode( samplingMode ),
-  mOrientationCorrection( orientationCorrection )
-{
-}
-
-BitmapLoader::~BitmapLoader()
-{
-}
-
-void BitmapLoader::Load()
-{
-  mPixelData = Dali::LoadImageFromFile( mUrl, mSize, mFittingMode, mSamplingMode, mOrientationCorrection );
-}
-
-bool BitmapLoader::IsLoaded()
-{
-  return mPixelData ? true : false ;
-}
-
-const std::string& BitmapLoader::GetUrl() const
-{
-  return mUrl;
-}
-
-Dali::PixelData BitmapLoader::GetPixelData() const
-{
-  return mPixelData;
-}
-
-} // namespace Internal
-} // namespace Dali
diff --git a/adaptors/common/bitmap-loader-impl.h b/adaptors/common/bitmap-loader-impl.h
deleted file mode 100644 (file)
index f328889..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef __DALI_BITMAP_LOADER_IMPL_H__
-#define __DALI_BITMAP_LOADER_IMPL_H__
-
-/*
- * Copyright (c) 2014 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.
- */
-
-// EXTERNAL INCLUDES
-#include <string>
-#include <dali/public-api/images/pixel.h>
-#include <dali/public-api/object/base-object.h>
-#include <dali/public-api/common/intrusive-ptr.h>
-#include <dali/integration-api/bitmap.h>
-#include <dali/integration-api/resource-types.h>
-
-// INTERNAL INCLUDES
-#include <bitmap-loader.h>
-
-namespace Dali
-{
-namespace Internal
-{
-
-class BitmapLoader : public BaseObject
-{
-public:
-
-  /**
-   * @copydoc Dali::BitmapLoader::New
-   */
-  static IntrusivePtr<BitmapLoader> New( const std::string& url,
-                                         ImageDimensions size,
-                                         FittingMode::Type fittingMode,
-                                         SamplingMode::Type samplingMode,
-                                         bool orientationCorrection);
-
-  /**
-   * Create the bitmap loader object.
-   */
-   BitmapLoader(const std::string& url,
-               ImageDimensions size,
-               FittingMode::Type fittingMode,
-               SamplingMode::Type samplingMode,
-               bool orientationCorrection);
-
-protected:
-  /**
-   * Destructor
-   */
-  ~BitmapLoader();
-
-public:
-
-  /**
-   * @copydoc Dali::BitmapLoader::Load
-   */
-  void Load();
-
-  /**
-   * @copydoc Dali::BitmapLoader::IsLoaded
-   */
-  bool IsLoaded();
-
-  /**
-   * @copydoc Dali::BitmapLoader::GetUrl()
-   */
-  const std::string& GetUrl() const;
-
-  /**
-   * @copydoc Dali::BitmapLoader::GetPixelData
-   */
-  Dali::PixelData GetPixelData() const;
-
-private:
-
-  Dali::PixelData mPixelData;
-  const std::string mUrl;
-  ImageDimensions mSize;
-  FittingMode::Type mFittingMode;
-  SamplingMode::Type mSamplingMode;
-  bool mOrientationCorrection;
-
-};
-
-} // Internal
-
-
-inline Internal::BitmapLoader& GetImplementation(Dali::BitmapLoader& handle)
-{
-  DALI_ASSERT_ALWAYS( handle && "handle is empty" );
-
-  BaseObject& object = handle.GetBaseObject();
-
-  return static_cast<Internal::BitmapLoader&>(object);
-}
-
-inline const Internal::BitmapLoader& GetImplementation(const Dali::BitmapLoader& handle)
-{
-  DALI_ASSERT_ALWAYS( handle && "handle is empty" );
-
-  const BaseObject& object = handle.GetBaseObject();
-
-  return static_cast<const Internal::BitmapLoader&>(object);
-}
-
-} // Dali
-
-#endif // __DALI_BITMAP_LOADER_IMPL_H__
index af0bebe..af15d62 100644 (file)
@@ -7,7 +7,6 @@ adaptor_common_internal_src_files = \
   $(adaptor_common_dir)/adaptor.cpp \
   $(adaptor_common_dir)/adaptor-impl.cpp \
   $(adaptor_common_dir)/application-impl.cpp \
-  $(adaptor_common_dir)/bitmap-loader-impl.cpp \
   $(adaptor_common_dir)/clipboard-event-notifier-impl.cpp \
   $(adaptor_common_dir)/command-line-options.cpp \
   $(adaptor_common_dir)/drag-and-drop-detector-impl.cpp \
@@ -22,6 +21,7 @@ adaptor_common_internal_src_files = \
   $(adaptor_common_dir)/orientation-impl.cpp  \
   $(adaptor_common_dir)/performance-logger-impl.cpp \
   $(adaptor_common_dir)/physical-keyboard-impl.cpp \
+  $(adaptor_common_dir)/pixel-buffer-impl.cpp \
   $(adaptor_common_dir)/shared-file.cpp \
   $(adaptor_common_dir)/singleton-service-impl.cpp \
   $(adaptor_common_dir)/sound-player-impl.cpp \
diff --git a/adaptors/common/pixel-buffer-impl.cpp b/adaptors/common/pixel-buffer-impl.cpp
new file mode 100644 (file)
index 0000000..a2b1610
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017 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.
+ *
+ */
+
+// CLASS HEADER
+#include "pixel-buffer-impl.h"
+
+// EXTERNAL INCLUDES
+#include <stdlib.h>
+#include <cstring>
+
+// INTERNAL INCLUDES
+#include "pixel-manipulation.h"
+#include "alpha-mask.h"
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+PixelBuffer::PixelBuffer( unsigned char* buffer,
+                          unsigned int bufferSize,
+                          unsigned int width,
+                          unsigned int height,
+                          Dali::Pixel::Format pixelFormat )
+: mBuffer( buffer ),
+  mBufferSize( bufferSize ),
+  mWidth( width ),
+  mHeight( height ),
+  mPixelFormat( pixelFormat )
+{
+}
+
+PixelBuffer::~PixelBuffer()
+{
+  ReleaseBuffer();
+}
+
+PixelBufferPtr PixelBuffer::New( unsigned int width,
+                                 unsigned int height,
+                                 Dali::Pixel::Format pixelFormat )
+{
+  unsigned int bufferSize = width * height * Dali::Pixel::GetBytesPerPixel( pixelFormat );
+  unsigned char* buffer = NULL;
+  if( bufferSize > 0 )
+  {
+    buffer = static_cast<unsigned char*>( malloc ( bufferSize ) );
+  }
+  return new PixelBuffer( buffer, bufferSize, width, height, pixelFormat );
+}
+
+PixelBufferPtr PixelBuffer::New( unsigned char* buffer,
+                                 unsigned int bufferSize,
+                                 unsigned int width,
+                                 unsigned int height,
+                                 Dali::Pixel::Format pixelFormat )
+{
+  return new PixelBuffer( buffer, bufferSize, width, height, pixelFormat );
+}
+
+Dali::PixelData PixelBuffer::Convert( PixelBuffer& pixelBuffer )
+{
+  Dali::PixelData pixelData = Dali::PixelData::New( pixelBuffer.mBuffer,
+                                                    pixelBuffer.mBufferSize,
+                                                    pixelBuffer.mWidth,
+                                                    pixelBuffer.mHeight,
+                                                    pixelBuffer.mPixelFormat,
+                                                    Dali::PixelData::FREE );
+  pixelBuffer.mBuffer = NULL;
+  pixelBuffer.mWidth = 0;
+  pixelBuffer.mHeight = 0;
+  pixelBuffer.mBufferSize = 0;
+
+  return pixelData;
+}
+
+unsigned int PixelBuffer::GetWidth() const
+{
+  return mWidth;
+}
+
+unsigned int PixelBuffer::GetHeight() const
+{
+  return mHeight;
+}
+
+Dali::Pixel::Format PixelBuffer::GetPixelFormat() const
+{
+  return mPixelFormat;
+}
+
+unsigned char* PixelBuffer::GetBuffer() const
+{
+  return mBuffer;
+}
+
+unsigned int PixelBuffer::GetBufferSize() const
+{
+  return mBufferSize;
+}
+
+Dali::PixelData PixelBuffer::CreatePixelData() const
+{
+  unsigned char* destBuffer = NULL;
+
+  if( mBufferSize > 0 )
+  {
+    destBuffer = static_cast<unsigned char*>( malloc( mBufferSize ) );
+    memcpy( destBuffer, mBuffer, mBufferSize );
+  }
+
+  Dali::PixelData pixelData = Dali::PixelData::New( destBuffer, mBufferSize,
+                                                    mWidth, mHeight,
+                                                    mPixelFormat,
+                                                    Dali::PixelData::FREE );
+  return pixelData;
+}
+
+void PixelBuffer::ApplyMask( const PixelBuffer& mask )
+{
+  int byteOffset=0;
+  int bitMask=0;
+
+  Dali::Pixel::GetAlphaOffsetAndMask(mPixelFormat, byteOffset, bitMask);
+
+  if( Dali::Pixel::HasAlpha( mPixelFormat ) && bitMask == 255 )
+  {
+    ApplyMaskToAlphaChannel( *this, mask );
+  }
+  else
+  {
+    PixelBufferPtr newPixelBuffer = CreateNewMaskedBuffer( *this, mask );
+    ReleaseBuffer();
+
+    // Take ownership of new buffer
+    mBuffer = newPixelBuffer->mBuffer;
+    newPixelBuffer->mBuffer = NULL;
+    mPixelFormat = newPixelBuffer->mPixelFormat;
+    mBufferSize = newPixelBuffer->mBufferSize;
+
+    // On leaving scope, newPixelBuffer will get destroyed.
+  }
+}
+
+void PixelBuffer::ReleaseBuffer()
+{
+  if( mBuffer )
+  {
+    free( mBuffer );
+  }
+}
+
+
+}// namespace Adaptor
+}// namespace Internal
+}// namespace Dali
diff --git a/adaptors/common/pixel-buffer-impl.h b/adaptors/common/pixel-buffer-impl.h
new file mode 100644 (file)
index 0000000..4853001
--- /dev/null
@@ -0,0 +1,201 @@
+#ifndef DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H
+#define DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H
+
+/*
+ * Copyright (c) 2017 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <pixel-buffer.h>
+#include <dali/public-api/images/pixel-data.h>
+#include <dali/public-api/object/base-object.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class PixelBuffer;
+typedef IntrusivePtr<PixelBuffer> PixelBufferPtr;
+
+class PixelBuffer : public BaseObject
+{
+public:
+
+  /**
+   * @brief Create a PixelBuffer object with a pre-allocated buffer.
+   * The PixelBuffer object owns this buffer, which may be retrieved
+   * and modified using GetBuffer().
+   *
+   * @param [in] width            Buffer width in pixels
+   * @param [in] height           Buffer height in pixels
+   * @param [in] pixelFormat      The pixel format
+   */
+  static PixelBufferPtr New( unsigned int width,
+                             unsigned int height,
+                             Pixel::Format pixelFormat );
+
+  /**
+   * @brief Create a PixelBuffer object. For internal use only.
+   *
+   * @param [in] buffer           The raw pixel data.
+   * @param [in] bufferSize       The size of the buffer in bytes
+   * @param [in] width            Buffer width in pixels
+   * @param [in] height           Buffer height in pixels
+   * @param [in] pixelFormat      The pixel format
+   * @param [in] releaseFunction  The function used to release the memory.
+   */
+  static PixelBufferPtr New( unsigned char* buffer,
+                             unsigned int bufferSize,
+                             unsigned int width,
+                             unsigned int height,
+                             Pixel::Format pixelFormat );
+
+  /**
+   * Convert a pixelBuffer object into a PixelData object.
+   * The new object takes ownership of the buffer data, and the
+   * mBuffer pointer is reset to NULL.
+   * @param[in] pixelBuffer The buffer to convert
+   * @return the pixelData
+   */
+  static Dali::PixelData Convert( PixelBuffer& pixelBuffer );
+
+  /**
+   * @brief Constructor.
+   *
+   * @param [in] buffer           The raw pixel data.
+   * @param [in] bufferSize       The size of the buffer in bytes
+   * @param [in] width            Buffer width in pixels
+   * @param [in] height           Buffer height in pixels
+   * @param [in] pixelFormat      The pixel format
+   */
+  PixelBuffer( unsigned char* buffer,
+               unsigned int bufferSize,
+               unsigned int width,
+               unsigned int height,
+               Pixel::Format pixelFormat );
+
+protected:
+
+  /**
+   * @brief Destructor.
+   *
+   * Release the pixel buffer if exists.
+   */
+  ~PixelBuffer();
+
+public:
+
+  /**
+   * Get the width of the buffer in pixels.
+   * @return The width of the buffer in pixels
+   */
+  unsigned int GetWidth() const;
+
+  /**
+   * Get the height of the buffer in pixels
+   * @return The height of the buffer in pixels
+   */
+  unsigned int GetHeight() const;
+
+  /**
+   * Get the pixel format
+   * @return The pixel format
+   */
+  Pixel::Format GetPixelFormat() const;
+
+  /**
+   * Get the pixel buffer if it's present.
+   * @return The buffer if exists, or NULL if there is no pixel buffer.
+   */
+  unsigned char* GetBuffer() const;
+
+  /**
+   * Get the size of the buffer in bytes
+   * @return The size of the buffer
+   */
+  unsigned int GetBufferSize() const;
+
+  /**
+   * Copy the buffer into a new PixelData
+   */
+  Dali::PixelData CreatePixelData() const;
+
+  /**
+   * Apply the mask to the current buffer. This method may update the
+   * internal object - e.g. the new buffer may have a different pixel
+   * format - as an alpha channel may be added.
+   * @param[in] mask The mask to apply to this pixel buffer
+   */
+  void ApplyMask( const PixelBuffer& mask );
+
+private:
+  /*
+   * Undefined copy constructor.
+   */
+  PixelBuffer(const PixelBuffer& other);
+
+  /*
+   * Undefined assignment operator.
+   */
+  PixelBuffer& operator= (const PixelBuffer& other);
+
+  /**
+   * Release the buffer
+   */
+  void ReleaseBuffer();
+
+private:
+
+  unsigned char* mBuffer;           ///< The raw pixel data
+  unsigned int   mBufferSize;       ///< Buffer sized in bytes
+  unsigned int   mWidth;            ///< Buffer width in pixels
+  unsigned int   mHeight;           ///< Buffer height in pixels
+  Pixel::Format  mPixelFormat;      ///< Pixel format
+};
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+/**
+ * Helper methods for public API
+ */
+inline Internal::Adaptor::PixelBuffer& GetImplementation( Devel::PixelBuffer& handle )
+{
+  DALI_ASSERT_ALWAYS( handle && "handle is empty" );
+
+  BaseObject& object = handle.GetBaseObject();
+
+  return static_cast<Internal::Adaptor::PixelBuffer&>( object );
+}
+
+inline const Internal::Adaptor::PixelBuffer& GetImplementation( const Devel::PixelBuffer& handle )
+{
+  DALI_ASSERT_ALWAYS( handle && "handle is empty" );
+
+  const BaseObject& object = handle.GetBaseObject();
+
+  return static_cast<const Internal::Adaptor::PixelBuffer&>( object );
+}
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_ADAPTOR_PIXEL_BUFFER_H__
diff --git a/adaptors/devel-api/adaptor-framework/bitmap-loader.cpp b/adaptors/devel-api/adaptor-framework/bitmap-loader.cpp
deleted file mode 100644 (file)
index 4aa2bd6..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2015 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.
- */
-
-// CLASS HEADER
-#include "bitmap-loader.h"
-
-// EXTERNAL INCLUDES
-#include <string>
-
-// INTERNAL INCLUDES
-#include <bitmap-loader-impl.h>
-
-namespace Dali
-{
-
-BitmapLoader BitmapLoader::New( const std::string& url,
-                                ImageDimensions size,
-                                FittingMode::Type fittingMode,
-                                SamplingMode::Type samplingMode,
-                                bool orientationCorrection)
-{
-  IntrusivePtr<Internal::BitmapLoader> internal = Internal::BitmapLoader::New(url, size, fittingMode, samplingMode, orientationCorrection);
-  return BitmapLoader( internal.Get() );
-}
-
-BitmapLoader::BitmapLoader()
-{
-}
-
-BitmapLoader::BitmapLoader(Internal::BitmapLoader* internal)
-: BaseHandle( internal )
-{
-}
-
-BitmapLoader::~BitmapLoader()
-{
-}
-
-BitmapLoader::BitmapLoader( const BitmapLoader& handle )
-: BaseHandle( handle )
-{
-}
-
-BitmapLoader& BitmapLoader::operator=(const BitmapLoader& rhs)
-{
-  BaseHandle::operator=(rhs);
-  return *this;
-}
-
-void BitmapLoader::Load()
-{
-  GetImplementation(*this).Load();
-}
-
-bool BitmapLoader::IsLoaded()
-{
-  return GetImplementation(*this).IsLoaded();
-}
-
-std::string BitmapLoader::GetUrl() const
-{
-  return GetImplementation(*this).GetUrl();
-}
-
-PixelData BitmapLoader::GetPixelData() const
-{
-  return GetImplementation(*this).GetPixelData();
-}
-
-} // namespace Dali
diff --git a/adaptors/devel-api/adaptor-framework/bitmap-loader.h b/adaptors/devel-api/adaptor-framework/bitmap-loader.h
deleted file mode 100644 (file)
index 7849db4..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef DALI_BITMAP_LOADER_H
-#define DALI_BITMAP_LOADER_H
-
-/*
- * Copyright (c) 2015 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.
- */
-
-// EXTERNAL INCLUDES
-#include <string>
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/images/image-operations.h>
-#include <dali/public-api/images/pixel.h>
-#include <dali/public-api/images/pixel-data.h>
-#include <dali/public-api/object/base-handle.h>
-
-namespace Dali
-{
-namespace Internal
-{
-class BitmapLoader;
-}
-
-/**
- * @brief The BitmapLoader class is used to load bitmap from the URL synchronously.
- *
- * As the loading is synchronous, it will block the loop whilst executing.
- * Therefore, it should be used sparingly in the main event thread, and better to be called in the worker thread.
- * The Load() API is thread safe, it can be called from any thread without changing the state of DALI.
- */
-class DALI_IMPORT_API BitmapLoader : public BaseHandle
-{
-public:
-
-  /**
-   * @brief Create an initialized bitmap loader.
-   *
-   * By calling Load(), the synchronous loading is started immediately.
-   *
-   * @param [in] url The URL of the image file to load.
-   * @param [in] size The width and height to fit the loaded image to.
-   * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
-   * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
-   * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
-   */
-  static BitmapLoader New( const std::string& url,
-                           ImageDimensions size = ImageDimensions( 0, 0 ),
-                           FittingMode::Type fittingMode = FittingMode::DEFAULT,
-                           SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR,
-                           bool orientationCorrection = true);
-
-  /**
-   * @brief Create an empty handle.
-   *
-   * Use BitmapLoader::New() to create an initialized object.
-   */
-  BitmapLoader();
-
-  /**
-   * Destructor
-   */
-  ~BitmapLoader();
-
-  /**
-   * @brief This copy constructor is required for (smart) pointer semantics.
-   *
-   * @param [in] handle A reference to the copied handle
-   */
-  BitmapLoader(const BitmapLoader& handle);
-
-  /**
-   * @brief This assignment operator is required for (smart) pointer semantics.
-   *
-   * @param [in] rhs  A reference to the copied handle
-   * @return A reference to this
-   */
-  BitmapLoader& operator=(const BitmapLoader& rhs);
-
-public:
-
-  /**
-   * @brief Start the synchronous loading.
-   */
-  void Load();
-
-  /**
-   * @brief Query whether the image is loaded.
-   *
-   * @return true if the image is loaded, false otherwise.
-   */
-  bool IsLoaded();
-
-  /**
-   * @brief Returns the URL of the image.
-   *
-   * @return The URL of the image file.
-   */
-  std::string GetUrl() const;
-
-  /**
-   * @brief Get the pixel data.
-   *
-   * The returned pixel data is still valid after the BitmapLoader been destroyed.
-   *
-   * @return The pixel data.
-   */
-  PixelData GetPixelData() const;
-
-public: // Not intended for application developers
-
-  explicit DALI_INTERNAL BitmapLoader(Internal::BitmapLoader*);
-};
-
-} // Dali
-
-#endif // DALI_BITMAP_LOADER_H
index 701ccc7..d8f8adf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
@@ -21,6 +21,7 @@
 #include "image-loaders/image-loader.h"
 #include <resource-loader/network/file-download.h>
 #include <platform-abstractions/portable/file-closer.h>
+#include "pixel-buffer-impl.h"
 
 namespace Dali
 {
@@ -31,25 +32,34 @@ namespace
 const size_t MAXIMUM_DOWNLOAD_IMAGE_SIZE  = 50 * 1024 * 1024 ;
 }
 
-PixelData LoadImageFromFile( const std::string& url, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
+Devel::PixelBuffer LoadImageFromFile( const std::string& url, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
 {
   Integration::BitmapResourceType resourceType( size, fittingMode, samplingMode, orientationCorrection );
-  IntrusivePtr<Dali::RefObject> resource = TizenPlatform::ImageLoader::LoadImageSynchronously( resourceType, url );
 
-  if( resource )
+  Internal::Platform::FileCloser fc( url.c_str(), "rb");
+  FILE * const fp = fc.GetFile();
+  if( fp != NULL )
   {
-    Integration::Bitmap* bitmap = static_cast<Integration::Bitmap*>( resource.Get() );
-
-    // Use bitmap->GetBufferOwnership() to transfer the buffer ownership to pixelData.
-    // The destroy of bitmap will not release the buffer, instead, the pixelData is responsible for releasing when its reference count falls to zero.
-    return Dali::PixelData::New( bitmap->GetBufferOwnership(),
-                                 bitmap->GetBufferSize(),
-                                 bitmap->GetImageWidth(),
-                                 bitmap->GetImageHeight(),
-                                 bitmap->GetPixelFormat(),
-                                 Dali::PixelData::FREE );
+    Integration::BitmapPtr bitmap;
+    bool success = TizenPlatform::ImageLoader::ConvertStreamToBitmap( resourceType, url, fp, bitmap );
+    if( success && bitmap )
+    {
+      // Use bitmap->GetBufferOwnership() to transfer the buffer ownership
+      // to pixelData.  The destroy of bitmap will not release the buffer,
+      // instead, the pixelBuffer is responsible for releasing when its
+      // reference count falls to zero.
+      Internal::Adaptor::PixelBufferPtr pixelBufferImpl =
+        Internal::Adaptor::PixelBuffer::New( bitmap->GetBufferOwnership(),
+                                             bitmap->GetBufferSize(),
+                                             bitmap->GetImageWidth(),
+                                             bitmap->GetImageHeight(),
+                                             bitmap->GetPixelFormat() );
+
+      Dali::Devel::PixelBuffer pixelBuffer( pixelBufferImpl.Get() );
+      return pixelBuffer;
+    }
   }
-  return Dali::PixelData();
+  return Dali::Devel::PixelBuffer();
 }
 
 ImageDimensions GetClosestImageSize( const std::string& filename,
@@ -62,7 +72,7 @@ ImageDimensions GetClosestImageSize( const std::string& filename,
 }
 
 
-PixelData DownloadImageSynchronously( const std::string& url, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
+Devel::PixelBuffer DownloadImageSynchronously( const std::string& url, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
 {
   Integration::BitmapResourceType resourceType( size, fittingMode, samplingMode, orientationCorrection );
 
@@ -96,12 +106,15 @@ PixelData DownloadImageSynchronously( const std::string& url, ImageDimensions si
 
         if ( result && bitmap )
         {
-          return Dali::PixelData::New( bitmap->GetBufferOwnership(),
-                                       bitmap->GetBufferSize(),
-                                       bitmap->GetImageWidth(),
-                                       bitmap->GetImageHeight(),
-                                       bitmap->GetPixelFormat(),
-                                       Dali::PixelData::FREE );
+          Internal::Adaptor::PixelBufferPtr pixelBufferImpl =
+            Internal::Adaptor::PixelBuffer::New( bitmap->GetBufferOwnership(),
+                                                 bitmap->GetBufferSize(),
+                                                 bitmap->GetImageWidth(),
+                                                 bitmap->GetImageHeight(),
+                                                 bitmap->GetPixelFormat() );
+
+          Dali::Devel::PixelBuffer pixelBuffer( pixelBufferImpl.Get() );
+          return pixelBuffer;
         }
         else
         {
@@ -109,9 +122,8 @@ PixelData DownloadImageSynchronously( const std::string& url, ImageDimensions si
         }
       }
     }
-
   }
-  return Dali::PixelData();
+  return Dali::Devel::PixelBuffer();
 }
 
 
index 124b27b..00a6a45 100644 (file)
 #include <string>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/images/image-operations.h>
-#include <dali/public-api/images/pixel-data.h>
+
+#ifdef DALI_ADAPTOR_COMPILATION  // full path doesn't exist until adaptor is installed so we have to use relative
+// @todo Make dali-adaptor code folder structure mirror the folder structure installed to dali-env
+#include <pixel-buffer.h>
+#else
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#endif
 
 namespace Dali
 {
@@ -36,9 +42,9 @@ namespace Dali
  * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
  * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
  * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
- * @return handle to the loaded PixelData object or an empty handle in case loading failed.
+ * @return handle to the loaded PixelBuffer object or an empty handle in case loading failed.
  */
-DALI_IMPORT_API PixelData LoadImageFromFile(
+DALI_IMPORT_API Devel::PixelBuffer LoadImageFromFile(
   const std::string& url,
   ImageDimensions size = ImageDimensions( 0, 0 ),
   FittingMode::Type fittingMode = FittingMode::DEFAULT,
@@ -77,9 +83,9 @@ DALI_IMPORT_API ImageDimensions GetClosestImageSize(
  * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
  * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
  *
- * @return handle to the loaded PixelData object or an empty handle in case downloading or decoding failed.
+ * @return handle to the loaded PixelBuffer object or an empty handle in case downloading or decoding failed.
  */
-DALI_IMPORT_API PixelData DownloadImageSynchronously(
+DALI_IMPORT_API Devel::PixelBuffer DownloadImageSynchronously(
   const std::string& url,
   ImageDimensions size = ImageDimensions( 0, 0 ),
   FittingMode::Type fittingMode = FittingMode::DEFAULT,
diff --git a/adaptors/devel-api/adaptor-framework/pixel-buffer.cpp b/adaptors/devel-api/adaptor-framework/pixel-buffer.cpp
new file mode 100644 (file)
index 0000000..52d8b8f
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 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.
+ *
+ */
+
+// CLASS HEADER
+#include "pixel-buffer.h"
+
+// EXTERNAL INLCUDES
+#include <stdlib.h>
+
+// INTERNAL INCLUDES
+#include <pixel-buffer-impl.h>
+
+namespace Dali
+{
+namespace Devel
+{
+
+PixelBuffer PixelBuffer::New( unsigned int width,
+                              unsigned int height,
+                              Dali::Pixel::Format pixelFormat )
+{
+  Internal::Adaptor::PixelBufferPtr internal =
+    Internal::Adaptor::PixelBuffer::New( width, height, pixelFormat );
+  return Devel::PixelBuffer( internal.Get() );
+}
+
+Dali::PixelData PixelBuffer::Convert( PixelBuffer& pixelBuffer )
+{
+  Dali::PixelData pixelData =
+    Internal::Adaptor::PixelBuffer::Convert( GetImplementation(pixelBuffer) );
+  pixelBuffer.Reset();
+  return pixelData;
+}
+
+Dali::PixelData PixelBuffer::CreatePixelData() const
+{
+  return GetImplementation(*this).CreatePixelData();
+}
+
+
+PixelBuffer::PixelBuffer()
+{
+}
+
+PixelBuffer::~PixelBuffer()
+{
+}
+
+PixelBuffer::PixelBuffer( Internal::Adaptor::PixelBuffer* internal )
+: BaseHandle( internal )
+{
+}
+
+PixelBuffer::PixelBuffer(const PixelBuffer& handle)
+: BaseHandle( handle )
+{
+}
+
+PixelBuffer& PixelBuffer::operator=(const PixelBuffer& rhs)
+{
+  BaseHandle::operator=(rhs);
+  return *this;
+}
+
+unsigned int PixelBuffer::GetWidth() const
+{
+  return GetImplementation(*this).GetWidth();
+}
+
+unsigned int PixelBuffer::GetHeight() const
+{
+  return GetImplementation(*this).GetHeight();
+}
+
+Pixel::Format PixelBuffer::GetPixelFormat() const
+{
+  return GetImplementation(*this).GetPixelFormat();
+}
+
+unsigned char* PixelBuffer::GetBuffer()
+{
+  return GetImplementation(*this).GetBuffer();
+}
+
+void PixelBuffer::ApplyMask( PixelBuffer mask )
+{
+  GetImplementation(*this).ApplyMask( GetImplementation( mask ) );
+}
+
+} // namespace Devel
+
+} // namespace Dali
diff --git a/adaptors/devel-api/adaptor-framework/pixel-buffer.h b/adaptors/devel-api/adaptor-framework/pixel-buffer.h
new file mode 100644 (file)
index 0000000..deb7823
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef DALI_PIXEL_BUFFER_H
+#define DALI_PIXEL_BUFFER_H
+
+/*
+ * Copyright (c) 2017 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 <dali/public-api/images/pixel.h>
+#include <dali/public-api/images/pixel-data.h>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+namespace Adaptor
+{
+class PixelBuffer;
+}
+}
+
+// Use namespace to separate from PixelBuffer typedef in buffer-image.h
+namespace Devel
+{
+
+/**
+ * @brief The PixelBuffer object holds a pixel buffer.
+ *
+ * The PixelBuffer keeps ownership of it's initial buffer however, the
+ * user is free to modify the pixel data, either directly, or via
+ * image operations.
+ *
+ * In order to upload the pixel data to texture memory, there are two
+ * possibilities - either convert it back to a PixelData object, which
+ * releases the PixelBuffer object, leaving the user with an empty handle
+ * (ideal for one-time indirect image manipulation), or create a new
+ * PixelData object from this object, leaving the buffer intact (ideal
+ * for continuous manipulation)
+ *
+ * @SINCE_1_2.46
+ */
+class DALI_IMPORT_API PixelBuffer : public BaseHandle
+{
+public:
+
+  /**
+   * Create a PixelBuffer with it's own data buffer.
+   */
+  static PixelBuffer New( unsigned int width,
+                          unsigned int height,
+                          Dali::Pixel::Format pixelFormat );
+
+  /**
+   * @brief Creates an empty handle.
+   * Use PixelBuffer::New() to create an initialized object.
+   *
+   * @SINCE_1_2.46
+   */
+  PixelBuffer();
+
+  /**
+   * @brief Destructor.
+   *
+   * @SINCE_1_2.46
+   */
+  ~PixelBuffer();
+
+  /**
+   * @brief This copy constructor is required for (smart) pointer semantics.
+   *
+   * @SINCE_1_2.46
+   * @param[in] handle A reference to the copied handle
+   */
+  PixelBuffer(const PixelBuffer& handle);
+
+  /**
+   * @brief This assignment operator is required for (smart) pointer semantics.
+   *
+   * @SINCE_1_2.46
+   * @param[in] rhs A reference to the copied handle
+   * @return A reference to this object
+   */
+  PixelBuffer& operator=(const PixelBuffer& rhs);
+
+  /**
+   * Convert to a pixel data and release the pixelBuffer's object.
+   * This handle is left empty.
+   *
+   * @warning Any other handles that keep a reference to this object
+   * will be left with no buffer, trying to access it will return NULL.
+   *
+   * @SINCE_1_2.46
+   * @param[in,out] pixelBuffer
+   * @return a new PixelData which takes ownership of the PixelBuffer's buffer.
+   */
+  static PixelData Convert( PixelBuffer& pixelBuffer );
+
+  /**
+   * Copy the data from this object into a new PixelData object, which could be
+   * used for uploading to a texture.
+   * @return a new PixelData object containing a copy of this pixel buffer's data.
+   */
+  Dali::PixelData CreatePixelData() const;
+
+  /**
+   * @brief Gets the pixel buffer. This is a pointer to the internal
+   * pixel buffer.
+   *
+   * @warning If there is no pixel buffer (e.g. this object has been
+   * converted to a PixelData), this method will return NULL.
+   *
+   * @SINCE_1_2.46
+   * @return The pixel buffer, or NULL.
+   */
+  unsigned char* GetBuffer();
+
+  /**
+   * @brief Gets the width of the buffer in pixels.
+   *
+   * @SINCE_1_2.46
+   * @return The width of the buffer in pixels
+   */
+  unsigned int GetWidth() const;
+
+  /**
+   * @brief Gets the height of the buffer in pixels.
+   *
+   * @SINCE_1_2.46
+   * @return The height of the buffer in pixels
+   */
+  unsigned int GetHeight() const;
+
+  /**
+   * @brief Gets the pixel format.
+   *
+   * @SINCE_1_2.46
+   * @return The pixel format
+   */
+  Pixel::Format GetPixelFormat() const;
+
+  /**
+   * Apply the mask to this pixel data, and return a new pixel data
+   * containing the masked image. If this PixelBuffer doesn't have an alpha channel,
+   * then the resultant PixelBuffer will be converted to a format that
+   * supports at least the width of the color channels and the alpha channel
+   * from the mask.
+   * @param[in] mask The mask to apply.
+   */
+  void ApplyMask( PixelBuffer mask );
+
+public:
+
+  /**
+   * @brief The constructor.
+   * @note  Not intended for application developers.
+   * @SINCE_1_2.46
+   * @param[in] pointer A pointer to a newly allocated PixelBuffer
+   */
+  explicit DALI_INTERNAL PixelBuffer( Internal::Adaptor::PixelBuffer* pointer );
+};
+
+} // namespace Devel
+} // namespace Dali
+
+#endif // DALI_PIXEL_BUFFER_H
index 6cdeb53..0ce6e62 100644 (file)
@@ -2,7 +2,6 @@ devel_api_src_files = \
   $(adaptor_devel_api_dir)/adaptor-framework/accessibility-adaptor.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/application-devel.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/application-extensions.cpp \
-  $(adaptor_devel_api_dir)/adaptor-framework/bitmap-loader.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/bitmap-saver.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/clipboard.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/clipboard-event-notifier.cpp \
@@ -20,6 +19,7 @@ devel_api_src_files = \
   $(adaptor_devel_api_dir)/adaptor-framework/orientation.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/performance-logger.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/physical-keyboard.cpp \
+  $(adaptor_devel_api_dir)/adaptor-framework/pixel-buffer.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/singleton-service.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/sound-player.cpp \
   $(adaptor_devel_api_dir)/adaptor-framework/style-monitor.cpp \
@@ -36,7 +36,6 @@ devel_api_adaptor_framework_header_files = \
   $(adaptor_devel_api_dir)/adaptor-framework/accessibility-gesture-handler.h \
   $(adaptor_devel_api_dir)/adaptor-framework/application-devel.h \
   $(adaptor_devel_api_dir)/adaptor-framework/application-extensions.h \
-  $(adaptor_devel_api_dir)/adaptor-framework/bitmap-loader.h \
   $(adaptor_devel_api_dir)/adaptor-framework/bitmap-saver.h \
   $(adaptor_devel_api_dir)/adaptor-framework/clipboard-event-notifier.h \
   $(adaptor_devel_api_dir)/adaptor-framework/clipboard.h \
@@ -56,6 +55,7 @@ devel_api_adaptor_framework_header_files = \
   $(adaptor_devel_api_dir)/adaptor-framework/lifecycle-controller.h \
   $(adaptor_devel_api_dir)/adaptor-framework/orientation.h \
   $(adaptor_devel_api_dir)/adaptor-framework/performance-logger.h \
+  $(adaptor_devel_api_dir)/adaptor-framework/pixel-buffer.h \
   $(adaptor_devel_api_dir)/adaptor-framework/render-surface.h \
   $(adaptor_devel_api_dir)/adaptor-framework/singleton-service.h \
   $(adaptor_devel_api_dir)/adaptor-framework/sound-player.h \
@@ -67,4 +67,3 @@ devel_api_adaptor_framework_header_files = \
   $(adaptor_devel_api_dir)/adaptor-framework/virtual-keyboard.h \
   $(adaptor_devel_api_dir)/adaptor-framework/physical-keyboard.h \
   $(adaptor_devel_api_dir)/adaptor-framework/window-devel.h
-
index bc108fa..bc51cfb 100755 (executable)
@@ -75,7 +75,7 @@ rm -f tct*core-tests.xml
 
 # Clean up old coverage data
 if [ -d ../build/tizen ] ; then
-    rm -f ../build/tizen/dali-toolkit/.libs/*.gcda
+    rm -f ../build/tizen/dali/.libs/*.gcda
 fi
 
 find build \( -name "*.gcda" \) -exec rm '{}' \;
@@ -138,9 +138,9 @@ else
             ret=$?
             if [ $ret -ne 6 ] ; then
                 if [ $opt_debug -ne 0 ] ; then
-                    if [ $ret -eq 0 ] ; then
-                        gdb --args build/src/$mod/tct-$mod-core $1
-                    fi
+                    echo DEBUGGING:
+                    gdb --args build/src/$mod/tct-$mod-core $1
+
                 else
                     echo $output
                     if [ $ret -eq 0 ] ; then echo -e "\nPassed" ; fi
index af08fd1..c41bc4d 100644 (file)
@@ -12,6 +12,7 @@ SET(TC_SOURCES
     utc-Dali-GifLoader.cpp
     utc-Dali-IcoLoader.cpp
     utc-Dali-ImageOperations.cpp
+    utc-Dali-Internal-PixelBuffer.cpp
     utc-Dali-Lifecycle-Controller.cpp
     utc-Dali-TiltSensor.cpp
 )
diff --git a/automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp b/automated-tests/src/dali-adaptor-internal/utc-Dali-Internal-PixelBuffer.cpp
new file mode 100644 (file)
index 0000000..710e52c
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014 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 <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+
+#include <dali-test-suite-utils.h>
+
+// Internal headers are allowed here
+
+#include <platform-abstractions/portable/pixel-manipulation.h>
+
+using namespace Dali;
+using namespace Dali::Internal::Adaptor;
+void utc_dali_internal_pixel_data_startup()
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_internal_pixel_data_cleanup()
+{
+  test_return_value = TET_PASS;
+}
+
+const char* ChannelToString( Dali::Internal::Adaptor::Channel channel )
+{
+  switch(channel)
+  {
+    case LUMINANCE: return "Luminance";
+    case RED: return "Red";
+    case GREEN: return "Green";
+    case BLUE: return "Blue";
+    case ALPHA: return "Alpha";
+    default:
+      return "Unknown";
+  }
+}
+
+const char* FormatToString( Dali::Pixel::Format format )
+{
+  switch(format)
+  {
+    case Dali::Pixel::A8: return "A8";
+    case Dali::Pixel::L8: return "L8";
+    case Dali::Pixel::LA88: return "LA88";
+    case Dali::Pixel::RGB565: return "RGB565";
+    case Dali::Pixel::BGR565: return "BGR565";
+    case Dali::Pixel::RGBA4444: return "RGBA4444";
+    case Dali::Pixel::BGRA4444: return "BGRA4444";
+    case Dali::Pixel::RGBA5551: return "RGBA5551";
+    case Dali::Pixel::BGRA5551: return "BGRA5551";
+
+    case Dali::Pixel::RGB888: return "RGB888";
+    case Dali::Pixel::RGBA8888: return "RGBA8888";
+    case Dali::Pixel::BGRA8888: return "BGRA8888";
+
+    default:
+      return "Unknown";
+  }
+}
+
+
+int UtcDaliPixelManipulation01(void)
+{
+  tet_infoline("Testing Dali::Internal::AdaptorManipulation HasChannel");
+
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::A8, Dali::Internal::Adaptor::ALPHA ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::A8, Dali::Internal::Adaptor::LUMINANCE ), false, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::L8, Dali::Internal::Adaptor::LUMINANCE ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::L8, Dali::Internal::Adaptor::ALPHA ), false, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::LA88, Dali::Internal::Adaptor::LUMINANCE ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::LA88, Dali::Internal::Adaptor::ALPHA ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::LA88, Dali::Internal::Adaptor::RED ), false, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGB565, Dali::Internal::Adaptor::RED ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGB565, Dali::Internal::Adaptor::GREEN ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGB565, Dali::Internal::Adaptor::BLUE ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGB565, Dali::Internal::Adaptor::LUMINANCE ), false, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGBA8888, Dali::Internal::Adaptor::RED ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGBA8888, Dali::Internal::Adaptor::GREEN ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGBA8888, Dali::Internal::Adaptor::BLUE ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGBA8888, Dali::Internal::Adaptor::ALPHA ), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::RGBA8888, Dali::Internal::Adaptor::LUMINANCE ), false, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Dali::Internal::Adaptor::HasChannel( Dali::Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR, Dali::Internal::Adaptor::BLUE ), false, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+
+int UtcDaliPixelManipulation02(void)
+{
+  tet_infoline("Testing Dali::Internal::AdaptorManipulation Read/WriteChannel");
+
+  unsigned char pixel[4] = {0,0,0,0};
+
+  for( int formatIdx=1; formatIdx<Dali::Pixel::COMPRESSED_R11_EAC; ++formatIdx)
+  {
+    pixel[0] = 0xFF;
+    pixel[1] = 0xFF;
+    pixel[2] = 0xFF;
+    pixel[3] = 0xFF;
+
+    for( int channelIdx=0; channelIdx < Dali::Internal::Adaptor::MAX_NUMBER_OF_CHANNELS; ++channelIdx )
+    {
+      Dali::Pixel::Format format = static_cast<Dali::Pixel::Format>(formatIdx);
+      Dali::Internal::Adaptor::Channel channel = static_cast<Dali::Internal::Adaptor::Channel>(channelIdx);
+      if( Dali::Internal::Adaptor::HasChannel( format, channel ) )
+      {
+        Dali::Internal::Adaptor::WriteChannel( &pixel[0], format, channel, 0x15);
+        unsigned int value = Dali::Internal::Adaptor::ReadChannel( &pixel[0], format, channel );
+
+        tet_printf( "Testing writing and reading to %s channel in %s format:\n",
+                      ChannelToString(channel), FormatToString(format) );
+
+        if( channel == Dali::Internal::Adaptor::ALPHA && (format == Dali::Pixel::RGBA5551 || format == Dali::Pixel::BGRA5551 ) )
+        {
+          DALI_TEST_EQUALS( value, 0x1, TEST_LOCATION );
+        }
+        else if( format == Dali::Pixel::RGBA4444 || format == Dali::Pixel::BGRA4444 )
+        {
+          DALI_TEST_EQUALS( value, 0x05, TEST_LOCATION );
+        }
+        else
+        {
+          DALI_TEST_EQUALS( value, 0x15, TEST_LOCATION );
+        }
+      }
+    }
+  }
+
+  END_TEST;
+}
+
+
+int UtcDaliPixelManipulation03N(void)
+{
+  tet_infoline("Testing Dali::Internal::AdaptorManipulation Read/WriteChannel");
+
+  unsigned char pixel[4] = {0,0,0,0};
+
+  for( int formatIdx=1; formatIdx<Dali::Pixel::COMPRESSED_R11_EAC; ++formatIdx)
+  {
+    pixel[0] = 0xFF;
+    pixel[1] = 0xFF;
+    pixel[2] = 0xFF;
+    pixel[3] = 0xFF;
+
+    for( int channelIdx=0; channelIdx < Dali::Internal::Adaptor::MAX_NUMBER_OF_CHANNELS; ++channelIdx )
+    {
+      Dali::Pixel::Format format = static_cast<Dali::Pixel::Format>(formatIdx);
+      Dali::Internal::Adaptor::Channel channel = static_cast<Dali::Internal::Adaptor::Channel>(channelIdx);
+      if( ! Dali::Internal::Adaptor::HasChannel( format, channel ) )
+      {
+        unsigned int value = Dali::Internal::Adaptor::ReadChannel( &pixel[0], format, channel );
+
+        tet_printf( "Testing reading from %s channel in %s format:\n",
+                      ChannelToString(channel), FormatToString(format) );
+
+        DALI_TEST_EQUALS( value, 0x00, TEST_LOCATION );
+      }
+    }
+  }
+
+  END_TEST;
+}
index 04311e0..4ae66c4 100644 (file)
@@ -6,12 +6,12 @@ SET(RPM_NAME "core-${PKG_NAME}-tests")
 SET(CAPI_LIB "dali-adaptor")
 SET(TC_SOURCES
     utc-Dali-Application.cpp
-    utc-Dali-BitmapLoader.cpp
     utc-Dali-FileLoader.cpp
     utc-Dali-GifLoading.cpp
     utc-Dali-ImageLoading.cpp
     utc-Dali-Key.cpp
     utc-Dali-NativeImageSource.cpp
+    utc-Dali-PixelBuffer.cpp
     utc-Dali-SingletonService.cpp
     utc-Dali-Timer.cpp
     utc-Dali-TtsPlayer.cpp
diff --git a/automated-tests/src/dali-adaptor/utc-Dali-BitmapLoader.cpp b/automated-tests/src/dali-adaptor/utc-Dali-BitmapLoader.cpp
deleted file mode 100644 (file)
index 1490ea4..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2015 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 <stdlib.h>
-#include <dali/dali.h>
-#include <dali-test-suite-utils.h>
-#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
-
-using namespace Dali;
-
-namespace
-{
-// resolution: 34*34, pixel format: RGBA8888
-static const char* gImage_34_RGBA = TEST_RESOURCE_DIR "/icon-edit.png";
-// resolution: 128*128, pixel format: RGB888
-static const char* gImage_128_RGB = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
-
-// this is image is not exist, for negative test
-static const char* gImageNonExist = "non-exist.jpg";
-}
-
-void utc_dali_bitmap_loader_startup(void)
-{
-  test_return_value = TET_UNDEF;
-}
-
-void utc_dali_bitmap_loader_cleanup(void)
-{
-  test_return_value = TET_PASS;
-}
-
-int UtcDaliBitmapLoaderNew(void)
-{
-  TestApplication application;
-
-  // invoke default handle constructor
-  BitmapLoader loader;
-
-  DALI_TEST_CHECK( !loader );
-
-  // initialise handle
-  loader = BitmapLoader::New( gImage_34_RGBA );
-
-  DALI_TEST_CHECK( loader );
-  END_TEST;
-}
-
-int UtcDaliBitmapLoaderCopyConstructor(void)
-{
-  TestApplication application;
-
-  BitmapLoader loader = BitmapLoader::New( gImage_34_RGBA);
-  BitmapLoader loaderCopy(loader);
-
-  DALI_TEST_EQUALS( (bool)loaderCopy, true, TEST_LOCATION );
-  END_TEST;
-}
-
-int UtcDaliBitmapLoaderAssignmentOperator(void)
-{
-  TestApplication application;
-
-  BitmapLoader loader = BitmapLoader::New( gImage_34_RGBA );
-
-  BitmapLoader loader2;
-  DALI_TEST_EQUALS( (bool)loader2, false, TEST_LOCATION );
-
-  loader2 = loader;
-  DALI_TEST_EQUALS( (bool)loader2, true, TEST_LOCATION );
-
-  END_TEST;
-}
-
-int UtcDaliBitmapLoaderGetUrl(void)
-{
-  TestApplication application;
-
-  BitmapLoader loader = BitmapLoader::New( gImage_34_RGBA );
-  DALI_TEST_CHECK( loader.GetUrl() == gImage_34_RGBA );
-
-  END_TEST;
-}
-
-
-int UtcDaliBitmapLoaderLoadP(void)
-{
-  TestApplication application;
-
-  BitmapLoader loader1 = BitmapLoader::New( gImage_34_RGBA );
-  DALI_TEST_CHECK( ! loader1.IsLoaded() );
-  loader1.Load();
-  DALI_TEST_CHECK( loader1.IsLoaded() );
-  PixelData pixelData1 = loader1.GetPixelData();
-  DALI_TEST_CHECK( pixelData1 );
-  DALI_TEST_CHECK( pixelData1.GetWidth() == 34u );
-  DALI_TEST_CHECK( pixelData1.GetHeight() == 34u );
-  DALI_TEST_CHECK( pixelData1.GetPixelFormat() == Pixel::RGBA8888 );
-
-  BitmapLoader loader2 = BitmapLoader::New( gImage_128_RGB );
-  DALI_TEST_CHECK( ! loader2.IsLoaded() );
-  loader2.Load();
-  DALI_TEST_CHECK( loader2.IsLoaded() );
-  PixelData pixelData2 = loader2.GetPixelData();
-  DALI_TEST_CHECK( pixelData2 );
-  DALI_TEST_CHECK( pixelData2.GetWidth() == 128u );
-  DALI_TEST_CHECK( pixelData2.GetHeight() == 128u );
-  DALI_TEST_CHECK( pixelData2.GetPixelFormat() == Pixel::RGB888 );
-
-  END_TEST;
-}
-
-int UtcDaliBitmapLoaderLoadN(void)
-{
-  TestApplication application;
-
-  BitmapLoader loader = BitmapLoader::New( gImageNonExist );
-  DALI_TEST_CHECK( ! loader.IsLoaded() );
-  loader.Load();
-
-  // cannot load image that is not exist
-  DALI_TEST_CHECK( ! loader.IsLoaded() );
-  PixelData pixelData = loader.GetPixelData();
-  DALI_TEST_CHECK( !pixelData);
-
-  END_TEST;
-}
index a4682bc..b05ffed 100644 (file)
@@ -45,25 +45,25 @@ void utc_dali_load_image_cleanup(void)
 
 int UtcDaliLoadImageP(void)
 {
-  PixelData pixelData = Dali::LoadImageFromFile( gImage_34_RGBA );
-  DALI_TEST_CHECK( pixelData );
-  DALI_TEST_EQUALS( pixelData.GetWidth(), 34u, TEST_LOCATION );
-  DALI_TEST_EQUALS( pixelData.GetHeight(), 34u, TEST_LOCATION );
-  DALI_TEST_EQUALS( pixelData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
-
-  PixelData pixelData2 = Dali::LoadImageFromFile( gImage_128_RGB );
-  DALI_TEST_CHECK( pixelData2 );
-  DALI_TEST_EQUALS( pixelData2.GetWidth(), 128u, TEST_LOCATION  );
-  DALI_TEST_EQUALS( pixelData2.GetHeight(), 128u, TEST_LOCATION  );
-  DALI_TEST_EQUALS( pixelData2.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION  );
+  Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile( gImage_34_RGBA );
+  DALI_TEST_CHECK( pixelBuffer );
+  DALI_TEST_EQUALS( pixelBuffer.GetWidth(), 34u, TEST_LOCATION );
+  DALI_TEST_EQUALS( pixelBuffer.GetHeight(), 34u, TEST_LOCATION );
+  DALI_TEST_EQUALS( pixelBuffer.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+
+  Devel::PixelBuffer pixelBuffer2 = Dali::LoadImageFromFile( gImage_128_RGB );
+  DALI_TEST_CHECK( pixelBuffer2 );
+  DALI_TEST_EQUALS( pixelBuffer2.GetWidth(), 128u, TEST_LOCATION  );
+  DALI_TEST_EQUALS( pixelBuffer2.GetHeight(), 128u, TEST_LOCATION  );
+  DALI_TEST_EQUALS( pixelBuffer2.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION  );
 
   END_TEST;
 }
 
 int UtcDaliLoadImageN(void)
 {
-  PixelData pixelData = Dali::LoadImageFromFile( gImageNonExist );
-  DALI_TEST_CHECK( !pixelData );
+  Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile( gImageNonExist );
+  DALI_TEST_CHECK( !pixelBuffer );
 
   END_TEST;
 }
@@ -77,25 +77,25 @@ int UtcDaliDownloadImageP(void)
   std::string url2("file://");
   url2.append( gImage_128_RGB );
 
-  PixelData pixelData = Dali::DownloadImageSynchronously( url );
-  DALI_TEST_CHECK( pixelData );
-  DALI_TEST_EQUALS( pixelData.GetWidth(), 34u, TEST_LOCATION );
-  DALI_TEST_EQUALS( pixelData.GetHeight(), 34u, TEST_LOCATION );
-  DALI_TEST_EQUALS( pixelData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
+  Devel::PixelBuffer pixelBuffer = Dali::DownloadImageSynchronously( url );
+  DALI_TEST_CHECK( pixelBuffer );
+  DALI_TEST_EQUALS( pixelBuffer.GetWidth(), 34u, TEST_LOCATION );
+  DALI_TEST_EQUALS( pixelBuffer.GetHeight(), 34u, TEST_LOCATION );
+  DALI_TEST_EQUALS( pixelBuffer.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION  );
 
-  PixelData pixelData2 = Dali::DownloadImageSynchronously( url2 );
-  DALI_TEST_CHECK( pixelData2 );
-  DALI_TEST_EQUALS( pixelData2.GetWidth(), 128u, TEST_LOCATION  );
-  DALI_TEST_EQUALS( pixelData2.GetHeight(), 128u, TEST_LOCATION  );
-  DALI_TEST_EQUALS( pixelData2.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION  );
+  Devel::PixelBuffer pixelBuffer2 = Dali::DownloadImageSynchronously( url2 );
+  DALI_TEST_CHECK( pixelBuffer2 );
+  DALI_TEST_EQUALS( pixelBuffer2.GetWidth(), 128u, TEST_LOCATION  );
+  DALI_TEST_EQUALS( pixelBuffer2.GetHeight(), 128u, TEST_LOCATION  );
+  DALI_TEST_EQUALS( pixelBuffer2.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION  );
 
   END_TEST;
 }
 
 int UtcDaliDownloadImageN(void)
 {
-  PixelData pixelData = Dali::DownloadImageSynchronously( gImageNonExist );
-  DALI_TEST_CHECK( !pixelData );
+  Devel::PixelBuffer pixelBuffer = Dali::DownloadImageSynchronously( gImageNonExist );
+  DALI_TEST_CHECK( !pixelBuffer );
 
   END_TEST;
 }
diff --git a/automated-tests/src/dali-adaptor/utc-Dali-PixelBuffer.cpp b/automated-tests/src/dali-adaptor/utc-Dali-PixelBuffer.cpp
new file mode 100644 (file)
index 0000000..4a83d8f
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2017 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 <dali/dali.h>
+#include <dali-test-suite-utils.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include "mesh-builder.h"
+using namespace Dali;
+
+void utc_dali_pixelbuffer_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_pixelbuffer_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+int UtcDaliPixelBufferCreatePixelData(void)
+{
+  TestApplication application;
+
+  unsigned int width = 20u;
+  unsigned int height = 20u;
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, Pixel::RGB888 );
+
+  PixelData pixelData = imageData.CreatePixelData();
+
+  DALI_TEST_EQUALS( true, (bool)pixelData, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+void Mask1stQuadrant( Devel::PixelBuffer maskData )
+{
+  int width = maskData.GetWidth();
+  int height = maskData.GetHeight();
+  Pixel::Format pixelFormat = maskData.GetPixelFormat();
+  int bpp = Pixel::GetBytesPerPixel(pixelFormat);
+
+  unsigned char* maskBuffer = maskData.GetBuffer();
+  memset( maskBuffer, 0, width*height*bpp );
+  int offset=0;
+  for( int x=0; x<width; ++x)
+  {
+    for( int y=0; y<height; ++y)
+    {
+      if(x>=width/2 || y>=height/2)
+      {
+        for(int b=0;b<bpp;++b)
+        {
+          maskBuffer[offset+b] = 0xff;
+        }
+      }
+      offset+=bpp;
+    }
+  }
+}
+
+void FillCheckerboard( Devel::PixelBuffer imageData )
+{
+  int width = imageData.GetWidth();
+  int height = imageData.GetHeight();
+  Pixel::Format pixelFormat = imageData.GetPixelFormat();
+  int bpp = Pixel::GetBytesPerPixel(pixelFormat);
+
+  unsigned char* imageBuffer = imageData.GetBuffer();
+  memset( imageBuffer, 0, width*height*bpp );
+  int offset=0;
+  for( int x=0; x<width; ++x)
+  {
+    for( int y=0; y<height; ++y)
+    {
+      // on even lines, odd pixels, or on odd lines, even pixels
+      if( (x%2 && y%2==0) || (x%2==0 && y%2) )
+      {
+        switch(pixelFormat)
+        {
+          case Pixel::RGBA5551:
+            imageBuffer[offset] = 0xFF;
+            imageBuffer[offset+1] = 0xFF;
+            break;
+          case Pixel::RGBA4444:
+            imageBuffer[offset] = 0xFF;
+            imageBuffer[offset+1] = 0xFF;
+            break;
+          case Pixel::RGB565:
+            imageBuffer[offset] = 0xFF;
+            imageBuffer[offset+1] = 0xFF;
+            break;
+          case Pixel::RGB888:
+            imageBuffer[offset] = 0xFF;
+            imageBuffer[offset+1] = 0xFF;
+            imageBuffer[offset+2] = 0xFF;
+            break;
+          case Pixel::RGBA8888:
+            imageBuffer[offset] = 0xFF;
+            imageBuffer[offset+1] = 0xFF;
+            imageBuffer[offset+2] = 0xFF;
+            imageBuffer[offset+3] = 0xFF;
+            break;
+          default:
+            break;
+        }
+      }
+      offset+=bpp;
+    }
+  }
+}
+
+int UtcDaliPixelBufferNew01P(void)
+{
+  TestApplication application;
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::RGBA8888 );
+  DALI_TEST_CHECK( pixbuf );
+  DALI_TEST_CHECK( pixbuf.GetBuffer() != NULL );
+  END_TEST;
+}
+
+int UtcDaliPixelBufferNew01N(void)
+{
+  TestApplication application;
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 0, 0, Pixel::RGBA8888 );
+  DALI_TEST_CHECK( pixbuf );
+  DALI_TEST_CHECK( pixbuf.GetBuffer() == NULL );
+  END_TEST;
+}
+
+int UtcDaliPixelBufferConvert(void)
+{
+  TestApplication application;
+  TestGlAbstraction& gl=application.GetGlAbstraction();
+  TraceCallStack& textureTrace=gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::RGB565 );
+  FillCheckerboard(pixbuf);
+
+  {
+    Devel::PixelBuffer pixbufPrime = pixbuf; // store a second handle to the data
+
+    Dali::PixelData pixelData = Devel::PixelBuffer::Convert( pixbuf );
+    DALI_TEST_CHECK( !pixbuf );
+
+    // check the buffer in the second handle is empty
+    DALI_TEST_CHECK( pixbufPrime.GetBuffer() == NULL );
+
+    DALI_TEST_CHECK( pixelData );
+    DALI_TEST_EQUALS( pixelData.GetWidth(), 10, TEST_LOCATION );
+    DALI_TEST_EQUALS( pixelData.GetHeight(), 10, TEST_LOCATION );
+    DALI_TEST_EQUALS( pixelData.GetPixelFormat(), Pixel::RGB565, TEST_LOCATION );
+
+    // Try drawing it
+    Texture t = Texture::New(TextureType::TEXTURE_2D, Pixel::RGB565, 10, 10);
+    t.Upload( pixelData );
+    TextureSet ts = TextureSet::New();
+    ts.SetTexture(0, t);
+    Geometry g = CreateQuadGeometry();
+    Shader s = Shader::New("v", "f");
+    Renderer r = Renderer::New( g, s );
+    r.SetTextures(ts);
+    Actor a = Actor::New();
+    a.AddRenderer(r);
+    a.SetSize(10, 10);
+    a.SetParentOrigin(ParentOrigin::CENTER);
+    Stage::GetCurrent().Add(a);
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+    // Let secondary scope destroy pixbufPrime
+  }
+
+  END_TEST;
+}
+
+int UtcDaliPixelBufferGetWidth(void)
+{
+  TestApplication application;
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::RGB565 );
+  FillCheckerboard(pixbuf);
+
+  DALI_TEST_EQUALS( pixbuf.GetWidth(), 10, TEST_LOCATION ) ;
+
+  END_TEST;
+}
+
+int UtcDaliPixelBufferGetHeight(void)
+{
+  TestApplication application;
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::RGB565 );
+  FillCheckerboard(pixbuf);
+
+  DALI_TEST_EQUALS( pixbuf.GetHeight(), 10, TEST_LOCATION ) ;
+
+  END_TEST;
+}
+
+int UtcDaliPixelBufferGetPixelFormat(void)
+{
+  TestApplication application;
+  Devel::PixelBuffer pixbuf = Devel::PixelBuffer::New( 10, 10, Pixel::RGB565 );
+  FillCheckerboard(pixbuf);
+
+  DALI_TEST_EQUALS( pixbuf.GetPixelFormat(), Pixel::RGB565, TEST_LOCATION ) ;
+
+  END_TEST;
+}
+
+
+
+int UtcDaliPixelBufferMask01(void)
+{
+  TestApplication application;
+
+  unsigned int width = 10u;
+  unsigned int height = 10u;
+  Pixel::Format pixelFormat = Pixel::L8;
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, pixelFormat );
+
+  Mask1stQuadrant(maskData);
+
+  width = 20u;
+  height = 20u;
+  pixelFormat = Pixel::RGBA5551;
+
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, pixelFormat );
+  FillCheckerboard(imageData);
+
+  imageData.ApplyMask( maskData );
+
+  // Test that the pixel format has been promoted to RGBA8888
+  DALI_TEST_EQUALS( imageData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+
+  // Test that a pixel in the first quadrant has no alpha value
+  unsigned char* buffer = imageData.GetBuffer();
+  DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
+
+  // Test that an even pixel in the second quadrant has a full alpha value
+  DALI_TEST_EQUALS( buffer[43], 0x00u, TEST_LOCATION );
+
+  // Test that an odd pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[47], 0xffu, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliPixelBufferMask02(void)
+{
+  TestApplication application;
+
+  unsigned int width = 10u;
+  unsigned int height = 10u;
+  Pixel::Format pixelFormat = Pixel::L8;
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, pixelFormat );
+
+  Mask1stQuadrant(maskData);
+
+  width = 20u;
+  height = 20u;
+  pixelFormat = Pixel::RGBA4444;
+
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, pixelFormat );
+  FillCheckerboard(imageData);
+
+  imageData.ApplyMask( maskData );
+
+  // Test that the pixel format has been promoted to RGBA8888
+  DALI_TEST_EQUALS( imageData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+
+  // Test that a pixel in the first quadrant has no alpha value
+  unsigned char* buffer = imageData.GetBuffer();
+  DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
+
+  // Test that an even pixel in the second quadrant has no alpha value
+  DALI_TEST_EQUALS( buffer[43], 0x00u, TEST_LOCATION );
+
+  // Test that an odd pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[47], 0xffu, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliPixelBufferMask03(void)
+{
+  TestApplication application;
+  tet_infoline("Test application of alpha mask to smaller RGB565 image");
+
+  unsigned int width = 20u;
+  unsigned int height = 20u;
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, Pixel::L8 );
+  Mask1stQuadrant(maskData);
+
+  width = 10u;
+  height = 10u;
+  Pixel::Format format = Pixel::RGB565;
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, format );
+  FillCheckerboard(imageData);
+
+  imageData.ApplyMask( maskData );
+
+  // Test that the pixel format has been promoted to RGBA8888
+  DALI_TEST_EQUALS( imageData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+
+  // Test that a pixel in the first quadrant has no alpha value
+  unsigned char* buffer = imageData.GetBuffer();
+  DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
+
+  // Test that an odd pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[23], 0xffu, TEST_LOCATION );
+
+  // Test that an even pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[27], 0xffu, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliPixelBufferMask04(void)
+{
+  TestApplication application;
+  tet_infoline("Test application of alpha mask to larger RGBA8888 image");
+
+  unsigned int width = 10u;
+  unsigned int height = 10u;
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, Pixel::L8 );
+  Mask1stQuadrant(maskData);
+
+  width = 20u;
+  height = 20u;
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, Pixel::RGBA8888 );
+  FillCheckerboard(imageData);
+
+  imageData.ApplyMask( maskData );
+
+  // Test that the pixel format has been promoted to RGBA8888
+  DALI_TEST_EQUALS( imageData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+
+  // Test that a pixel in the first quadrant has no alpha value
+  unsigned char* buffer = imageData.GetBuffer();
+  DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
+
+  // Test that an even pixel in the second quadrant has no alpha value
+  DALI_TEST_EQUALS( buffer[43], 0x00u, TEST_LOCATION );
+
+  // Test that an odd pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[47], 0xffu, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliPixelBufferMask05(void)
+{
+  TestApplication application;
+  tet_infoline("Test application of alpha mask to smaller RGBA8888 image");
+
+  unsigned int width = 20u;
+  unsigned int height = 20u;
+  Devel::PixelBuffer maskData = Devel::PixelBuffer::New( width, height, Pixel::L8 );
+  Mask1stQuadrant(maskData);
+
+  width = 10u;
+  height = 10u;
+  Devel::PixelBuffer imageData = Devel::PixelBuffer::New( width, height, Pixel::RGBA8888 );
+  FillCheckerboard(imageData);
+
+  imageData.ApplyMask( maskData );
+
+  // Test that the pixel format has been promoted to RGBA8888
+  DALI_TEST_EQUALS( imageData.GetPixelFormat(), Pixel::RGBA8888, TEST_LOCATION );
+
+  // Test that a pixel in the first quadrant has no alpha value
+  unsigned char* buffer = imageData.GetBuffer();
+  DALI_TEST_EQUALS( buffer[3], 0x00u, TEST_LOCATION );
+  DALI_TEST_EQUALS( buffer[7], 0x00u, TEST_LOCATION );
+
+  // Test that an odd pixel in the second quadrant has full alpha value
+  DALI_TEST_EQUALS( buffer[23], 0xffu, TEST_LOCATION );
+
+  // Test that an even pixel in the second quadrant has no alpha value
+  DALI_TEST_EQUALS( buffer[27], 0x00u, TEST_LOCATION );
+
+  END_TEST;
+}
diff --git a/platform-abstractions/portable/alpha-mask.cpp b/platform-abstractions/portable/alpha-mask.cpp
new file mode 100644 (file)
index 0000000..e930fc6
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2017 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 "pixel-manipulation.h"
+#include "alpha-mask.h"
+#include "pixel-buffer-impl.h"
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+
+void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask )
+{
+  const float rowFactor = float(mask.GetHeight()) / (1.0f * buffer.GetHeight());
+  const float colFactor = float(mask.GetWidth()) / (1.0f * buffer.GetWidth()) ;
+
+  int numSamples = 1;
+  if( mask.GetHeight() > buffer.GetHeight() || mask.GetWidth() > buffer.GetWidth() )
+  {
+    numSamples = 4;
+  }
+
+  int srcAlphaByteOffset=0;
+  int srcAlphaMask=0;
+  Dali::Pixel::Format srcPixelFormat = mask.GetPixelFormat();
+
+  Channel alphaChannel = ALPHA;
+  if( Pixel::HasAlpha(srcPixelFormat) )
+  {
+    Dali::Pixel::GetAlphaOffsetAndMask( srcPixelFormat, srcAlphaByteOffset, srcAlphaMask );
+  }
+  else if( srcPixelFormat == Pixel::L8 )
+  {
+    srcAlphaMask=0xFF;
+    alphaChannel = LUMINANCE;
+  }
+
+  int destAlphaByteOffset=0;
+  int destAlphaMask=0;
+  Dali::Pixel::GetAlphaOffsetAndMask( buffer.GetPixelFormat(), destAlphaByteOffset, destAlphaMask );
+
+  unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
+  int srcStride = mask.GetWidth() * srcBytesPerPixel;
+  unsigned char* srcBuffer = mask.GetBuffer();
+  unsigned char* destBuffer = buffer.GetBuffer();
+
+  unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel( buffer.GetPixelFormat() );
+
+  int srcOffset=0;
+  int destOffset=0;
+
+  float srcAlphaValue = 1.0f;
+
+  for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
+  {
+    for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
+    {
+      if( numSamples == 1 )
+      {
+        srcOffset = floorf(row * rowFactor) * srcStride + floorf(col * colFactor) * srcBytesPerPixel;
+        unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
+        srcAlphaValue = float(alpha)/255.0f;
+      }
+      else
+      {
+        srcAlphaValue = ReadWeightedSample( srcBuffer, srcPixelFormat, srcStride, col*colFactor, row*rowFactor, mask.GetWidth(), mask.GetHeight(), alphaChannel );
+      }
+
+      unsigned char destAlpha = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
+      float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
+      destAlpha = destAlphaValue;
+      destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
+      destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
+
+      destOffset += destBytesPerPixel;
+    }
+  }
+}
+
+PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuffer& mask )
+{
+  const float rowFactor = float(mask.GetHeight()) / (1.0f * buffer.GetHeight());
+  const float colFactor = float(mask.GetWidth()) / (1.0f * buffer.GetWidth()) ;
+
+  int numSamples = 1;
+  if( mask.GetHeight() > buffer.GetHeight() || mask.GetWidth() > buffer.GetWidth() )
+  {
+    numSamples = 4;
+  }
+
+  // Set up source alpha offsets
+  int srcAlphaByteOffset=0;
+  int srcAlphaMask=0;
+  Dali::Pixel::Format srcPixelFormat = mask.GetPixelFormat();
+  Channel alphaChannel = ALPHA;
+  if( Pixel::HasAlpha(srcPixelFormat) )
+  {
+    Dali::Pixel::GetAlphaOffsetAndMask( srcPixelFormat, srcAlphaByteOffset, srcAlphaMask );
+  }
+  else if( srcPixelFormat == Pixel::L8 )
+  {
+    srcAlphaMask=0xFF;
+    alphaChannel = LUMINANCE;
+  }
+
+  unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
+  int srcStride = mask.GetWidth() * srcBytesPerPixel;
+  unsigned char* srcBuffer = mask.GetBuffer();
+
+  // Set up source color offsets
+  Dali::Pixel::Format srcColorPixelFormat = buffer.GetPixelFormat();
+  unsigned int srcColorBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcColorPixelFormat );
+
+  // Setup destination offsets
+  Dali::Pixel::Format destPixelFormat = Dali::Pixel::RGBA8888;
+  unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel( destPixelFormat );
+  int destAlphaByteOffset=0;
+  int destAlphaMask=0;
+  Dali::Pixel::GetAlphaOffsetAndMask( destPixelFormat, destAlphaByteOffset, destAlphaMask );
+
+  PixelBufferPtr newPixelBuffer = PixelBuffer::New( buffer.GetWidth(), buffer.GetHeight(),
+                                                    destPixelFormat );
+  unsigned char* destBuffer = newPixelBuffer->GetBuffer();
+
+  unsigned char* oldBuffer = buffer.GetBuffer();
+
+  int srcAlphaOffset=0;
+  int srcColorOffset=0;
+  int destOffset=0;
+  bool hasAlpha = Dali::Pixel::HasAlpha(buffer.GetPixelFormat());
+
+  float srcAlphaValue = 1.0f;
+  unsigned char destAlpha = 0;
+
+  for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
+  {
+    for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
+    {
+      if( numSamples == 1 )
+      {
+        srcAlphaOffset = floorf(row * rowFactor) * srcStride + floorf(col * colFactor) * srcBytesPerPixel;
+        unsigned char alpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
+        srcAlphaValue = float(alpha)/255.0f;
+      }
+      else
+      {
+        srcAlphaValue = ReadWeightedSample( srcBuffer, srcPixelFormat, srcStride, col*colFactor, row*rowFactor, mask.GetWidth(), mask.GetHeight(), alphaChannel );
+      }
+
+      ConvertColorChannelsToRGBA8888(oldBuffer, srcColorOffset, srcColorPixelFormat, destBuffer, destOffset );
+
+      if( hasAlpha )
+      {
+        destAlpha = ConvertAlphaChannelToA8( oldBuffer, srcColorOffset, srcColorPixelFormat );
+        float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
+        destAlpha = destAlphaValue;
+      }
+      else
+      {
+        destAlpha = floorf(Clamp(srcAlphaValue * 255.0f, 0.0f, 255.0f));
+      }
+
+      destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
+      destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
+
+      srcColorOffset += srcColorBytesPerPixel;
+      destOffset += destBytesPerPixel;
+    }
+  }
+
+  return newPixelBuffer;
+}
+
+
+float ReadWeightedSample( unsigned char* buffer, Pixel::Format pixelFormat, int stride, float x, float y, int width, int height, Channel alphaChannel )
+{
+  int srcRow = floorf( y );
+  int srcCol = floorf( x );
+
+  int bytesPerPixel = Dali::Pixel::GetBytesPerPixel( pixelFormat );
+  int srcOffset = srcRow * stride + srcCol * bytesPerPixel;
+  float samples[4];
+
+  samples[0] = ReadChannel( buffer + srcOffset, pixelFormat, alphaChannel );
+
+  if( srcCol < width-1 )
+  {
+    samples[1] = ReadChannel( buffer + srcOffset+bytesPerPixel, pixelFormat, alphaChannel );
+  }
+  else
+  {
+    samples[1] = samples[0];
+  }
+
+  if( srcRow < height-1 )
+  {
+    samples[2] = ReadChannel( buffer + stride + srcOffset, pixelFormat, alphaChannel );
+  }
+  else
+  {
+    samples[2] = samples[0];
+  }
+
+  if( srcRow < height-1 && srcCol < width-1 )
+  {
+    samples[3] = ReadChannel( buffer + stride + srcOffset + bytesPerPixel, pixelFormat, alphaChannel );
+  }
+  else
+  {
+    samples[3] = samples[2];
+  }
+
+  // Bilinear interpolation:
+  float weight[4];
+  weight[0] = float(srcRow+1.0f) - y;
+  weight[1] = y - float(srcRow);
+  weight[2] = float(srcCol+1.0f) - x;
+  weight[3] = x - float(srcCol);
+
+  return ( weight[2] * (samples[0] * weight[0] + samples[1] * weight[1]) +
+           weight[3] * (samples[2] * weight[0] + samples[3] * weight[1]) ) / 255.0f;
+}
+
+} //namespace Adaptor
+
+}// namespace Internal
+
+}// namespace Dali
diff --git a/platform-abstractions/portable/alpha-mask.h b/platform-abstractions/portable/alpha-mask.h
new file mode 100644 (file)
index 0000000..192b9f5
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef DALI_INTERNAL_ADAPTOR_ALPHA_MASK_H
+#define DALI_INTERNAL_ADAPTOR_ALPHA_MASK_H
+
+/*
+ * Copyright (c) 2017 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 "pixel-buffer-impl.h"
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+
+/**
+ * Apply the mask to a buffer's alpha channel
+ * @param[in] buffer The buffer to apply the mask to
+ * @param[in] mask The mask to apply
+ */
+void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& mask );
+
+/**
+ * Create a new PixelBuffer with an alpha channel large enough to handle the alpha from
+ * the mask, converting the color values to the new size, and either multiplying the mask's
+ * alpha into the existing alpha value, or writing the mask's alpha value directly into
+ * the new buffer's alpha channel.
+ *
+ * @param[in] buffer The buffer to apply the mask to
+ * @param[in] mask The mask to apply
+ * @return A new pixel buffer containing the masked image
+ */
+PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuffer& mask );
+
+/**
+ * Read a weighted sample from the given channel for a given coordinate
+ * @param[in] buffer The buffer to read from
+ * @param[in] pixelFormat The pixel format of the buffer
+ * @param[in] stride The stride across the buffer
+ * @param[in] x The x coordinate to sample from
+ * @param[in] y The y coordinate to sample from
+ * @param[in] width The width of the buffer in pixels
+ * @param[in] height  The height of the buffer in pixels
+ * @param[in] channel The channel to read from
+ * @return An averaged value from the 4 pixels around the given coordinate
+ */
+float ReadWeightedSample( unsigned char* buffer, Pixel::Format pixelFormat, int stride, float x, float y, int width, int height, Channel channel );
+
+} //namespace Adaptor
+} //namespace Internal
+} //namespace Dali
+
+#endif // DALI_INTERNAL_ADAPTOR_ALPHA_MASK_H
diff --git a/platform-abstractions/portable/pixel-manipulation.cpp b/platform-abstractions/portable/pixel-manipulation.cpp
new file mode 100644 (file)
index 0000000..ef2defc
--- /dev/null
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+// CLASS HEADER
+#include "pixel-manipulation.h"
+
+// INTERNAL HEADERS
+#include <dali/public-api/images/pixel.h>
+#include <dali/integration-api/debug.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+struct Location
+{
+  unsigned int bitShift;
+  unsigned int bitMask;
+  bool available;
+};
+
+struct Locations
+{
+  Location luminance;
+  Location alpha;
+  Location red;
+  Location green;
+  Location blue;
+};
+
+
+bool HasChannel( Dali::Pixel::Format pixelFormat, Channel channel )
+{
+  switch (pixelFormat)
+  {
+    case Dali::Pixel::A8:
+    {
+      return (channel == ALPHA);
+    }
+    case Dali::Pixel::L8:
+    {
+      return (channel == LUMINANCE);
+    }
+    case Dali::Pixel::LA88:
+    {
+      return ( channel == LUMINANCE || channel == ALPHA );
+    }
+    case Dali::Pixel::RGB565:
+    case Dali::Pixel::BGR565:
+    case Dali::Pixel::RGB888:
+    case Dali::Pixel::RGB8888:
+    case Dali::Pixel::BGR8888:
+    {
+      return ( channel == RED || channel == GREEN || channel == BLUE );
+    }
+
+    case Dali::Pixel::RGBA8888:
+    case Dali::Pixel::BGRA8888:
+    case Dali::Pixel::RGBA4444:
+    case Dali::Pixel::BGRA4444:
+    case Dali::Pixel::RGBA5551:
+    case Dali::Pixel::BGRA5551:
+    {
+      return ( channel == RED || channel == GREEN || channel == BLUE || channel == ALPHA );
+    }
+
+    case Dali::Pixel::INVALID:
+    case Dali::Pixel::COMPRESSED_R11_EAC:
+    case Dali::Pixel::COMPRESSED_SIGNED_R11_EAC:
+    case Dali::Pixel::COMPRESSED_RG11_EAC:
+    case Dali::Pixel::COMPRESSED_SIGNED_RG11_EAC:
+    case Dali::Pixel::COMPRESSED_RGB8_ETC2:
+    case Dali::Pixel::COMPRESSED_SRGB8_ETC2:
+    case Dali::Pixel::COMPRESSED_RGB8_ETC1:
+    case Dali::Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
+    case Dali::Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+    case Dali::Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+    case Dali::Pixel::COMPRESSED_RGBA8_ETC2_EAC:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
+    case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+    case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+    {
+      DALI_LOG_ERROR("Pixel formats for compressed images are not compatible with simple channels.\n");
+      break;
+    }
+  }
+
+  return false;
+}
+
+unsigned int ReadChannel( unsigned char* pixelData,
+                          Dali::Pixel::Format pixelFormat,
+                          Channel channel )
+{
+  switch (pixelFormat)
+  {
+    case Dali::Pixel::A8:
+    {
+      if( channel == ALPHA )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else return 0u;
+    }
+    case Dali::Pixel::L8:
+    {
+      if( channel == LUMINANCE )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else return 0u;
+    }
+    case Dali::Pixel::LA88:
+    {
+      if( channel == LUMINANCE )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else if( channel == ALPHA )
+      {
+        return static_cast<unsigned int>(*(pixelData+1));
+      }
+      else return 0u;
+    }
+    case Dali::Pixel::RGB565:
+    {
+      if( channel == RED )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
+      }
+      else if( channel == GREEN )
+      {
+        return ((static_cast<unsigned int>(*pixelData) & 0x07) << 3) |
+          ((static_cast<unsigned int>(*(pixelData+1)) & 0xE0) >> 5);
+      }
+      else if( channel == BLUE )
+      {
+        return static_cast<unsigned int>(*(pixelData+1)) & 0x1F;
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::BGR565:
+    {
+      if( channel == BLUE )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
+      }
+      else if( channel == GREEN )
+      {
+        return ((static_cast<unsigned int>(*pixelData) & 0x07) << 3) |
+          ((static_cast<unsigned int>(*(pixelData+1)) & 0xE0) >> 5);
+      }
+      else if( channel == RED )
+      {
+        return (static_cast<unsigned int>(*(pixelData+1) & 0x1F) );
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::RGB888:
+    case Dali::Pixel::RGB8888:
+    {
+      if( channel == RED )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else if( channel == GREEN )
+      {
+        return static_cast<unsigned int>(*(pixelData+1));
+      }
+      else if( channel == BLUE )
+      {
+        return static_cast<unsigned int>(*(pixelData+2));
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::BGR8888:
+    {
+      if( channel == BLUE )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else if( channel == GREEN )
+      {
+        return static_cast<unsigned int>(*(pixelData+1));
+      }
+      else if( channel == RED )
+      {
+        return static_cast<unsigned int>(*(pixelData+2));
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::RGBA8888:
+    {
+      if( channel == RED )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else if( channel == GREEN )
+      {
+        return static_cast<unsigned int>(*(pixelData+1));
+      }
+      else if( channel == BLUE )
+      {
+        return static_cast<unsigned int>(*(pixelData+2));
+      }
+      else if( channel == ALPHA )
+      {
+        return static_cast<unsigned int>(*(pixelData+3));
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::BGRA8888:
+    {
+      if( channel == BLUE )
+      {
+        return static_cast<unsigned int>(*pixelData);
+      }
+      else if( channel == GREEN )
+      {
+        return static_cast<unsigned int>(*(pixelData+1));
+      }
+      else if( channel == RED )
+      {
+        return static_cast<unsigned int>(*(pixelData+2));
+      }
+      else if( channel == ALPHA )
+      {
+        return static_cast<unsigned int>(*(pixelData+3));
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::RGBA4444:
+    {
+      if( channel == RED )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0xF0) >> 4;
+      }
+      else if( channel == GREEN )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0x0F);
+      }
+      else if( channel == BLUE )
+      {
+        return (static_cast<unsigned int>(*(pixelData+1)) & 0xF0) >> 4;
+      }
+      else if( channel == ALPHA )
+      {
+        return (static_cast<unsigned int>(*(pixelData+1)) & 0x0F);
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::BGRA4444:
+    {
+      if( channel == BLUE )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0xF0) >> 4;
+      }
+      else if( channel == GREEN )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0x0F);
+      }
+      else if( channel == RED )
+      {
+        return (static_cast<unsigned int>(*(pixelData+1)) & 0xF0) >> 4;
+      }
+      else if( channel == ALPHA )
+      {
+        return (static_cast<unsigned int>(*(pixelData+1)) & 0x0F);
+      }
+      else return 0u;
+    }
+
+    case Dali::Pixel::RGBA5551:
+    {
+      if( channel == RED )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
+      }
+      else if( channel == GREEN )
+      {
+        return ((static_cast<unsigned int>(*pixelData) & 0x07) << 2) |
+          ((static_cast<unsigned int>(*(pixelData+1)) & 0xC0) >> 6);
+      }
+      else if( channel == BLUE )
+      {
+        return (static_cast<unsigned int>(*(pixelData+1)) & 0x3E) >> 1;
+      }
+      else if( channel == ALPHA )
+      {
+        return static_cast<unsigned int>(*(pixelData+1)) & 0x01;
+      }
+
+      else return 0u;
+    }
+
+    case Dali::Pixel::BGRA5551:
+    {
+      if( channel == BLUE )
+      {
+        return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
+      }
+      else if( channel == GREEN )
+      {
+        return ((static_cast<unsigned int>(*pixelData) & 0x07) << 2) |
+          ((static_cast<unsigned int>(*(pixelData+1)) & 0xC0) >> 6);
+      }
+      else if( channel == RED )
+      {
+        return ( static_cast<unsigned int>(*(pixelData+1)) & 0x3E) >> 1;
+      }
+      else if( channel == ALPHA )
+      {
+        return static_cast<unsigned int>(*(pixelData+1)) & 0x01;
+      }
+
+      else return 0u;
+    }
+
+    default:
+    {
+      return 0u;
+    }
+  }
+}
+
+void WriteChannel( unsigned char* pixelData,
+                   Dali::Pixel::Format pixelFormat,
+                   Channel channel,
+                   unsigned int channelValue )
+{
+  switch (pixelFormat)
+  {
+    case Dali::Pixel::A8:
+    {
+      if( channel == ALPHA )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+    case Dali::Pixel::L8:
+    {
+      if( channel == LUMINANCE )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+    case Dali::Pixel::LA88:
+    {
+      if( channel == LUMINANCE )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+    case Dali::Pixel::RGB565:
+    {
+      if( channel == RED )
+      {
+        *pixelData &= ~0xF8;
+        *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
+      }
+      else if( channel == GREEN )
+      {
+        *pixelData &= ~0x07;
+        *pixelData |= static_cast<unsigned char>( (channelValue >> 3) & 0x07 );
+
+        *(pixelData+1) &= ~0xE0;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 5) & 0xE0 );
+      }
+      else if( channel == BLUE )
+      {
+        *(pixelData+1) &= ~0x1F;
+        *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x1F );
+      }
+      break;
+    }
+
+    case Dali::Pixel::BGR565:
+    {
+      if( channel == BLUE )
+      {
+        *pixelData &= ~0xF8;
+        *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
+      }
+      else if( channel == GREEN )
+      {
+        *pixelData &= ~0x07;
+        *pixelData |= static_cast<unsigned char>( (channelValue >> 3) & 0x07 );
+
+        *(pixelData+1) &= ~0xE0;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 5) & 0xE0 );
+      }
+      else if( channel == RED )
+      {
+        *(pixelData+1) &= ~0x1F;
+        *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x1F );
+      }
+      break;
+    }
+
+    case Dali::Pixel::RGB888:
+    case Dali::Pixel::RGB8888:
+    {
+      if( channel == RED )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == GREEN )
+      {
+        *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == BLUE )
+      {
+        *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+
+    case Dali::Pixel::BGR8888:
+    {
+      if( channel == BLUE )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == GREEN )
+      {
+        *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == RED )
+      {
+        *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+
+    case Dali::Pixel::RGBA8888:
+    {
+      if( channel == RED )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == GREEN )
+      {
+        *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == BLUE )
+      {
+        *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+3) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+
+    case Dali::Pixel::BGRA8888:
+    {
+      if( channel == BLUE )
+      {
+        *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == GREEN )
+      {
+        *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == RED )
+      {
+        *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+3) = static_cast<unsigned char>( channelValue & 0xFF );
+      }
+      break;
+    }
+
+    case Dali::Pixel::RGBA4444:
+    {
+      if( channel == RED )
+      {
+        *pixelData &= ~0xF0;
+        *pixelData |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
+      }
+      else if( channel == GREEN )
+      {
+        *pixelData &= ~0x0F;
+        *pixelData |= static_cast<unsigned char>( channelValue & 0x0F );
+      }
+      else if( channel == BLUE )
+      {
+        *(pixelData+1) &= ~0xF0;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+1) &= ~0x0F;
+        *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x0F );
+      }
+      break;
+    }
+
+    case Dali::Pixel::BGRA4444:
+    {
+      if( channel == BLUE )
+      {
+        *pixelData &= ~0xF0;
+        *pixelData |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
+      }
+      else if( channel == GREEN )
+      {
+        *pixelData &= ~0x0F;
+        *pixelData |= static_cast<unsigned char>( channelValue & 0x0F );
+      }
+      else if( channel == RED )
+      {
+        *(pixelData+1) &= ~0xF0;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+1) &= ~0x0F;
+        *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x0F );
+      }
+      break;
+    }
+
+    case Dali::Pixel::RGBA5551:
+    {
+      // rrrrrggg ggbbbbba
+      //    F8  7 C0  3E 1
+      if( channel == RED )
+      {
+        *pixelData &= ~0xF8;
+        *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
+      }
+      else if( channel == GREEN )
+      {
+        *pixelData &= ~0x07;
+        *pixelData |= static_cast<unsigned char>( (channelValue >> 2) & 0x07 );
+
+        *(pixelData+1) &= ~0xC0;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 6) & 0xC0 );
+      }
+      else if( channel == BLUE )
+      {
+        *(pixelData+1) &= ~0x3E;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 1) & 0x3E );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+1) &= ~0x01;
+        *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x01 );
+      }
+      break;
+    }
+
+    case Dali::Pixel::BGRA5551:
+    {
+      if( channel == BLUE )
+      {
+        *pixelData &= ~0xF8;
+        *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
+      }
+      else if( channel == GREEN )
+      {
+        *pixelData &= ~0x07;
+        *pixelData |= static_cast<unsigned char>( (channelValue >> 2) & 0x07 );
+
+        *(pixelData+1) &= ~0xC0;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 6) & 0xC0 );
+      }
+      else if( channel == RED )
+      {
+        *(pixelData+1) &= ~0x3E;
+        *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 1 ) & 0x3E );
+      }
+      else if( channel == ALPHA )
+      {
+        *(pixelData+1) &= ~0x01;
+        *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x01 );
+      }
+      break;
+    }
+
+    default:
+      break;
+  }
+}
+
+void ConvertColorChannelsToRGBA8888(
+  unsigned char* srcPixel,  int srcOffset,  Dali::Pixel::Format srcFormat,
+  unsigned char* destPixel, int destOffset )
+{
+  int red   = ReadChannel(srcPixel+srcOffset, srcFormat, RED );
+  int green = ReadChannel(srcPixel+srcOffset, srcFormat, GREEN );
+  int blue  = ReadChannel(srcPixel+srcOffset, srcFormat, BLUE );
+  switch( srcFormat )
+  {
+    case Dali::Pixel::RGB565:
+    case Dali::Pixel::BGR565:
+    {
+      red = (red<<3) | (red & 0x07);
+      green = (green << 2) | (green & 0x03);
+      blue = (blue<<3) | (blue & 0x07);
+      break;
+    }
+    case Dali::Pixel::RGBA4444:
+    case Dali::Pixel::BGRA4444:
+    {
+      red = (red<<4) | (red&0x0F);
+      green = (green<<4) | (green&0x0F);
+      blue = (blue<<4) | (blue&0x0F);
+      break;
+    }
+    case Dali::Pixel::RGBA5551:
+    case Dali::Pixel::BGRA5551:
+    {
+      red = (red<<3) | (red&0x07);
+      green = (green<<3) | (green&0x07);
+      blue = (blue<<3) | (blue&0x07);
+      break;
+    }
+    default:
+      break;
+  }
+  WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, RED, red);
+  WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, GREEN, green);
+  WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, BLUE, blue);
+}
+
+
+int ConvertAlphaChannelToA8( unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat )
+{
+  int alpha = ReadChannel(srcPixel+srcOffset, srcFormat, ALPHA );
+  int destAlpha = alpha;
+  switch( srcFormat )
+  {
+    case Pixel::RGBA5551:
+    case Pixel::BGRA5551:
+    {
+      destAlpha = (alpha==0)?0:255;
+      break;
+    }
+    case Pixel::RGBA4444:
+    case Pixel::BGRA4444:
+    {
+      destAlpha = (alpha<<4) | (alpha&0x0F);
+      break;
+    }
+    default:
+      break;
+  }
+  return destAlpha;
+}
+
+} // Adaptor
+} // Internal
+} // Dali
diff --git a/platform-abstractions/portable/pixel-manipulation.h b/platform-abstractions/portable/pixel-manipulation.h
new file mode 100644 (file)
index 0000000..611b5a6
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef DALI_INTERNAL_ADAPTOR_PIXEL_MANIPULATION_H
+#define DALI_INTERNAL_ADAPTOR_PIXEL_MANIPULATION_H
+
+/*
+ * Copyright (c) 2017 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 <dali/public-api/images/pixel.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+enum Channel
+{
+  LUMINANCE,
+  RED,
+  GREEN,
+  BLUE,
+  ALPHA,
+  MAX_NUMBER_OF_CHANNELS
+};
+
+/**
+ * Return true if the channel exists in the pixel format
+ * @param[in] pixelFormat The pixelFormat
+ * @param[in] channel The channel to test for
+ * @return true if the channel exists
+ */
+bool HasChannel( Dali::Pixel::Format pixelFormat, Channel channel );
+
+
+/**
+ * Read a colour channel from the pixel with the given pixel format.
+ * Returns zero if the format does not support the channel
+ * @param[in] pixelData Location of the pixel
+ * @param[in] pixelFormat The format of the pixel
+ * @param[in] channel The channel to read
+ * @return the channel value
+ */
+unsigned int ReadChannel( unsigned char* pixelData,
+                          Dali::Pixel::Format pixelFormat,
+                          Channel channel );
+
+/**
+ * Write a colour channel to the pixel with the given pixel format.
+ * @param[in] pixelData Location of the pixel
+ * @param[in] pixelFormat The format of the pixel
+ * @param[in] channel The channel to write
+ * @param[in] channelValue the value to write to the channel
+ */
+void WriteChannel( unsigned char* pixelData,
+                   Dali::Pixel::Format pixelFormat,
+                   Channel channel,
+                   unsigned int channelValue );
+
+/**
+ * Convert the colors in the source pixel from their natural format to RGBA8888.
+ * @param[in] srcBuffer The source buffer to read from
+ * @param[in] srcOffset The offset of the pixel to convert
+ * @param[in] srcFormat The pixel format of the source pixel
+ * @param[in] destBuffer The destination buffer to write to
+ * @param[in] destOffset The offset of the pixel to write
+ */
+void ConvertColorChannelsToRGBA8888(
+  unsigned char* srcBuffer,  int srcOffset,  Dali::Pixel::Format srcFormat,
+  unsigned char* destBuffer, int destOffset );
+
+/**
+ * Convert the alpha in the source pixel to A8.
+ * @param[in] srcBuffer The source buffer to read from
+ * @param[in] srcOffset The offset of the pixel to convert
+ * @param[in] srcFormat The pixel format of the source pixel
+ * @return the alpha value in the range 0-255
+ */
+int ConvertAlphaChannelToA8( unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat );
+
+
+} // Adaptor
+} // Internal
+} // Dali
+
+
+#endif // DALI_INTERNAL_ADAPTOR_PIXEL_MANIPULATION_H
index be5f212..bb4e908 100755 (executable)
@@ -16,7 +16,10 @@ tizen_platform_abstraction_src_files = \
   $(tizen_platform_abstraction_src_dir)/image-loaders/loader-png.cpp \
   $(tizen_platform_abstraction_src_dir)/image-loaders/loader-wbmp.cpp \
   $(tizen_platform_abstraction_src_dir)/image-loaders/image-loader.cpp \
-  $(portable_platform_abstraction_src_dir)/image-operations.cpp
+  \
+  $(portable_platform_abstraction_src_dir)/image-operations.cpp \
+  $(portable_platform_abstraction_src_dir)/pixel-manipulation.cpp \
+  $(portable_platform_abstraction_src_dir)/alpha-mask.cpp
 
 # Add public headers here: