[4.0] Fixed BMP loader.
[platform/core/uifw/dali-adaptor.git] / platform-abstractions / tizen / image-loaders / loader-bmp.cpp
index 3c10913..72799b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 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.
 #include "loader-bmp.h"
 
 #include <dali/public-api/common/vector-wrapper.h>
+#include <adaptors/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/integration-api/debug.h>
-#include <dali/integration-api/bitmap.h>
-#include <dali/public-api/images/image-attributes.h>
-
-#include <cstdlib>
 
 namespace Dali
 {
-using Integration::Bitmap;
-using Dali::Integration::PixelBuffer;
+
 namespace TizenPlatform
 {
 
@@ -85,10 +81,10 @@ struct BmpInfoHeader
 template<typename T>
 inline bool ReadHeader(FILE* fp, T& header)
 {
-  unsigned int readLength = sizeof(T);
+  const unsigned int readLength = sizeof(T);
 
   // Load the information directly into our structure
-  if (fread((void*)&header, 1, readLength, fp) != readLength)
+  if ( fread( &header, 1, readLength, fp ) != readLength )
   {
     return false;
   }
@@ -109,7 +105,12 @@ bool LoadBmpHeader(FILE *fp, unsigned int &width, unsigned int &height, BmpFileH
   }
 
   width = infoHeader.width;
-  height = infoHeader.height;
+  height = abs(infoHeader.height);
+
+  if( infoHeader.width == 0 )
+  {
+    return false;
+  }
 
   return true;
 }
@@ -126,7 +127,7 @@ bool LoadBmpHeader(FILE *fp, unsigned int &width, unsigned int &height, BmpFileH
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRGB24V5(FILE *fp,
-                   PixelBuffer *pixels,
+                   unsigned char* pixels,
                    unsigned int width,
                    unsigned int height,
                    unsigned int offset,
@@ -147,7 +148,7 @@ bool DecodeRGB24V5(FILE *fp,
 
   for(unsigned int yPos = 0; yPos < height; yPos ++)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if(topDown)
     {
       pixelsPtr = pixels + ( yPos * rowStride);
@@ -193,7 +194,7 @@ bool DecodeRGB24V5(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeBF32V4(FILE *fp,
-                  PixelBuffer *pixels,
+                  unsigned char* pixels,
                   unsigned int width,
                   unsigned int height,
                   unsigned int offset,
@@ -214,7 +215,7 @@ bool DecodeBF32V4(FILE *fp,
 
   for(unsigned int yPos = 0; yPos < height; yPos ++)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if(topDown)
     {
       pixelsPtr = pixels + ( yPos * rowStride);
@@ -260,7 +261,7 @@ bool DecodeBF32V4(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeBF32(FILE *fp,
-                PixelBuffer *pixels,
+                unsigned char* pixels,
                 unsigned int width,
                 unsigned int height,
                 unsigned int offset,
@@ -281,7 +282,7 @@ bool DecodeBF32(FILE *fp,
 
   for (unsigned int yPos = 0; yPos < height; yPos++)
   {
-    PixelBuffer *pixelsPtr;
+    unsigned char* pixelsPtr;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -328,7 +329,7 @@ bool DecodeBF32(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeBF565(FILE *fp,
-                 PixelBuffer *pixels,
+                 unsigned char* pixels,
                  unsigned int width,
                  unsigned int height,
                  unsigned int offset,
@@ -350,7 +351,7 @@ bool DecodeBF565(FILE *fp,
 
   for(unsigned int i = 0; i < height; i++)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -381,7 +382,7 @@ bool DecodeBF565(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeBF555(FILE *fp,
-                 PixelBuffer *pixels,
+                 unsigned char* pixels,
                  unsigned int width,
                  unsigned int height,
                  unsigned int offset,
@@ -417,7 +418,7 @@ bool DecodeBF555(FILE *fp,
 
   for (unsigned int yPos = 0; yPos < height; yPos++)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -451,7 +452,7 @@ bool DecodeBF555(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRGB555(FILE *fp,
-                  PixelBuffer *pixels,
+                  unsigned char* pixels,
                   unsigned int width,
                   unsigned int height,
                   unsigned int offset,
@@ -484,7 +485,7 @@ bool DecodeRGB555(FILE *fp,
   }
   for(unsigned int i = 0; i < height; i++)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -518,7 +519,7 @@ bool DecodeRGB555(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRGB1(FILE *fp,
-                PixelBuffer *pixels,
+                unsigned char* pixels,
                 unsigned int width,
                 unsigned int height,
                 unsigned int offset,
@@ -566,7 +567,7 @@ bool DecodeRGB1(FILE *fp,
 
   for(unsigned int index = 0; index < height; index = index + 1)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -579,7 +580,7 @@ bool DecodeRGB1(FILE *fp,
     }
     for(unsigned int j = 0; j < fillw; j ++)
     {
-      int ctIndex = 0;
+      unsigned int ctIndex = 0;
       if((fillw * index + j ) < (fillw * height))
       {
         ctIndex = colorIndex[ fillw * index + j ];
@@ -611,7 +612,7 @@ bool DecodeRGB1(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRGB4(FILE *fp,
-                PixelBuffer *pixels,
+                unsigned char* pixels,
                 unsigned int width,
                 unsigned int height,
                 unsigned int offset,
@@ -649,11 +650,11 @@ bool DecodeRGB4(FILE *fp,
     colorIndex[i] = cmd >> 4;
     colorIndex[i + 1] = cmd & (0x0F);
   }
-  int ctIndex = 0;
+  unsigned int ctIndex = 0;
 
   for(unsigned int index = 0; index < height; index = index + 1)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -687,7 +688,7 @@ bool DecodeRGB4(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRGB8(FILE *fp,
-                PixelBuffer *pixels,
+                unsigned char* pixels,
                 unsigned int width,
                 unsigned int height,
                 unsigned int offset,
@@ -723,10 +724,10 @@ bool DecodeRGB8(FILE *fp,
 
     colorIndex[i] = cmd;
   }
-  int ctIndex = 0;
+  unsigned int ctIndex = 0;
   for(unsigned int index = 0; index < height; index = index + 1)
   {
-    PixelBuffer *pixelsPtr = NULL;
+    unsigned char* pixelsPtr = NULL;
     if (topDown)
     {
       // the data in the file is top down, and we store the data top down
@@ -759,7 +760,7 @@ bool DecodeRGB8(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRLE4(FILE *fp,
-                PixelBuffer *pixels,
+                unsigned char* pixels,
                 unsigned int width,
                 unsigned int height,
                 unsigned int offset,
@@ -770,17 +771,17 @@ bool DecodeRLE4(FILE *fp,
     DALI_LOG_ERROR("Error decoding BMP_RLE4 format\n");
     return false;
   }
-  PixelBuffer *pixelsPtr = pixels;
+  unsigned char* pixelsPtr = pixels;
   width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
   char cmd[2];
   unsigned int cmdStride = 2;
   char colorTable[64];
   std::vector<char> colorIndex(width * height >> 1);
   std::vector<char> run;
-  int x = 0;
-  int y = 0;
-  int dx = 0;
-  int dy = 0;
+  unsigned int x = 0;
+  unsigned int y = 0;
+  unsigned int dx = 0;
+  unsigned int dy = 0;
   width += (width & 1);
   width = width >> 1;
 
@@ -927,7 +928,7 @@ bool DecodeRLE4(FILE *fp,
  * @return true, if decode successful, false otherwise
  */
 bool DecodeRLE8(FILE *fp,
-                PixelBuffer *pixels,
+                unsigned char* pixels,
                 unsigned int width,
                 unsigned int height,
                 unsigned int offset,
@@ -938,9 +939,9 @@ bool DecodeRLE8(FILE *fp,
     DALI_LOG_ERROR("Error decoding BMP_RLE8 format\n");
     return false;
   }
-  PixelBuffer *pixelsPtr = pixels;
-  int x = 0;
-  int y = 0;
+  unsigned char* pixelsPtr = pixels;
+  unsigned int x = 0;
+  unsigned int y = 0;
   unsigned int cmdStride = 2;
 
   width = ((width & 3) != 0) ? width + 4 - (width & 3) : width;
@@ -959,8 +960,8 @@ bool DecodeRLE8(FILE *fp,
     return false;
   }
 
-  int dx = 0;
-  int dy = 0;
+  unsigned int dx = 0;
+  unsigned int dy = 0;
   bool finish = false;
   unsigned int length = 0;
   unsigned int copylength = 0;
@@ -1042,19 +1043,20 @@ bool DecodeRLE8(FILE *fp,
 
 } // unnamed namespace
 
-bool LoadBmpHeader(FILE *fp, const ImageAttributes& attributes, unsigned int &width, unsigned int &height)
+bool LoadBmpHeader( const ImageLoader::Input& input, unsigned int& width, unsigned int& height )
 {
   BmpFileHeader fileHeader;
   BmpInfoHeader infoHeader;
 
-  bool ret = LoadBmpHeader(fp, width, height, fileHeader, infoHeader);
+  bool ret = LoadBmpHeader( input.file, width, height, fileHeader, infoHeader );
 
   return ret;
 }
 
-bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, const ResourceLoadingClient& client )
+bool LoadBitmapFromBmp( const ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap )
 {
-  DALI_ASSERT_DEBUG(bitmap.GetPackedPixelsProfile() != 0 && "Need a packed pixel bitmap to load into.");
+  //DALI_ASSERT_DEBUG( bitmap.GetPackedPixelsProfile() != 0 && "Need a packed pixel bitmap to load into." );
+  FILE* const fp = input.file;
   if(fp == NULL)
   {
     DALI_LOG_ERROR("Error loading bitmap\n");
@@ -1194,9 +1196,11 @@ bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, c
     padding = 4 - padding;
   }
 
-  PixelBuffer *pixels =  NULL;
   int imageW = infoHeader.width;
-  int pixelBufferW = 0;
+  int pixelBufferW = infoHeader.width;
+  int pixelBufferH = infoHeader.height;
+  auto newPixelFormat = Pixel::Format::INVALID;
+
   switch(customizedFormat)
   {
   case BMP_RLE8:
@@ -1207,43 +1211,51 @@ bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, c
   case BMP_BITFIELDS555:
   {
     pixelBufferW = ((imageW & 3) != 0) ? imageW + 4 - (imageW & 3) : imageW;
-    pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGB888, pixelBufferW, abs(infoHeader.height));
+    pixelBufferH = abs(infoHeader.height);
+    newPixelFormat = Pixel::RGB888;
     break;
   }
   case BMP_RGB1:
   {
     pixelBufferW = ((imageW & 63) != 0) ? imageW + 64 - (imageW & 63) : imageW;
-    pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGB888, pixelBufferW, abs(infoHeader.height));
+    pixelBufferH = abs(infoHeader.height);
+    newPixelFormat = Pixel::RGB888;
     break;
   }
   case BMP_BITFIELDS32:
   case BMP_BITFIELDS32V4:
   {
-    pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGB8888, infoHeader.width, abs(infoHeader.height));
+    pixelBufferH = abs(infoHeader.height);
+    newPixelFormat = Pixel::RGB8888;
     break;
   }
   case BMP_RGB24V5:
   {
-    pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGB888, infoHeader.width, infoHeader.height);
+    newPixelFormat = Pixel::RGB888;
     break;
   }
   default:
     if(pixelFormat == Pixel::RGB565 )
     {
       pixelBufferW = ((imageW & 3) != 0) ? imageW + 4 - (imageW & 3) : imageW;
-      pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGB565, pixelBufferW, abs(infoHeader.height));
+      pixelBufferH = abs(infoHeader.height);
+      newPixelFormat = Pixel::RGB565;
     }
     else
     {
-      pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(pixelFormat, infoHeader.width, infoHeader.height);
+      pixelBufferW = infoHeader.width;
+      pixelBufferH = infoHeader.height;
+      newPixelFormat = pixelFormat;
     }
     break;
   }
 
-  // TODO: Add scaling support
+  bitmap = Dali::Devel::PixelBuffer::New(pixelBufferW, pixelBufferH, newPixelFormat);
+  auto pixels = bitmap.GetBuffer();
 
   // Read the raw bitmap data
-  PixelBuffer *pixelsPtr;
+  decltype(pixels) pixelsIterator = nullptr;
+
   bool decodeResult(false);
   switch(customizedFormat)
   {
@@ -1254,7 +1266,7 @@ bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, c
     }
     case BMP_RGB4:
     {
-      decodeResult = DecodeRGB4(fp, pixels, infoHeader.width, infoHeader.height, 14 + infoHeader.infoHeaderSize, topDown);
+      decodeResult = DecodeRGB4(fp, pixels, infoHeader.width, abs(infoHeader.height), 14 + infoHeader.infoHeaderSize, topDown);
       break;
     }
     case BMP_RLE4:
@@ -1310,15 +1322,15 @@ bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, c
           if (topDown)
           {
             // the data in the file is top down, and we store the data top down
-            pixelsPtr = pixels + ( yPos * rowStride);
+            pixelsIterator = pixels + ( yPos * rowStride);
           }
           else
           {
             // the data in the file is bottom up, and we store the data top down
-            pixelsPtr = pixels + (((height-1)-yPos) * rowStride);
+            pixelsIterator = pixels + (((height-1)-yPos) * rowStride);
           }
 
-          if (fread(pixelsPtr, 1, rowStride, fp) != rowStride)
+          if (fread(pixelsIterator, 1, rowStride, fp) != rowStride)
           {
             DALI_LOG_ERROR("Error reading the BMP image\n");
             break;
@@ -1330,9 +1342,9 @@ bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, c
           {
             for(unsigned int i = 0; i < rowStride; i += 3)
             {
-              unsigned char temp = pixelsPtr[i];
-              pixelsPtr[i] = pixelsPtr[i+2];
-              pixelsPtr[i+2] = temp;
+              unsigned char temp = pixelsIterator[i];
+              pixelsIterator[i] = pixelsIterator[i+2];
+              pixelsIterator[i+2] = temp;
             }
           }
 
@@ -1355,7 +1367,6 @@ bool LoadBitmapFromBmp( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, c
     return false;
   }
 
-  attributes.SetSize(infoHeader.width, infoHeader.height);
   return true;
 }