summaryrefslogtreecommitdiff
path: root/src/modules/evas/image_savers
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2016-12-22 16:34:11 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-12-22 17:43:23 +0900
commit3425ad2abda77ef708600d19b3cf6a711b15902b (patch)
tree8c333fbaf951a2c33fa1e9fad57e15f2cc593cbf /src/modules/evas/image_savers
parent5eef9da416801702c43e109adc35b93ece26bf17 (diff)
evas: Implement GRY8/AGRY88 save support for PNG
This enables the PNG saver to save images with gray and alpha + gray colorspaces. GRY8 is usually used for alpha only. Note: This commit also introduces whitespace changes. Sorry about the mess, but at least now we have spaces only. Read the commit with show -w :) @feature
Diffstat (limited to 'src/modules/evas/image_savers')
-rw-r--r--src/modules/evas/image_savers/png/evas_image_save_png.c131
1 files changed, 80 insertions, 51 deletions
diff --git a/src/modules/evas/image_savers/png/evas_image_save_png.c b/src/modules/evas/image_savers/png/evas_image_save_png.c
index e7149be1e7..6eef2fe221 100644
--- a/src/modules/evas/image_savers/png/evas_image_save_png.c
+++ b/src/modules/evas/image_savers/png/evas_image_save_png.c
@@ -26,16 +26,23 @@ save_image_png(RGBA_Image *im, const char *file, int do_compress, int interlace)
26 FILE *f; 26 FILE *f;
27 png_structp png_ptr; 27 png_structp png_ptr;
28 png_infop info_ptr; 28 png_infop info_ptr;
29 DATA32 *ptr, *data = NULL; 29 uint8_t *ptr, *data = NULL;
30 unsigned int x, y, j; 30 unsigned int x, y, j;
31 png_bytep row_ptr; 31 png_bytep row_ptr;
32 volatile png_bytep png_data = NULL; 32 volatile png_bytep png_data = NULL;
33 png_color_8 sig_bit; 33 png_color_8 sig_bit = {};
34 int num_passes = 1, pass; 34 int num_passes = 1, pass;
35 Eina_Bool gry8 = EINA_FALSE, agry88 = EINA_FALSE, free_data = EINA_FALSE;
36 int pixel_size = 4;
35 37
36 if (!im || !im->image.data || !file) 38 if (!im || !im->image.data || !file)
37 return 0; 39 return 0;
38 40
41 if ((im->cache_entry.space != EFL_GFX_COLORSPACE_ARGB8888) &&
42 (im->cache_entry.space != EFL_GFX_COLORSPACE_AGRY88) &&
43 (im->cache_entry.space != EFL_GFX_COLORSPACE_GRY8))
44 return 0;
45
39 f = fopen(file, "wb"); 46 f = fopen(file, "wb");
40 if (!f) return 0; 47 if (!f) return 0;
41 48
@@ -46,61 +53,83 @@ save_image_png(RGBA_Image *im, const char *file, int do_compress, int interlace)
46 info_ptr = png_create_info_struct(png_ptr); 53 info_ptr = png_create_info_struct(png_ptr);
47 if (!info_ptr) 54 if (!info_ptr)
48 { 55 {
49 png_destroy_write_struct(&png_ptr, NULL); 56 png_destroy_write_struct(&png_ptr, NULL);
50 goto close_file; 57 goto close_file;
51 } 58 }
52 if (setjmp(png_jmpbuf(png_ptr))) 59 if (setjmp(png_jmpbuf(png_ptr)))
53 { 60 {
54 png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr); 61 png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
55 png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr); 62 png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
56 goto close_file; 63 goto close_file;
57 } 64 }
58 65
59 if (interlace) 66 if (interlace)
60 { 67 {
61#ifdef PNG_WRITE_INTERLACING_SUPPORTED 68#ifdef PNG_WRITE_INTERLACING_SUPPORTED
62 interlace = PNG_INTERLACE_ADAM7; 69 interlace = PNG_INTERLACE_ADAM7;
63#else 70#else
64 interlace = PNG_INTERLACE_NONE; 71 interlace = PNG_INTERLACE_NONE;
65#endif 72#endif
66 } 73 }
67 else 74 else
68 interlace = PNG_INTERLACE_NONE; 75 interlace = PNG_INTERLACE_NONE;
69 76
70 if (im->cache_entry.flags.alpha) 77 if (im->cache_entry.space == EFL_GFX_COLORSPACE_GRY8)
78 {
79 gry8 = EINA_TRUE;
80 pixel_size = 1;
81 data = im->image.data8;
82 png_init_io(png_ptr, f);
83 png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8,
84 PNG_COLOR_TYPE_GRAY, interlace,
85 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
86 }
87 else if (im->cache_entry.space == EFL_GFX_COLORSPACE_AGRY88)
71 { 88 {
72 data = malloc(im->cache_entry.w * im->cache_entry.h * sizeof(DATA32)); 89 agry88 = EINA_TRUE;
73 if (!data) 90 pixel_size = 2;
74 { 91 data = im->image.data8;
75 png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr); 92 png_init_io(png_ptr, f);
76 png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
77 goto close_file;
78 }
79 memcpy(data, im->image.data, im->cache_entry.w * im->cache_entry.h * sizeof(DATA32));
80 evas_common_convert_argb_unpremul(data, im->cache_entry.w * im->cache_entry.h);
81 png_init_io(png_ptr, f);
82 png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8, 93 png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8,
83 PNG_COLOR_TYPE_RGB_ALPHA, interlace, 94 PNG_COLOR_TYPE_GRAY_ALPHA, interlace,
84 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 95 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
96 }
97 else if (im->cache_entry.flags.alpha)
98 {
99 data = malloc(im->cache_entry.w * im->cache_entry.h * sizeof(DATA32));
100 if (!data)
101 {
102 png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
103 png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
104 goto close_file;
105 }
106 free_data = EINA_TRUE;
107 memcpy(data, im->image.data, im->cache_entry.w * im->cache_entry.h * sizeof(DATA32));
108 evas_common_convert_argb_unpremul((DATA32 *) data, im->cache_entry.w * im->cache_entry.h);
109 png_init_io(png_ptr, f);
110 png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8,
111 PNG_COLOR_TYPE_RGB_ALPHA, interlace,
112 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
85#ifdef WORDS_BIGENDIAN 113#ifdef WORDS_BIGENDIAN
86 png_set_swap_alpha(png_ptr); 114 png_set_swap_alpha(png_ptr);
87#else 115#else
88 png_set_bgr(png_ptr); 116 png_set_bgr(png_ptr);
89#endif 117#endif
90 } 118 }
91 else 119 else
92 { 120 {
93 data = im->image.data; 121 data = im->image.data8;
94 png_init_io(png_ptr, f); 122 png_init_io(png_ptr, f);
95 png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8, 123 png_set_IHDR(png_ptr, info_ptr, im->cache_entry.w, im->cache_entry.h, 8,
96 PNG_COLOR_TYPE_RGB, interlace, 124 PNG_COLOR_TYPE_RGB, interlace,
97 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 125 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
98 png_data = alloca(im->cache_entry.w * 3 * sizeof(char)); 126 png_data = alloca(im->cache_entry.w * 3 * sizeof(char));
99 } 127 }
100 sig_bit.red = 8; 128 sig_bit.red = 8;
101 sig_bit.green = 8; 129 sig_bit.green = 8;
102 sig_bit.blue = 8; 130 sig_bit.blue = 8;
103 sig_bit.alpha = 8; 131 sig_bit.alpha = 8;
132 sig_bit.gray = 8;
104 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 133 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
105 134
106 png_set_compression_level(png_ptr, do_compress); 135 png_set_compression_level(png_ptr, do_compress);
@@ -114,32 +143,32 @@ save_image_png(RGBA_Image *im, const char *file, int do_compress, int interlace)
114 143
115 for (pass = 0; pass < num_passes; pass++) 144 for (pass = 0; pass < num_passes; pass++)
116 { 145 {
117 ptr = data; 146 ptr = data;
118 147
119 for (y = 0; y < im->cache_entry.h; y++) 148 for (y = 0; y < im->cache_entry.h; y++)
120 { 149 {
121 if (im->cache_entry.flags.alpha) 150 if (gry8 || agry88 || im->cache_entry.flags.alpha)
122 row_ptr = (png_bytep) ptr; 151 row_ptr = (png_bytep) ptr;
123 else 152 else
124 { 153 {
125 for (j = 0, x = 0; x < im->cache_entry.w; x++) 154 DATA32 *ptr32 = (DATA32 *) ptr;
126 { 155 for (j = 0, x = 0; x < im->cache_entry.w; x++)
127 png_data[j++] = (ptr[x] >> 16) & 0xff; 156 {
128 png_data[j++] = (ptr[x] >> 8) & 0xff; 157 png_data[j++] = (ptr32[x] >> 16) & 0xff;
129 png_data[j++] = (ptr[x]) & 0xff; 158 png_data[j++] = (ptr32[x] >> 8) & 0xff;
130 } 159 png_data[j++] = (ptr32[x]) & 0xff;
131 row_ptr = (png_bytep) png_data; 160 }
132 } 161 row_ptr = (png_bytep) png_data;
133 png_write_rows(png_ptr, &row_ptr, 1); 162 }
134 ptr += im->cache_entry.w; 163 png_write_rows(png_ptr, &row_ptr, 1);
135 } 164 ptr += im->cache_entry.w * pixel_size;
165 }
136 } 166 }
137 png_write_end(png_ptr, info_ptr); 167 png_write_end(png_ptr, info_ptr);
138 png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr); 168 png_destroy_write_struct(&png_ptr, (png_infopp) & info_ptr);
139 png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr); 169 png_destroy_info_struct(png_ptr, (png_infopp) & info_ptr);
140 170
141 if (im->cache_entry.flags.alpha) 171 if (free_data) free(data);
142 free(data);
143 fclose(f); 172 fclose(f);
144 return 1; 173 return 1;
145 174