forked from enlightenment/efl
141 lines
3.5 KiB
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
|
|
|