2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <png.h>
|
2008-11-05 12:39:10 -08:00
|
|
|
#include <setjmp.h>
|
2008-11-05 09:21:04 -08:00
|
|
|
|
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h"
|
2006-01-14 12:03:42 -08:00
|
|
|
#include "evas_private.h"
|
|
|
|
|
|
|
|
#define PNG_BYTES_TO_CHECK 4
|
|
|
|
|
2013-01-02 23:57:18 -08:00
|
|
|
typedef struct _Evas_PNG_Info Evas_PNG_Info;
|
|
|
|
struct _Evas_PNG_Info
|
|
|
|
{
|
|
|
|
unsigned char *map;
|
|
|
|
size_t length;
|
|
|
|
size_t position;
|
|
|
|
};
|
|
|
|
|
2013-05-06 03:01:35 -07:00
|
|
|
typedef struct _Evas_Loader_Internal Evas_Loader_Internal;
|
|
|
|
struct _Evas_Loader_Internal
|
|
|
|
{
|
|
|
|
Eina_File *f;
|
|
|
|
Evas_Image_Load_Opts *opts;
|
|
|
|
};
|
|
|
|
|
2014-03-18 20:20:07 -07:00
|
|
|
static const Evas_Colorspace cspace_grey[2] = {
|
|
|
|
EVAS_COLORSPACE_GRY8,
|
|
|
|
EVAS_COLORSPACE_ARGB8888
|
|
|
|
};
|
|
|
|
|
|
|
|
static const Evas_Colorspace cspace_grey_alpha[2] = {
|
|
|
|
EVAS_COLORSPACE_AGRY88,
|
|
|
|
EVAS_COLORSPACE_ARGB8888
|
|
|
|
};
|
|
|
|
|
2013-01-02 23:57:18 -08:00
|
|
|
static void
|
|
|
|
_evas_image_png_read(png_structp png_ptr, png_bytep out, png_size_t count)
|
|
|
|
{
|
2013-01-03 04:04:37 -08:00
|
|
|
Evas_PNG_Info *epi = png_get_io_ptr(png_ptr);
|
2013-01-02 23:57:18 -08:00
|
|
|
|
2013-06-20 04:28:18 -07:00
|
|
|
if (!epi) return;
|
|
|
|
if (epi->position == epi->length) return;
|
2013-01-02 23:57:18 -08:00
|
|
|
|
|
|
|
if (epi->position + count > epi->length) count = epi->length - epi->position;
|
|
|
|
memcpy(out, epi->map + epi->position, count);
|
|
|
|
epi->position += count;
|
|
|
|
}
|
|
|
|
|
2013-05-06 03:01:35 -07:00
|
|
|
static void *
|
2013-07-01 23:33:32 -07:00
|
|
|
evas_image_load_file_open_png(Eina_File *f, Eina_Stringshare *key EINA_UNUSED,
|
2013-05-06 03:01:35 -07:00
|
|
|
Evas_Image_Load_Opts *opts,
|
|
|
|
Evas_Image_Animated *animated EINA_UNUSED,
|
|
|
|
int *error)
|
|
|
|
{
|
|
|
|
Evas_Loader_Internal *loader;
|
|
|
|
|
|
|
|
loader = calloc(1, sizeof (Evas_Loader_Internal));
|
|
|
|
if (!loader)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
loader->f = f;
|
|
|
|
loader->opts = opts;
|
|
|
|
return loader;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_image_load_file_close_png(void *loader_data)
|
|
|
|
{
|
|
|
|
free(loader_data);
|
|
|
|
}
|
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
2013-05-06 03:01:35 -07:00
|
|
|
evas_image_load_file_head_png(void *loader_data,
|
|
|
|
Evas_Image_Property *prop,
|
|
|
|
int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2013-05-06 03:01:35 -07:00
|
|
|
Evas_Loader_Internal *loader = loader_data;
|
|
|
|
Evas_Image_Load_Opts *opts;
|
|
|
|
Eina_File *f;
|
|
|
|
|
2013-01-02 23:57:18 -08:00
|
|
|
Evas_PNG_Info epi;
|
2006-01-14 12:03:42 -08:00
|
|
|
png_structp png_ptr = NULL;
|
|
|
|
png_infop info_ptr = NULL;
|
2013-01-02 23:57:18 -08:00
|
|
|
png_uint_32 w32, h32;
|
2006-01-14 12:03:42 -08:00
|
|
|
int bit_depth, color_type, interlace_type;
|
2007-08-24 19:36:18 -07:00
|
|
|
char hasa;
|
2015-04-25 10:59:18 -07:00
|
|
|
volatile Eina_Bool r = EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2013-05-06 03:01:35 -07:00
|
|
|
opts = loader->opts;
|
|
|
|
f = loader->f;
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
hasa = 0;
|
2013-08-01 18:25:26 -07:00
|
|
|
epi.map = eina_file_map_all(f, EINA_FILE_RANDOM);
|
2013-01-02 23:57:18 -08:00
|
|
|
if (!epi.map)
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
|
|
|
goto close_file;
|
|
|
|
}
|
|
|
|
epi.length = eina_file_size_get(f);
|
|
|
|
epi.position = 0;
|
|
|
|
|
|
|
|
if (epi.length < PNG_BYTES_TO_CHECK)
|
2009-12-22 15:11:57 -08:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
goto close_file;
|
|
|
|
}
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2013-01-02 23:57:18 -08:00
|
|
|
if (png_sig_cmp(epi.map, 0, PNG_BYTES_TO_CHECK))
|
2009-12-22 15:11:57 -08:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
goto close_file;
|
|
|
|
}
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
|
|
if (!png_ptr)
|
2009-12-22 15:11:57 -08:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
goto close_file;
|
|
|
|
}
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
|
|
|
if (!info_ptr)
|
|
|
|
{
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2013-01-02 23:57:18 -08:00
|
|
|
|
|
|
|
png_set_read_fn(png_ptr, &epi, _evas_image_png_read);
|
|
|
|
|
2008-11-06 10:54:19 -08:00
|
|
|
if (setjmp(png_jmpbuf(png_ptr)))
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2013-01-02 23:57:18 -08:00
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
png_read_info(png_ptr, info_ptr);
|
|
|
|
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
|
|
|
|
(png_uint_32 *) (&h32), &bit_depth, &color_type,
|
|
|
|
&interlace_type, NULL, NULL);
|
2009-09-16 02:48:05 -07:00
|
|
|
if ((w32 < 1) || (h32 < 1) || (w32 > IMG_MAX_SIZE) || (h32 > IMG_MAX_SIZE) ||
|
|
|
|
IMG_TOO_BIG(w32, h32))
|
2006-11-04 21:07:53 -08:00
|
|
|
{
|
2009-12-22 15:11:57 -08:00
|
|
|
if (IMG_TOO_BIG(w32, h32))
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
else
|
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-11-04 21:07:53 -08:00
|
|
|
}
|
2013-04-24 23:07:11 -07:00
|
|
|
if (opts->scale_down_by > 1)
|
2011-10-19 02:04:34 -07:00
|
|
|
{
|
2013-04-24 23:07:11 -07:00
|
|
|
prop->w = (int) w32 / opts->scale_down_by;
|
|
|
|
prop->h = (int) h32 / opts->scale_down_by;
|
|
|
|
if ((prop->w < 1) || (prop->h < 1))
|
2011-10-19 02:04:34 -07:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
|
|
|
goto close_file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-04-24 23:07:11 -07:00
|
|
|
prop->w = (int) w32;
|
|
|
|
prop->h = (int) h32;
|
2011-10-19 02:04:34 -07:00
|
|
|
}
|
2007-08-24 19:36:18 -07:00
|
|
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
|
2014-03-18 20:20:07 -07:00
|
|
|
switch (color_type)
|
|
|
|
{
|
|
|
|
case PNG_COLOR_TYPE_RGB_ALPHA:
|
|
|
|
hasa = 1;
|
|
|
|
break;
|
|
|
|
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
|
|
|
hasa = 1;
|
|
|
|
prop->cspaces = cspace_grey_alpha;
|
|
|
|
break;
|
|
|
|
case PNG_COLOR_TYPE_GRAY:
|
2014-06-26 01:00:37 -07:00
|
|
|
if (!hasa) prop->cspaces = cspace_grey;
|
2014-03-18 20:20:07 -07:00
|
|
|
break;
|
|
|
|
}
|
2013-04-24 23:07:11 -07:00
|
|
|
if (hasa) prop->alpha = 1;
|
2009-12-22 15:11:57 -08:00
|
|
|
|
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
2013-01-02 23:57:18 -08:00
|
|
|
r = EINA_TRUE;
|
2008-11-09 11:32:12 -08:00
|
|
|
|
|
|
|
close_file:
|
2013-01-02 23:57:18 -08:00
|
|
|
if (png_ptr) png_destroy_read_struct(&png_ptr,
|
|
|
|
info_ptr ? &info_ptr : NULL,
|
|
|
|
NULL);
|
|
|
|
if (epi.map) eina_file_map_free(f, epi. map);
|
|
|
|
|
|
|
|
return r;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
static Eina_Bool
|
2013-05-06 03:01:35 -07:00
|
|
|
evas_image_load_file_data_png(void *loader_data,
|
|
|
|
Evas_Image_Property *prop,
|
|
|
|
void *pixels,
|
2013-05-02 01:17:42 -07:00
|
|
|
int *error)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
2013-05-06 03:01:35 -07:00
|
|
|
Evas_Loader_Internal *loader = loader_data;
|
|
|
|
Evas_Image_Load_Opts *opts;
|
|
|
|
Eina_File *f;
|
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
unsigned char *surface;
|
2013-01-02 23:57:18 -08:00
|
|
|
unsigned char *tmp_line;
|
2006-01-14 12:03:42 -08:00
|
|
|
png_structp png_ptr = NULL;
|
|
|
|
png_infop info_ptr = NULL;
|
2013-01-02 23:57:18 -08:00
|
|
|
Evas_PNG_Info epi;
|
|
|
|
png_uint_32 w32, h32;
|
2014-03-18 20:20:07 -07:00
|
|
|
unsigned int pack_offset;
|
2013-01-02 23:57:18 -08:00
|
|
|
int w, h;
|
2006-01-14 12:03:42 -08:00
|
|
|
int bit_depth, color_type, interlace_type;
|
2015-04-25 10:59:18 -07:00
|
|
|
volatile char hasa;
|
|
|
|
char passes;
|
2014-04-15 01:56:07 -07:00
|
|
|
int i, j, p, k;
|
2015-04-25 10:59:18 -07:00
|
|
|
volatile int scale_ratio = 1;
|
|
|
|
int image_w = 0, image_h = 0;
|
|
|
|
volatile Eina_Bool r = EINA_FALSE;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2013-05-06 03:01:35 -07:00
|
|
|
opts = loader->opts;
|
|
|
|
f = loader->f;
|
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
hasa = 0;
|
|
|
|
|
2013-01-02 23:57:18 -08:00
|
|
|
epi.map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
|
|
|
|
if (!epi.map)
|
2010-09-18 16:39:30 -07:00
|
|
|
{
|
2013-01-02 23:57:18 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
2010-09-18 16:39:30 -07:00
|
|
|
goto close_file;
|
|
|
|
}
|
2013-01-02 23:57:18 -08:00
|
|
|
epi.length = eina_file_size_get(f);
|
|
|
|
epi.position = 0;
|
|
|
|
|
|
|
|
if (epi.length < PNG_BYTES_TO_CHECK)
|
2009-12-22 15:11:57 -08:00
|
|
|
{
|
2013-01-02 23:57:18 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
|
|
|
goto close_file;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we havent read the header before, set the header data */
|
|
|
|
if (png_sig_cmp(epi.map, 0, PNG_BYTES_TO_CHECK))
|
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
|
2009-12-22 15:11:57 -08:00
|
|
|
goto close_file;
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
|
|
if (!png_ptr)
|
2009-12-22 15:11:57 -08:00
|
|
|
{
|
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
|
|
goto close_file;
|
|
|
|
}
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
|
|
|
if (!info_ptr)
|
|
|
|
{
|
|
|
|
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2013-01-02 23:57:18 -08:00
|
|
|
|
|
|
|
png_set_read_fn(png_ptr, &epi, _evas_image_png_read);
|
|
|
|
|
2008-11-06 10:54:19 -08:00
|
|
|
if (setjmp(png_jmpbuf(png_ptr)))
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_CORRUPT_FILE;
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
2013-01-02 23:57:18 -08:00
|
|
|
|
2006-01-14 12:03:42 -08:00
|
|
|
png_read_info(png_ptr, info_ptr);
|
|
|
|
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
|
|
|
|
(png_uint_32 *) (&h32), &bit_depth, &color_type,
|
|
|
|
&interlace_type, NULL, NULL);
|
2011-10-19 02:04:34 -07:00
|
|
|
image_w = w32;
|
2014-04-15 01:56:07 -07:00
|
|
|
image_h = h32;
|
2013-05-02 01:17:42 -07:00
|
|
|
if (opts->scale_down_by > 1)
|
2011-10-19 02:04:34 -07:00
|
|
|
{
|
2013-05-02 01:17:42 -07:00
|
|
|
scale_ratio = opts->scale_down_by;
|
2011-10-19 02:04:34 -07:00
|
|
|
w32 /= scale_ratio;
|
|
|
|
h32 /= scale_ratio;
|
|
|
|
}
|
2013-05-02 01:17:42 -07:00
|
|
|
if (prop->w != w32 ||
|
|
|
|
prop->h != h32)
|
2006-11-04 21:07:53 -08:00
|
|
|
{
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_GENERIC;
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-11-04 21:07:53 -08:00
|
|
|
}
|
2013-05-02 01:17:42 -07:00
|
|
|
|
|
|
|
surface = pixels;
|
2014-03-20 18:47:03 -07:00
|
|
|
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
|
|
|
|
{
|
|
|
|
/* expand transparency entry -> alpha channel if present */
|
|
|
|
png_set_tRNS_to_alpha(png_ptr);
|
|
|
|
hasa = 1;
|
|
|
|
}
|
2007-08-24 19:36:18 -07:00
|
|
|
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
|
|
|
|
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
|
2013-05-02 01:17:42 -07:00
|
|
|
if (hasa) prop->alpha = 1;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2007-08-24 19:36:18 -07:00
|
|
|
/* Prep for transformations... ultimately we want ARGB */
|
|
|
|
/* expand palette -> RGB if necessary */
|
|
|
|
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
|
|
|
|
/* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
|
|
|
|
if ((color_type == PNG_COLOR_TYPE_GRAY) ||
|
|
|
|
(color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
|
|
|
|
{
|
2014-03-18 20:20:07 -07:00
|
|
|
if (prop->cspace == EVAS_COLORSPACE_ARGB8888)
|
|
|
|
png_set_gray_to_rgb(png_ptr);
|
2007-08-24 19:36:18 -07:00
|
|
|
if (bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
|
|
|
|
}
|
|
|
|
/* reduce 16bit color -> 8bit color if necessary */
|
|
|
|
if (bit_depth > 8) png_set_strip_16(png_ptr);
|
|
|
|
/* pack all pixels to byte boundaries */
|
|
|
|
png_set_packing(png_ptr);
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2013-05-02 01:17:42 -07:00
|
|
|
w = w32;
|
|
|
|
h = h32;
|
2006-01-14 12:03:42 -08:00
|
|
|
|
2014-03-18 20:20:07 -07:00
|
|
|
switch (prop->cspace)
|
|
|
|
{
|
2014-03-20 18:47:03 -07:00
|
|
|
case EVAS_COLORSPACE_ARGB8888:
|
|
|
|
/* we want ARGB */
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
png_set_swap_alpha(png_ptr);
|
|
|
|
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
|
|
|
#else
|
|
|
|
png_set_bgr(png_ptr);
|
|
|
|
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
|
|
|
#endif
|
|
|
|
pack_offset = sizeof(DATA32);
|
|
|
|
break;
|
|
|
|
case EVAS_COLORSPACE_AGRY88:
|
|
|
|
/* we want AGRY */
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
png_set_swap_alpha(png_ptr);
|
|
|
|
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
|
|
|
|
#else
|
|
|
|
if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
|
|
|
#endif
|
|
|
|
pack_offset = sizeof(DATA16);
|
|
|
|
break;
|
2014-03-18 20:20:07 -07:00
|
|
|
case EVAS_COLORSPACE_GRY8: pack_offset = sizeof(DATA8); break;
|
|
|
|
default: abort();
|
|
|
|
}
|
|
|
|
|
2014-04-15 01:56:07 -07:00
|
|
|
passes = png_set_interlace_handling(png_ptr);
|
|
|
|
|
2011-10-19 02:04:34 -07:00
|
|
|
/* we read image line by line if scale down was set */
|
|
|
|
if (scale_ratio == 1)
|
|
|
|
{
|
2014-04-15 01:56:07 -07:00
|
|
|
for (p = 0; p < passes; p++)
|
|
|
|
{
|
|
|
|
for (i = 0; i < h; i++)
|
|
|
|
png_read_row(png_ptr, surface + (i * w * pack_offset), NULL);
|
|
|
|
}
|
2011-10-19 02:04:34 -07:00
|
|
|
png_read_end(png_ptr, info_ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-03-18 20:20:07 -07:00
|
|
|
unsigned char *src_ptr, *dst_ptr;
|
|
|
|
|
|
|
|
dst_ptr = surface;
|
2014-04-15 01:56:07 -07:00
|
|
|
if (passes == 1)
|
2011-10-19 02:04:34 -07:00
|
|
|
{
|
2014-04-15 01:56:07 -07:00
|
|
|
tmp_line = (unsigned char *) alloca(image_w * pack_offset);
|
|
|
|
for (i = 0; i < h; i++)
|
2011-10-19 02:04:34 -07:00
|
|
|
{
|
2014-04-15 01:56:07 -07:00
|
|
|
png_read_row(png_ptr, tmp_line, NULL);
|
|
|
|
src_ptr = tmp_line;
|
|
|
|
for (j = 0; j < w; j++)
|
|
|
|
{
|
|
|
|
for (k = 0; k < (int)pack_offset; k++)
|
|
|
|
dst_ptr[k] = src_ptr[k];
|
|
|
|
dst_ptr += pack_offset;
|
|
|
|
src_ptr += scale_ratio * pack_offset;
|
|
|
|
}
|
|
|
|
for (j = 0; j < (scale_ratio - 1); j++)
|
|
|
|
png_read_row(png_ptr, tmp_line, NULL);
|
2011-10-19 02:04:34 -07:00
|
|
|
}
|
2014-04-15 01:56:07 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned char *pixels2 = malloc(image_w * image_h * pack_offset);
|
|
|
|
|
|
|
|
if (pixels2)
|
2011-10-19 02:04:34 -07:00
|
|
|
{
|
2014-04-15 01:56:07 -07:00
|
|
|
for (p = 0; p < passes; p++)
|
|
|
|
{
|
|
|
|
for (i = 0; i < image_h; i++)
|
|
|
|
png_read_row(png_ptr, pixels2 + (i * image_w * pack_offset), NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < h; i++)
|
|
|
|
{
|
|
|
|
src_ptr = pixels2 + (i * scale_ratio * image_w * pack_offset);
|
|
|
|
for (j = 0; j < w; j++)
|
|
|
|
{
|
|
|
|
for (k = 0; k < (int)pack_offset; k++)
|
|
|
|
dst_ptr[k] = src_ptr[k];
|
|
|
|
src_ptr += scale_ratio * pack_offset;
|
|
|
|
dst_ptr += pack_offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(pixels2);
|
2011-10-19 02:04:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-02 01:17:42 -07:00
|
|
|
prop->premul = EINA_TRUE;
|
2008-04-11 17:32:30 -07:00
|
|
|
|
2009-12-22 15:11:57 -08:00
|
|
|
*error = EVAS_LOAD_ERROR_NONE;
|
2013-01-02 23:57:18 -08:00
|
|
|
r = EINA_TRUE;
|
2008-11-09 11:32:12 -08:00
|
|
|
|
|
|
|
close_file:
|
2013-01-02 23:57:18 -08:00
|
|
|
if (png_ptr) png_destroy_read_struct(&png_ptr,
|
|
|
|
info_ptr ? &info_ptr : NULL,
|
|
|
|
NULL);
|
|
|
|
if (epi.map) eina_file_map_free(f, epi.map);
|
|
|
|
return r;
|
2006-01-14 12:03:42 -08:00
|
|
|
}
|
|
|
|
|
2013-05-02 01:17:42 -07:00
|
|
|
static Evas_Image_Load_Func evas_image_load_png_func =
|
|
|
|
{
|
2013-05-06 03:01:35 -07:00
|
|
|
evas_image_load_file_open_png,
|
|
|
|
evas_image_load_file_close_png,
|
2013-05-02 01:17:42 -07:00
|
|
|
evas_image_load_file_head_png,
|
|
|
|
evas_image_load_file_data_png,
|
|
|
|
NULL,
|
2013-05-06 18:50:57 -07:00
|
|
|
EINA_TRUE,
|
2013-05-02 01:17:42 -07:00
|
|
|
EINA_FALSE
|
|
|
|
};
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static int
|
2006-09-06 00:28:46 -07:00
|
|
|
module_open(Evas_Module *em)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
if (!em) return 0;
|
|
|
|
em->functions = (void *)(&evas_image_load_png_func);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static void
|
2012-11-04 03:51:42 -08:00
|
|
|
module_close(Evas_Module *em EINA_UNUSED)
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static Evas_Module_Api evas_modapi =
|
2006-01-14 12:03:42 -08:00
|
|
|
{
|
|
|
|
EVAS_MODULE_API_VERSION,
|
2009-06-16 06:01:36 -07:00
|
|
|
"png",
|
|
|
|
"none",
|
|
|
|
{
|
|
|
|
module_open,
|
|
|
|
module_close
|
|
|
|
}
|
2006-01-14 12:03:42 -08:00
|
|
|
};
|
2009-06-16 06:01:36 -07:00
|
|
|
|
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, png);
|
|
|
|
|
|
|
|
#ifndef EVAS_STATIC_BUILD_PNG
|
|
|
|
EVAS_EINA_MODULE_DEFINE(image_loader, png);
|
|
|
|
#endif
|