From a6a2c2f2574b3ae36188695868f3d9f3249ff8c4 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Fri, 11 Nov 2005 07:56:10 +0000 Subject: [PATCH] add the file to cvs SVN revision: 18426 --- .../src/lib/engines/common/evas_image_save.c | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 legacy/evas/src/lib/engines/common/evas_image_save.c diff --git a/legacy/evas/src/lib/engines/common/evas_image_save.c b/legacy/evas/src/lib/engines/common/evas_image_save.c new file mode 100644 index 0000000000..883402a78f --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_image_save.c @@ -0,0 +1,311 @@ +#include "config.h" +#include "evas_options.h" + +#define SWAP32(x) (x) = ((((x) & 0x000000ff ) << 24) | (((x) & 0x0000ff00 ) << 8) | (((x) & 0x00ff0000 ) >> 8) | (((x) & 0xff000000 ) >> 24)) + +#ifdef BUILD_LOADER_PNG +#include +#include +#define PNG_BYTES_TO_CHECK 4 +#endif + +#ifdef BUILD_LOADER_JPEG +#include +#include +#include +#endif + +#ifdef BUILD_LOADER_EET +#include +#endif + +#ifdef BUILD_LOADER_EDB +#include +#include +#endif + +#ifdef BUILD_LOADER_TEMPLATE +#include +#endif + +#include "evas_common.h" +#include "evas_private.h" + +#ifdef BUILD_LOADER_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; + DATA32 *ptr; + int x, y, j; + png_bytep row_ptr, data = NULL; + png_color_8 sig_bit; + int quality = 75, compression = 3, num_passes = 1, pass; + + f = fopen(file, "wb"); + if (!f) return 0; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + { + fclose(f); + return 0; + } + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + { + fclose(f); + png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + return 0; + } + if (setjmp(png_ptr->jmpbuf)) + { + fclose(f); + png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr); + png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr); + return 0; + } + + if (interlace) + { +#ifdef PNG_WRITE_INTERLACING_SUPPORTED + png_ptr->interlaced = PNG_INTERLACE_ADAM7; + num_passes = png_set_interlace_handling(png_ptr); +#endif + } + + png_init_io(png_ptr, f); + + if (im->flags & RGBA_IMAGE_HAS_ALPHA) + { + png_set_IHDR(png_ptr, info_ptr, im->image->w, im->image->h, 8, + 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 + { + png_set_IHDR(png_ptr, info_ptr, im->image->w, im->image->h, 8, + PNG_COLOR_TYPE_RGB, png_ptr->interlaced, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + data = malloc(im->image->w * 3 * sizeof(char)); + if (!data) + { + 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); + fclose(f); + } + } + 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); + + 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++) + { + ptr = im->image->data; + + for (y = 0; y < im->image->h; y++) + { + if (im->flags & RGBA_IMAGE_HAS_ALPHA) + row_ptr = (png_bytep) ptr; + else + { + for (j = 0, x = 0; x < im->image->w; x++) + { + data[j++] = (ptr[x] >> 16) & 0xff; + data[j++] = (ptr[x] >> 8) & 0xff; + data[j++] = (ptr[x]) & 0xff; + } + row_ptr = (png_bytep) data; + } + png_write_rows(png_ptr, &row_ptr, 1); + ptr += im->image->w; + } + } + if (data) free(data); + 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); + + fclose(f); + return 1; +} +#endif + +#ifdef BUILD_LOADER_JPEG +struct _JPEG_error_mgr +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; +typedef struct _JPEG_error_mgr *emptr; + +static void _JPEGFatalErrorHandler(j_common_ptr cinfo); +static void +_JPEGFatalErrorHandler(j_common_ptr cinfo) +{ + emptr errmgr; + + errmgr = (emptr) cinfo->err; + longjmp(errmgr->setjmp_buffer, 1); + return; +} + +static void _JPEGErrorHandler(j_common_ptr cinfo); +static void +_JPEGErrorHandler(j_common_ptr cinfo) +{ + emptr errmgr; + + errmgr = (emptr) cinfo->err; + return; +} + +static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level); +static void +_JPEGErrorHandler2(j_common_ptr cinfo, int msg_level) +{ + emptr errmgr; + + errmgr = (emptr) cinfo->err; + return; + msg_level = 0; +} + +static int +save_image_jpeg(RGBA_Image *im, const char *file, int quality) +{ + struct _JPEG_error_mgr jerr; + struct jpeg_compress_struct cinfo; + FILE *f; + DATA8 *buf; + DATA32 *ptr; + JSAMPROW *jbuf; + int y = 0; + int i, j; + + buf = malloc(im->image->w * 3 * sizeof(DATA8)); + if (!buf) return 0; + f = fopen(file, "wb"); + if (!f) + { + free(buf); + return 0; + } + jerr.pub.error_exit = _JPEGFatalErrorHandler; + jerr.pub.emit_message = _JPEGErrorHandler2; + jerr.pub.output_message = _JPEGErrorHandler; + cinfo.err = jpeg_std_error(&(jerr.pub)); + if (sigsetjmp(jerr.setjmp_buffer, 1)) + { + jpeg_destroy_compress(&cinfo); + free(buf); + fclose(f); + return 0; + } + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, f); + cinfo.image_width = im->image->w; + cinfo.image_height = im->image->h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, quality, TRUE); + jpeg_start_compress(&cinfo, TRUE); + ptr = im->image->data; + while (cinfo.next_scanline < cinfo.image_height) + { + for (j = 0, i = 0; i < im->image->w; i++) + { + buf[j++] = ((*ptr) >> 16) & 0xff; + buf[j++] = ((*ptr) >> 8) & 0xff; + buf[j++] = ((*ptr)) & 0xff; + ptr++; + } + jbuf = (JSAMPROW *) (&buf); + jpeg_write_scanlines(&cinfo, jbuf, 1); + y++; + } + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + free(buf); + fclose(f); + return 1; +} +#endif + +#ifdef BUILD_LOADER_EET +static int +save_image_eet(RGBA_Image *im, const char *file, const char *key, int quality, int compress) +{ + Eet_File *ef; + int alpha = 0, lossy = 0, ok = 0; + + ef = eet_open((char *)file, EET_FILE_MODE_READ_WRITE); + if (!ef) ef = eet_open((char *)file, EET_FILE_MODE_WRITE); + if (!ef) return 0; + if ((quality <= 100) || (compress < 0)) lossy = 1; + if (im->flags & RGBA_IMAGE_HAS_ALPHA) alpha = 1; + ok = eet_data_image_write(ef, (char *)key, im->image->data, + im->image->w, im->image->h, alpha, compress, + quality, lossy); + eet_close(ef); + return ok; +} +#endif + +#ifdef BUILD_LOADER_EDB +static int +save_image_edb(RGBA_Image *im, const char *file, const char *key, int quality, int compress) +{ + return 0; +} +#endif + +#ifdef BUILD_LOADER_TEMPLATE +#endif + +int +evas_common_save_image_to_file(RGBA_Image *im, const char *file, const char *key, int quality, int compress) +{ + char *p; + + p = strrchr(file, '.'); + if (p) + { + p++; + +#ifdef BUILD_LOADER_PNG + if (!strcasecmp(p, "png")) + return save_image_png(im, file, compress, 0); +#endif +#ifdef BUILD_LOADER_JPEG + if ((!strcasecmp(p, "jpg")) || + (!strcasecmp(p, "jpeg")) || + (!strcasecmp(p, "jfif"))) + return save_image_jpeg(im, file, quality); +#endif +#ifdef BUILD_LOADER_EET + if (!strcasecmp(p, "eet")) + return save_image_eet(im, file, key, quality, compress); +#endif +#ifdef BUILD_LOADER_EDB + if (!strcasecmp(p, "edb")) + return save_image_edb(im, file, key, quality, compress); +#endif + } +}