move around - flatter.
[profile/ivi/evas.git] / src / modules / savers / tiff / evas_image_save_tiff.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3
4 #include <tiffio.h>
5
6 int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key, int quality, int compress);
7
8 Evas_Image_Save_Func evas_image_save_tiff_func =
9 {
10    evas_image_save_file_tiff
11 };
12
13 static int
14 save_image_tiff(RGBA_Image *im, const char *file, int compress, int interlace)
15 {
16    TIFF               *tif = NULL;
17    uint8              *buf = NULL;
18    DATA32              pixel;
19    DATA32             *data;
20    uint32              x, y;
21    uint8               r, g, b, a = 0;
22    int                 i = 0;
23    int                 has_alpha;
24
25    if (!im || !im->image.data || !file)
26       return 0;
27
28    has_alpha = im->cache_entry.flags.alpha;
29    data = im->image.data;
30
31    tif = TIFFOpen(file, "w");
32    if (!tif)
33       return 0;
34
35    /* None of the TIFFSetFields are checked for errors, but since they */
36    /* shouldn't fail, this shouldn't be a problem */
37
38    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->cache_entry.h);
39    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->cache_entry.w);
40    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
41    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
42    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
43    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
44
45    /* By default uses patent-free use COMPRESSION_DEFLATE,
46     * another lossless compression technique */
47    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
48    
49    if (has_alpha)
50      {
51         uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA };
52         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
53         TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, extras);
54      }
55    else
56      {
57         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
58      }
59
60    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
61    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, 0));
62
63    buf = (uint8 *) _TIFFmalloc(TIFFScanlineSize(tif));
64    if (!buf)
65      {
66         TIFFClose(tif);
67         return 0;
68      }
69
70    for (y = 0; y < im->cache_entry.h; y++)
71      {
72         i = 0;
73         for (x = 0; x < im->cache_entry.w; x++)
74           {
75              pixel = data[(y * im->cache_entry.w) + x];
76
77              r = (pixel >> 16) & 0xff;
78              g = (pixel >> 8) & 0xff;
79              b = pixel & 0xff;
80              if (has_alpha)
81                 a = (pixel >> 24) & 0xff;
82
83              /* This might be endian dependent */
84              buf[i++] = r;
85              buf[i++] = g;
86              buf[i++] = b;
87              if (has_alpha)
88                 buf[i++] = a;
89           }
90
91         if (!TIFFWriteScanline(tif, buf, y, 0))
92           {
93              _TIFFfree(buf);
94              TIFFClose(tif);
95              return 0;
96           }
97      }
98
99    _TIFFfree(buf);
100    TIFFClose(tif);
101
102    return 1;
103 }
104
105 int evas_image_save_file_tiff(RGBA_Image *im, const char *file, const char *key, int quality, int compress)
106 {
107    return save_image_tiff(im, file, compress, 0);
108 }
109
110 EAPI int
111 module_open(Evas_Module *em)
112 {
113    if (!em) return 0;
114    em->functions = (void *)(&evas_image_save_tiff_func);
115    return 1;
116 }
117
118 EAPI void
119 module_close(void)
120 {
121    
122 }
123
124 EAPI Evas_Module_Api evas_modapi =
125 {
126    EVAS_MODULE_API_VERSION,
127      EVAS_MODULE_TYPE_IMAGE_SAVER,
128      "tiff",
129      "none"
130 };