imagecore 0.0.1

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.
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
+ }