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