/*
- * 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 <dali/integration-api/bitmap.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/images/image.h>
-#include <dali/public-api/images/image-attributes.h>
#include "dali/public-api/math/math-utils.h"
#include "dali/public-api/math/vector2.h"
#include "platform-capabilities.h"
} // namespace - anonymous
-bool LoadPngHeader(FILE *fp, const ImageAttributes& attributes, unsigned int &width, unsigned int &height )
+bool LoadPngHeader( const ImageLoader::Input& input, unsigned int& width, unsigned int& height )
{
png_structp png = NULL;
png_infop info = NULL;
auto_png autoPng(png, info);
- bool success = LoadPngHeader(fp, width, height, png, info);
+ bool success = LoadPngHeader( input.file, width, height, png, info );
return success;
}
-bool LoadBitmapFromPng( FILE *fp, Bitmap& bitmap, ImageAttributes& attributes, const ResourceLoadingClient& client )
+bool LoadBitmapFromPng( const ImageLoader::Input& input, Integration::Bitmap& bitmap )
{
png_structp png = NULL;
png_infop info = NULL;
bool valid = false;
// Load info from the header
- if( !LoadPngHeader(fp, width, height, png, info) )
+ if( !LoadPngHeader( input.file, width, height, png, info ) )
{
return false;
}
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 )
{
{
switch(colordepth)
{
+ case 1:
+ {
+ pixelFormat = Pixel::LA88;
+ valid = true;
+ break;
+ }
+
case 2:
case 4:
case 8:
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
png_read_image(png, rows);
- // set the attributes
- attributes.SetSize( width, height );
-
free(rows);
return true;
: png(_png),
info(_info)
{
- DALI_ASSERT_DEBUG(&_png != 0 && &_info != 0);
}
~AutoPngWrite()
* */
extern "C" void WriteData(png_structp png_ptr, png_bytep data, png_size_t length)
{
- using Dali::TizenPlatform::PngBuffer;
DALI_ASSERT_DEBUG(png_ptr && data);
if(!png_ptr || !data)
{
return;
}
// Make sure we don't try to propagate a C++ exception up the call stack of a pure C library:
- try {
+ try
+ {
// Recover our buffer for writing into:
- PngBuffer* const encoded_img = (PngBuffer*) png_get_io_ptr(png_ptr);
+ Vector<unsigned char>* const encoded_img = static_cast< Vector<unsigned char>* >( png_get_io_ptr(png_ptr) );
if(encoded_img)
{
- const PngBuffer::size_type bufferSize = encoded_img->size();
- encoded_img->resize(encoded_img->size() + length); //< Can throw OOM.
- PngBuffer::value_type* const bufferBack = &((*encoded_img)[bufferSize]);
+ const Vector<unsigned char>::SizeType bufferSize = encoded_img->Count();
+ 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(...)
+ }
+ catch(...)
{
- DALI_LOG_ERROR("C++ Exception caught");
+ DALI_LOG_ERROR("C++ Exception caught\n");
}
}
* 7. If caller asks for no compression, bypass libpng and blat raw data to
* disk, topped and tailed with header/tail blocks.
*/
-bool EncodeToPng( const unsigned char* const pixelBuffer, PngBuffer& encodedPixels, std::size_t width, std::size_t height, Pixel::Format pixelFormat )
+bool EncodeToPng( const unsigned char* const pixelBuffer, Vector<unsigned char>& encodedPixels, std::size_t width, std::size_t height, Pixel::Format pixelFormat )
{
// Translate pixel format enum:
int pngPixelFormat = -1;
}
default:
{
- DALI_LOG_ERROR( "Unsupported pixel format for encoding to PNG." );
+ DALI_LOG_ERROR( "Unsupported pixel format for encoding to PNG.\n" );
return false;
}
}
// Since we are going to write to memory instead of a file, lets provide
// libpng with a custom write function and ask it to pass back our
- // std::vector buffer each time it calls back to flush data to "file":
+ // Vector buffer each time it calls back to flush data to "file":
png_set_write_fn(png_ptr, &encodedPixels, WriteData, FlushData);
// png_set_compression_level( png_ptr, Z_BEST_COMPRESSION);