efl/src/modules/evas/image_savers/tiff/evas_image_save_tiff.c

141 lines
3.5 KiB
C

#include "evas_common_private.h"
#include "evas_private.h"
#include <tiffio.h>
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