1 /*
2  #
3  #  File        : gmic_libc.cpp
4  #                ( C++ source file )
5  #
6  #  Description : GREYC's Magic for Image Computing - C bridge to the libgmic
7  #                ( http://gmic.eu )
8  #
9  #  Copyright   : Tobias Fleischer
10  #                ( https://plus.google.com/u/0/b/117441237982283011318/+TobiasFleischer )
11  #
12  #  License     : CeCILL-B v1.0
13  #                ( http://cecill.info/licences/Licence_CeCILL-B_V1-en.html )
14  #
15  #  This software is governed either by the CeCILL-B license
16  #  under French law and abiding by the rules of distribution of free software.
17  #  You can  use, modify and or redistribute the software under the terms of
18  #  the CeCILL-B licenses as circulated by CEA, CNRS and INRIA
19  #  at the following URL: "http://cecill.info".
20  #
21  #  As a counterpart to the access to the source code and  rights to copy,
22  #  modify and redistribute granted by the license, users are provided only
23  #  with a limited warranty  and the software's author,  the holder of the
24  #  economic rights,  and the successive licensors  have only  limited
25  #  liability.
26  #
27  #  In this respect, the user's attention is drawn to the risks associated
28  #  with loading,  using,  modifying and/or developing or reproducing the
29  #  software by the user in light of its specific status of free software,
30  #  that may mean  that it is complicated to manipulate,  and  that  also
31  #  therefore means  that it is reserved for developers  and  experienced
32  #  professionals having in-depth computer knowledge. Users are therefore
33  #  encouraged to load and test the software's suitability as regards their
34  #  requirements in conditions enabling the security of their systems and/or
35  #  data to be ensured and,  more generally, to use and operate it in the
36  #  same conditions as regards security.
37  #
38  #  The fact that you are presently reading this means that you have had
39  #  knowledge of the CeCILL-B licenses and that you accept its terms.
40  #
41 */
42 
43 #include "gmic_libc.h"
44 #include "gmic.h"
45 
gmic_delete_external(float * p)46 GMIC_DLLINTERFACE int GMIC_CALLCONV gmic_delete_external(float* p) {
47   delete[] p;
48   return 0;
49 }
50 
gmic_call(const char * _cmd,unsigned int * _nofImages,gmic_interface_image * _images,gmic_interface_options * _options)51 GMIC_DLLINTERFACE int GMIC_CALLCONV gmic_call(const char* _cmd, unsigned int* _nofImages,
52                                               gmic_interface_image* _images, gmic_interface_options* _options) {
53   int err = 0;
54   bool no_inplace = _options?_options->no_inplace_processing:false;
55   int nofImages = 0;
56   if (_nofImages && _images) nofImages = *_nofImages;
57   gmic_list<float> images;
58   gmic_list<char> images_names;
59   images.assign(nofImages);
60   images_names.assign(nofImages);
61 
62   for (unsigned int i = 0; i < images._width; ++i) {
63     gmic_image<float>& img = images[i];
64     if (_images[i].format == E_FORMAT_BYTE) {
65       gmic_image<unsigned char> img_tmp;
66       if (_images[i].is_interleaved) {
67         img_tmp.assign((unsigned char*)_images[i].data, _images[i].spectrum, _images[i].width,
68                        _images[i].height, _images[i].depth, true);
69         img_tmp.permute_axes("YZCX");
70       } else {
71         img_tmp.assign((unsigned char*)_images[i].data, _images[i].width, _images[i].height,
72                        _images[i].depth, _images[i].spectrum, true);
73       }
74       img = img_tmp;
75     } else {
76       if (no_inplace) {
77         gmic_image<float> img_tmp;
78         if (_images[i].is_interleaved) {
79           img_tmp.assign((float*)_images[i].data, _images[i].spectrum, _images[i].width,
80                          _images[i].height, _images[i].depth, true);
81           img_tmp.permute_axes("YZCX");
82         } else {
83           img_tmp.assign((float*)_images[i].data, _images[i].width, _images[i].height,
84                          _images[i].depth, _images[i].spectrum, true);
85         }
86         img = img_tmp;
87       } else {
88         if (_images[i].is_interleaved) {
89           img.assign((float*)_images[i].data, _images[i].spectrum, _images[i].width,
90                      _images[i].height, _images[i].depth, true);
91           img.permute_axes("YZCX");
92         } else {
93           img.assign((float*)_images[i].data, _images[i].width, _images[i].height,
94                      _images[i].depth, _images[i].spectrum, true);
95         }
96       }
97     }
98     images_names[i].assign(std::strlen(_images[i].name) + 1);
99     std::strcpy(images_names[i], _images[i].name);
100   }
101 
102   try {
103     if (_options)
104       gmic(_cmd, images, images_names, _options->custom_commands, !_options->ignore_stdlib,
105            _options->p_progress, _options->p_is_abort);
106     else
107       gmic(_cmd, images, images_names);
108 
109   } catch (gmic_exception &e) { // catch exception, if an error occurred in the interpreter.
110     std::string error_string = e.what();
111     std::fprintf(stderr, "\n- Error encountered when calling G'MIC : '%s'\n", e.what());
112     if (_options && _options->error_message_buffer) {
113       std::strcpy(_options->error_message_buffer, error_string.substr(0, 255).c_str());
114     }
115     err = -1;
116   }
117 
118   if (_nofImages && _images && err == 0) {
119     *_nofImages = images._width;
120     for (unsigned int i = 0; i < images._width; ++i) {
121       gmic_image<float>& img = images[i];
122       if (_options && _options->interleave_output) {
123         img.permute_axes("CXYZ");
124 		    _images[i].is_interleaved = true;
125         _images[i].width = img._height;
126         _images[i].height = img._depth;
127         _images[i].depth = img._spectrum;
128         _images[i].spectrum = img._width;
129       } else {
130 		    _images[i].is_interleaved = false;
131         _images[i].width = img._width;
132         _images[i].height = img._height;
133         _images[i].depth = img._depth;
134         _images[i].spectrum = img._spectrum;
135 	  }
136       if (_options && _options->output_format == E_FORMAT_BYTE) {
137         gmic_image<unsigned char> img_tmp;
138         img_tmp = img;
139         _images[i].format = E_FORMAT_BYTE;
140         _images[i].data = img_tmp._data;
141         img_tmp._is_shared = true;
142         img._is_shared = false;
143       } else {
144         _images[i].format = E_FORMAT_FLOAT;
145         _images[i].data = img._data;
146         img._is_shared = true;
147       }
148       std::strcpy(_images[i].name, images_names[i]);
149     }
150   }
151   images.assign(0U);
152   images_names.assign(0U);
153   return err;
154 }
155 
gmic_get_stdlib()156 GMIC_DLLINTERFACE const char* GMIC_CALLCONV gmic_get_stdlib() {
157   gmic_image<char> lib = gmic::decompress_stdlib();
158   lib._is_shared = true;
159   return lib.data();
160 }
161