#include "evas_common_private.h" #include "evas_private.h" #include static int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key, int quality, int compress, const char *encoding); static Evas_Image_Save_Func evas_image_save_tiff_func = { evas_image_save_file_tiff }; static int save_image_tiff(RGBA_Image *im, const char *file, int compress EINA_UNUSED, int interlace EINA_UNUSED) { TIFF *tif = NULL; uint8 *buf = NULL; DATA32 pixel; DATA32 *data; uint32 x, y; uint8 r, g, b, a = 0; int i = 0; int has_alpha; if (!im || !im->image.data || !file) return 0; has_alpha = im->cache_entry.flags.alpha; data = im->image.data; tif = TIFFOpen(file, "w"); if (!tif) return 0; /* None of the TIFFSetFields are checked for errors, but since they */ /* shouldn't fail, this shouldn't be a problem */ TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->cache_entry.h); TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->cache_entry.w); TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE); /* By default uses patent-free use COMPRESSION_DEFLATE, * another lossless compression technique */ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); if (has_alpha) { uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA }; TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4); TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, extras); } else { TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3); } TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0)); buf = (uint8 *) _TIFFmalloc(TIFFScanlineSize(tif)); if (!buf) { TIFFClose(tif); return 0; } for (y = 0; y < im->cache_entry.h; y++) { i = 0; for (x = 0; x < im->cache_entry.w; x++) { pixel = data[(y * im->cache_entry.w) + x]; r = (pixel >> 16) & 0xff; g = (pixel >> 8) & 0xff; b = pixel & 0xff; if (has_alpha) a = (pixel >> 24) & 0xff; /* This might be endian dependent */ buf[i++] = r; buf[i++] = g; buf[i++] = b; if (has_alpha) buf[i++] = a; } if (!TIFFWriteScanline(tif, buf, y, 0)) { _TIFFfree(buf); TIFFClose(tif); return 0; } } _TIFFfree(buf); TIFFClose(tif); return 1; } static int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key EINA_UNUSED, int quality EINA_UNUSED, int compress, const char *encoding EINA_UNUSED) { return save_image_tiff(im, file, compress, 0); } static int module_open(Evas_Module *em) { if (!em) return 0; em->functions = (void *)(&evas_image_save_tiff_func); return 1; } static void module_close(Evas_Module *em EINA_UNUSED) { } static Evas_Module_Api evas_modapi = { EVAS_MODULE_API_VERSION, "tiff", "none", { module_open, module_close } }; EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, tiff); #ifndef EVAS_STATIC_BUILD_TIFF EVAS_EINA_MODULE_DEFINE(image_saver, tiff); #endif