Add api for load image from encoded buffer + fix file-reader.h bug 19/259119/5
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 2 Jun 2021 00:54:41 +0000 (09:54 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 10 Jun 2021 01:10:20 +0000 (10:10 +0900)
Add api ImageLoading::LoadImageFromBuffer(const Dali::Vector<uint8_t>&)
We can load image from encoded image buffer.
+
Fix some portential error when we use Internal::Platform::FileReader
This patch will increase the convenience
of using a Internal::Platform::FileReader

Change-Id: I0e9b77fc4665261959ed6e027e398e78db2c1d31
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-adaptor/utc-Dali-ImageLoading.cpp
dali/devel-api/adaptor-framework/image-loading.cpp
dali/devel-api/adaptor-framework/image-loading.h
dali/internal/system/common/file-reader.h

index 23e2450..1019707 100644 (file)
@@ -70,6 +70,23 @@ const char* IMAGE_WIDTH_EVEN_EXIF8_RGB = TEST_RESOURCE_DIR "/f-even-exif-8.jpg";
 
 // this is image is not exist, for negative test
 const char* IMAGENONEXIST = "non-exist.jpg";
+
+Dali::Vector<uint8_t> FileToMemory(const char* filename)
+{
+  Dali::Vector<uint8_t> buffer;
+  FILE *fp;
+  fp = fopen(filename, "rb");
+  if(fp != NULL)
+  {
+    fseek(fp, 0, SEEK_END);
+    size_t size = ftell(fp);
+    buffer.Resize(size);
+    fseek(fp, 0, SEEK_SET);
+    fread(buffer.Begin(), size, sizeof(uint8_t), fp);
+    fclose(fp);
+  }
+  return buffer;
+}
 } // namespace
 
 void utc_dali_load_image_startup(void)
@@ -223,6 +240,154 @@ int UtcDaliLoadImageN(void)
   END_TEST;
 }
 
+int UtcDaliLoadImageFromBufferP(void)
+{
+  Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_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::LoadImageFromBuffer(FileToMemory(IMAGE_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);
+
+  Devel::PixelBuffer pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_LARGE_EXIF3_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 2000u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 2560u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+
+  Devel::PixelBuffer BufferJpeg1 = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF1_RGB));
+  DALI_TEST_CHECK(BufferJpeg1);
+  DALI_TEST_EQUALS(BufferJpeg1.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(BufferJpeg1.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(BufferJpeg1.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF2_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF3_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF4_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF5_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF6_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF7_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF8_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 55u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  BufferJpeg1 = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF1_RGB));
+  DALI_TEST_CHECK(BufferJpeg1);
+  DALI_TEST_EQUALS(BufferJpeg1.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(BufferJpeg1.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(BufferJpeg1.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF2_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF3_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF4_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF5_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF6_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF7_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_EVEN_EXIF8_RGB));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 50u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 64u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+  DALI_IMAGE_TEST_EQUALS(BufferJpeg1, pixelBufferJpeg, 8, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliLoadImageFromBufferN(void)
+{
+  Devel::PixelBuffer pixelBufferEmpty = Dali::LoadImageFromBuffer(Dali::Vector<uint8_t>());
+  DALI_TEST_CHECK(!pixelBufferEmpty);
+
+  Dali::Vector<uint8_t> strange;
+  strange.PushBack(0x11);
+  strange.PushBack(0x22);
+  strange.PushBack(0x33);
+  Devel::PixelBuffer pixelBufferStrange = Dali::LoadImageFromBuffer(strange);
+  DALI_TEST_CHECK(!pixelBufferStrange);
+
+  END_TEST;
+}
+
 int UtcDaliDownloadImageP(void)
 {
   std::string url("file://");
index 44bcac7..cfaaa12 100644 (file)
@@ -51,6 +51,30 @@ Devel::PixelBuffer LoadImageFromFile(const std::string& url, ImageDimensions siz
   return Dali::Devel::PixelBuffer();
 }
 
+Devel::PixelBuffer LoadImageFromBuffer(const Dali::Vector<uint8_t>& buffer, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection)
+{
+  if(buffer.Empty())
+  {
+    DALI_LOG_ERROR("buffer is empty!\n");
+    return Dali::Devel::PixelBuffer();
+  }
+  Integration::BitmapResourceType resourceType(size, fittingMode, samplingMode, orientationCorrection);
+
+  Internal::Platform::FileReader fileReader(buffer);
+  FILE* const                    fp = fileReader.GetFile();
+  if(fp != NULL)
+  {
+    Dali::Devel::PixelBuffer bitmap;
+    // Make path as empty string. Path information just for file format hint.
+    bool                     success = TizenPlatform::ImageLoader::ConvertStreamToBitmap(resourceType, std::string(""), fp, bitmap);
+    if(success && bitmap)
+    {
+      return bitmap;
+    }
+  }
+  return Dali::Devel::PixelBuffer();
+}
+
 ImageDimensions GetClosestImageSize(const std::string& filename,
                                     ImageDimensions    size,
                                     FittingMode::Type  fittingMode,
index a66028d..c1f7ad8 100644 (file)
@@ -47,6 +47,26 @@ DALI_ADAPTOR_API Devel::PixelBuffer LoadImageFromFile(
   bool               orientationCorrection = true);
 
 /**
+ * @brief Load an image synchronously from encoded buffer.
+ *
+ * @note This method is thread safe, i.e. can be called from any thread.
+ *
+ * @param [in] buffer The encoded buffer of the image to load.
+ *                    The buffer is not owned by FileStream and must be valid for entire lifetime of FileStream
+ * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image
+ * @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 PixelBuffer object or an empty handle in case loading failed.
+ */
+DALI_ADAPTOR_API Devel::PixelBuffer LoadImageFromBuffer(
+  const Dali::Vector<uint8_t>& buffer,
+  ImageDimensions              size                  = ImageDimensions(0, 0),
+  FittingMode::Type            fittingMode           = FittingMode::DEFAULT,
+  SamplingMode::Type           samplingMode          = SamplingMode::BOX_THEN_LINEAR,
+  bool                         orientationCorrection = true);
+
+/**
  * @brief Determine the size of an image that LoadImageFromFile will provide when
  * given the same image loading parameters.
  *
index 031ad2d..b6c3b5d 100644 (file)
@@ -36,14 +36,18 @@ public:
   {
   }
 
-  FileReader(Dali::Vector<uint8_t>& vector)
-  : FileStream(&vector[0], vector.Size(), FileStream::READ | FileStream::BINARY)
+  FileReader(const Dali::Vector<uint8_t>& vector)
+  : FileStream(vector.Begin(), vector.Size(), FileStream::READ | FileStream::BINARY)
   {
   }
 
-  FileReader(Dali::Vector<uint8_t>& vector, size_t dataSize)
-  : FileStream(&vector[0], dataSize, FileStream::READ | FileStream::BINARY)
+  FileReader(const Dali::Vector<uint8_t>& vector, size_t dataSize)
+  : FileStream(vector.Begin(), dataSize, FileStream::READ | FileStream::BINARY)
   {
+    if(dataSize > vector.Size())
+    {
+      DALI_LOG_ERROR("dataSize(%u) is bigger than vector.Size(%u)!\n", static_cast<uint32_t>(dataSize), static_cast<uint32_t>(vector.Size()));
+    }
   }
 
   FileReader(uint8_t* data, size_t dataSize)