2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2006-10-27 20:02:23 -07:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif
|
|
|
|
|
2008-11-09 11:32:12 -08:00
|
|
|
#include <stdio.h>
|
2006-01-15 02:35:02 -08:00
|
|
|
#include <png.h>
|
|
|
|
#include <setjmp.h>
|
|
|
|
|
2008-11-05 09:21:04 -08:00
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2008-11-09 11:32:12 -08:00
|
|
|
#ifdef _WIN32_WCE
|
|
|
|
# define E_FOPEN(file, mode) evil_fopen_native((file), (mode))
|
|
|
|
# define E_FCLOSE(stream) evil_fclose_native(stream)
|
|
|
|
#else
|
|
|
|
# define E_FOPEN(file, mode) fopen((file), (mode))
|
|
|
|
# define E_FCLOSE(stream) fclose(stream)
|
|
|
|
#endif
|
|
|
|
|
2006-01-15 02:35:02 -08:00
|
|
|
#include "evas_common.h"
|
|
|
|
#include "evas_private.h"
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static int evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
|
2006-01-15 02:35:02 -08:00
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static Evas_Image_Save_Func evas_image_save_png_func =
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
|
|
|
evas_image_save_file_png
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
|
|
|
save_image_png(RGBA_Image *im, const char *file, int compress, int interlace)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
png_structp png_ptr;
|
|
|
|
png_infop info_ptr;
|
2006-10-01 22:19:39 -07:00
|
|
|
DATA32 *ptr, *data = NULL;
|
2006-01-15 02:35:02 -08:00
|
|
|
int x, y, j;
|
2006-09-30 03:21:23 -07:00
|
|
|
png_bytep row_ptr, png_data = NULL;
|
2006-01-15 02:35:02 -08:00
|
|
|
png_color_8 sig_bit;
|
2006-04-10 00:27:54 -07:00
|
|
|
int num_passes = 1, pass;
|
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
if (!im || !im->image.data || !file)
|
2006-04-10 00:27:54 -07:00
|
|
|
return 0;
|
2008-11-09 11:32:12 -08:00
|
|
|
|
|
|
|
f = E_FOPEN(file, "wb");
|
2006-01-15 02:35:02 -08:00
|
|
|
if (!f) return 0;
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2006-01-15 02:35:02 -08:00
|
|
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
|
|
|
if (!png_ptr)
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
|
|
|
|
2006-01-15 02:35:02 -08:00
|
|
|
info_ptr = png_create_info_struct(png_ptr);
|
2010-08-21 06:52:25 -07:00
|
|
|
if (!info_ptr)
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
2008-11-09 11:32:12 -08:00
|
|
|
png_destroy_write_struct(&png_ptr, NULL);
|
|
|
|
goto close_file;
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
2008-11-06 10:54:19 -08:00
|
|
|
if (setjmp(png_jmpbuf(png_ptr)))
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
|
|
|
png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
|
|
|
|
png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2006-01-15 02:35:02 -08:00
|
|
|
if (interlace)
|
|
|
|
{
|
|
|
|
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
|
|
|
|
png_ptr->interlaced = PNG_INTERLACE_ADAM7;
|
|
|
|
num_passes = png_set_interlace_handling(png_ptr);
|
|
|
|
#endif
|
|
|
|
}
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (im->cache_entry.flags.alpha)
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
data = malloc(im->cache_entry.w * im->cache_entry.h * sizeof(DATA32));
|
2006-09-30 03:21:23 -07:00
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
|
|
|
|
png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
|
2008-11-09 11:32:12 -08:00
|
|
|
goto close_file;
|
2006-09-30 03:21:23 -07:00
|
|
|
}
|
2008-04-11 17:32:30 -07:00
|
|
|
memcpy(data, im->image.data, im->cache_entry.w * im->cache_entry.h * sizeof(DATA32));
|
|
|
|
evas_common_convert_argb_unpremul(data, im->cache_entry.w * im->cache_entry.h);
|
2006-09-30 03:21:23 -07:00
|
|
|
png_init_io(png_ptr, f);
|
2008-04-11 17:32:30 -07:00
|
|
|
png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8,
|
2006-01-15 02:35:02 -08:00
|
|
|
PNG_COLOR_TYPE_RGB_ALPHA, png_ptr->interlaced,
|
|
|
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
png_set_swap_alpha(png_ptr);
|
|
|
|
#else
|
|
|
|
png_set_bgr(png_ptr);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
data = im->image.data;
|
2006-09-30 03:21:23 -07:00
|
|
|
png_init_io(png_ptr, f);
|
2008-04-11 17:32:30 -07:00
|
|
|
png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8,
|
2006-01-15 02:35:02 -08:00
|
|
|
PNG_COLOR_TYPE_RGB, png_ptr->interlaced,
|
|
|
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
2008-04-11 17:32:30 -07:00
|
|
|
png_data = alloca(im->cache_entry.w * 3 * sizeof(char));
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
|
|
|
sig_bit.red = 8;
|
|
|
|
sig_bit.green = 8;
|
|
|
|
sig_bit.blue = 8;
|
|
|
|
sig_bit.alpha = 8;
|
|
|
|
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2006-01-15 02:35:02 -08:00
|
|
|
png_set_compression_level(png_ptr, compress);
|
|
|
|
png_write_info(png_ptr, info_ptr);
|
|
|
|
png_set_shift(png_ptr, &sig_bit);
|
|
|
|
png_set_packing(png_ptr);
|
|
|
|
|
|
|
|
for (pass = 0; pass < num_passes; pass++)
|
|
|
|
{
|
2006-09-30 03:21:23 -07:00
|
|
|
ptr = data;
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2008-04-11 17:32:30 -07:00
|
|
|
for (y = 0; y < im->cache_entry.h; y++)
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
2008-06-03 02:09:39 -07:00
|
|
|
if (im->cache_entry.flags.alpha)
|
2006-01-15 02:35:02 -08:00
|
|
|
row_ptr = (png_bytep) ptr;
|
|
|
|
else
|
|
|
|
{
|
2008-04-11 17:32:30 -07:00
|
|
|
for (j = 0, x = 0; x < im->cache_entry.w; x++)
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
2006-09-30 03:21:23 -07:00
|
|
|
png_data[j++] = (ptr[x] >> 16) & 0xff;
|
|
|
|
png_data[j++] = (ptr[x] >> 8) & 0xff;
|
|
|
|
png_data[j++] = (ptr[x]) & 0xff;
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
2006-09-30 03:21:23 -07:00
|
|
|
row_ptr = (png_bytep) png_data;
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
|
|
|
png_write_rows(png_ptr, &row_ptr, 1);
|
2008-04-11 17:32:30 -07:00
|
|
|
ptr += im->cache_entry.w;
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
png_write_end(png_ptr, info_ptr);
|
|
|
|
png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
|
|
|
|
png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
|
2008-11-09 11:32:12 -08:00
|
|
|
|
2008-06-03 02:09:39 -07:00
|
|
|
if (im->cache_entry.flags.alpha)
|
2006-10-01 22:19:39 -07:00
|
|
|
free(data);
|
2008-11-09 11:32:12 -08:00
|
|
|
E_FCLOSE(f);
|
2006-01-15 02:35:02 -08:00
|
|
|
return 1;
|
2008-11-09 11:32:12 -08:00
|
|
|
|
|
|
|
close_file:
|
|
|
|
E_FCLOSE(f);
|
|
|
|
return 0;
|
2006-01-15 02:35:02 -08:00
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static int evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key __UNUSED__, int quality __UNUSED__, int compress)
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
|
|
|
return save_image_png(im, file, compress, 0);
|
|
|
|
}
|
|
|
|
|
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-15 02:35:02 -08:00
|
|
|
{
|
|
|
|
if (!em) return 0;
|
|
|
|
em->functions = (void *)(&evas_image_save_png_func);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static void
|
cleanup: fix some "unused" errors from -Wextra.
As we're heading for a release we better remove as much errors as
possible and as the first step I'm removing warnings due unused
parameters, variables and functions. These tend to pollute real errors
spotted by -Wall and clang/llvm.
This does not fixes all, just the clear that could be set to
__UNUSED__, particularly to do (and I'd like some help from the
authors):
* src/lib/engines/common/evas_font_{draw,query}.c (tasn):
intl_props is just used while doing BIDI, but also used in other
#ifdef blocks :-/
* evas_map_* (raster):
huge amount of warnings, code is quite confusing and thus I'm not
touching it. I have no idea whenever the commented blocks or extra
parameters are intended to be used or no.
* src/modules/engines/fbevas_fb_main.c (raster?):
is fb_setvt() to be used? If not do you mind removing it?
* src/modules/engines/gl_{common,x11} (raster):
huge amount of warnings, code is quite nested and full of #ifdefs
that does not help to give a clear picture of what's going on.
* src/bin/evas_cserve_main.c (raster):
I could have ignored most of the errors, but is the code correct? I
mean, there is no unload of images being applied. If you confirm
none of those warnings are harmful I can flag them as unused.
* src/lib/engines/common_8 (dottedmag):
lots of unused functions that were acquired from common_16, they
are unused and if they will not, then they should be removed.
SVN revision: 52421
2010-09-18 12:17:41 -07:00
|
|
|
module_close(Evas_Module *em __UNUSED__)
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-06-16 06:01:36 -07:00
|
|
|
static Evas_Module_Api evas_modapi =
|
2006-01-15 02:35:02 -08:00
|
|
|
{
|
|
|
|
EVAS_MODULE_API_VERSION,
|
2009-06-16 06:01:36 -07:00
|
|
|
"png",
|
|
|
|
"none",
|
|
|
|
{
|
|
|
|
module_open,
|
|
|
|
module_close
|
|
|
|
}
|
2006-01-15 02:35:02 -08:00
|
|
|
};
|
2009-06-16 06:01:36 -07:00
|
|
|
|
|
|
|
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, png);
|
|
|
|
|
|
|
|
#ifndef EVAS_STATIC_BUILD_PNG
|
|
|
|
EVAS_EINA_MODULE_DEFINE(image_saver, png);
|
|
|
|
#endif
|
|
|
|
|