cimg.cxx 3.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/plugins/ipl.h ADDED
@@ -0,0 +1,309 @@
1
+ /*
2
+ #
3
+ # File : ipl.h
4
+ # ( C++ header file - CImg plug-in )
5
+ #
6
+ # Description : CImg plug-in providing the CImg->IPL and IPL->CImg
7
+ # conversions for generic image types
8
+ # ( IPL = Intel Performance Library )
9
+ # This file is a part of the CImg Library project.
10
+ # ( http://cimg.eu )
11
+ #
12
+ # Copyright : Hon-Kwok Fung (oldfung@graduate.hku.hk)
13
+ #
14
+ # License : CeCILL v2.0
15
+ # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
16
+ #
17
+ # This software is governed by the CeCILL license under French law and
18
+ # abiding by the rules of distribution of free software. You can use,
19
+ # modify and/ or redistribute the software under the terms of the CeCILL
20
+ # license as circulated by CEA, CNRS and INRIA at the following URL
21
+ # "http://www.cecill.info".
22
+ #
23
+ # As a counterpart to the access to the source code and rights to copy,
24
+ # modify and redistribute granted by the license, users are provided only
25
+ # with a limited warranty and the software's author, the holder of the
26
+ # economic rights, and the successive licensors have only limited
27
+ # liability.
28
+ #
29
+ # In this respect, the user's attention is drawn to the risks associated
30
+ # with loading, using, modifying and/or developing or reproducing the
31
+ # software by the user in light of its specific status of free software,
32
+ # that may mean that it is complicated to manipulate, and that also
33
+ # therefore means that it is reserved for developers and experienced
34
+ # professionals having in-depth computer knowledge. Users are therefore
35
+ # encouraged to load and test the software's suitability as regards their
36
+ # requirements in conditions enabling the security of their systems and/or
37
+ # data to be ensured and, more generally, to use and operate it in the
38
+ # same conditions as regards security.
39
+ #
40
+ # The fact that you are presently reading this means that you have had
41
+ # knowledge of the CeCILL license and that you accept its terms.
42
+ #
43
+ #
44
+ #
45
+ # Usage :
46
+ #
47
+ # In your application code, #define the path of this plugin file as
48
+ # something like
49
+ #
50
+ # #define cimg_plugin1 "../some_directory/ipl.h"
51
+ #
52
+ # You should define such macro before the line #include <CImg.h>. The source
53
+ # code of CImg provides eight slots cimg_plugin1, cimg_plugin2, ...,
54
+ # cimg_plugin8 for insertion of plugins. You may assign a different slot to
55
+ # this plugin if cimg_plugin1 is already occupied.
56
+ #
57
+ # You need also to include prior to CImg.h the following files :
58
+ #
59
+ # #include <cstdlib>
60
+ # #include <typeinfo>
61
+ #
62
+ # To create an IplImage from a CImg instance, you may write:
63
+ #
64
+ # // Given a CImg instance, say, c_img, ...
65
+ # IplImage *img = c_img.get_IplImage(); // (a) copy construction of IplImage
66
+ #
67
+ # CImg supports any number of color channels, while IplImage supports up to 4
68
+ # channels. When the number of channels is 1 or 2, it is hard to tell if these
69
+ # channels have genuine color semantics. Even if the number of channels is 3,
70
+ # CImg and IplImage can have different channel orders (IplImage: usually BGR;
71
+ # CImg: always RGB). The default behaviour of get_IplImage() is to assume that
72
+ # the IplImage instance has a BGR channel order (which is the default order in
73
+ # OpenCV) and swap the channel order in the destination image buffer. That is,
74
+ # the default is to map OpenCV's blue (1st) and red (3rd) channels to CImg's
75
+ # blue (2nd) and red (0th) channel respectively. If the user wants to specify
76
+ # this default option explicitly, he/she can write:
77
+ #
78
+ # IplImage *img = c_img.get_IplImage(CV_CVTIMG_SWAP_RB); // identical to (a)
79
+ #
80
+ # where CV_CVTIMG_SWAP_RB is a flag value defined by OpenCV. If the user wants
81
+ # to keep the channel order unchanged (i.e. maps IplImage's 1st, 2nd, ...
82
+ # channels to CImg's 0th, 1st, ... channels resp.), he/she can use a zero flag
83
+ # value:
84
+ #
85
+ # IplImage *img = c_img.get_IplImage(0);
86
+ #
87
+ # However, when the number of channels is smaller than 3, this option will be
88
+ # ignored and the default behaviour (flag value CV_CVTIMG_SWAP_RB) will be
89
+ # assumed.
90
+ #
91
+ # CImg also differs from IplImage in that the latter represents a 2D image but
92
+ # the former can be a 3D image. If the size of the z-dimension (depth) of the
93
+ # CImg instance is larger than 1, one must choose which slice to copy:
94
+ #
95
+ # IplImage *img1 = c_img.get_IplImage(0, z);
96
+ # IplImage *img2 = c_img.get_IplImage(CV_CVTIMG_SWAP_RB, z);
97
+ #
98
+ # The default z-value is 0.
99
+ #
100
+ # To do conversion in another direction, write something like this:
101
+ #
102
+ # // Suppose img1 and img2 are two pointers to IplImage, where
103
+ # // img1->depth == IPL_DEPTH_8U and img2->depth == IPL_DEPTH_32F.
104
+ # CImg<unsigned char> c_img1(img1); // (b)
105
+ # CImg<unsigned char> c_img1(img1,CV_CVTIMG_SWAP_RB); // identical to (b)
106
+ # CImg<float> c_img2(img2); // (c)
107
+ # CImg<float> c_img2(img2,CV_CVTIMG_SWAP_RB); // identical to (c)
108
+ #
109
+ # Again, if one wants to keep the channel order unchanged when the number of
110
+ # channels is >= 3, one can write:
111
+ #
112
+ # CImg<unsigned char> c_img1(img1,0);
113
+ # CImg<float> c_img2(img2,0);
114
+ #
115
+ # All such conversions are deep copy constructions, because CImg and IplImage
116
+ # have different internal memory layouts.
117
+ #
118
+ # Technically, we can write code to do conversion between an IplImage instance
119
+ # and a CImg instance with different pixel types (e.g. between an IPL_DEPTH_8S
120
+ # IplImage instance and a CImg<unsigned char> instance), but such conversion is
121
+ # problematic because either the semantics of the pixel type is lost or some
122
+ # casting is needed. Therefore, the conversion code in this plugin only allows
123
+ # conversions of images of identical pixel types. For instance, in line (b) of
124
+ # the example code above, if one writes
125
+ #
126
+ # CImg<char> c_img1(img1); // error; img1's pixel type is IPL_DEPTH_8U
127
+ #
128
+ # the conversion will generate a runtime error, despite sizeof(char) is equal
129
+ # to sizeof(unsigned char). The is certainly inconvenient to some users as
130
+ # the pixel type of CImg has to be defined at compile time but the pixel type
131
+ # of IplImage is determined at runtime.
132
+ #
133
+ # Some architecture-dependent code is contained in the two helper functions
134
+ #
135
+ # bool not_pixel_type_of(const IplImage*)
136
+ #
137
+ # and
138
+ #
139
+ # int get_ipl_bit_depth() const
140
+ #
141
+ # which establish correspondences between IplImage's pixel type and C++ data
142
+ # type. For example, they assume that IPL_DEPTH_16S corresponds to a signed
143
+ # short and IPL_DEPTH_64F corresponds to a signed double, etc.. Change the
144
+ # code if necessary.
145
+ #
146
+ # Currently, this plugin provides only conversions of OpenCV IplImage instances
147
+ # to and from CImg instances. Conversions of general IplImage instances (e.g.
148
+ # those with bit-depth IPL_DEPTH_1U or those with origin==1) are not supported.
149
+ # Yet the conversion code has taken care of the data alignment to 4-byte or
150
+ # 8-byte boundary as well as the use of both interleaved and non-interleaved
151
+ # color channels in IplImage.
152
+ */
153
+
154
+ #ifndef cimg_plugin_ipl
155
+ #define cimg_plugin_ipl
156
+
157
+ //----------------------------
158
+ // Architecture-dependent helper functions; change to suit your needs
159
+ //----------------------------
160
+
161
+ // Check if this CImg<T> instance and a given IplImage have identical pixel types.
162
+ bool not_pixel_type_of(const IplImage *const img) const {
163
+ // to do : handle IPL_DEPTH_1U?
164
+ return (((unsigned int)img->depth == IPL_DEPTH_8U && typeid(T) != typeid(unsigned char)) ||
165
+ ((unsigned int)img->depth == IPL_DEPTH_8S && typeid(T) != typeid(char)) ||
166
+ ((unsigned int)img->depth == IPL_DEPTH_16U && typeid(T) != typeid(unsigned short)) ||
167
+ ((unsigned int)img->depth == IPL_DEPTH_16S && typeid(T) != typeid(unsigned)) ||
168
+ ((unsigned int)img->depth == IPL_DEPTH_32S && typeid(T) != typeid(int)) ||
169
+ ((unsigned int)img->depth == IPL_DEPTH_32F && typeid(T) != typeid(float)) ||
170
+ ((unsigned int)img->depth == IPL_DEPTH_64F && typeid(T) != typeid(double)));
171
+ }
172
+
173
+ // Given this CImg<T> instance, return the corresponding bit-depth flag for use in IplImage header.
174
+ int get_ipl_bit_depth() const {
175
+ // to do : handle IPL_DEPTH_1U?
176
+ if (typeid(T) == typeid(unsigned char)) return IPL_DEPTH_8U;
177
+ if (typeid(T) == typeid(char)) return IPL_DEPTH_8S;
178
+ if (typeid(T) == typeid(unsigned short)) return IPL_DEPTH_16U;
179
+ if (typeid(T) == typeid(short)) return IPL_DEPTH_16S;
180
+ if (typeid(T) == typeid(int)) return IPL_DEPTH_32S;
181
+ if (typeid(T) == typeid(float)) return IPL_DEPTH_32F;
182
+ if (typeid(T) == typeid(double)) return IPL_DEPTH_64F;
183
+ return 0;
184
+ }
185
+
186
+ //----------------------------
187
+ // IplImage-to-CImg conversion
188
+ //----------------------------
189
+
190
+ // Copy constructor; the optional flag will be ignored when the number of color channels is less than 3.
191
+ // Current flag options are 0 and CV_CVTIMG_SWAP_RB;
192
+ // may add CV_CVTIMG_FLIP and CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB in the future.
193
+ CImg(const IplImage *const img, const int flag=0):
194
+ _width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
195
+ assign(img,flag);
196
+ }
197
+
198
+ // In-place constructor; the optional flag will be ignored when the number of color channels is less than 3.
199
+ // Current flag options are 0 and CV_CVTIMG_SWAP_RB;
200
+ // may add CV_CVTIMG_FLIP and CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB in the future.
201
+ CImg<T> & assign(const IplImage *const img, const int flag=CV_CVTIMG_SWAP_RB) {
202
+ if (!img) return assign();
203
+ if (not_pixel_type_of(img))
204
+ throw CImgInstanceException(_cimg_instance
205
+ "assign(const IplImage*) : IplImage has no corresponding pixel type.",
206
+ cimg_instance);
207
+ // to do: handle roi
208
+ const int W = img->width, H = img->height;
209
+ const char *const dataPtrI = img->imageData;
210
+ assign(W,H,1,img->nChannels);
211
+ char *const dataPtrC = (char *)_data;
212
+
213
+ const int
214
+ byte_depth = (img->depth & 255) >> 3, // number of bytes per color
215
+ widthStepI = img->widthStep, // to do: handle the case img->origin==1 (currently: img->origin==0)
216
+ widthStepC = W*byte_depth,
217
+ channelStepC = H*widthStepC;
218
+
219
+ if (img->dataOrder==0) { // interleaved color channels
220
+ const int pix_size = byte_depth*img->nChannels;
221
+ for (int n = 0; n<img->nChannels; ++n) {
222
+ const char *linePtrI = dataPtrI + n*byte_depth;
223
+ char *linePtrC = dataPtrC + (img->nChannels>=3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC;
224
+ // color order is BGR in IplImage and RGB in CImg
225
+
226
+ for (int i = 0; i<H; ++i, linePtrI+=widthStepI, linePtrC+=widthStepC) {
227
+ const char *intensityPtrI = linePtrI;
228
+ char *intensityPtrC = linePtrC;
229
+ for (int j = 0; j<W; ++j, intensityPtrI+=pix_size, intensityPtrC+=byte_depth)
230
+ std::memcpy(intensityPtrC, intensityPtrI, byte_depth);
231
+ }
232
+ }
233
+ } else { // non-interleaved color channels
234
+ for (int n = 0; n<img->nChannels; ++n) {
235
+ const char *linePtrI = dataPtrI + n*byte_depth;
236
+ char *linePtrC = dataPtrC + (img->nChannels >= 3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC;
237
+ for (int i = 0; i<H; ++i, linePtrI+=widthStepI, linePtrC+=widthStepC)
238
+ std::memcpy(linePtrC, linePtrI, widthStepC);
239
+ }
240
+ }
241
+ return *this;
242
+ }
243
+
244
+ //----------------------------
245
+ // CImg-to-IplImage conversion
246
+ //----------------------------
247
+ // The 'get' function; the optional flag will be ignored when the number of color channels is less than 3.
248
+ // Current flag options are 0 and CV_CVTIMG_SWAP_RB;
249
+ // may add CV_CVTIMG_FLIP and CV_CVTIMG_FLIP|CV_CVTIMG_SWAP_RB in future.
250
+ // z is the z-coordinate of the CImg slice that one wants to copy.
251
+ IplImage* get_IplImage(const int flag=CV_CVTIMG_SWAP_RB, const unsigned z=0) const {
252
+ const int bit_depth = get_ipl_bit_depth();
253
+ if (!bit_depth)
254
+ throw CImgInstanceException(_cimg_instance
255
+ "get_IplImage() : IplImage has no corresponding pixel type.",
256
+ cimg_instance);
257
+ if (is_empty())
258
+ throw CImgArgumentException(_cimg_instance
259
+ "get_IplImage() : Empty instance.",
260
+ cimg_instance);
261
+ if (z>=_depth)
262
+ throw CImgInstanceException(_cimg_instance
263
+ "get_IplImage() : Instance has not Z-dimension %u.",
264
+ cimg_instance,
265
+ z);
266
+ if (_spectrum>4)
267
+ cimg::warn(_cimg_instance
268
+ "get_IplImage() : OpenCV supports only 4 channels, so only the first four will be copied.",
269
+ cimg_instance);
270
+
271
+ IplImage *const img = cvCreateImage(cvSize(_width,_height),bit_depth,_spectrum);
272
+ const int
273
+ W = _width,
274
+ H = _height,
275
+ byte_depth = (img->depth & 255) >> 3, // number of bytes per color
276
+ widthStepI = img->widthStep, // to do: handle the case img->origin==1 (currently: img->origin==0)
277
+ widthStepC = W*byte_depth,
278
+ channelStepC = H*_depth*widthStepC;
279
+ const char *const dataPtrC = (char*)_data + z*H*widthStepC;
280
+ char *const dataPtrI = img->imageData;
281
+
282
+ if (!img->dataOrder) { // interleaved color channels
283
+ const int pix_size = byte_depth*img->nChannels;
284
+ for (int n = 0; n<img->nChannels; ++n) {
285
+ const char
286
+ *linePtrC = dataPtrC + (img->nChannels >= 3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC;
287
+ char *linePtrI = dataPtrI + n*byte_depth;
288
+
289
+ // color order is BGR in IplImage and RGB in CImg
290
+ for (int i = 0; i<H; ++i, linePtrI+=widthStepI, linePtrC+=widthStepC) {
291
+ const char *intensityPtrC = linePtrC;
292
+ char *intensityPtrI = linePtrI;
293
+ for (int j = 0; j<W; ++j, intensityPtrI+=pix_size, intensityPtrC+=byte_depth)
294
+ std::memcpy(intensityPtrI, intensityPtrC, byte_depth);
295
+ }
296
+ }
297
+ } else { // non-interleaved color channels
298
+ for (int n = 0; n<img->nChannels; ++n) {
299
+ const char
300
+ *linePtrC = dataPtrC + (img->nChannels>= 3 && (flag & CV_CVTIMG_SWAP_RB) && n<3?(2 - n):n)*channelStepC;
301
+ char *linePtrI = dataPtrI + n*byte_depth;
302
+ for (int i = 0; i<H; ++i, linePtrI+=widthStepI, linePtrC+=widthStepC)
303
+ std::memcpy(linePtrI, linePtrC, widthStepC);
304
+ }
305
+ }
306
+ return img;
307
+ }
308
+
309
+ #endif /* cimg_plugin_ipl */
@@ -0,0 +1,122 @@
1
+ /*
2
+ #
3
+ # File : ipl_alt.h
4
+ # ( C++ header file - CImg plug-in )
5
+ #
6
+ # Description : CImg plug-in providing the CImg->IPL and IPL->CImg
7
+ # conversions for generic image types
8
+ # ( IPL = Intel Performance Library )
9
+ # This file is a part of the CImg Library project.
10
+ # ( http://cimg.eu )
11
+ #
12
+ # Copyright : newleft (haibo.zheng@gmail.com)
13
+ # newleftist@hotmail.com
14
+ #
15
+ # License : CeCILL v2.0
16
+ # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
17
+ #
18
+ # This software is governed by the CeCILL license under French law and
19
+ # abiding by the rules of distribution of free software. You can use,
20
+ # modify and/ or redistribute the software under the terms of the CeCILL
21
+ # license as circulated by CEA, CNRS and INRIA at the following URL
22
+ # "http://www.cecill.info".
23
+ #
24
+ # As a counterpart to the access to the source code and rights to copy,
25
+ # modify and redistribute granted by the license, users are provided only
26
+ # with a limited warranty and the software's author, the holder of the
27
+ # economic rights, and the successive licensors have only limited
28
+ # liability.
29
+ #
30
+ # In this respect, the user's attention is drawn to the risks associated
31
+ # with loading, using, modifying and/or developing or reproducing the
32
+ # software by the user in light of its specific status of free software,
33
+ # that may mean that it is complicated to manipulate, and that also
34
+ # therefore means that it is reserved for developers and experienced
35
+ # professionals having in-depth computer knowledge. Users are therefore
36
+ # encouraged to load and test the software's suitability as regards their
37
+ # requirements in conditions enabling the security of their systems and/or
38
+ # data to be ensured and, more generally, to use and operate it in the
39
+ # same conditions as regards security.
40
+ #
41
+ # The fact that you are presently reading this means that you have had
42
+ # knowledge of the CeCILL license and that you accept its terms.
43
+ #
44
+ */
45
+
46
+ #ifndef cimg_plugin_IPL
47
+ #define cimg_plugin_IPL
48
+
49
+ // Conversion IPL -> CImg (constructor)
50
+ CImg(const IplImage* src):_width(0),_height(0),_depth(0),_spectrum(0),_is_shared(false),_data(0) {
51
+ assign(src);
52
+ }
53
+
54
+ // Conversion IPL -> CImg (in-place constructor)
55
+ CImg<T>& assign(const IplImage* src) {
56
+ if (!src) return assign();
57
+ switch (src->depth) {
58
+ case IPL_DEPTH_1U: { // 1-bit int.
59
+ IplImage *src1 = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
60
+ cvConvert(src,src1);
61
+ CImg<ucharT>((unsigned char*)src1->imageData,src1->nChannels,src1->width,src1->height,1,true).
62
+ get_permute_axes("yzcx").move_to(*this);
63
+ cvReleaseImage(&src1);
64
+ } break;
65
+ case IPL_DEPTH_8U: // 8-bit unsigned int.
66
+ CImg<ucharT>((unsigned char*)src->imageData,src->nChannels,src->width,src->height,1,true).
67
+ get_permute_axes("yzcx").move_to(*this);
68
+ break;
69
+ case IPL_DEPTH_8S: // 8-bit signed int.
70
+ CImg<charT>((char*)src->imageData,src->nChannels,src->width,src->height,1,true).
71
+ get_permute_axes("yzcx").move_to(*this);
72
+ break;
73
+ case IPL_DEPTH_16U: // 16-bit unsigned int.
74
+ CImg<ushortT>((unsigned short*)src->imageData,src->nChannels,src->width,src->height,1,true).
75
+ get_permute_axes("yzcx").move_to(*this);
76
+ break;
77
+ case IPL_DEPTH_16S: // 16-bit signed int.
78
+ CImg<shortT>((short*)src->imageData,src->nChannels,src->width,src->height,1,true).
79
+ get_permute_axes("yzcx").move_to(*this);
80
+ break;
81
+ case IPL_DEPTH_32S: // 32-bit signed int.
82
+ CImg<intT>((int*)src->imageData,src->nChannels,src->width,src->height,1,true).
83
+ get_permute_axes("yzcx").move_to(*this);
84
+ break;
85
+ case IPL_DEPTH_32F: // 32-bit float.
86
+ CImg<floatT>((float*)src->imageData,src->nChannels,src->width,src->height,1,true).
87
+ get_permute_axes("yzcx").move_to(*this);
88
+ break;
89
+ case IPL_DEPTH_64F: // 64-bit double.
90
+ CImg<doubleT>((double*)src->imageData,src->nChannels,src->width,src->height,1,true).
91
+ get_permute_axes("yzcx").move_to(*this);
92
+ break;
93
+ default:
94
+ throw CImgInstanceException("CImg<%s>::assign(const IplImage* img) : IplImage depth is invalid.",
95
+ pixel_type());
96
+ break;
97
+ }
98
+ if (!std::strcmp(src->channelSeq,"BGR")) mirror('v');
99
+ else if (!std::strcmp(src->channelSeq,"BGRA")) get_shared_channels(0,2).mirror('v');
100
+ return *this;
101
+ }
102
+
103
+ // Conversion CImg -> IPL
104
+ IplImage* get_IPL(const unsigned int z=0) const {
105
+ if (is_empty())
106
+ throw CImgInstanceException("CImg<%s>::get_IPL() : instance image (%u,%u,%u,%u,%p) is empty.",
107
+ pixel_type(),_width,_height,_depth,_spectrum,_data);
108
+ if (z>=_depth)
109
+ throw CImgInstanceException("CImg<%s>::get_IPL() : specified slice %u is out of image bounds (%u,%u,%u,%u,%p).",
110
+ pixel_type(),z,_width,_height,_depth,_spectrum,_data);
111
+ const CImg<T>
112
+ _slice = _depth>1?get_slice(z):CImg<T>(),
113
+ &slice = _depth>1?_slice:*this;
114
+ CImg<T> buf(slice);
115
+ if (_spectrum==3 || _spectrum==4) buf.get_shared_channels(0,2).mirror('v');
116
+ buf.permute_axes("cxyz");
117
+ IplImage* const dst = cvCreateImage(cvSize(_width,_height),sizeof(T)*8,_spectrum);
118
+ std::memcpy(dst->imageData,buf.data(),buf.size()*sizeof(T));
119
+ return dst;
120
+ }
121
+
122
+ #endif /* cimg_plugin_IPL */