[4.0] support 1, 2, 4 bit depths about PNG_COLOR_TYPE_GRAY
[platform/core/uifw/dali-adaptor.git] / platform-abstractions / tizen / image-loaders / loader-png.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 077d40c..09e8819
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 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.
@@ -128,7 +128,7 @@ bool LoadPngHeader( const ImageLoader::Input& input, unsigned int& width, unsign
   return success;
 }
 
-bool LoadBitmapFromPng( const ResourceLoadingClient& client, const ImageLoader::Input& input, Integration::Bitmap& bitmap )
+bool LoadBitmapFromPng( const ImageLoader::Input& input, Integration::Bitmap& bitmap )
 {
   png_structp png = NULL;
   png_infop info = NULL;
@@ -162,37 +162,30 @@ bool LoadBitmapFromPng( const ResourceLoadingClient& client, const ImageLoader::
 
   png_byte colortype = png_get_color_type(png, info);
 
-  if(colortype == PNG_COLOR_TYPE_GRAY)
+  if( colortype == PNG_COLOR_TYPE_GRAY ||
+      colortype == PNG_COLOR_TYPE_GRAY_ALPHA )
   {
-    switch( colordepth )
+    if( png_get_valid(png, info, PNG_INFO_tRNS) )
     {
-      case 8:
-      {
-        pixelFormat = Pixel::L8;
-        valid = true;
-        break;
-      }
-      default:
-      {
-        break;
-      }
+      colortype = PNG_COLOR_TYPE_GRAY_ALPHA;
+      /* expand transparency entry -> alpha channel if present */
+      png_set_tRNS_to_alpha(png);
+      pixelFormat = Pixel::LA88;
     }
-  }
-  else if(colortype == PNG_COLOR_TYPE_GRAY_ALPHA)
-  {
-    switch(colordepth)
+    else
     {
-      case 8:
-      {
-        pixelFormat = Pixel::LA88;
-        valid = true;
-        break;
-      }
-      default:
-      {
-        break;
-      }
+      colortype = PNG_COLOR_TYPE_GRAY;
+      pixelFormat = Pixel::L8;
     }
+
+    if( colordepth < 8 )
+    {
+      /* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
+      png_set_expand_gray_1_2_4_to_8(png);
+      /* pack all pixels to byte boundaries */
+      png_set_packing(png);
+    }
+    valid = true;
   }
   else if(colortype == PNG_COLOR_TYPE_RGB )
   {
@@ -299,17 +292,30 @@ bool LoadBitmapFromPng( const ResourceLoadingClient& client, const ImageLoader::
   if( rowBytes > stride )
   {
     stride = GetTextureDimension(rowBytes);
-    bufferWidth = stride / bpp;
+
+    bpp = stride / bufferWidth;
+    switch(bpp)
+    {
+      case 3:
+        pixelFormat = Pixel::RGB888;
+        break;
+      case 4:
+        pixelFormat = Pixel::RGBA8888;
+        break;
+      default:
+        break;
+    }
+
   }
 
   // decode the whole image into bitmap buffer
   pixels = bitmap.GetPackedPixelsProfile()->ReserveBuffer(pixelFormat, width, height, bufferWidth, bufferHeight);
 
   DALI_ASSERT_DEBUG(pixels);
-  rows = (png_bytep*) malloc(sizeof(png_bytep) * height);
+  rows = reinterpret_cast< png_bytep* >( malloc(sizeof(png_bytep) * height) );
   for(y=0; y<height; y++)
   {
-    rows[y] = (png_byte*) (pixels + y * stride);
+    rows[y] = pixels + y * stride;
   }
 
   // decode image
@@ -327,7 +333,6 @@ struct AutoPngWrite
   : png(_png),
     info(_info)
   {
-    DALI_ASSERT_DEBUG(&_png != 0 && &_info != 0);
   }
 
   ~AutoPngWrite()
@@ -367,18 +372,18 @@ namespace
       if(encoded_img)
       {
         const Vector<unsigned char>::SizeType bufferSize = encoded_img->Count();
-        encoded_img->Reserve( bufferSize + length ); //< Can throw OOM.
+        encoded_img->Resize( bufferSize + length ); //< Can throw OOM.
         unsigned char* const bufferBack = encoded_img->Begin() + bufferSize;
         memcpy(bufferBack, data, length);
       }
       else
       {
-        DALI_LOG_ERROR("PNG buffer for write to memory was passed from libpng as null.");
+        DALI_LOG_ERROR("PNG buffer for write to memory was passed from libpng as null.\n");
       }
     }
     catch(...)
     {
-      DALI_LOG_ERROR("C++ Exception caught");
+      DALI_LOG_ERROR("C++ Exception caught\n");
     }
   }
 
@@ -432,7 +437,7 @@ bool EncodeToPng( const unsigned char* const pixelBuffer, Vector<unsigned char>&
     }
     default:
     {
-      DALI_LOG_ERROR( "Unsupported pixel format for encoding to PNG." );
+      DALI_LOG_ERROR( "Unsupported pixel format for encoding to PNG.\n" );
       return false;
     }
   }