1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #include <Eina.h>
6 #include <Evas.h>
7 #include <Ecore.h>
8 #include <Ecore_Getopt.h>
9 #include <Ecore_Evas.h>
10
11 #if defined(_WIN32)
12 # define NO_SIGNAL
13 #else
14 # include <signal.h>
15 #endif
16
17 #undef EINA_LOG_DOMAIN_DEFAULT
18 #define EINA_LOG_DOMAIN_DEFAULT _log_dom
19 static int _log_dom = -1;
20
21 const Ecore_Getopt optdesc = {
22 "ecore_evas_convert",
23 "%prog [options] <filename-source> <filename-destination>",
24 PACKAGE_VERSION,
25 "(C) 2014 Enlightenment",
26 "BSD with advertisement clause",
27 "Simple application to convert image.",
28 0,
29 {
30 ECORE_GETOPT_STORE_INT('q', "quality", "define encoding quality in percent."),
31 ECORE_GETOPT_STORE_TRUE('c', "compress", "define if data should be compressed."),
32 ECORE_GETOPT_STORE_STR('e', "encoding", "define the codec (for TGV files: 'etc1', 'etc2', 'etc1+alpha')"),
33 ECORE_GETOPT_STORE_STR('m', "max-geometry", "define the max size in pixels (WidthxHeight) of any converted image, splitting the image as necessary in a grid pattern ('_XxY' will be appended to the file name)"),
34 ECORE_GETOPT_LICENSE('L', "license"),
35 ECORE_GETOPT_COPYRIGHT('C', "copyright"),
36 ECORE_GETOPT_VERSION('V', "version"),
37 ECORE_GETOPT_HELP('h', "help"),
38 ECORE_GETOPT_SENTINEL
39 }
40 };
41
42 typedef struct _Save_Job {
43 const char *output;
44 const char *extension;
45 const char *flags;
46 Evas_Object *im;
47 int ret;
48 } Save_Job;
49
50 static Save_Job job = { NULL, NULL, NULL, NULL, -1 };
51 static unsigned int width = 0, height = 0;
52 static unsigned int x = 0, y = 0;
53 static int image_w, image_h;
54
55 static void
_save_do(void * data EINA_UNUSED)56 _save_do(void *data EINA_UNUSED)
57 {
58 const char *output = job.output;
59
60 job.ret = 0;
61 if (width && height)
62 {
63 Eina_Slstr *str;
64
65 str = eina_slstr_printf("%s_%ux%u.%s", output, x / width, y / height, job.extension);
66 output = str;
67
68 evas_object_image_load_region_set(job.im, x, y, width, height);
69 x += width;
70
71 if ((int)x > image_w)
72 {
73 y += height;
74 x = 0;
75 }
76
77 }
78
79 fprintf(stderr, "Saving image '%s'\n", output);
80 if (!evas_object_image_save(job.im, output, NULL, job.flags))
81 {
82 EINA_LOG_ERR("Could not convert file to '%s'.", job.output);
83 job.ret = 1;
84 }
85
86 if (!width || ((int)y > image_h)) ecore_main_loop_quit();
87 else ecore_job_add(_save_do, NULL);
88 }
89
90 #ifndef NO_SIGNAL
91 static void
_sigint(int sig EINA_UNUSED)92 _sigint(int sig EINA_UNUSED)
93 {
94 EINA_LOG_ERR("Image save interrupted by SIGINT: '%s'.", job.output);
95 // eina_file_unlink
96 unlink(job.output);
97 exit(-1);
98 }
99 #endif
100
101 int
main(int argc,char * argv[])102 main(int argc, char *argv[])
103 {
104 Ecore_Evas *ee;
105 Evas *e;
106 Evas_Object *im;
107 int arg_index;
108 int quality = -1;
109 int r = -1;
110 char *encoding = NULL;
111 char *maxgeometry = NULL;
112 Eina_Bool compress = 1;
113 Eina_Bool quit_option = EINA_FALSE;
114 Eina_Strbuf *flags = NULL;
115
116 Ecore_Getopt_Value values[] = {
117 ECORE_GETOPT_VALUE_INT(quality),
118 ECORE_GETOPT_VALUE_BOOL(compress),
119 ECORE_GETOPT_VALUE_STR(encoding),
120 ECORE_GETOPT_VALUE_STR(maxgeometry),
121 ECORE_GETOPT_VALUE_BOOL(quit_option),
122 ECORE_GETOPT_VALUE_BOOL(quit_option),
123 ECORE_GETOPT_VALUE_BOOL(quit_option),
124 ECORE_GETOPT_VALUE_BOOL(quit_option),
125 ECORE_GETOPT_VALUE_NONE
126 };
127
128 eina_init();
129 _log_dom = eina_log_domain_register(argv[0], EINA_COLOR_CYAN);
130
131 ecore_init();
132 ecore_evas_init();
133
134 arg_index = ecore_getopt_parse(&optdesc, values, argc, argv);
135 if (quit_option) goto end;
136
137 if (arg_index < 0)
138 {
139 EINA_LOG_ERR("Could not parse argument.");
140 goto end;
141 }
142 if (arg_index + 2 != argc)
143 {
144 EINA_LOG_ERR("File not correctly specified.");
145 goto end;
146 }
147
148 if (maxgeometry)
149 {
150 if (sscanf(maxgeometry, "%ux%u", &width, &height) != 2)
151 {
152 EINA_LOG_ERR("max-geometry should be specified as WidthxHeight, like 1920x1280.");
153 goto end;
154 }
155 if (width == 0 || height == 0)
156 {
157 EINA_LOG_ERR("max-geometry width and height must be greater than 0.");
158 goto end;
159 }
160 }
161
162 ee = ecore_evas_buffer_new(1, 1);
163 e = ecore_evas_get(ee);
164 if (!e)
165 {
166 EINA_LOG_ERR("Impossible to create a canvas to do the conversion.");
167 goto end;
168 }
169
170 flags = eina_strbuf_new();
171 eina_strbuf_append_printf(flags, "compress=%d", compress);
172 if (quality >= 0)
173 eina_strbuf_append_printf(flags, " quality=%d", quality);
174 if (encoding)
175 eina_strbuf_append_printf(flags, " encoding=%s", encoding);
176
177 im = evas_object_image_add(e);
178 evas_object_image_file_set(im, argv[arg_index], NULL);
179
180 if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE)
181 {
182 EINA_LOG_ERR("Could not open '%s'. Error was \"%s\".",
183 argv[arg_index],
184 evas_load_error_str(evas_object_image_load_error_get(im)));
185 goto end;
186 }
187
188 evas_object_image_size_get(im, &image_w, &image_h);
189
190 #ifndef NO_SIGNAL
191 // Brutal way of
192 signal(SIGINT, _sigint);
193 #endif
194
195 // Find the extension and remove it
196 if (width || height)
197 {
198 char *tmp = strrchr(argv[arg_index + 1], '.');
199
200 if (tmp) *tmp = '\0';
201 if (tmp) job.extension = tmp + 1;
202 }
203
204 job.output = argv[arg_index + 1];
205 job.flags = eina_strbuf_string_get(flags);
206 job.im = im;
207 ecore_job_add(_save_do, NULL);
208 ecore_main_loop_begin();
209 r = job.ret;
210
211 end:
212 if (flags) eina_strbuf_free(flags);
213 ecore_evas_shutdown();
214 ecore_shutdown();
215
216 return r;
217 }
218