imagecore 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +24 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/ext/imagecore/analyze_image.cxx +58 -0
- data/ext/imagecore/analyze_image.h +6 -0
- data/ext/imagecore/extconf.rb +9 -0
- data/ext/imagecore/imagecore.cxx +34 -0
- data/ext/opencv/core/___.c +3 -0
- data/ext/opencv/core/alloc.cpp +697 -0
- data/ext/opencv/core/array.cpp +3206 -0
- data/ext/opencv/core/datastructs.cpp +4064 -0
- data/ext/opencv/core/extconf.rb +22 -0
- data/ext/opencv/core/matrix.cpp +3777 -0
- data/ext/opencv/core/precomp.hpp +216 -0
- data/ext/opencv/core/system.cpp +832 -0
- data/ext/opencv/core/tables.cpp +3512 -0
- data/ext/opencv/highgui/___.c +3 -0
- data/ext/opencv/highgui/bitstrm.cpp +582 -0
- data/ext/opencv/highgui/bitstrm.hpp +182 -0
- data/ext/opencv/highgui/extconf.rb +28 -0
- data/ext/opencv/highgui/grfmt_base.cpp +128 -0
- data/ext/opencv/highgui/grfmt_base.hpp +113 -0
- data/ext/opencv/highgui/grfmt_bmp.cpp +564 -0
- data/ext/opencv/highgui/grfmt_bmp.hpp +99 -0
- data/ext/opencv/highgui/grfmt_exr.hpp +113 -0
- data/ext/opencv/highgui/grfmt_imageio.hpp +56 -0
- data/ext/opencv/highgui/grfmt_jpeg.cpp +622 -0
- data/ext/opencv/highgui/grfmt_jpeg.hpp +90 -0
- data/ext/opencv/highgui/grfmt_jpeg2000.cpp +529 -0
- data/ext/opencv/highgui/grfmt_jpeg2000.hpp +95 -0
- data/ext/opencv/highgui/grfmt_png.cpp +406 -0
- data/ext/opencv/highgui/grfmt_png.hpp +101 -0
- data/ext/opencv/highgui/grfmt_pxm.cpp +513 -0
- data/ext/opencv/highgui/grfmt_pxm.hpp +92 -0
- data/ext/opencv/highgui/grfmt_sunras.cpp +425 -0
- data/ext/opencv/highgui/grfmt_sunras.hpp +105 -0
- data/ext/opencv/highgui/grfmt_tiff.cpp +718 -0
- data/ext/opencv/highgui/grfmt_tiff.hpp +136 -0
- data/ext/opencv/highgui/grfmts.hpp +56 -0
- data/ext/opencv/highgui/loadsave.cpp +535 -0
- data/ext/opencv/highgui/precomp.hpp +223 -0
- data/ext/opencv/highgui/utils.cpp +689 -0
- data/ext/opencv/highgui/utils.hpp +128 -0
- data/ext/opencv/imgproc/___.c +3 -0
- data/ext/opencv/imgproc/_geom.h +72 -0
- data/ext/opencv/imgproc/color.cpp +3179 -0
- data/ext/opencv/imgproc/contours.cpp +1780 -0
- data/ext/opencv/imgproc/extconf.rb +11 -0
- data/ext/opencv/imgproc/filter.cpp +3063 -0
- data/ext/opencv/imgproc/precomp.hpp +159 -0
- data/ext/opencv/imgproc/shapedescr.cpp +1306 -0
- data/ext/opencv/imgproc/smooth.cpp +1566 -0
- data/ext/opencv/imgproc/tables.cpp +214 -0
- data/ext/opencv/imgproc/thresh.cpp +636 -0
- data/ext/opencv/imgproc/utils.cpp +242 -0
- data/ext/opencv/include/opencv2/core/core.hpp +4344 -0
- data/ext/opencv/include/opencv2/core/core_c.h +1885 -0
- data/ext/opencv/include/opencv2/core/internal.hpp +710 -0
- data/ext/opencv/include/opencv2/core/mat.hpp +2557 -0
- data/ext/opencv/include/opencv2/core/operations.hpp +3623 -0
- data/ext/opencv/include/opencv2/core/types_c.h +1875 -0
- data/ext/opencv/include/opencv2/core/version.hpp +58 -0
- data/ext/opencv/include/opencv2/highgui/highgui.hpp +198 -0
- data/ext/opencv/include/opencv2/highgui/highgui_c.h +506 -0
- data/ext/opencv/include/opencv2/imgproc/imgproc.hpp +1139 -0
- data/ext/opencv/include/opencv2/imgproc/imgproc_c.h +783 -0
- data/ext/opencv/include/opencv2/imgproc/types_c.h +538 -0
- data/imagecore.gemspec +20 -0
- data/lib/imagecore.rb +16 -0
- data/lib/imagecore/version.rb +3 -0
- metadata +119 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
/*M///////////////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
4
|
+
//
|
5
|
+
// By downloading, copying, installing or using the software you agree to this license.
|
6
|
+
// If you do not agree to this license, do not download, install,
|
7
|
+
// copy or use the software.
|
8
|
+
//
|
9
|
+
//
|
10
|
+
// License Agreement
|
11
|
+
// For Open Source Computer Vision Library
|
12
|
+
//
|
13
|
+
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
14
|
+
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
15
|
+
// Third party copyrights are property of their respective owners.
|
16
|
+
//
|
17
|
+
// Redistribution and use in source and binary forms, with or without modification,
|
18
|
+
// are permitted provided that the following conditions are met:
|
19
|
+
//
|
20
|
+
// * Redistribution's of source code must retain the above copyright notice,
|
21
|
+
// this list of conditions and the following disclaimer.
|
22
|
+
//
|
23
|
+
// * Redistribution's in binary form must reproduce the above copyright notice,
|
24
|
+
// this list of conditions and the following disclaimer in the documentation
|
25
|
+
// and/or other materials provided with the distribution.
|
26
|
+
//
|
27
|
+
// * The name of the copyright holders may not be used to endorse or promote products
|
28
|
+
// derived from this software without specific prior written permission.
|
29
|
+
//
|
30
|
+
// This software is provided by the copyright holders and contributors "as is" and
|
31
|
+
// any express or implied warranties, including, but not limited to, the implied
|
32
|
+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
33
|
+
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
34
|
+
// indirect, incidental, special, exemplary, or consequential damages
|
35
|
+
// (including, but not limited to, procurement of substitute goods or services;
|
36
|
+
// loss of use, data, or profits; or business interruption) however caused
|
37
|
+
// and on any theory of liability, whether in contract, strict liability,
|
38
|
+
// or tort (including negligence or otherwise) arising in any way out of
|
39
|
+
// the use of this software, even if advised of the possibility of such damage.
|
40
|
+
//
|
41
|
+
//M*/
|
42
|
+
|
43
|
+
#ifndef _GRFMT_PNG_H_
|
44
|
+
#define _GRFMT_PNG_H_
|
45
|
+
|
46
|
+
#ifdef HAVE_PNG
|
47
|
+
|
48
|
+
#include "grfmt_base.hpp"
|
49
|
+
#include "bitstrm.hpp"
|
50
|
+
|
51
|
+
namespace cv
|
52
|
+
{
|
53
|
+
|
54
|
+
class PngDecoder : public BaseImageDecoder
|
55
|
+
{
|
56
|
+
public:
|
57
|
+
|
58
|
+
PngDecoder();
|
59
|
+
virtual ~PngDecoder();
|
60
|
+
|
61
|
+
bool readData( Mat& img );
|
62
|
+
bool readHeader();
|
63
|
+
void close();
|
64
|
+
|
65
|
+
ImageDecoder newDecoder() const;
|
66
|
+
|
67
|
+
protected:
|
68
|
+
|
69
|
+
static void readDataFromBuf(void* png_ptr, uchar* dst, size_t size);
|
70
|
+
|
71
|
+
int m_bit_depth;
|
72
|
+
void* m_png_ptr; // pointer to decompression structure
|
73
|
+
void* m_info_ptr; // pointer to image information structure
|
74
|
+
void* m_end_info; // pointer to one more image information structure
|
75
|
+
FILE* m_f;
|
76
|
+
int m_color_type;
|
77
|
+
size_t m_buf_pos;
|
78
|
+
};
|
79
|
+
|
80
|
+
|
81
|
+
class PngEncoder : public BaseImageEncoder
|
82
|
+
{
|
83
|
+
public:
|
84
|
+
PngEncoder();
|
85
|
+
virtual ~PngEncoder();
|
86
|
+
|
87
|
+
bool isFormatSupported( int depth ) const;
|
88
|
+
bool write( const Mat& img, const vector<int>& params );
|
89
|
+
|
90
|
+
ImageEncoder newEncoder() const;
|
91
|
+
|
92
|
+
protected:
|
93
|
+
static void writeDataToBuf(void* png_ptr, uchar* src, size_t size);
|
94
|
+
static void flushBuf(void* png_ptr);
|
95
|
+
};
|
96
|
+
|
97
|
+
}
|
98
|
+
|
99
|
+
#endif
|
100
|
+
|
101
|
+
#endif/*_GRFMT_PNG_H_*/
|
@@ -0,0 +1,513 @@
|
|
1
|
+
/*M///////////////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
4
|
+
//
|
5
|
+
// By downloading, copying, installing or using the software you agree to this license.
|
6
|
+
// If you do not agree to this license, do not download, install,
|
7
|
+
// copy or use the software.
|
8
|
+
//
|
9
|
+
//
|
10
|
+
// License Agreement
|
11
|
+
// For Open Source Computer Vision Library
|
12
|
+
//
|
13
|
+
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
14
|
+
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
15
|
+
// Third party copyrights are property of their respective owners.
|
16
|
+
//
|
17
|
+
// Redistribution and use in source and binary forms, with or without modification,
|
18
|
+
// are permitted provided that the following conditions are met:
|
19
|
+
//
|
20
|
+
// * Redistribution's of source code must retain the above copyright notice,
|
21
|
+
// this list of conditions and the following disclaimer.
|
22
|
+
//
|
23
|
+
// * Redistribution's in binary form must reproduce the above copyright notice,
|
24
|
+
// this list of conditions and the following disclaimer in the documentation
|
25
|
+
// and/or other materials provided with the distribution.
|
26
|
+
//
|
27
|
+
// * The name of the copyright holders may not be used to endorse or promote products
|
28
|
+
// derived from this software without specific prior written permission.
|
29
|
+
//
|
30
|
+
// This software is provided by the copyright holders and contributors "as is" and
|
31
|
+
// any express or implied warranties, including, but not limited to, the implied
|
32
|
+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
33
|
+
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
34
|
+
// indirect, incidental, special, exemplary, or consequential damages
|
35
|
+
// (including, but not limited to, procurement of substitute goods or services;
|
36
|
+
// loss of use, data, or profits; or business interruption) however caused
|
37
|
+
// and on any theory of liability, whether in contract, strict liability,
|
38
|
+
// or tort (including negligence or otherwise) arising in any way out of
|
39
|
+
// the use of this software, even if advised of the possibility of such damage.
|
40
|
+
//
|
41
|
+
//M*/
|
42
|
+
|
43
|
+
#include "precomp.hpp"
|
44
|
+
#include "utils.hpp"
|
45
|
+
#include "grfmt_pxm.hpp"
|
46
|
+
|
47
|
+
namespace cv
|
48
|
+
{
|
49
|
+
|
50
|
+
///////////////////////// P?M reader //////////////////////////////
|
51
|
+
|
52
|
+
static int ReadNumber( RLByteStream& strm, int maxdigits )
|
53
|
+
{
|
54
|
+
int code;
|
55
|
+
int val = 0;
|
56
|
+
int digits = 0;
|
57
|
+
|
58
|
+
code = strm.getByte();
|
59
|
+
|
60
|
+
if( !isdigit(code))
|
61
|
+
{
|
62
|
+
do
|
63
|
+
{
|
64
|
+
if( code == '#' )
|
65
|
+
{
|
66
|
+
do
|
67
|
+
{
|
68
|
+
code = strm.getByte();
|
69
|
+
}
|
70
|
+
while( code != '\n' && code != '\r' );
|
71
|
+
}
|
72
|
+
|
73
|
+
code = strm.getByte();
|
74
|
+
|
75
|
+
while( isspace(code))
|
76
|
+
code = strm.getByte();
|
77
|
+
}
|
78
|
+
while( !isdigit( code ));
|
79
|
+
}
|
80
|
+
|
81
|
+
do
|
82
|
+
{
|
83
|
+
val = val*10 + code - '0';
|
84
|
+
if( ++digits >= maxdigits ) break;
|
85
|
+
code = strm.getByte();
|
86
|
+
}
|
87
|
+
while( isdigit(code));
|
88
|
+
|
89
|
+
return val;
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
PxMDecoder::PxMDecoder()
|
94
|
+
{
|
95
|
+
m_offset = -1;
|
96
|
+
m_buf_supported = true;
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
PxMDecoder::~PxMDecoder()
|
101
|
+
{
|
102
|
+
close();
|
103
|
+
}
|
104
|
+
|
105
|
+
size_t PxMDecoder::signatureLength() const
|
106
|
+
{
|
107
|
+
return 3;
|
108
|
+
}
|
109
|
+
|
110
|
+
bool PxMDecoder::checkSignature( const string& signature ) const
|
111
|
+
{
|
112
|
+
return signature.size() >= 3 && signature[0] == 'P' &&
|
113
|
+
'1' <= signature[1] && signature[1] <= '6' &&
|
114
|
+
isspace(signature[2]);
|
115
|
+
}
|
116
|
+
|
117
|
+
ImageDecoder PxMDecoder::newDecoder() const
|
118
|
+
{
|
119
|
+
return new PxMDecoder;
|
120
|
+
}
|
121
|
+
|
122
|
+
void PxMDecoder::close()
|
123
|
+
{
|
124
|
+
m_strm.close();
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
bool PxMDecoder::readHeader()
|
129
|
+
{
|
130
|
+
bool result = false;
|
131
|
+
|
132
|
+
if( !m_buf.empty() )
|
133
|
+
{
|
134
|
+
if( !m_strm.open(m_buf) )
|
135
|
+
return false;
|
136
|
+
}
|
137
|
+
else if( !m_strm.open( m_filename ))
|
138
|
+
return false;
|
139
|
+
|
140
|
+
try
|
141
|
+
{
|
142
|
+
int code = m_strm.getByte();
|
143
|
+
if( code != 'P' )
|
144
|
+
throw RBS_BAD_HEADER;
|
145
|
+
|
146
|
+
code = m_strm.getByte();
|
147
|
+
switch( code )
|
148
|
+
{
|
149
|
+
case '1': case '4': m_bpp = 1; break;
|
150
|
+
case '2': case '5': m_bpp = 8; break;
|
151
|
+
case '3': case '6': m_bpp = 24; break;
|
152
|
+
default: throw RBS_BAD_HEADER;
|
153
|
+
}
|
154
|
+
|
155
|
+
m_binary = code >= '4';
|
156
|
+
m_type = m_bpp > 8 ? CV_8UC3 : CV_8UC1;
|
157
|
+
|
158
|
+
m_width = ReadNumber( m_strm, INT_MAX );
|
159
|
+
m_height = ReadNumber( m_strm, INT_MAX );
|
160
|
+
|
161
|
+
m_maxval = m_bpp == 1 ? 1 : ReadNumber( m_strm, INT_MAX );
|
162
|
+
if( m_maxval > 65535 )
|
163
|
+
throw RBS_BAD_HEADER;
|
164
|
+
|
165
|
+
//if( m_maxval > 255 ) m_binary = false; nonsense
|
166
|
+
if( m_maxval > 255 )
|
167
|
+
m_type = CV_MAKETYPE(CV_16U, CV_MAT_CN(m_type));
|
168
|
+
|
169
|
+
if( m_width > 0 && m_height > 0 && m_maxval > 0 && m_maxval < (1 << 16))
|
170
|
+
{
|
171
|
+
m_offset = m_strm.getPos();
|
172
|
+
result = true;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
catch(...)
|
176
|
+
{
|
177
|
+
}
|
178
|
+
|
179
|
+
if( !result )
|
180
|
+
{
|
181
|
+
m_offset = -1;
|
182
|
+
m_width = m_height = -1;
|
183
|
+
m_strm.close();
|
184
|
+
}
|
185
|
+
return result;
|
186
|
+
}
|
187
|
+
|
188
|
+
|
189
|
+
bool PxMDecoder::readData( Mat& img )
|
190
|
+
{
|
191
|
+
int color = img.channels() > 1;
|
192
|
+
uchar* data = img.data;
|
193
|
+
int step = (int)img.step;
|
194
|
+
PaletteEntry palette[256];
|
195
|
+
bool result = false;
|
196
|
+
int bit_depth = CV_ELEM_SIZE1(m_type)*8;
|
197
|
+
int src_pitch = (m_width*m_bpp*bit_depth/8 + 7)/8;
|
198
|
+
int nch = CV_MAT_CN(m_type);
|
199
|
+
int width3 = m_width*nch;
|
200
|
+
int i, x, y;
|
201
|
+
|
202
|
+
if( m_offset < 0 || !m_strm.isOpened())
|
203
|
+
return false;
|
204
|
+
|
205
|
+
AutoBuffer<uchar,1024> _src(src_pitch + 32);
|
206
|
+
uchar* src = _src;
|
207
|
+
AutoBuffer<uchar,1024> _gray_palette;
|
208
|
+
uchar* gray_palette = _gray_palette;
|
209
|
+
|
210
|
+
// create LUT for converting colors
|
211
|
+
if( bit_depth == 8 )
|
212
|
+
{
|
213
|
+
_gray_palette.allocate(m_maxval + 1);
|
214
|
+
gray_palette = _gray_palette;
|
215
|
+
|
216
|
+
for( i = 0; i <= m_maxval; i++ )
|
217
|
+
gray_palette[i] = (uchar)((i*255/m_maxval)^(m_bpp == 1 ? 255 : 0));
|
218
|
+
|
219
|
+
FillGrayPalette( palette, m_bpp==1 ? 1 : 8 , m_bpp == 1 );
|
220
|
+
}
|
221
|
+
|
222
|
+
try
|
223
|
+
{
|
224
|
+
m_strm.setPos( m_offset );
|
225
|
+
|
226
|
+
switch( m_bpp )
|
227
|
+
{
|
228
|
+
////////////////////////// 1 BPP /////////////////////////
|
229
|
+
case 1:
|
230
|
+
if( !m_binary )
|
231
|
+
{
|
232
|
+
for( y = 0; y < m_height; y++, data += step )
|
233
|
+
{
|
234
|
+
for( x = 0; x < m_width; x++ )
|
235
|
+
src[x] = ReadNumber( m_strm, 1 ) != 0;
|
236
|
+
|
237
|
+
if( color )
|
238
|
+
FillColorRow8( data, src, m_width, palette );
|
239
|
+
else
|
240
|
+
FillGrayRow8( data, src, m_width, gray_palette );
|
241
|
+
}
|
242
|
+
}
|
243
|
+
else
|
244
|
+
{
|
245
|
+
for( y = 0; y < m_height; y++, data += step )
|
246
|
+
{
|
247
|
+
m_strm.getBytes( src, src_pitch );
|
248
|
+
|
249
|
+
if( color )
|
250
|
+
FillColorRow1( data, src, m_width, palette );
|
251
|
+
else
|
252
|
+
FillGrayRow1( data, src, m_width, gray_palette );
|
253
|
+
}
|
254
|
+
}
|
255
|
+
result = true;
|
256
|
+
break;
|
257
|
+
|
258
|
+
////////////////////////// 8 BPP /////////////////////////
|
259
|
+
case 8:
|
260
|
+
case 24:
|
261
|
+
for( y = 0; y < m_height; y++, data += step )
|
262
|
+
{
|
263
|
+
if( !m_binary )
|
264
|
+
{
|
265
|
+
for( x = 0; x < width3; x++ )
|
266
|
+
{
|
267
|
+
int code = ReadNumber( m_strm, INT_MAX );
|
268
|
+
if( (unsigned)code > (unsigned)m_maxval ) code = m_maxval;
|
269
|
+
if( bit_depth == 8 )
|
270
|
+
src[x] = gray_palette[code];
|
271
|
+
else
|
272
|
+
((ushort *)src)[x] = (ushort)code;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
else
|
276
|
+
{
|
277
|
+
m_strm.getBytes( src, src_pitch );
|
278
|
+
if( bit_depth == 16 && !isBigEndian() )
|
279
|
+
{
|
280
|
+
for( x = 0; x < width3; x++ )
|
281
|
+
{
|
282
|
+
uchar v = src[x * 2];
|
283
|
+
src[x * 2] = src[x * 2 + 1];
|
284
|
+
src[x * 2 + 1] = v;
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
if( img.depth() == CV_8U && bit_depth == 16 )
|
290
|
+
{
|
291
|
+
for( x = 0; x < width3; x++ )
|
292
|
+
{
|
293
|
+
int v = ((ushort *)src)[x];
|
294
|
+
src[x] = (uchar)(v >> 8);
|
295
|
+
}
|
296
|
+
}
|
297
|
+
|
298
|
+
if( m_bpp == 8 ) // image has one channel
|
299
|
+
{
|
300
|
+
if( color )
|
301
|
+
{
|
302
|
+
if( img.depth() == CV_8U ) {
|
303
|
+
uchar *d = data, *s = src, *end = src + m_width;
|
304
|
+
for( ; s < end; d += 3, s++)
|
305
|
+
d[0] = d[1] = d[2] = *s;
|
306
|
+
} else {
|
307
|
+
ushort *d = (ushort *)data, *s = (ushort *)src, *end = ((ushort *)src) + m_width;
|
308
|
+
for( ; s < end; s++, d += 3)
|
309
|
+
d[0] = d[1] = d[2] = *s;
|
310
|
+
}
|
311
|
+
}
|
312
|
+
else
|
313
|
+
memcpy( data, src, m_width*(bit_depth/8) );
|
314
|
+
}
|
315
|
+
else
|
316
|
+
{
|
317
|
+
if( color )
|
318
|
+
{
|
319
|
+
if( img.depth() == CV_8U )
|
320
|
+
icvCvt_RGB2BGR_8u_C3R( src, 0, data, 0, cvSize(m_width,1) );
|
321
|
+
else
|
322
|
+
icvCvt_RGB2BGR_16u_C3R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1) );
|
323
|
+
}
|
324
|
+
else if( img.depth() == CV_8U )
|
325
|
+
icvCvt_BGR2Gray_8u_C3C1R( src, 0, data, 0, cvSize(m_width,1), 2 );
|
326
|
+
else
|
327
|
+
icvCvt_BGRA2Gray_16u_CnC1R( (ushort *)src, 0, (ushort *)data, 0, cvSize(m_width,1), 3, 2 );
|
328
|
+
}
|
329
|
+
}
|
330
|
+
result = true;
|
331
|
+
break;
|
332
|
+
default:
|
333
|
+
assert(0);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
catch(...)
|
337
|
+
{
|
338
|
+
}
|
339
|
+
|
340
|
+
return result;
|
341
|
+
}
|
342
|
+
|
343
|
+
|
344
|
+
//////////////////////////////////////////////////////////////////////////////////////////
|
345
|
+
|
346
|
+
PxMEncoder::PxMEncoder()
|
347
|
+
{
|
348
|
+
m_description = "Portable image format (*.pbm;*.pgm;*.ppm;*.pxm;*.pnm)";
|
349
|
+
m_buf_supported = true;
|
350
|
+
}
|
351
|
+
|
352
|
+
|
353
|
+
PxMEncoder::~PxMEncoder()
|
354
|
+
{
|
355
|
+
}
|
356
|
+
|
357
|
+
|
358
|
+
ImageEncoder PxMEncoder::newEncoder() const
|
359
|
+
{
|
360
|
+
return new PxMEncoder;
|
361
|
+
}
|
362
|
+
|
363
|
+
|
364
|
+
bool PxMEncoder::isFormatSupported( int depth ) const
|
365
|
+
{
|
366
|
+
return depth == CV_8U || depth == CV_16U;
|
367
|
+
}
|
368
|
+
|
369
|
+
|
370
|
+
bool PxMEncoder::write( const Mat& img, const vector<int>& params )
|
371
|
+
{
|
372
|
+
bool isBinary = true;
|
373
|
+
|
374
|
+
int width = img.cols, height = img.rows;
|
375
|
+
int _channels = img.channels(), depth = (int)img.elemSize1()*8;
|
376
|
+
int channels = _channels > 1 ? 3 : 1;
|
377
|
+
int fileStep = width*(int)img.elemSize();
|
378
|
+
int x, y;
|
379
|
+
|
380
|
+
for( size_t i = 0; i < params.size(); i += 2 )
|
381
|
+
if( params[i] == CV_IMWRITE_PXM_BINARY )
|
382
|
+
isBinary = params[i+1] != 0;
|
383
|
+
|
384
|
+
WLByteStream strm;
|
385
|
+
|
386
|
+
if( m_buf )
|
387
|
+
{
|
388
|
+
if( !strm.open(*m_buf) )
|
389
|
+
return false;
|
390
|
+
int t = CV_MAKETYPE(img.depth(), channels);
|
391
|
+
m_buf->reserve( alignSize(256 + (isBinary ? fileStep*height :
|
392
|
+
((t == CV_8UC1 ? 4 : t == CV_8UC3 ? 4*3+2 :
|
393
|
+
t == CV_16UC1 ? 6 : 6*3+2)*width+1)*height), 256));
|
394
|
+
}
|
395
|
+
else if( !strm.open(m_filename) )
|
396
|
+
return false;
|
397
|
+
|
398
|
+
int lineLength;
|
399
|
+
int bufferSize = 128; // buffer that should fit a header
|
400
|
+
|
401
|
+
if( isBinary )
|
402
|
+
lineLength = width * (int)img.elemSize();
|
403
|
+
else
|
404
|
+
lineLength = (6 * channels + (channels > 1 ? 2 : 0)) * width + 32;
|
405
|
+
|
406
|
+
if( bufferSize < lineLength )
|
407
|
+
bufferSize = lineLength;
|
408
|
+
|
409
|
+
AutoBuffer<char> _buffer(bufferSize);
|
410
|
+
char* buffer = _buffer;
|
411
|
+
|
412
|
+
// write header;
|
413
|
+
sprintf( buffer, "P%c\n%d %d\n%d\n",
|
414
|
+
'2' + (channels > 1 ? 1 : 0) + (isBinary ? 3 : 0),
|
415
|
+
width, height, (1 << depth) - 1 );
|
416
|
+
|
417
|
+
strm.putBytes( buffer, (int)strlen(buffer) );
|
418
|
+
|
419
|
+
for( y = 0; y < height; y++ )
|
420
|
+
{
|
421
|
+
uchar* data = img.data + img.step*y;
|
422
|
+
if( isBinary )
|
423
|
+
{
|
424
|
+
if( _channels == 3 )
|
425
|
+
{
|
426
|
+
if( depth == 8 )
|
427
|
+
icvCvt_BGR2RGB_8u_C3R( (uchar*)data, 0,
|
428
|
+
(uchar*)buffer, 0, cvSize(width,1) );
|
429
|
+
else
|
430
|
+
icvCvt_BGR2RGB_16u_C3R( (ushort*)data, 0,
|
431
|
+
(ushort*)buffer, 0, cvSize(width,1) );
|
432
|
+
}
|
433
|
+
|
434
|
+
// swap endianness if necessary
|
435
|
+
if( depth == 16 && !isBigEndian() )
|
436
|
+
{
|
437
|
+
if( _channels == 1 )
|
438
|
+
memcpy( buffer, data, fileStep );
|
439
|
+
for( x = 0; x < width*channels*2; x += 2 )
|
440
|
+
{
|
441
|
+
uchar v = buffer[x];
|
442
|
+
buffer[x] = buffer[x + 1];
|
443
|
+
buffer[x + 1] = v;
|
444
|
+
}
|
445
|
+
}
|
446
|
+
strm.putBytes( (channels > 1 || depth > 8) ? buffer : (char*)data, fileStep );
|
447
|
+
}
|
448
|
+
else
|
449
|
+
{
|
450
|
+
char* ptr = buffer;
|
451
|
+
|
452
|
+
if( channels > 1 )
|
453
|
+
{
|
454
|
+
if( depth == 8 )
|
455
|
+
{
|
456
|
+
for( x = 0; x < width*channels; x += channels )
|
457
|
+
{
|
458
|
+
sprintf( ptr, "% 4d", data[x + 2] );
|
459
|
+
ptr += 4;
|
460
|
+
sprintf( ptr, "% 4d", data[x + 1] );
|
461
|
+
ptr += 4;
|
462
|
+
sprintf( ptr, "% 4d", data[x] );
|
463
|
+
ptr += 4;
|
464
|
+
*ptr++ = ' ';
|
465
|
+
*ptr++ = ' ';
|
466
|
+
}
|
467
|
+
}
|
468
|
+
else
|
469
|
+
{
|
470
|
+
for( x = 0; x < width*channels; x += channels )
|
471
|
+
{
|
472
|
+
sprintf( ptr, "% 6d", ((ushort *)data)[x + 2] );
|
473
|
+
ptr += 6;
|
474
|
+
sprintf( ptr, "% 6d", ((ushort *)data)[x + 1] );
|
475
|
+
ptr += 6;
|
476
|
+
sprintf( ptr, "% 6d", ((ushort *)data)[x] );
|
477
|
+
ptr += 6;
|
478
|
+
*ptr++ = ' ';
|
479
|
+
*ptr++ = ' ';
|
480
|
+
}
|
481
|
+
}
|
482
|
+
}
|
483
|
+
else
|
484
|
+
{
|
485
|
+
if( depth == 8 )
|
486
|
+
{
|
487
|
+
for( x = 0; x < width; x++ )
|
488
|
+
{
|
489
|
+
sprintf( ptr, "% 4d", data[x] );
|
490
|
+
ptr += 4;
|
491
|
+
}
|
492
|
+
}
|
493
|
+
else
|
494
|
+
{
|
495
|
+
for( x = 0; x < width; x++ )
|
496
|
+
{
|
497
|
+
sprintf( ptr, "% 6d", ((ushort *)data)[x] );
|
498
|
+
ptr += 6;
|
499
|
+
}
|
500
|
+
}
|
501
|
+
}
|
502
|
+
|
503
|
+
*ptr++ = '\n';
|
504
|
+
|
505
|
+
strm.putBytes( buffer, (int)(ptr - buffer) );
|
506
|
+
}
|
507
|
+
}
|
508
|
+
|
509
|
+
strm.close();
|
510
|
+
return true;
|
511
|
+
}
|
512
|
+
|
513
|
+
}
|