imagecore 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/.gitignore +24 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +2 -0
  4. data/ext/imagecore/analyze_image.cxx +58 -0
  5. data/ext/imagecore/analyze_image.h +6 -0
  6. data/ext/imagecore/extconf.rb +9 -0
  7. data/ext/imagecore/imagecore.cxx +34 -0
  8. data/ext/opencv/core/___.c +3 -0
  9. data/ext/opencv/core/alloc.cpp +697 -0
  10. data/ext/opencv/core/array.cpp +3206 -0
  11. data/ext/opencv/core/datastructs.cpp +4064 -0
  12. data/ext/opencv/core/extconf.rb +22 -0
  13. data/ext/opencv/core/matrix.cpp +3777 -0
  14. data/ext/opencv/core/precomp.hpp +216 -0
  15. data/ext/opencv/core/system.cpp +832 -0
  16. data/ext/opencv/core/tables.cpp +3512 -0
  17. data/ext/opencv/highgui/___.c +3 -0
  18. data/ext/opencv/highgui/bitstrm.cpp +582 -0
  19. data/ext/opencv/highgui/bitstrm.hpp +182 -0
  20. data/ext/opencv/highgui/extconf.rb +28 -0
  21. data/ext/opencv/highgui/grfmt_base.cpp +128 -0
  22. data/ext/opencv/highgui/grfmt_base.hpp +113 -0
  23. data/ext/opencv/highgui/grfmt_bmp.cpp +564 -0
  24. data/ext/opencv/highgui/grfmt_bmp.hpp +99 -0
  25. data/ext/opencv/highgui/grfmt_exr.hpp +113 -0
  26. data/ext/opencv/highgui/grfmt_imageio.hpp +56 -0
  27. data/ext/opencv/highgui/grfmt_jpeg.cpp +622 -0
  28. data/ext/opencv/highgui/grfmt_jpeg.hpp +90 -0
  29. data/ext/opencv/highgui/grfmt_jpeg2000.cpp +529 -0
  30. data/ext/opencv/highgui/grfmt_jpeg2000.hpp +95 -0
  31. data/ext/opencv/highgui/grfmt_png.cpp +406 -0
  32. data/ext/opencv/highgui/grfmt_png.hpp +101 -0
  33. data/ext/opencv/highgui/grfmt_pxm.cpp +513 -0
  34. data/ext/opencv/highgui/grfmt_pxm.hpp +92 -0
  35. data/ext/opencv/highgui/grfmt_sunras.cpp +425 -0
  36. data/ext/opencv/highgui/grfmt_sunras.hpp +105 -0
  37. data/ext/opencv/highgui/grfmt_tiff.cpp +718 -0
  38. data/ext/opencv/highgui/grfmt_tiff.hpp +136 -0
  39. data/ext/opencv/highgui/grfmts.hpp +56 -0
  40. data/ext/opencv/highgui/loadsave.cpp +535 -0
  41. data/ext/opencv/highgui/precomp.hpp +223 -0
  42. data/ext/opencv/highgui/utils.cpp +689 -0
  43. data/ext/opencv/highgui/utils.hpp +128 -0
  44. data/ext/opencv/imgproc/___.c +3 -0
  45. data/ext/opencv/imgproc/_geom.h +72 -0
  46. data/ext/opencv/imgproc/color.cpp +3179 -0
  47. data/ext/opencv/imgproc/contours.cpp +1780 -0
  48. data/ext/opencv/imgproc/extconf.rb +11 -0
  49. data/ext/opencv/imgproc/filter.cpp +3063 -0
  50. data/ext/opencv/imgproc/precomp.hpp +159 -0
  51. data/ext/opencv/imgproc/shapedescr.cpp +1306 -0
  52. data/ext/opencv/imgproc/smooth.cpp +1566 -0
  53. data/ext/opencv/imgproc/tables.cpp +214 -0
  54. data/ext/opencv/imgproc/thresh.cpp +636 -0
  55. data/ext/opencv/imgproc/utils.cpp +242 -0
  56. data/ext/opencv/include/opencv2/core/core.hpp +4344 -0
  57. data/ext/opencv/include/opencv2/core/core_c.h +1885 -0
  58. data/ext/opencv/include/opencv2/core/internal.hpp +710 -0
  59. data/ext/opencv/include/opencv2/core/mat.hpp +2557 -0
  60. data/ext/opencv/include/opencv2/core/operations.hpp +3623 -0
  61. data/ext/opencv/include/opencv2/core/types_c.h +1875 -0
  62. data/ext/opencv/include/opencv2/core/version.hpp +58 -0
  63. data/ext/opencv/include/opencv2/highgui/highgui.hpp +198 -0
  64. data/ext/opencv/include/opencv2/highgui/highgui_c.h +506 -0
  65. data/ext/opencv/include/opencv2/imgproc/imgproc.hpp +1139 -0
  66. data/ext/opencv/include/opencv2/imgproc/imgproc_c.h +783 -0
  67. data/ext/opencv/include/opencv2/imgproc/types_c.h +538 -0
  68. data/imagecore.gemspec +20 -0
  69. data/lib/imagecore.rb +16 -0
  70. data/lib/imagecore/version.rb +3 -0
  71. metadata +119 -0
@@ -0,0 +1,105 @@
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_SUNRAS_H_
44
+ #define _GRFMT_SUNRAS_H_
45
+
46
+ #include "grfmt_base.hpp"
47
+
48
+ namespace cv
49
+ {
50
+
51
+ enum SunRasType
52
+ {
53
+ RAS_OLD = 0,
54
+ RAS_STANDARD = 1,
55
+ RAS_BYTE_ENCODED = 2, /* RLE encoded */
56
+ RAS_FORMAT_RGB = 3 /* RGB instead of BGR */
57
+ };
58
+
59
+ enum SunRasMapType
60
+ {
61
+ RMT_NONE = 0, /* direct color encoding */
62
+ RMT_EQUAL_RGB = 1 /* paletted image */
63
+ };
64
+
65
+
66
+ // Sun Raster Reader
67
+ class SunRasterDecoder : public BaseImageDecoder
68
+ {
69
+ public:
70
+
71
+ SunRasterDecoder();
72
+ virtual ~SunRasterDecoder();
73
+
74
+ bool readData( Mat& img );
75
+ bool readHeader();
76
+ void close();
77
+
78
+ ImageDecoder newDecoder() const;
79
+
80
+ protected:
81
+
82
+ RMByteStream m_strm;
83
+ PaletteEntry m_palette[256];
84
+ int m_bpp;
85
+ int m_offset;
86
+ SunRasType m_encoding;
87
+ SunRasMapType m_maptype;
88
+ int m_maplength;
89
+ };
90
+
91
+
92
+ class SunRasterEncoder : public BaseImageEncoder
93
+ {
94
+ public:
95
+ SunRasterEncoder();
96
+ virtual ~SunRasterEncoder();
97
+
98
+ bool write( const Mat& img, const vector<int>& params );
99
+
100
+ ImageEncoder newEncoder() const;
101
+ };
102
+
103
+ }
104
+
105
+ #endif/*_GRFMT_SUNRAS_H_*/
@@ -0,0 +1,718 @@
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
+ /****************************************************************************************\
44
+ A part of the file implements TIFF reader on base of libtiff library
45
+ (see otherlibs/_graphics/readme.txt for copyright notice)
46
+ \****************************************************************************************/
47
+
48
+ #include "precomp.hpp"
49
+ #include "grfmt_tiff.hpp"
50
+
51
+ namespace cv
52
+ {
53
+ static const char fmtSignTiffII[] = "II\x2a\x00";
54
+ static const char fmtSignTiffMM[] = "MM\x00\x2a";
55
+
56
+ #ifdef HAVE_TIFF
57
+
58
+ #include "tiff.h"
59
+ #include "tiffio.h"
60
+
61
+ static int grfmt_tiff_err_handler_init = 0;
62
+ static void GrFmtSilentTIFFErrorHandler( const char*, const char*, va_list ) {}
63
+
64
+ TiffDecoder::TiffDecoder()
65
+ {
66
+ m_tif = 0;
67
+ if( !grfmt_tiff_err_handler_init )
68
+ {
69
+ grfmt_tiff_err_handler_init = 1;
70
+
71
+ TIFFSetErrorHandler( GrFmtSilentTIFFErrorHandler );
72
+ TIFFSetWarningHandler( GrFmtSilentTIFFErrorHandler );
73
+ }
74
+ }
75
+
76
+
77
+ void TiffDecoder::close()
78
+ {
79
+ if( m_tif )
80
+ {
81
+ TIFF* tif = (TIFF*)m_tif;
82
+ TIFFClose( tif );
83
+ m_tif = 0;
84
+ }
85
+ }
86
+
87
+ TiffDecoder::~TiffDecoder()
88
+ {
89
+ close();
90
+ }
91
+
92
+ size_t TiffDecoder::signatureLength() const
93
+ {
94
+ return 4;
95
+ }
96
+
97
+ bool TiffDecoder::checkSignature( const string& signature ) const
98
+ {
99
+ return signature.size() >= 4 &&
100
+ (memcmp(signature.c_str(), fmtSignTiffII, 4) == 0 ||
101
+ memcmp(signature.c_str(), fmtSignTiffMM, 4) == 0);
102
+ }
103
+
104
+ ImageDecoder TiffDecoder::newDecoder() const
105
+ {
106
+ return new TiffDecoder;
107
+ }
108
+
109
+ bool TiffDecoder::readHeader()
110
+ {
111
+ bool result = false;
112
+
113
+ close();
114
+ TIFF* tif = TIFFOpen( m_filename.c_str(), "rb" );
115
+
116
+ if( tif )
117
+ {
118
+ int width = 0, height = 0, photometric = 0;
119
+ m_tif = tif;
120
+
121
+ if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &width ) &&
122
+ TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &height ) &&
123
+ TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
124
+ {
125
+ int bpp=8, ncn = photometric > 1 ? 3 : 1;
126
+ TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
127
+ TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
128
+
129
+ m_width = width;
130
+ m_height = height;
131
+ if( bpp > 8 &&
132
+ ((photometric != 2 && photometric != 1) ||
133
+ (ncn != 1 && ncn != 3 && ncn != 4)))
134
+ bpp = 8;
135
+
136
+ switch(bpp)
137
+ {
138
+ case 8:
139
+ m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? 3 : 1);
140
+ break;
141
+ case 16:
142
+ m_type = CV_MAKETYPE(CV_16U, photometric > 1 ? 3 : 1);
143
+ break;
144
+
145
+ case 32:
146
+ m_type = CV_MAKETYPE(CV_32F, photometric > 1 ? 3 : 1);
147
+ break;
148
+ case 64:
149
+ m_type = CV_MAKETYPE(CV_64F, photometric > 1 ? 3 : 1);
150
+ break;
151
+
152
+ default:
153
+ result = false;
154
+ }
155
+ result = true;
156
+ }
157
+ }
158
+
159
+ if( !result )
160
+ close();
161
+
162
+ return result;
163
+ }
164
+
165
+
166
+ bool TiffDecoder::readData( Mat& img )
167
+ {
168
+ bool result = false;
169
+ bool color = img.channels() > 1;
170
+ uchar* data = img.data;
171
+ int step = (int)img.step;
172
+
173
+ if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F )
174
+ return false;
175
+
176
+ if( m_tif && m_width && m_height )
177
+ {
178
+ TIFF* tif = (TIFF*)m_tif;
179
+ int tile_width0 = m_width, tile_height0 = 0;
180
+ int x, y, i;
181
+ int is_tiled = TIFFIsTiled(tif);
182
+ int photometric;
183
+ TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
184
+ int bpp = 8, ncn = photometric > 1 ? 3 : 1;
185
+ TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
186
+ TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
187
+ const int bitsPerByte = 8;
188
+ int dst_bpp = (int)(img.elemSize1() * bitsPerByte);
189
+
190
+ if(dst_bpp == 8)
191
+ {
192
+ char errmsg[1024];
193
+ if(!TIFFRGBAImageOK( tif, errmsg ))
194
+ {
195
+ close();
196
+ return false;
197
+ }
198
+ }
199
+
200
+ if( (!is_tiled &&
201
+ TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 )) ||
202
+ (is_tiled &&
203
+ TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) &&
204
+ TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 )))
205
+ {
206
+ if( tile_width0 <= 0 )
207
+ tile_width0 = m_width;
208
+
209
+ if( tile_height0 <= 0 )
210
+ tile_height0 = m_height;
211
+
212
+ AutoBuffer<uchar> _buffer(tile_height0*tile_width0*8);
213
+ uchar* buffer = _buffer;
214
+ ushort* buffer16 = (ushort*)buffer;
215
+ float* buffer32 = (float*)buffer;
216
+ double* buffer64 = (double*)buffer;
217
+ int tileidx = 0;
218
+
219
+ for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 )
220
+ {
221
+ int tile_height = tile_height0;
222
+
223
+ if( y + tile_height > m_height )
224
+ tile_height = m_height - y;
225
+
226
+ for( x = 0; x < m_width; x += tile_width0, tileidx++ )
227
+ {
228
+ int tile_width = tile_width0, ok;
229
+
230
+ if( x + tile_width > m_width )
231
+ tile_width = m_width - x;
232
+
233
+ switch(dst_bpp)
234
+ {
235
+ case 8:
236
+ {
237
+ if( !is_tiled )
238
+ ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
239
+ else
240
+ ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );
241
+
242
+ if( !ok )
243
+ {
244
+ close();
245
+ return false;
246
+ }
247
+
248
+ for( i = 0; i < tile_height; i++ )
249
+ if( color )
250
+ icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
251
+ data + x*3 + step*(tile_height - i - 1), 0,
252
+ cvSize(tile_width,1), 2 );
253
+ else
254
+ icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
255
+ data + x + step*(tile_height - i - 1), 0,
256
+ cvSize(tile_width,1), 2 );
257
+ break;
258
+ }
259
+
260
+ case 16:
261
+ {
262
+ if( !is_tiled )
263
+ ok = (int)TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0;
264
+ else
265
+ ok = (int)TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0;
266
+
267
+ if( !ok )
268
+ {
269
+ close();
270
+ return false;
271
+ }
272
+
273
+ for( i = 0; i < tile_height; i++ )
274
+ {
275
+ if( color )
276
+ {
277
+ if( ncn == 1 )
278
+ {
279
+ icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width*ncn, 0,
280
+ (ushort*)(data + step*i) + x*3, 0,
281
+ cvSize(tile_width,1) );
282
+ }
283
+ else if( ncn == 3 )
284
+ {
285
+ icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width*ncn, 0,
286
+ (ushort*)(data + step*i) + x*3, 0,
287
+ cvSize(tile_width,1) );
288
+ }
289
+ else
290
+ {
291
+ icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width*ncn, 0,
292
+ (ushort*)(data + step*i) + x*3, 0,
293
+ cvSize(tile_width,1), 2 );
294
+ }
295
+ }
296
+ else
297
+ {
298
+ if( ncn == 1 )
299
+ {
300
+ memcpy((ushort*)(data + step*i)+x,
301
+ buffer16 + i*tile_width*ncn,
302
+ tile_width*sizeof(buffer16[0]));
303
+ }
304
+ else
305
+ {
306
+ icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width*ncn, 0,
307
+ (ushort*)(data + step*i) + x, 0,
308
+ cvSize(tile_width,1), ncn, 2 );
309
+ }
310
+ }
311
+ }
312
+ break;
313
+ }
314
+
315
+ case 32:
316
+ case 64:
317
+ {
318
+ if( !is_tiled )
319
+ ok = (int)TIFFReadEncodedStrip( tif, tileidx, buffer, (tsize_t)-1 ) >= 0;
320
+ else
321
+ ok = (int)TIFFReadEncodedTile( tif, tileidx, buffer, (tsize_t)-1 ) >= 0;
322
+
323
+ if( !ok || ncn != 1 )
324
+ {
325
+ close();
326
+ return false;
327
+ }
328
+
329
+ for( i = 0; i < tile_height; i++ )
330
+ {
331
+ if(dst_bpp == 32)
332
+ {
333
+ memcpy((float*)(data + step*i)+x,
334
+ buffer32 + i*tile_width*ncn,
335
+ tile_width*sizeof(buffer32[0]));
336
+ }
337
+ else
338
+ {
339
+ memcpy((double*)(data + step*i)+x,
340
+ buffer64 + i*tile_width*ncn,
341
+ tile_width*sizeof(buffer64[0]));
342
+ }
343
+ }
344
+
345
+ break;
346
+ }
347
+ default:
348
+ {
349
+ close();
350
+ return false;
351
+ }
352
+ }
353
+ }
354
+ }
355
+
356
+ result = true;
357
+ }
358
+ }
359
+
360
+ close();
361
+ return result;
362
+ }
363
+
364
+ #endif
365
+
366
+ //////////////////////////////////////////////////////////////////////////////////////////
367
+
368
+ TiffEncoder::TiffEncoder()
369
+ {
370
+ m_description = "TIFF Files (*.tiff;*.tif)";
371
+ #ifdef HAVE_TIFF
372
+ m_buf_supported = false;
373
+ #else
374
+ m_buf_supported = true;
375
+ #endif
376
+ }
377
+
378
+ TiffEncoder::~TiffEncoder()
379
+ {
380
+ }
381
+
382
+ ImageEncoder TiffEncoder::newEncoder() const
383
+ {
384
+ return new TiffEncoder;
385
+ }
386
+
387
+ bool TiffEncoder::isFormatSupported( int depth ) const
388
+ {
389
+ return depth == CV_8U || depth == CV_16U;
390
+ }
391
+
392
+ void TiffEncoder::writeTag( WLByteStream& strm, TiffTag tag,
393
+ TiffFieldType fieldType,
394
+ int count, int value )
395
+ {
396
+ strm.putWord( tag );
397
+ strm.putWord( fieldType );
398
+ strm.putDWord( count );
399
+ strm.putDWord( value );
400
+ }
401
+
402
+ #ifdef HAVE_TIFF
403
+ bool TiffEncoder::writeLibTiff( const Mat& img, const vector<int>& /*params*/)
404
+ {
405
+ int channels = img.channels();
406
+ int width = img.cols, height = img.rows;
407
+ int depth = img.depth();
408
+
409
+ int bitsPerChannel = -1;
410
+ switch (depth)
411
+ {
412
+ case CV_8U:
413
+ {
414
+ bitsPerChannel = 8;
415
+ break;
416
+ }
417
+ case CV_16U:
418
+ {
419
+ bitsPerChannel = 16;
420
+ break;
421
+ }
422
+ default:
423
+ {
424
+ return false;
425
+ }
426
+ }
427
+
428
+ const int bitsPerByte = 8;
429
+ size_t fileStep = (width * channels * bitsPerChannel) / bitsPerByte;
430
+ int rowsPerStrip = (int)((1 << 13)/fileStep);
431
+
432
+ if( rowsPerStrip < 1 )
433
+ rowsPerStrip = 1;
434
+
435
+ if( rowsPerStrip > height )
436
+ rowsPerStrip = height;
437
+
438
+
439
+ // do NOT put "wb" as the mode, because the b means "big endian" mode, not "binary" mode.
440
+ // http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
441
+ TIFF* pTiffHandle = TIFFOpen(m_filename.c_str(), "w");
442
+ if (!pTiffHandle)
443
+ {
444
+ return false;
445
+ }
446
+
447
+ // defaults for now, maybe base them on params in the future
448
+ int compression = COMPRESSION_LZW;
449
+ int predictor = PREDICTOR_HORIZONTAL;
450
+
451
+ int colorspace = channels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK;
452
+
453
+ if ( !TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width)
454
+ || !TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height)
455
+ || !TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, bitsPerChannel)
456
+ || !TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression)
457
+ || !TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, colorspace)
458
+ || !TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, channels)
459
+ || !TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)
460
+ || !TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, rowsPerStrip)
461
+ || !TIFFSetField(pTiffHandle, TIFFTAG_PREDICTOR, predictor)
462
+ )
463
+ {
464
+ TIFFClose(pTiffHandle);
465
+ return false;
466
+ }
467
+
468
+ // row buffer, because TIFFWriteScanline modifies the original data!
469
+ size_t scanlineSize = TIFFScanlineSize(pTiffHandle);
470
+ AutoBuffer<uchar,1024> _buffer(scanlineSize+32);
471
+ uchar* buffer = _buffer;
472
+ if (!buffer)
473
+ {
474
+ TIFFClose(pTiffHandle);
475
+ return false;
476
+ }
477
+
478
+ for (int y = 0; y < height; ++y)
479
+ {
480
+ switch(channels)
481
+ {
482
+ case 1:
483
+ {
484
+ memcpy(buffer, img.data + img.step * y, scanlineSize);
485
+ break;
486
+ }
487
+
488
+ case 3:
489
+ {
490
+ if (depth == CV_8U)
491
+ icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
492
+ else
493
+ icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
494
+ break;
495
+ }
496
+
497
+ case 4:
498
+ {
499
+ if (depth == CV_8U)
500
+ icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
501
+ else
502
+ icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
503
+ }
504
+
505
+ default:
506
+ {
507
+ TIFFClose(pTiffHandle);
508
+ return false;
509
+ }
510
+ }
511
+
512
+ int writeResult = TIFFWriteScanline(pTiffHandle, buffer, y, 0);
513
+ if (writeResult != 1)
514
+ {
515
+ TIFFClose(pTiffHandle);
516
+ return false;
517
+ }
518
+ }
519
+
520
+ TIFFClose(pTiffHandle);
521
+ return true;
522
+ }
523
+
524
+ #endif
525
+
526
+ #ifdef HAVE_TIFF
527
+ bool TiffEncoder::write( const Mat& img, const vector<int>& params)
528
+ #else
529
+ bool TiffEncoder::write( const Mat& img, const vector<int>& /*params*/)
530
+ #endif
531
+ {
532
+ int channels = img.channels();
533
+ int width = img.cols, height = img.rows;
534
+ int depth = img.depth();
535
+
536
+ if (depth != CV_8U && depth != CV_16U)
537
+ return false;
538
+
539
+ int bytesPerChannel = depth == CV_8U ? 1 : 2;
540
+ int fileStep = width * channels * bytesPerChannel;
541
+
542
+ WLByteStream strm;
543
+
544
+ if( m_buf )
545
+ {
546
+ if( !strm.open(*m_buf) )
547
+ return false;
548
+ }
549
+ else
550
+ {
551
+ #ifdef HAVE_TIFF
552
+ return writeLibTiff(img, params);
553
+ #else
554
+ if( !strm.open(m_filename) )
555
+ return false;
556
+ #endif
557
+ }
558
+
559
+ int rowsPerStrip = (1 << 13)/fileStep;
560
+
561
+ if( rowsPerStrip < 1 )
562
+ rowsPerStrip = 1;
563
+
564
+ if( rowsPerStrip > height )
565
+ rowsPerStrip = height;
566
+
567
+ int i, stripCount = (height + rowsPerStrip - 1) / rowsPerStrip;
568
+
569
+ if( m_buf )
570
+ m_buf->reserve( alignSize(stripCount*8 + fileStep*height + 256, 256) );
571
+
572
+ /*#if defined _DEBUG || !defined WIN32
573
+ int uncompressedRowSize = rowsPerStrip * fileStep;
574
+ #endif*/
575
+ int directoryOffset = 0;
576
+
577
+ AutoBuffer<int,1024> stripOffsets(stripCount);
578
+ AutoBuffer<short,1024> stripCounts(stripCount);
579
+ AutoBuffer<uchar,1024> _buffer(fileStep+32);
580
+ uchar* buffer = _buffer;
581
+ int stripOffsetsOffset = 0;
582
+ int stripCountsOffset = 0;
583
+ int bitsPerSample = 8 * bytesPerChannel;
584
+ int y = 0;
585
+
586
+ strm.putBytes( fmtSignTiffII, 4 );
587
+ strm.putDWord( directoryOffset );
588
+
589
+ // write an image data first (the most reasonable way
590
+ // for compressed images)
591
+ for( i = 0; i < stripCount; i++ )
592
+ {
593
+ int limit = y + rowsPerStrip;
594
+
595
+ if( limit > height )
596
+ limit = height;
597
+
598
+ stripOffsets[i] = strm.getPos();
599
+
600
+ for( ; y < limit; y++ )
601
+ {
602
+ if( channels == 3 )
603
+ {
604
+ if (depth == CV_8U)
605
+ icvCvt_BGR2RGB_8u_C3R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
606
+ else
607
+ icvCvt_BGR2RGB_16u_C3R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
608
+ }
609
+ else
610
+ {
611
+ if( channels == 4 )
612
+ {
613
+ if (depth == CV_8U)
614
+ icvCvt_BGRA2RGBA_8u_C4R( img.data + img.step*y, 0, buffer, 0, cvSize(width,1) );
615
+ else
616
+ icvCvt_BGRA2RGBA_16u_C4R( (const ushort*)(img.data + img.step*y), 0, (ushort*)buffer, 0, cvSize(width,1) );
617
+ }
618
+ }
619
+
620
+ strm.putBytes( channels > 1 ? buffer : img.data + img.step*y, fileStep );
621
+ }
622
+
623
+ stripCounts[i] = (short)(strm.getPos() - stripOffsets[i]);
624
+ /*assert( stripCounts[i] == uncompressedRowSize ||
625
+ stripCounts[i] < uncompressedRowSize &&
626
+ i == stripCount - 1);*/
627
+ }
628
+
629
+ if( stripCount > 2 )
630
+ {
631
+ stripOffsetsOffset = strm.getPos();
632
+ for( i = 0; i < stripCount; i++ )
633
+ strm.putDWord( stripOffsets[i] );
634
+
635
+ stripCountsOffset = strm.getPos();
636
+ for( i = 0; i < stripCount; i++ )
637
+ strm.putWord( stripCounts[i] );
638
+ }
639
+ else if(stripCount == 2)
640
+ {
641
+ stripOffsetsOffset = strm.getPos();
642
+ for (i = 0; i < stripCount; i++)
643
+ {
644
+ strm.putDWord (stripOffsets [i]);
645
+ }
646
+ stripCountsOffset = stripCounts [0] + (stripCounts [1] << 16);
647
+ }
648
+ else
649
+ {
650
+ stripOffsetsOffset = stripOffsets[0];
651
+ stripCountsOffset = stripCounts[0];
652
+ }
653
+
654
+ if( channels > 1 )
655
+ {
656
+ int bitsPerSamplePos = strm.getPos();
657
+ strm.putWord(bitsPerSample);
658
+ strm.putWord(bitsPerSample);
659
+ strm.putWord(bitsPerSample);
660
+ if( channels == 4 )
661
+ strm.putWord(bitsPerSample);
662
+ bitsPerSample = bitsPerSamplePos;
663
+ }
664
+
665
+ directoryOffset = strm.getPos();
666
+
667
+ // write header
668
+ strm.putWord( 9 );
669
+
670
+ /* warning: specification 5.0 of Tiff want to have tags in
671
+ ascending order. This is a non-fatal error, but this cause
672
+ warning with some tools. So, keep this in ascending order */
673
+
674
+ writeTag( strm, TIFF_TAG_WIDTH, TIFF_TYPE_LONG, 1, width );
675
+ writeTag( strm, TIFF_TAG_HEIGHT, TIFF_TYPE_LONG, 1, height );
676
+ writeTag( strm, TIFF_TAG_BITS_PER_SAMPLE,
677
+ TIFF_TYPE_SHORT, channels, bitsPerSample );
678
+ writeTag( strm, TIFF_TAG_COMPRESSION, TIFF_TYPE_LONG, 1, TIFF_UNCOMP );
679
+ writeTag( strm, TIFF_TAG_PHOTOMETRIC, TIFF_TYPE_SHORT, 1, channels > 1 ? 2 : 1 );
680
+
681
+ writeTag( strm, TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG,
682
+ stripCount, stripOffsetsOffset );
683
+
684
+ writeTag( strm, TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, channels );
685
+ writeTag( strm, TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, rowsPerStrip );
686
+
687
+ writeTag( strm, TIFF_TAG_STRIP_COUNTS,
688
+ stripCount > 1 ? TIFF_TYPE_SHORT : TIFF_TYPE_LONG,
689
+ stripCount, stripCountsOffset );
690
+
691
+ strm.putDWord(0);
692
+ strm.close();
693
+
694
+ if( m_buf )
695
+ {
696
+ (*m_buf)[4] = (uchar)directoryOffset;
697
+ (*m_buf)[5] = (uchar)(directoryOffset >> 8);
698
+ (*m_buf)[6] = (uchar)(directoryOffset >> 16);
699
+ (*m_buf)[7] = (uchar)(directoryOffset >> 24);
700
+ }
701
+ else
702
+ {
703
+ // write directory offset
704
+ FILE* f = fopen( m_filename.c_str(), "r+b" );
705
+ buffer[0] = (uchar)directoryOffset;
706
+ buffer[1] = (uchar)(directoryOffset >> 8);
707
+ buffer[2] = (uchar)(directoryOffset >> 16);
708
+ buffer[3] = (uchar)(directoryOffset >> 24);
709
+
710
+ fseek( f, 4, SEEK_SET );
711
+ fwrite( buffer, 1, 4, f );
712
+ fclose(f);
713
+ }
714
+
715
+ return true;
716
+ }
717
+
718
+ }