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,3206 @@
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
+ // Intel License Agreement
11
+ // For Open Source Computer Vision Library
12
+ //
13
+ // Copyright (C) 2000, Intel Corporation, all rights reserved.
14
+ // Third party copyrights are property of their respective owners.
15
+ //
16
+ // Redistribution and use in source and binary forms, with or without modification,
17
+ // are permitted provided that the following conditions are met:
18
+ //
19
+ // * Redistribution's of source code must retain the above copyright notice,
20
+ // this list of conditions and the following disclaimer.
21
+ //
22
+ // * Redistribution's in binary form must reproduce the above copyright notice,
23
+ // this list of conditions and the following disclaimer in the documentation
24
+ // and/or other materials provided with the distribution.
25
+ //
26
+ // * The name of Intel Corporation may not be used to endorse or promote products
27
+ // derived from this software without specific prior written permission.
28
+ //
29
+ // This software is provided by the copyright holders and contributors "as is" and
30
+ // any express or implied warranties, including, but not limited to, the implied
31
+ // warranties of merchantability and fitness for a particular purpose are disclaimed.
32
+ // In no event shall the Intel Corporation or contributors be liable for any direct,
33
+ // indirect, incidental, special, exemplary, or consequential damages
34
+ // (including, but not limited to, procurement of substitute goods or services;
35
+ // loss of use, data, or profits; or business interruption) however caused
36
+ // and on any theory of liability, whether in contract, strict liability,
37
+ // or tort (including negligence or otherwise) arising in any way out of
38
+ // the use of this software, even if advised of the possibility of such damage.
39
+ //
40
+ //M*/
41
+
42
+ /* ////////////////////////////////////////////////////////////////////
43
+ //
44
+ // CvMat, CvMatND, CvSparceMat and IplImage support functions
45
+ // (creation, deletion, copying, retrieving and setting elements etc.)
46
+ //
47
+ // */
48
+
49
+ #include "precomp.hpp"
50
+
51
+
52
+ static struct
53
+ {
54
+ Cv_iplCreateImageHeader createHeader;
55
+ Cv_iplAllocateImageData allocateData;
56
+ Cv_iplDeallocate deallocate;
57
+ Cv_iplCreateROI createROI;
58
+ Cv_iplCloneImage cloneImage;
59
+ }
60
+ CvIPL;
61
+
62
+ // Makes the library use native IPL image allocators
63
+ CV_IMPL void
64
+ cvSetIPLAllocators( Cv_iplCreateImageHeader createHeader,
65
+ Cv_iplAllocateImageData allocateData,
66
+ Cv_iplDeallocate deallocate,
67
+ Cv_iplCreateROI createROI,
68
+ Cv_iplCloneImage cloneImage )
69
+ {
70
+ int count = (createHeader != 0) + (allocateData != 0) + (deallocate != 0) +
71
+ (createROI != 0) + (cloneImage != 0);
72
+
73
+ if( count != 0 && count != 5 )
74
+ CV_Error( CV_StsBadArg, "Either all the pointers should be null or "
75
+ "they all should be non-null" );
76
+
77
+ CvIPL.createHeader = createHeader;
78
+ CvIPL.allocateData = allocateData;
79
+ CvIPL.deallocate = deallocate;
80
+ CvIPL.createROI = createROI;
81
+ CvIPL.cloneImage = cloneImage;
82
+ }
83
+
84
+
85
+ /****************************************************************************************\
86
+ * CvMat creation and basic operations *
87
+ \****************************************************************************************/
88
+
89
+ // Creates CvMat and underlying data
90
+ CV_IMPL CvMat*
91
+ cvCreateMat( int height, int width, int type )
92
+ {
93
+ CvMat* arr = cvCreateMatHeader( height, width, type );
94
+ cvCreateData( arr );
95
+
96
+ return arr;
97
+ }
98
+
99
+
100
+ static void icvCheckHuge( CvMat* arr )
101
+ {
102
+ if( (int64)arr->step*arr->rows > INT_MAX )
103
+ arr->type &= ~CV_MAT_CONT_FLAG;
104
+ }
105
+
106
+ // Creates CvMat header only
107
+ CV_IMPL CvMat*
108
+ cvCreateMatHeader( int rows, int cols, int type )
109
+ {
110
+ type = CV_MAT_TYPE(type);
111
+
112
+ if( rows < 0 || cols <= 0 )
113
+ CV_Error( CV_StsBadSize, "Non-positive width or height" );
114
+
115
+ int min_step = CV_ELEM_SIZE(type)*cols;
116
+ if( min_step <= 0 )
117
+ CV_Error( CV_StsUnsupportedFormat, "Invalid matrix type" );
118
+
119
+ CvMat* arr = (CvMat*)cvAlloc( sizeof(*arr));
120
+
121
+ arr->step = min_step;
122
+ arr->type = CV_MAT_MAGIC_VAL | type | CV_MAT_CONT_FLAG;
123
+ arr->rows = rows;
124
+ arr->cols = cols;
125
+ arr->data.ptr = 0;
126
+ arr->refcount = 0;
127
+ arr->hdr_refcount = 1;
128
+
129
+ icvCheckHuge( arr );
130
+ return arr;
131
+ }
132
+
133
+
134
+ // Initializes CvMat header, allocated by the user
135
+ CV_IMPL CvMat*
136
+ cvInitMatHeader( CvMat* arr, int rows, int cols,
137
+ int type, void* data, int step )
138
+ {
139
+ if( !arr )
140
+ CV_Error( CV_StsNullPtr, "" );
141
+
142
+ if( (unsigned)CV_MAT_DEPTH(type) > CV_DEPTH_MAX )
143
+ CV_Error( CV_BadNumChannels, "" );
144
+
145
+ if( rows < 0 || cols <= 0 )
146
+ CV_Error( CV_StsBadSize, "Non-positive cols or rows" );
147
+
148
+ type = CV_MAT_TYPE( type );
149
+ arr->type = type | CV_MAT_MAGIC_VAL;
150
+ arr->rows = rows;
151
+ arr->cols = cols;
152
+ arr->data.ptr = (uchar*)data;
153
+ arr->refcount = 0;
154
+ arr->hdr_refcount = 0;
155
+
156
+ int pix_size = CV_ELEM_SIZE(type);
157
+ int min_step = arr->cols*pix_size;
158
+
159
+ if( step != CV_AUTOSTEP && step != 0 )
160
+ {
161
+ if( step < min_step )
162
+ CV_Error( CV_BadStep, "" );
163
+ arr->step = step;
164
+ }
165
+ else
166
+ {
167
+ arr->step = min_step;
168
+ }
169
+
170
+ arr->type = CV_MAT_MAGIC_VAL | type |
171
+ (arr->rows == 1 || arr->step == min_step ? CV_MAT_CONT_FLAG : 0);
172
+
173
+ icvCheckHuge( arr );
174
+ return arr;
175
+ }
176
+
177
+
178
+ // Deallocates the CvMat structure and underlying data
179
+ CV_IMPL void
180
+ cvReleaseMat( CvMat** array )
181
+ {
182
+ if( !array )
183
+ CV_Error( CV_HeaderIsNull, "" );
184
+
185
+ if( *array )
186
+ {
187
+ CvMat* arr = *array;
188
+
189
+ if( !CV_IS_MAT_HDR_Z(arr) && !CV_IS_MATND_HDR(arr) )
190
+ CV_Error( CV_StsBadFlag, "" );
191
+
192
+ *array = 0;
193
+
194
+ cvDecRefData( arr );
195
+ cvFree( &arr );
196
+ }
197
+ }
198
+
199
+
200
+ // Creates a copy of matrix
201
+ CV_IMPL CvMat*
202
+ cvCloneMat( const CvMat* src )
203
+ {
204
+ if( !CV_IS_MAT_HDR( src ))
205
+ CV_Error( CV_StsBadArg, "Bad CvMat header" );
206
+
207
+ CvMat* dst = cvCreateMatHeader( src->rows, src->cols, src->type );
208
+
209
+ if( src->data.ptr )
210
+ {
211
+ cvCreateData( dst );
212
+ cvCopy( src, dst );
213
+ }
214
+
215
+ return dst;
216
+ }
217
+
218
+
219
+ /****************************************************************************************\
220
+ * CvMatND creation and basic operations *
221
+ \****************************************************************************************/
222
+
223
+ CV_IMPL CvMatND*
224
+ cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes,
225
+ int type, void* data )
226
+ {
227
+ type = CV_MAT_TYPE(type);
228
+ int64 step = CV_ELEM_SIZE(type);
229
+
230
+ if( !mat )
231
+ CV_Error( CV_StsNullPtr, "NULL matrix header pointer" );
232
+
233
+ if( step == 0 )
234
+ CV_Error( CV_StsUnsupportedFormat, "invalid array data type" );
235
+
236
+ if( !sizes )
237
+ CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" );
238
+
239
+ if( dims <= 0 || dims > CV_MAX_DIM )
240
+ CV_Error( CV_StsOutOfRange,
241
+ "non-positive or too large number of dimensions" );
242
+
243
+ for( int i = dims - 1; i >= 0; i-- )
244
+ {
245
+ if( sizes[i] < 0 )
246
+ CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
247
+ mat->dim[i].size = sizes[i];
248
+ if( step > INT_MAX )
249
+ CV_Error( CV_StsOutOfRange, "The array is too big" );
250
+ mat->dim[i].step = (int)step;
251
+ step *= sizes[i];
252
+ }
253
+
254
+ mat->type = CV_MATND_MAGIC_VAL | (step <= INT_MAX ? CV_MAT_CONT_FLAG : 0) | type;
255
+ mat->dims = dims;
256
+ mat->data.ptr = (uchar*)data;
257
+ mat->refcount = 0;
258
+ mat->hdr_refcount = 0;
259
+ return mat;
260
+ }
261
+
262
+
263
+ // Creates CvMatND and underlying data
264
+ CV_IMPL CvMatND*
265
+ cvCreateMatND( int dims, const int* sizes, int type )
266
+ {
267
+ CvMatND* arr = cvCreateMatNDHeader( dims, sizes, type );
268
+ cvCreateData( arr );
269
+
270
+ return arr;
271
+ }
272
+
273
+
274
+ // Creates CvMatND header only
275
+ CV_IMPL CvMatND*
276
+ cvCreateMatNDHeader( int dims, const int* sizes, int type )
277
+ {
278
+ if( dims <= 0 || dims > CV_MAX_DIM )
279
+ CV_Error( CV_StsOutOfRange,
280
+ "non-positive or too large number of dimensions" );
281
+
282
+ CvMatND* arr = (CvMatND*)cvAlloc( sizeof(*arr) );
283
+
284
+ cvInitMatNDHeader( arr, dims, sizes, type, 0 );
285
+ arr->hdr_refcount = 1;
286
+ return arr;
287
+ }
288
+
289
+
290
+ // Creates a copy of nD array
291
+ CV_IMPL CvMatND*
292
+ cvCloneMatND( const CvMatND* src )
293
+ {
294
+ if( !CV_IS_MATND_HDR( src ))
295
+ CV_Error( CV_StsBadArg, "Bad CvMatND header" );
296
+
297
+ CV_Assert( src->dims <= CV_MAX_DIM );
298
+ int sizes[CV_MAX_DIM];
299
+
300
+ for( int i = 0; i < src->dims; i++ )
301
+ sizes[i] = src->dim[i].size;
302
+
303
+ CvMatND* dst = cvCreateMatNDHeader( src->dims, sizes, src->type );
304
+
305
+ if( src->data.ptr )
306
+ {
307
+ cvCreateData( dst );
308
+ cv::Mat _src(src), _dst(dst);
309
+ uchar* data0 = dst->data.ptr;
310
+ _src.copyTo(_dst);
311
+ CV_Assert(_dst.data == data0);
312
+ //cvCopy( src, dst );
313
+ }
314
+
315
+ return dst;
316
+ }
317
+
318
+
319
+ static CvMatND*
320
+ cvGetMatND( const CvArr* arr, CvMatND* matnd, int* coi )
321
+ {
322
+ CvMatND* result = 0;
323
+
324
+ if( coi )
325
+ *coi = 0;
326
+
327
+ if( !matnd || !arr )
328
+ CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
329
+
330
+ if( CV_IS_MATND_HDR(arr))
331
+ {
332
+ if( !((CvMatND*)arr)->data.ptr )
333
+ CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
334
+
335
+ result = (CvMatND*)arr;
336
+ }
337
+ else
338
+ {
339
+ CvMat stub, *mat = (CvMat*)arr;
340
+
341
+ if( CV_IS_IMAGE_HDR( mat ))
342
+ mat = cvGetMat( mat, &stub, coi );
343
+
344
+ if( !CV_IS_MAT_HDR( mat ))
345
+ CV_Error( CV_StsBadArg, "Unrecognized or unsupported array type" );
346
+
347
+ if( !mat->data.ptr )
348
+ CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
349
+
350
+ matnd->data.ptr = mat->data.ptr;
351
+ matnd->refcount = 0;
352
+ matnd->hdr_refcount = 0;
353
+ matnd->type = mat->type;
354
+ matnd->dims = 2;
355
+ matnd->dim[0].size = mat->rows;
356
+ matnd->dim[0].step = mat->step;
357
+ matnd->dim[1].size = mat->cols;
358
+ matnd->dim[1].step = CV_ELEM_SIZE(mat->type);
359
+ result = matnd;
360
+ }
361
+
362
+ return result;
363
+ }
364
+
365
+
366
+ // returns number of dimensions to iterate.
367
+ /*
368
+ Checks whether <count> arrays have equal type, sizes (mask is optional array
369
+ that needs to have the same size, but 8uC1 or 8sC1 type).
370
+ Returns number of dimensions to iterate through:
371
+ 0 means that all arrays are continuous,
372
+ 1 means that all arrays are vectors of continuous arrays etc.
373
+ and the size of largest common continuous part of the arrays
374
+ */
375
+ CV_IMPL int
376
+ cvInitNArrayIterator( int count, CvArr** arrs,
377
+ const CvArr* mask, CvMatND* stubs,
378
+ CvNArrayIterator* iterator, int flags )
379
+ {
380
+ int dims = -1;
381
+ int i, j, size, dim0 = -1;
382
+ int64 step;
383
+ CvMatND* hdr0 = 0;
384
+
385
+ if( count < 1 || count > CV_MAX_ARR )
386
+ CV_Error( CV_StsOutOfRange, "Incorrect number of arrays" );
387
+
388
+ if( !arrs || !stubs )
389
+ CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" );
390
+
391
+ if( !iterator )
392
+ CV_Error( CV_StsNullPtr, "Iterator pointer is NULL" );
393
+
394
+ for( i = 0; i <= count; i++ )
395
+ {
396
+ const CvArr* arr = i < count ? arrs[i] : mask;
397
+ CvMatND* hdr;
398
+
399
+ if( !arr )
400
+ {
401
+ if( i < count )
402
+ CV_Error( CV_StsNullPtr, "Some of required array pointers is NULL" );
403
+ break;
404
+ }
405
+
406
+ if( CV_IS_MATND( arr ))
407
+ hdr = (CvMatND*)arr;
408
+ else
409
+ {
410
+ int coi = 0;
411
+ hdr = cvGetMatND( arr, stubs + i, &coi );
412
+ if( coi != 0 )
413
+ CV_Error( CV_BadCOI, "COI set is not allowed here" );
414
+ }
415
+
416
+ iterator->hdr[i] = hdr;
417
+
418
+ if( i > 0 )
419
+ {
420
+ if( hdr->dims != hdr0->dims )
421
+ CV_Error( CV_StsUnmatchedSizes,
422
+ "Number of dimensions is the same for all arrays" );
423
+
424
+ if( i < count )
425
+ {
426
+ switch( flags & (CV_NO_DEPTH_CHECK|CV_NO_CN_CHECK))
427
+ {
428
+ case 0:
429
+ if( !CV_ARE_TYPES_EQ( hdr, hdr0 ))
430
+ CV_Error( CV_StsUnmatchedFormats,
431
+ "Data type is not the same for all arrays" );
432
+ break;
433
+ case CV_NO_DEPTH_CHECK:
434
+ if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
435
+ CV_Error( CV_StsUnmatchedFormats,
436
+ "Number of channels is not the same for all arrays" );
437
+ break;
438
+ case CV_NO_CN_CHECK:
439
+ if( !CV_ARE_CNS_EQ( hdr, hdr0 ))
440
+ CV_Error( CV_StsUnmatchedFormats,
441
+ "Depth is not the same for all arrays" );
442
+ break;
443
+ }
444
+ }
445
+ else
446
+ {
447
+ if( !CV_IS_MASK_ARR( hdr ))
448
+ CV_Error( CV_StsBadMask, "Mask should have 8uC1 or 8sC1 data type" );
449
+ }
450
+
451
+ if( !(flags & CV_NO_SIZE_CHECK) )
452
+ {
453
+ for( j = 0; j < hdr->dims; j++ )
454
+ if( hdr->dim[j].size != hdr0->dim[j].size )
455
+ CV_Error( CV_StsUnmatchedSizes,
456
+ "Dimension sizes are the same for all arrays" );
457
+ }
458
+ }
459
+ else
460
+ hdr0 = hdr;
461
+
462
+ step = CV_ELEM_SIZE(hdr->type);
463
+ for( j = hdr->dims - 1; j > dim0; j-- )
464
+ {
465
+ if( step != hdr->dim[j].step )
466
+ break;
467
+ step *= hdr->dim[j].size;
468
+ }
469
+
470
+ if( j == dim0 && step > INT_MAX )
471
+ j++;
472
+
473
+ if( j > dim0 )
474
+ dim0 = j;
475
+
476
+ iterator->hdr[i] = (CvMatND*)hdr;
477
+ iterator->ptr[i] = (uchar*)hdr->data.ptr;
478
+ }
479
+
480
+ size = 1;
481
+ for( j = hdr0->dims - 1; j > dim0; j-- )
482
+ size *= hdr0->dim[j].size;
483
+
484
+ dims = dim0 + 1;
485
+ iterator->dims = dims;
486
+ iterator->count = count;
487
+ iterator->size = cvSize(size,1);
488
+
489
+ for( i = 0; i < dims; i++ )
490
+ iterator->stack[i] = hdr0->dim[i].size;
491
+
492
+ return dims;
493
+ }
494
+
495
+
496
+ // returns zero value if iteration is finished, non-zero otherwise
497
+ CV_IMPL int cvNextNArraySlice( CvNArrayIterator* iterator )
498
+ {
499
+ assert( iterator != 0 );
500
+ int i, dims, size = 0;
501
+
502
+ for( dims = iterator->dims; dims > 0; dims-- )
503
+ {
504
+ for( i = 0; i < iterator->count; i++ )
505
+ iterator->ptr[i] += iterator->hdr[i]->dim[dims-1].step;
506
+
507
+ if( --iterator->stack[dims-1] > 0 )
508
+ break;
509
+
510
+ size = iterator->hdr[0]->dim[dims-1].size;
511
+
512
+ for( i = 0; i < iterator->count; i++ )
513
+ iterator->ptr[i] -= (size_t)size*iterator->hdr[i]->dim[dims-1].step;
514
+
515
+ iterator->stack[dims-1] = size;
516
+ }
517
+
518
+ return dims > 0;
519
+ }
520
+
521
+
522
+ /****************************************************************************************\
523
+ * CvSparseMat creation and basic operations *
524
+ \****************************************************************************************/
525
+
526
+
527
+ // Creates CvMatND and underlying data
528
+ CV_IMPL CvSparseMat*
529
+ cvCreateSparseMat( int dims, const int* sizes, int type )
530
+ {
531
+ type = CV_MAT_TYPE( type );
532
+ int pix_size1 = CV_ELEM_SIZE1(type);
533
+ int pix_size = pix_size1*CV_MAT_CN(type);
534
+ int i, size;
535
+ CvMemStorage* storage;
536
+
537
+ if( pix_size == 0 )
538
+ CV_Error( CV_StsUnsupportedFormat, "invalid array data type" );
539
+
540
+ if( dims <= 0 || dims > CV_MAX_DIM_HEAP )
541
+ CV_Error( CV_StsOutOfRange, "bad number of dimensions" );
542
+
543
+ if( !sizes )
544
+ CV_Error( CV_StsNullPtr, "NULL <sizes> pointer" );
545
+
546
+ for( i = 0; i < dims; i++ )
547
+ {
548
+ if( sizes[i] <= 0 )
549
+ CV_Error( CV_StsBadSize, "one of dimesion sizes is non-positive" );
550
+ }
551
+
552
+ CvSparseMat* arr = (CvSparseMat*)cvAlloc(sizeof(*arr)+MAX(0,dims-CV_MAX_DIM)*sizeof(arr->size[0]));
553
+
554
+ arr->type = CV_SPARSE_MAT_MAGIC_VAL | type;
555
+ arr->dims = dims;
556
+ arr->refcount = 0;
557
+ arr->hdr_refcount = 1;
558
+ memcpy( arr->size, sizes, dims*sizeof(sizes[0]));
559
+
560
+ arr->valoffset = (int)cvAlign(sizeof(CvSparseNode), pix_size1);
561
+ arr->idxoffset = (int)cvAlign(arr->valoffset + pix_size, sizeof(int));
562
+ size = (int)cvAlign(arr->idxoffset + dims*sizeof(int), sizeof(CvSetElem));
563
+
564
+ storage = cvCreateMemStorage( CV_SPARSE_MAT_BLOCK );
565
+ arr->heap = cvCreateSet( 0, sizeof(CvSet), size, storage );
566
+
567
+ arr->hashsize = CV_SPARSE_HASH_SIZE0;
568
+ size = arr->hashsize*sizeof(arr->hashtable[0]);
569
+
570
+ arr->hashtable = (void**)cvAlloc( size );
571
+ memset( arr->hashtable, 0, size );
572
+
573
+ return arr;
574
+ }
575
+
576
+
577
+ // Creates CvMatND and underlying data
578
+ CV_IMPL void
579
+ cvReleaseSparseMat( CvSparseMat** array )
580
+ {
581
+ if( !array )
582
+ CV_Error( CV_HeaderIsNull, "" );
583
+
584
+ if( *array )
585
+ {
586
+ CvSparseMat* arr = *array;
587
+
588
+ if( !CV_IS_SPARSE_MAT_HDR(arr) )
589
+ CV_Error( CV_StsBadFlag, "" );
590
+
591
+ *array = 0;
592
+
593
+ CvMemStorage* storage = arr->heap->storage;
594
+ cvReleaseMemStorage( &storage );
595
+ cvFree( &arr->hashtable );
596
+ cvFree( &arr );
597
+ }
598
+ }
599
+
600
+
601
+ // Creates CvMatND and underlying data
602
+ CV_IMPL CvSparseMat*
603
+ cvCloneSparseMat( const CvSparseMat* src )
604
+ {
605
+ if( !CV_IS_SPARSE_MAT_HDR(src) )
606
+ CV_Error( CV_StsBadArg, "Invalid sparse array header" );
607
+
608
+ CvSparseMat* dst = cvCreateSparseMat( src->dims, src->size, src->type );
609
+ cvCopy( src, dst );
610
+ return dst;
611
+ }
612
+
613
+
614
+ CvSparseNode*
615
+ cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* iterator )
616
+ {
617
+ CvSparseNode* node = 0;
618
+ int idx;
619
+
620
+ if( !CV_IS_SPARSE_MAT( mat ))
621
+ CV_Error( CV_StsBadArg, "Invalid sparse matrix header" );
622
+
623
+ if( !iterator )
624
+ CV_Error( CV_StsNullPtr, "NULL iterator pointer" );
625
+
626
+ iterator->mat = (CvSparseMat*)mat;
627
+ iterator->node = 0;
628
+
629
+ for( idx = 0; idx < mat->hashsize; idx++ )
630
+ if( mat->hashtable[idx] )
631
+ {
632
+ node = iterator->node = (CvSparseNode*)mat->hashtable[idx];
633
+ break;
634
+ }
635
+
636
+ iterator->curidx = idx;
637
+ return node;
638
+ }
639
+
640
+ #define ICV_SPARSE_MAT_HASH_MULTIPLIER cv::SparseMat::HASH_SCALE
641
+
642
+ static uchar*
643
+ icvGetNodePtr( CvSparseMat* mat, const int* idx, int* _type,
644
+ int create_node, unsigned* precalc_hashval )
645
+ {
646
+ uchar* ptr = 0;
647
+ int i, tabidx;
648
+ unsigned hashval = 0;
649
+ CvSparseNode *node;
650
+ assert( CV_IS_SPARSE_MAT( mat ));
651
+
652
+ if( !precalc_hashval )
653
+ {
654
+ for( i = 0; i < mat->dims; i++ )
655
+ {
656
+ int t = idx[i];
657
+ if( (unsigned)t >= (unsigned)mat->size[i] )
658
+ CV_Error( CV_StsOutOfRange, "One of indices is out of range" );
659
+ hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
660
+ }
661
+ }
662
+ else
663
+ {
664
+ hashval = *precalc_hashval;
665
+ }
666
+
667
+ tabidx = hashval & (mat->hashsize - 1);
668
+ hashval &= INT_MAX;
669
+
670
+ if( create_node >= -1 )
671
+ {
672
+ for( node = (CvSparseNode*)mat->hashtable[tabidx];
673
+ node != 0; node = node->next )
674
+ {
675
+ if( node->hashval == hashval )
676
+ {
677
+ int* nodeidx = CV_NODE_IDX(mat,node);
678
+ for( i = 0; i < mat->dims; i++ )
679
+ if( idx[i] != nodeidx[i] )
680
+ break;
681
+ if( i == mat->dims )
682
+ {
683
+ ptr = (uchar*)CV_NODE_VAL(mat,node);
684
+ break;
685
+ }
686
+ }
687
+ }
688
+ }
689
+
690
+ if( !ptr && create_node )
691
+ {
692
+ if( mat->heap->active_count >= mat->hashsize*CV_SPARSE_HASH_RATIO )
693
+ {
694
+ void** newtable;
695
+ int newsize = MAX( mat->hashsize*2, CV_SPARSE_HASH_SIZE0);
696
+ int newrawsize = newsize*sizeof(newtable[0]);
697
+
698
+ CvSparseMatIterator iterator;
699
+ assert( (newsize & (newsize - 1)) == 0 );
700
+
701
+ // resize hash table
702
+ newtable = (void**)cvAlloc( newrawsize );
703
+ memset( newtable, 0, newrawsize );
704
+
705
+ node = cvInitSparseMatIterator( mat, &iterator );
706
+ while( node )
707
+ {
708
+ CvSparseNode* next = cvGetNextSparseNode( &iterator );
709
+ int newidx = node->hashval & (newsize - 1);
710
+ node->next = (CvSparseNode*)newtable[newidx];
711
+ newtable[newidx] = node;
712
+ node = next;
713
+ }
714
+
715
+ cvFree( &mat->hashtable );
716
+ mat->hashtable = newtable;
717
+ mat->hashsize = newsize;
718
+ tabidx = hashval & (newsize - 1);
719
+ }
720
+
721
+ node = (CvSparseNode*)cvSetNew( mat->heap );
722
+ node->hashval = hashval;
723
+ node->next = (CvSparseNode*)mat->hashtable[tabidx];
724
+ mat->hashtable[tabidx] = node;
725
+ memcpy(CV_NODE_IDX(mat,node), idx, mat->dims*sizeof(idx[0]));
726
+ ptr = (uchar*)CV_NODE_VAL(mat,node);
727
+ if( create_node > 0 )
728
+ memset( ptr, 0, CV_ELEM_SIZE(mat->type));
729
+ }
730
+
731
+ if( _type )
732
+ *_type = CV_MAT_TYPE(mat->type);
733
+
734
+ return ptr;
735
+ }
736
+
737
+
738
+ static void
739
+ icvDeleteNode( CvSparseMat* mat, const int* idx, unsigned* precalc_hashval )
740
+ {
741
+ int i, tabidx;
742
+ unsigned hashval = 0;
743
+ CvSparseNode *node, *prev = 0;
744
+ assert( CV_IS_SPARSE_MAT( mat ));
745
+
746
+ if( !precalc_hashval )
747
+ {
748
+ for( i = 0; i < mat->dims; i++ )
749
+ {
750
+ int t = idx[i];
751
+ if( (unsigned)t >= (unsigned)mat->size[i] )
752
+ CV_Error( CV_StsOutOfRange, "One of indices is out of range" );
753
+ hashval = hashval*ICV_SPARSE_MAT_HASH_MULTIPLIER + t;
754
+ }
755
+ }
756
+ else
757
+ {
758
+ hashval = *precalc_hashval;
759
+ }
760
+
761
+ tabidx = hashval & (mat->hashsize - 1);
762
+ hashval &= INT_MAX;
763
+
764
+ for( node = (CvSparseNode*)mat->hashtable[tabidx];
765
+ node != 0; prev = node, node = node->next )
766
+ {
767
+ if( node->hashval == hashval )
768
+ {
769
+ int* nodeidx = CV_NODE_IDX(mat,node);
770
+ for( i = 0; i < mat->dims; i++ )
771
+ if( idx[i] != nodeidx[i] )
772
+ break;
773
+ if( i == mat->dims )
774
+ break;
775
+ }
776
+ }
777
+
778
+ if( node )
779
+ {
780
+ if( prev )
781
+ prev->next = node->next;
782
+ else
783
+ mat->hashtable[tabidx] = node->next;
784
+ cvSetRemoveByPtr( mat->heap, node );
785
+ }
786
+ }
787
+
788
+
789
+ /****************************************************************************************\
790
+ * Common for multiple array types operations *
791
+ \****************************************************************************************/
792
+
793
+ // Allocates underlying array data
794
+ CV_IMPL void
795
+ cvCreateData( CvArr* arr )
796
+ {
797
+ if( CV_IS_MAT_HDR_Z( arr ))
798
+ {
799
+ size_t step, total_size;
800
+ CvMat* mat = (CvMat*)arr;
801
+ step = mat->step;
802
+
803
+ if( mat->rows == 0 || mat->cols == 0 )
804
+ return;
805
+
806
+ if( mat->data.ptr != 0 )
807
+ CV_Error( CV_StsError, "Data is already allocated" );
808
+
809
+ if( step == 0 )
810
+ step = CV_ELEM_SIZE(mat->type)*mat->cols;
811
+
812
+ int64 _total_size = (int64)step*mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
813
+ total_size = (size_t)_total_size;
814
+ if(_total_size != (int64)total_size)
815
+ CV_Error(CV_StsNoMem, "Too big buffer is allocated" );
816
+ mat->refcount = (int*)cvAlloc( (size_t)total_size );
817
+ mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
818
+ *mat->refcount = 1;
819
+ }
820
+ else if( CV_IS_IMAGE_HDR(arr))
821
+ {
822
+ IplImage* img = (IplImage*)arr;
823
+
824
+ if( img->imageData != 0 )
825
+ CV_Error( CV_StsError, "Data is already allocated" );
826
+
827
+ if( !CvIPL.allocateData )
828
+ {
829
+ img->imageData = img->imageDataOrigin =
830
+ (char*)cvAlloc( (size_t)img->imageSize );
831
+ }
832
+ else
833
+ {
834
+ int depth = img->depth;
835
+ int width = img->width;
836
+
837
+ if( img->depth == IPL_DEPTH_32F || img->depth == IPL_DEPTH_64F )
838
+ {
839
+ img->width *= img->depth == IPL_DEPTH_32F ? sizeof(float) : sizeof(double);
840
+ img->depth = IPL_DEPTH_8U;
841
+ }
842
+
843
+ CvIPL.allocateData( img, 0, 0 );
844
+
845
+ img->width = width;
846
+ img->depth = depth;
847
+ }
848
+ }
849
+ else if( CV_IS_MATND_HDR( arr ))
850
+ {
851
+ CvMatND* mat = (CvMatND*)arr;
852
+ int i;
853
+ size_t total_size = CV_ELEM_SIZE(mat->type);
854
+
855
+ if( mat->dim[0].size == 0 )
856
+ return;
857
+
858
+ if( mat->data.ptr != 0 )
859
+ CV_Error( CV_StsError, "Data is already allocated" );
860
+
861
+ if( CV_IS_MAT_CONT( mat->type ))
862
+ {
863
+ total_size = (size_t)mat->dim[0].size*(mat->dim[0].step != 0 ?
864
+ mat->dim[0].step : total_size);
865
+ }
866
+ else
867
+ {
868
+ for( i = mat->dims - 1; i >= 0; i-- )
869
+ {
870
+ size_t size = (size_t)mat->dim[i].step*mat->dim[i].size;
871
+
872
+ if( total_size < size )
873
+ total_size = size;
874
+ }
875
+ }
876
+
877
+ mat->refcount = (int*)cvAlloc( total_size +
878
+ sizeof(int) + CV_MALLOC_ALIGN );
879
+ mat->data.ptr = (uchar*)cvAlignPtr( mat->refcount + 1, CV_MALLOC_ALIGN );
880
+ *mat->refcount = 1;
881
+ }
882
+ else
883
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
884
+ }
885
+
886
+
887
+ // Assigns external data to array
888
+ CV_IMPL void
889
+ cvSetData( CvArr* arr, void* data, int step )
890
+ {
891
+ int pix_size, min_step;
892
+
893
+ if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) )
894
+ cvReleaseData( arr );
895
+
896
+ if( CV_IS_MAT_HDR( arr ))
897
+ {
898
+ CvMat* mat = (CvMat*)arr;
899
+
900
+ int type = CV_MAT_TYPE(mat->type);
901
+ pix_size = CV_ELEM_SIZE(type);
902
+ min_step = mat->cols*pix_size;
903
+
904
+ if( step != CV_AUTOSTEP && step != 0 )
905
+ {
906
+ if( step < min_step && data != 0 )
907
+ CV_Error( CV_BadStep, "" );
908
+ mat->step = step;
909
+ }
910
+ else
911
+ mat->step = min_step;
912
+
913
+ mat->data.ptr = (uchar*)data;
914
+ mat->type = CV_MAT_MAGIC_VAL | type |
915
+ (mat->rows == 1 || mat->step == min_step ? CV_MAT_CONT_FLAG : 0);
916
+ icvCheckHuge( mat );
917
+ }
918
+ else if( CV_IS_IMAGE_HDR( arr ))
919
+ {
920
+ IplImage* img = (IplImage*)arr;
921
+
922
+ pix_size = ((img->depth & 255) >> 3)*img->nChannels;
923
+ min_step = img->width*pix_size;
924
+
925
+ if( step != CV_AUTOSTEP && img->height > 1 )
926
+ {
927
+ if( step < min_step && data != 0 )
928
+ CV_Error( CV_BadStep, "" );
929
+ img->widthStep = step;
930
+ }
931
+ else
932
+ {
933
+ img->widthStep = min_step;
934
+ }
935
+
936
+ img->imageSize = img->widthStep * img->height;
937
+ img->imageData = img->imageDataOrigin = (char*)data;
938
+
939
+ if( (((int)(size_t)data | step) & 7) == 0 &&
940
+ cvAlign(img->width * pix_size, 8) == step )
941
+ img->align = 8;
942
+ else
943
+ img->align = 4;
944
+ }
945
+ else if( CV_IS_MATND_HDR( arr ))
946
+ {
947
+ CvMatND* mat = (CvMatND*)arr;
948
+ int i;
949
+ int64 cur_step;
950
+
951
+ if( step != CV_AUTOSTEP )
952
+ CV_Error( CV_BadStep,
953
+ "For multidimensional array only CV_AUTOSTEP is allowed here" );
954
+
955
+ mat->data.ptr = (uchar*)data;
956
+ cur_step = CV_ELEM_SIZE(mat->type);
957
+
958
+ for( i = mat->dims - 1; i >= 0; i-- )
959
+ {
960
+ if( cur_step > INT_MAX )
961
+ CV_Error( CV_StsOutOfRange, "The array is too big" );
962
+ mat->dim[i].step = (int)cur_step;
963
+ cur_step *= mat->dim[i].size;
964
+ }
965
+ }
966
+ else
967
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
968
+ }
969
+
970
+
971
+ // Deallocates array's data
972
+ CV_IMPL void
973
+ cvReleaseData( CvArr* arr )
974
+ {
975
+ if( CV_IS_MAT_HDR( arr ) || CV_IS_MATND_HDR( arr ))
976
+ {
977
+ CvMat* mat = (CvMat*)arr;
978
+ cvDecRefData( mat );
979
+ }
980
+ else if( CV_IS_IMAGE_HDR( arr ))
981
+ {
982
+ IplImage* img = (IplImage*)arr;
983
+
984
+ if( !CvIPL.deallocate )
985
+ {
986
+ char* ptr = img->imageDataOrigin;
987
+ img->imageData = img->imageDataOrigin = 0;
988
+ cvFree( &ptr );
989
+ }
990
+ else
991
+ {
992
+ CvIPL.deallocate( img, IPL_IMAGE_DATA );
993
+ }
994
+ }
995
+ else
996
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
997
+ }
998
+
999
+
1000
+ // Retrieves essential information about image ROI or CvMat data
1001
+ CV_IMPL void
1002
+ cvGetRawData( const CvArr* arr, uchar** data, int* step, CvSize* roi_size )
1003
+ {
1004
+ if( CV_IS_MAT( arr ))
1005
+ {
1006
+ CvMat *mat = (CvMat*)arr;
1007
+
1008
+ if( step )
1009
+ *step = mat->step;
1010
+
1011
+ if( data )
1012
+ *data = mat->data.ptr;
1013
+
1014
+ if( roi_size )
1015
+ *roi_size = cvGetMatSize( mat );
1016
+ }
1017
+ else if( CV_IS_IMAGE( arr ))
1018
+ {
1019
+ IplImage* img = (IplImage*)arr;
1020
+
1021
+ if( step )
1022
+ *step = img->widthStep;
1023
+
1024
+ if( data )
1025
+ *data = cvPtr2D( img, 0, 0 );
1026
+
1027
+ if( roi_size )
1028
+ {
1029
+ if( img->roi )
1030
+ {
1031
+ *roi_size = cvSize( img->roi->width, img->roi->height );
1032
+ }
1033
+ else
1034
+ {
1035
+ *roi_size = cvSize( img->width, img->height );
1036
+ }
1037
+ }
1038
+ }
1039
+ else if( CV_IS_MATND( arr ))
1040
+ {
1041
+ CvMatND* mat = (CvMatND*)arr;
1042
+
1043
+ if( !CV_IS_MAT_CONT( mat->type ))
1044
+ CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
1045
+
1046
+ if( data )
1047
+ *data = mat->data.ptr;
1048
+
1049
+ if( roi_size || step )
1050
+ {
1051
+ int i, size1 = mat->dim[0].size, size2 = 1;
1052
+
1053
+ if( mat->dims > 2 )
1054
+ for( i = 1; i < mat->dims; i++ )
1055
+ size1 *= mat->dim[i].size;
1056
+ else
1057
+ size2 = mat->dim[1].size;
1058
+
1059
+ if( roi_size )
1060
+ {
1061
+ roi_size->width = size2;
1062
+ roi_size->height = size1;
1063
+ }
1064
+
1065
+ if( step )
1066
+ *step = mat->dim[0].step;
1067
+ }
1068
+ }
1069
+ else
1070
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1071
+ }
1072
+
1073
+
1074
+ CV_IMPL int
1075
+ cvGetElemType( const CvArr* arr )
1076
+ {
1077
+ int type = -1;
1078
+ if( CV_IS_MAT_HDR(arr) || CV_IS_MATND_HDR(arr) || CV_IS_SPARSE_MAT_HDR(arr))
1079
+ type = CV_MAT_TYPE( ((CvMat*)arr)->type );
1080
+ else if( CV_IS_IMAGE(arr))
1081
+ {
1082
+ IplImage* img = (IplImage*)arr;
1083
+ type = CV_MAKETYPE( IPL2CV_DEPTH(img->depth), img->nChannels );
1084
+ }
1085
+ else
1086
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1087
+
1088
+ return type;
1089
+ }
1090
+
1091
+
1092
+ // Returns a number of array dimensions
1093
+ CV_IMPL int
1094
+ cvGetDims( const CvArr* arr, int* sizes )
1095
+ {
1096
+ int dims = -1;
1097
+ if( CV_IS_MAT_HDR( arr ))
1098
+ {
1099
+ CvMat* mat = (CvMat*)arr;
1100
+
1101
+ dims = 2;
1102
+ if( sizes )
1103
+ {
1104
+ sizes[0] = mat->rows;
1105
+ sizes[1] = mat->cols;
1106
+ }
1107
+ }
1108
+ else if( CV_IS_IMAGE( arr ))
1109
+ {
1110
+ IplImage* img = (IplImage*)arr;
1111
+ dims = 2;
1112
+
1113
+ if( sizes )
1114
+ {
1115
+ sizes[0] = img->height;
1116
+ sizes[1] = img->width;
1117
+ }
1118
+ }
1119
+ else if( CV_IS_MATND_HDR( arr ))
1120
+ {
1121
+ CvMatND* mat = (CvMatND*)arr;
1122
+ dims = mat->dims;
1123
+
1124
+ if( sizes )
1125
+ {
1126
+ int i;
1127
+ for( i = 0; i < dims; i++ )
1128
+ sizes[i] = mat->dim[i].size;
1129
+ }
1130
+ }
1131
+ else if( CV_IS_SPARSE_MAT_HDR( arr ))
1132
+ {
1133
+ CvSparseMat* mat = (CvSparseMat*)arr;
1134
+ dims = mat->dims;
1135
+
1136
+ if( sizes )
1137
+ memcpy( sizes, mat->size, dims*sizeof(sizes[0]));
1138
+ }
1139
+ else
1140
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1141
+
1142
+ return dims;
1143
+ }
1144
+
1145
+
1146
+ // Returns the size of particular array dimension
1147
+ CV_IMPL int
1148
+ cvGetDimSize( const CvArr* arr, int index )
1149
+ {
1150
+ int size = -1;
1151
+
1152
+ if( CV_IS_MAT( arr ))
1153
+ {
1154
+ CvMat *mat = (CvMat*)arr;
1155
+
1156
+ switch( index )
1157
+ {
1158
+ case 0:
1159
+ size = mat->rows;
1160
+ break;
1161
+ case 1:
1162
+ size = mat->cols;
1163
+ break;
1164
+ default:
1165
+ CV_Error( CV_StsOutOfRange, "bad dimension index" );
1166
+ }
1167
+ }
1168
+ else if( CV_IS_IMAGE( arr ))
1169
+ {
1170
+ IplImage* img = (IplImage*)arr;
1171
+
1172
+ switch( index )
1173
+ {
1174
+ case 0:
1175
+ size = !img->roi ? img->height : img->roi->height;
1176
+ break;
1177
+ case 1:
1178
+ size = !img->roi ? img->width : img->roi->width;
1179
+ break;
1180
+ default:
1181
+ CV_Error( CV_StsOutOfRange, "bad dimension index" );
1182
+ }
1183
+ }
1184
+ else if( CV_IS_MATND_HDR( arr ))
1185
+ {
1186
+ CvMatND* mat = (CvMatND*)arr;
1187
+
1188
+ if( (unsigned)index >= (unsigned)mat->dims )
1189
+ CV_Error( CV_StsOutOfRange, "bad dimension index" );
1190
+
1191
+ size = mat->dim[index].size;
1192
+ }
1193
+ else if( CV_IS_SPARSE_MAT_HDR( arr ))
1194
+ {
1195
+ CvSparseMat* mat = (CvSparseMat*)arr;
1196
+
1197
+ if( (unsigned)index >= (unsigned)mat->dims )
1198
+ CV_Error( CV_StsOutOfRange, "bad dimension index" );
1199
+
1200
+ size = mat->size[index];
1201
+ }
1202
+ else
1203
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1204
+
1205
+ return size;
1206
+ }
1207
+
1208
+
1209
+ // Returns the size of CvMat or IplImage
1210
+ CV_IMPL CvSize
1211
+ cvGetSize( const CvArr* arr )
1212
+ {
1213
+ CvSize size = { 0, 0 };
1214
+
1215
+ if( CV_IS_MAT_HDR_Z( arr ))
1216
+ {
1217
+ CvMat *mat = (CvMat*)arr;
1218
+
1219
+ size.width = mat->cols;
1220
+ size.height = mat->rows;
1221
+ }
1222
+ else if( CV_IS_IMAGE_HDR( arr ))
1223
+ {
1224
+ IplImage* img = (IplImage*)arr;
1225
+
1226
+ if( img->roi )
1227
+ {
1228
+ size.width = img->roi->width;
1229
+ size.height = img->roi->height;
1230
+ }
1231
+ else
1232
+ {
1233
+ size.width = img->width;
1234
+ size.height = img->height;
1235
+ }
1236
+ }
1237
+ else
1238
+ CV_Error( CV_StsBadArg, "Array should be CvMat or IplImage" );
1239
+
1240
+ return size;
1241
+ }
1242
+
1243
+
1244
+ // Selects sub-array (no data is copied)
1245
+ CV_IMPL CvMat*
1246
+ cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect )
1247
+ {
1248
+ CvMat* res = 0;
1249
+ CvMat stub, *mat = (CvMat*)arr;
1250
+
1251
+ if( !CV_IS_MAT( mat ))
1252
+ mat = cvGetMat( mat, &stub );
1253
+
1254
+ if( !submat )
1255
+ CV_Error( CV_StsNullPtr, "" );
1256
+
1257
+ if( (rect.x|rect.y|rect.width|rect.height) < 0 )
1258
+ CV_Error( CV_StsBadSize, "" );
1259
+
1260
+ if( rect.x + rect.width > mat->cols ||
1261
+ rect.y + rect.height > mat->rows )
1262
+ CV_Error( CV_StsBadSize, "" );
1263
+
1264
+ {
1265
+ /*
1266
+ int* refcount = mat->refcount;
1267
+
1268
+ if( refcount )
1269
+ ++*refcount;
1270
+
1271
+ cvDecRefData( submat );
1272
+ */
1273
+ submat->data.ptr = mat->data.ptr + (size_t)rect.y*mat->step +
1274
+ rect.x*CV_ELEM_SIZE(mat->type);
1275
+ submat->step = mat->step;
1276
+ submat->type = (mat->type & (rect.width < mat->cols ? ~CV_MAT_CONT_FLAG : -1)) |
1277
+ (rect.height <= 1 ? CV_MAT_CONT_FLAG : 0);
1278
+ submat->rows = rect.height;
1279
+ submat->cols = rect.width;
1280
+ submat->refcount = 0;
1281
+ res = submat;
1282
+ }
1283
+
1284
+ return res;
1285
+ }
1286
+
1287
+
1288
+ // Selects array's row span.
1289
+ CV_IMPL CvMat*
1290
+ cvGetRows( const CvArr* arr, CvMat* submat,
1291
+ int start_row, int end_row, int delta_row )
1292
+ {
1293
+ CvMat* res = 0;
1294
+ CvMat stub, *mat = (CvMat*)arr;
1295
+
1296
+ if( !CV_IS_MAT( mat ))
1297
+ mat = cvGetMat( mat, &stub );
1298
+
1299
+ if( !submat )
1300
+ CV_Error( CV_StsNullPtr, "" );
1301
+
1302
+ if( (unsigned)start_row >= (unsigned)mat->rows ||
1303
+ (unsigned)end_row > (unsigned)mat->rows || delta_row <= 0 )
1304
+ CV_Error( CV_StsOutOfRange, "" );
1305
+
1306
+ {
1307
+ /*
1308
+ int* refcount = mat->refcount;
1309
+
1310
+ if( refcount )
1311
+ ++*refcount;
1312
+
1313
+ cvDecRefData( submat );
1314
+ */
1315
+ if( delta_row == 1 )
1316
+ {
1317
+ submat->rows = end_row - start_row;
1318
+ submat->step = mat->step;
1319
+ }
1320
+ else
1321
+ {
1322
+ submat->rows = (end_row - start_row + delta_row - 1)/delta_row;
1323
+ submat->step = mat->step * delta_row;
1324
+ }
1325
+
1326
+ submat->cols = mat->cols;
1327
+ submat->step &= submat->rows > 1 ? -1 : 0;
1328
+ submat->data.ptr = mat->data.ptr + (size_t)start_row*mat->step;
1329
+ submat->type = (mat->type | (submat->rows == 1 ? CV_MAT_CONT_FLAG : 0)) &
1330
+ (delta_row != 1 && submat->rows > 1 ? ~CV_MAT_CONT_FLAG : -1);
1331
+ submat->refcount = 0;
1332
+ submat->hdr_refcount = 0;
1333
+ res = submat;
1334
+ }
1335
+
1336
+ return res;
1337
+ }
1338
+
1339
+
1340
+ // Selects array's column span.
1341
+ CV_IMPL CvMat*
1342
+ cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col )
1343
+ {
1344
+ CvMat* res = 0;
1345
+ CvMat stub, *mat = (CvMat*)arr;
1346
+ int cols;
1347
+
1348
+ if( !CV_IS_MAT( mat ))
1349
+ mat = cvGetMat( mat, &stub );
1350
+
1351
+ if( !submat )
1352
+ CV_Error( CV_StsNullPtr, "" );
1353
+
1354
+ cols = mat->cols;
1355
+ if( (unsigned)start_col >= (unsigned)cols ||
1356
+ (unsigned)end_col > (unsigned)cols )
1357
+ CV_Error( CV_StsOutOfRange, "" );
1358
+
1359
+ {
1360
+ /*
1361
+ int* refcount = mat->refcount;
1362
+
1363
+ if( refcount )
1364
+ ++*refcount;
1365
+
1366
+ cvDecRefData( submat );
1367
+ */
1368
+ submat->rows = mat->rows;
1369
+ submat->cols = end_col - start_col;
1370
+ submat->step = mat->step;
1371
+ submat->data.ptr = mat->data.ptr + (size_t)start_col*CV_ELEM_SIZE(mat->type);
1372
+ submat->type = mat->type & (submat->rows > 1 && submat->cols < cols ? ~CV_MAT_CONT_FLAG : -1);
1373
+ submat->refcount = 0;
1374
+ submat->hdr_refcount = 0;
1375
+ res = submat;
1376
+ }
1377
+
1378
+ return res;
1379
+ }
1380
+
1381
+
1382
+ // Selects array diagonal
1383
+ CV_IMPL CvMat*
1384
+ cvGetDiag( const CvArr* arr, CvMat* submat, int diag )
1385
+ {
1386
+ CvMat* res = 0;
1387
+ CvMat stub, *mat = (CvMat*)arr;
1388
+ int len, pix_size;
1389
+
1390
+ if( !CV_IS_MAT( mat ))
1391
+ mat = cvGetMat( mat, &stub );
1392
+
1393
+ if( !submat )
1394
+ CV_Error( CV_StsNullPtr, "" );
1395
+
1396
+ pix_size = CV_ELEM_SIZE(mat->type);
1397
+
1398
+ /*{
1399
+ int* refcount = mat->refcount;
1400
+
1401
+ if( refcount )
1402
+ ++*refcount;
1403
+
1404
+ cvDecRefData( submat );
1405
+ }*/
1406
+
1407
+ if( diag >= 0 )
1408
+ {
1409
+ len = mat->cols - diag;
1410
+
1411
+ if( len <= 0 )
1412
+ CV_Error( CV_StsOutOfRange, "" );
1413
+
1414
+ len = CV_IMIN( len, mat->rows );
1415
+ submat->data.ptr = mat->data.ptr + diag*pix_size;
1416
+ }
1417
+ else
1418
+ {
1419
+ len = mat->rows + diag;
1420
+
1421
+ if( len <= 0 )
1422
+ CV_Error( CV_StsOutOfRange, "" );
1423
+
1424
+ len = CV_IMIN( len, mat->cols );
1425
+ submat->data.ptr = mat->data.ptr - diag*mat->step;
1426
+ }
1427
+
1428
+ submat->rows = len;
1429
+ submat->cols = 1;
1430
+ submat->step = mat->step + (submat->rows > 1 ? pix_size : 0);
1431
+ submat->type = mat->type;
1432
+ if( submat->rows > 1 )
1433
+ submat->type &= ~CV_MAT_CONT_FLAG;
1434
+ else
1435
+ submat->type |= CV_MAT_CONT_FLAG;
1436
+ submat->refcount = 0;
1437
+ submat->hdr_refcount = 0;
1438
+ res = submat;
1439
+
1440
+ return res;
1441
+ }
1442
+
1443
+
1444
+ /****************************************************************************************\
1445
+ * Operations on CvScalar and accessing array elements *
1446
+ \****************************************************************************************/
1447
+
1448
+ // Converts CvScalar to specified type
1449
+ CV_IMPL void
1450
+ cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 )
1451
+ {
1452
+ type = CV_MAT_TYPE(type);
1453
+ int cn = CV_MAT_CN( type );
1454
+ int depth = type & CV_MAT_DEPTH_MASK;
1455
+
1456
+ assert( scalar && data );
1457
+ if( (unsigned)(cn - 1) >= 4 )
1458
+ CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
1459
+
1460
+ switch( depth )
1461
+ {
1462
+ case CV_8UC1:
1463
+ while( cn-- )
1464
+ {
1465
+ int t = cvRound( scalar->val[cn] );
1466
+ ((uchar*)data)[cn] = CV_CAST_8U(t);
1467
+ }
1468
+ break;
1469
+ case CV_8SC1:
1470
+ while( cn-- )
1471
+ {
1472
+ int t = cvRound( scalar->val[cn] );
1473
+ ((char*)data)[cn] = CV_CAST_8S(t);
1474
+ }
1475
+ break;
1476
+ case CV_16UC1:
1477
+ while( cn-- )
1478
+ {
1479
+ int t = cvRound( scalar->val[cn] );
1480
+ ((ushort*)data)[cn] = CV_CAST_16U(t);
1481
+ }
1482
+ break;
1483
+ case CV_16SC1:
1484
+ while( cn-- )
1485
+ {
1486
+ int t = cvRound( scalar->val[cn] );
1487
+ ((short*)data)[cn] = CV_CAST_16S(t);
1488
+ }
1489
+ break;
1490
+ case CV_32SC1:
1491
+ while( cn-- )
1492
+ ((int*)data)[cn] = cvRound( scalar->val[cn] );
1493
+ break;
1494
+ case CV_32FC1:
1495
+ while( cn-- )
1496
+ ((float*)data)[cn] = (float)(scalar->val[cn]);
1497
+ break;
1498
+ case CV_64FC1:
1499
+ while( cn-- )
1500
+ ((double*)data)[cn] = (double)(scalar->val[cn]);
1501
+ break;
1502
+ default:
1503
+ assert(0);
1504
+ CV_Error( CV_BadDepth, "" );
1505
+ }
1506
+
1507
+ if( extend_to_12 )
1508
+ {
1509
+ int pix_size = CV_ELEM_SIZE(type);
1510
+ int offset = CV_ELEM_SIZE1(depth)*12;
1511
+
1512
+ do
1513
+ {
1514
+ offset -= pix_size;
1515
+ memcpy((char*)data + offset, data, pix_size);
1516
+ }
1517
+ while( offset > pix_size );
1518
+ }
1519
+ }
1520
+
1521
+
1522
+ // Converts data of specified type to CvScalar
1523
+ CV_IMPL void
1524
+ cvRawDataToScalar( const void* data, int flags, CvScalar* scalar )
1525
+ {
1526
+ int cn = CV_MAT_CN( flags );
1527
+
1528
+ assert( scalar && data );
1529
+
1530
+ if( (unsigned)(cn - 1) >= 4 )
1531
+ CV_Error( CV_StsOutOfRange, "The number of channels must be 1, 2, 3 or 4" );
1532
+
1533
+ memset( scalar->val, 0, sizeof(scalar->val));
1534
+
1535
+ switch( CV_MAT_DEPTH( flags ))
1536
+ {
1537
+ case CV_8U:
1538
+ while( cn-- )
1539
+ scalar->val[cn] = CV_8TO32F(((uchar*)data)[cn]);
1540
+ break;
1541
+ case CV_8S:
1542
+ while( cn-- )
1543
+ scalar->val[cn] = CV_8TO32F(((char*)data)[cn]);
1544
+ break;
1545
+ case CV_16U:
1546
+ while( cn-- )
1547
+ scalar->val[cn] = ((ushort*)data)[cn];
1548
+ break;
1549
+ case CV_16S:
1550
+ while( cn-- )
1551
+ scalar->val[cn] = ((short*)data)[cn];
1552
+ break;
1553
+ case CV_32S:
1554
+ while( cn-- )
1555
+ scalar->val[cn] = ((int*)data)[cn];
1556
+ break;
1557
+ case CV_32F:
1558
+ while( cn-- )
1559
+ scalar->val[cn] = ((float*)data)[cn];
1560
+ break;
1561
+ case CV_64F:
1562
+ while( cn-- )
1563
+ scalar->val[cn] = ((double*)data)[cn];
1564
+ break;
1565
+ default:
1566
+ assert(0);
1567
+ CV_Error( CV_BadDepth, "" );
1568
+ }
1569
+ }
1570
+
1571
+
1572
+ static double icvGetReal( const void* data, int type )
1573
+ {
1574
+ switch( type )
1575
+ {
1576
+ case CV_8U:
1577
+ return *(uchar*)data;
1578
+ case CV_8S:
1579
+ return *(char*)data;
1580
+ case CV_16U:
1581
+ return *(ushort*)data;
1582
+ case CV_16S:
1583
+ return *(short*)data;
1584
+ case CV_32S:
1585
+ return *(int*)data;
1586
+ case CV_32F:
1587
+ return *(float*)data;
1588
+ case CV_64F:
1589
+ return *(double*)data;
1590
+ }
1591
+
1592
+ return 0;
1593
+ }
1594
+
1595
+
1596
+ static void icvSetReal( double value, const void* data, int type )
1597
+ {
1598
+ if( type < CV_32F )
1599
+ {
1600
+ int ivalue = cvRound(value);
1601
+ switch( type )
1602
+ {
1603
+ case CV_8U:
1604
+ *(uchar*)data = CV_CAST_8U(ivalue);
1605
+ break;
1606
+ case CV_8S:
1607
+ *(char*)data = CV_CAST_8S(ivalue);
1608
+ break;
1609
+ case CV_16U:
1610
+ *(ushort*)data = CV_CAST_16U(ivalue);
1611
+ break;
1612
+ case CV_16S:
1613
+ *(short*)data = CV_CAST_16S(ivalue);
1614
+ break;
1615
+ case CV_32S:
1616
+ *(int*)data = CV_CAST_32S(ivalue);
1617
+ break;
1618
+ }
1619
+ }
1620
+ else
1621
+ {
1622
+ switch( type )
1623
+ {
1624
+ case CV_32F:
1625
+ *(float*)data = (float)value;
1626
+ break;
1627
+ case CV_64F:
1628
+ *(double*)data = value;
1629
+ break;
1630
+ }
1631
+ }
1632
+ }
1633
+
1634
+
1635
+ // Returns pointer to specified element of array (linear index is used)
1636
+ CV_IMPL uchar*
1637
+ cvPtr1D( const CvArr* arr, int idx, int* _type )
1638
+ {
1639
+ uchar* ptr = 0;
1640
+ if( CV_IS_MAT( arr ))
1641
+ {
1642
+ CvMat* mat = (CvMat*)arr;
1643
+
1644
+ int type = CV_MAT_TYPE(mat->type);
1645
+ int pix_size = CV_ELEM_SIZE(type);
1646
+
1647
+ if( _type )
1648
+ *_type = type;
1649
+
1650
+ // the first part is mul-free sufficient check
1651
+ // that the index is within the matrix
1652
+ if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
1653
+ (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
1654
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1655
+
1656
+ if( CV_IS_MAT_CONT(mat->type))
1657
+ {
1658
+ ptr = mat->data.ptr + (size_t)idx*pix_size;
1659
+ }
1660
+ else
1661
+ {
1662
+ int row, col;
1663
+ if( mat->cols == 1 )
1664
+ row = idx, col = 0;
1665
+ else
1666
+ row = idx/mat->cols, col = idx - row*mat->cols;
1667
+ ptr = mat->data.ptr + (size_t)row*mat->step + col*pix_size;
1668
+ }
1669
+ }
1670
+ else if( CV_IS_IMAGE_HDR( arr ))
1671
+ {
1672
+ IplImage* img = (IplImage*)arr;
1673
+ int width = !img->roi ? img->width : img->roi->width;
1674
+ int y = idx/width, x = idx - y*width;
1675
+
1676
+ ptr = cvPtr2D( arr, y, x, _type );
1677
+ }
1678
+ else if( CV_IS_MATND( arr ))
1679
+ {
1680
+ CvMatND* mat = (CvMatND*)arr;
1681
+ int j, type = CV_MAT_TYPE(mat->type);
1682
+ size_t size = mat->dim[0].size;
1683
+
1684
+ if( _type )
1685
+ *_type = type;
1686
+
1687
+ for( j = 1; j < mat->dims; j++ )
1688
+ size *= mat->dim[j].size;
1689
+
1690
+ if((unsigned)idx >= (unsigned)size )
1691
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1692
+
1693
+ if( CV_IS_MAT_CONT(mat->type))
1694
+ {
1695
+ int pix_size = CV_ELEM_SIZE(type);
1696
+ ptr = mat->data.ptr + (size_t)idx*pix_size;
1697
+ }
1698
+ else
1699
+ {
1700
+ ptr = mat->data.ptr;
1701
+ for( j = mat->dims - 1; j >= 0; j-- )
1702
+ {
1703
+ int sz = mat->dim[j].size;
1704
+ if( sz )
1705
+ {
1706
+ int t = idx/sz;
1707
+ ptr += (idx - t*sz)*mat->dim[j].step;
1708
+ idx = t;
1709
+ }
1710
+ }
1711
+ }
1712
+ }
1713
+ else if( CV_IS_SPARSE_MAT( arr ))
1714
+ {
1715
+ CvSparseMat* m = (CvSparseMat*)arr;
1716
+ if( m->dims == 1 )
1717
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, _type, 1, 0 );
1718
+ else
1719
+ {
1720
+ int i, n = m->dims;
1721
+ CV_DbgAssert( n <= CV_MAX_DIM_HEAP );
1722
+ int _idx[CV_MAX_DIM_HEAP];
1723
+
1724
+ for( i = n - 1; i >= 0; i-- )
1725
+ {
1726
+ int t = idx / m->size[i];
1727
+ _idx[i] = idx - t*m->size[i];
1728
+ idx = t;
1729
+ }
1730
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, _idx, _type, 1, 0 );
1731
+ }
1732
+ }
1733
+ else
1734
+ {
1735
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1736
+ }
1737
+
1738
+ return ptr;
1739
+ }
1740
+
1741
+
1742
+ // Returns pointer to specified element of 2d array
1743
+ CV_IMPL uchar*
1744
+ cvPtr2D( const CvArr* arr, int y, int x, int* _type )
1745
+ {
1746
+ uchar* ptr = 0;
1747
+ if( CV_IS_MAT( arr ))
1748
+ {
1749
+ CvMat* mat = (CvMat*)arr;
1750
+ int type;
1751
+
1752
+ if( (unsigned)y >= (unsigned)(mat->rows) ||
1753
+ (unsigned)x >= (unsigned)(mat->cols) )
1754
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1755
+
1756
+ type = CV_MAT_TYPE(mat->type);
1757
+ if( _type )
1758
+ *_type = type;
1759
+
1760
+ ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
1761
+ }
1762
+ else if( CV_IS_IMAGE( arr ))
1763
+ {
1764
+ IplImage* img = (IplImage*)arr;
1765
+ int pix_size = (img->depth & 255) >> 3;
1766
+ int width, height;
1767
+ ptr = (uchar*)img->imageData;
1768
+
1769
+ if( img->dataOrder == 0 )
1770
+ pix_size *= img->nChannels;
1771
+
1772
+ if( img->roi )
1773
+ {
1774
+ width = img->roi->width;
1775
+ height = img->roi->height;
1776
+
1777
+ ptr += img->roi->yOffset*img->widthStep +
1778
+ img->roi->xOffset*pix_size;
1779
+
1780
+ if( img->dataOrder )
1781
+ {
1782
+ int coi = img->roi->coi;
1783
+ if( !coi )
1784
+ CV_Error( CV_BadCOI,
1785
+ "COI must be non-null in case of planar images" );
1786
+ ptr += (coi - 1)*img->imageSize;
1787
+ }
1788
+ }
1789
+ else
1790
+ {
1791
+ width = img->width;
1792
+ height = img->height;
1793
+ }
1794
+
1795
+ if( (unsigned)y >= (unsigned)height ||
1796
+ (unsigned)x >= (unsigned)width )
1797
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1798
+
1799
+ ptr += y*img->widthStep + x*pix_size;
1800
+
1801
+ if( _type )
1802
+ {
1803
+ int type = IPL2CV_DEPTH(img->depth);
1804
+ if( type < 0 || (unsigned)(img->nChannels - 1) > 3 )
1805
+ CV_Error( CV_StsUnsupportedFormat, "" );
1806
+
1807
+ *_type = CV_MAKETYPE( type, img->nChannels );
1808
+ }
1809
+ }
1810
+ else if( CV_IS_MATND( arr ))
1811
+ {
1812
+ CvMatND* mat = (CvMatND*)arr;
1813
+
1814
+ if( mat->dims != 2 ||
1815
+ (unsigned)y >= (unsigned)(mat->dim[0].size) ||
1816
+ (unsigned)x >= (unsigned)(mat->dim[1].size) )
1817
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1818
+
1819
+ ptr = mat->data.ptr + (size_t)y*mat->dim[0].step + x*mat->dim[1].step;
1820
+ if( _type )
1821
+ *_type = CV_MAT_TYPE(mat->type);
1822
+ }
1823
+ else if( CV_IS_SPARSE_MAT( arr ))
1824
+ {
1825
+ int idx[] = { y, x };
1826
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
1827
+ }
1828
+ else
1829
+ {
1830
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1831
+ }
1832
+
1833
+ return ptr;
1834
+ }
1835
+
1836
+
1837
+ // Returns pointer to specified element of 3d array
1838
+ CV_IMPL uchar*
1839
+ cvPtr3D( const CvArr* arr, int z, int y, int x, int* _type )
1840
+ {
1841
+ uchar* ptr = 0;
1842
+ if( CV_IS_MATND( arr ))
1843
+ {
1844
+ CvMatND* mat = (CvMatND*)arr;
1845
+
1846
+ if( mat->dims != 3 ||
1847
+ (unsigned)z >= (unsigned)(mat->dim[0].size) ||
1848
+ (unsigned)y >= (unsigned)(mat->dim[1].size) ||
1849
+ (unsigned)x >= (unsigned)(mat->dim[2].size) )
1850
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1851
+
1852
+ ptr = mat->data.ptr + (size_t)z*mat->dim[0].step +
1853
+ (size_t)y*mat->dim[1].step + x*mat->dim[2].step;
1854
+
1855
+ if( _type )
1856
+ *_type = CV_MAT_TYPE(mat->type);
1857
+ }
1858
+ else if( CV_IS_SPARSE_MAT( arr ))
1859
+ {
1860
+ int idx[] = { z, y, x };
1861
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, _type, 1, 0 );
1862
+ }
1863
+ else
1864
+ {
1865
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1866
+ }
1867
+
1868
+ return ptr;
1869
+ }
1870
+
1871
+
1872
+ // Returns pointer to specified element of n-d array
1873
+ CV_IMPL uchar*
1874
+ cvPtrND( const CvArr* arr, const int* idx, int* _type,
1875
+ int create_node, unsigned* precalc_hashval )
1876
+ {
1877
+ uchar* ptr = 0;
1878
+ if( !idx )
1879
+ CV_Error( CV_StsNullPtr, "NULL pointer to indices" );
1880
+
1881
+ if( CV_IS_SPARSE_MAT( arr ))
1882
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx,
1883
+ _type, create_node, precalc_hashval );
1884
+ else if( CV_IS_MATND( arr ))
1885
+ {
1886
+ CvMatND* mat = (CvMatND*)arr;
1887
+ int i;
1888
+ ptr = mat->data.ptr;
1889
+
1890
+ for( i = 0; i < mat->dims; i++ )
1891
+ {
1892
+ if( (unsigned)idx[i] >= (unsigned)(mat->dim[i].size) )
1893
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1894
+ ptr += (size_t)idx[i]*mat->dim[i].step;
1895
+ }
1896
+
1897
+ if( _type )
1898
+ *_type = CV_MAT_TYPE(mat->type);
1899
+ }
1900
+ else if( CV_IS_MAT_HDR(arr) || CV_IS_IMAGE_HDR(arr) )
1901
+ ptr = cvPtr2D( arr, idx[0], idx[1], _type );
1902
+ else
1903
+ CV_Error( CV_StsBadArg, "unrecognized or unsupported array type" );
1904
+
1905
+ return ptr;
1906
+ }
1907
+
1908
+
1909
+ // Returns specifed element of n-D array given linear index
1910
+ CV_IMPL CvScalar
1911
+ cvGet1D( const CvArr* arr, int idx )
1912
+ {
1913
+ CvScalar scalar = {{0,0,0,0}};
1914
+ int type = 0;
1915
+ uchar* ptr;
1916
+
1917
+ if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
1918
+ {
1919
+ CvMat* mat = (CvMat*)arr;
1920
+
1921
+ type = CV_MAT_TYPE(mat->type);
1922
+ int pix_size = CV_ELEM_SIZE(type);
1923
+
1924
+ // the first part is mul-free sufficient check
1925
+ // that the index is within the matrix
1926
+ if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
1927
+ (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
1928
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1929
+
1930
+ ptr = mat->data.ptr + (size_t)idx*pix_size;
1931
+ }
1932
+ else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
1933
+ ptr = cvPtr1D( arr, idx, &type );
1934
+ else
1935
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
1936
+
1937
+ if( ptr )
1938
+ cvRawDataToScalar( ptr, type, &scalar );
1939
+
1940
+ return scalar;
1941
+ }
1942
+
1943
+
1944
+ // Returns specifed element of 2D array
1945
+ CV_IMPL CvScalar
1946
+ cvGet2D( const CvArr* arr, int y, int x )
1947
+ {
1948
+ CvScalar scalar = {{0,0,0,0}};
1949
+ int type = 0;
1950
+ uchar* ptr;
1951
+
1952
+ if( CV_IS_MAT( arr ))
1953
+ {
1954
+ CvMat* mat = (CvMat*)arr;
1955
+
1956
+ if( (unsigned)y >= (unsigned)(mat->rows) ||
1957
+ (unsigned)x >= (unsigned)(mat->cols) )
1958
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
1959
+
1960
+ type = CV_MAT_TYPE(mat->type);
1961
+ ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
1962
+ }
1963
+ else if( !CV_IS_SPARSE_MAT( arr ))
1964
+ ptr = cvPtr2D( arr, y, x, &type );
1965
+ else
1966
+ {
1967
+ int idx[] = { y, x };
1968
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
1969
+ }
1970
+
1971
+ if( ptr )
1972
+ cvRawDataToScalar( ptr, type, &scalar );
1973
+
1974
+ return scalar;
1975
+ }
1976
+
1977
+
1978
+ // Returns specifed element of 3D array
1979
+ CV_IMPL CvScalar
1980
+ cvGet3D( const CvArr* arr, int z, int y, int x )
1981
+ {
1982
+ CvScalar scalar = {{0,0,0,0}};
1983
+ int type = 0;
1984
+ uchar* ptr;
1985
+
1986
+ if( !CV_IS_SPARSE_MAT( arr ))
1987
+ ptr = cvPtr3D( arr, z, y, x, &type );
1988
+ else
1989
+ {
1990
+ int idx[] = { z, y, x };
1991
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
1992
+ }
1993
+
1994
+ if( ptr )
1995
+ cvRawDataToScalar( ptr, type, &scalar );
1996
+ return scalar;
1997
+ }
1998
+
1999
+
2000
+ // Returns specifed element of nD array
2001
+ CV_IMPL CvScalar
2002
+ cvGetND( const CvArr* arr, const int* idx )
2003
+ {
2004
+ CvScalar scalar = {{0,0,0,0}};
2005
+ int type = 0;
2006
+ uchar* ptr;
2007
+
2008
+ if( !CV_IS_SPARSE_MAT( arr ))
2009
+ ptr = cvPtrND( arr, idx, &type );
2010
+ else
2011
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2012
+
2013
+ if( ptr )
2014
+ cvRawDataToScalar( ptr, type, &scalar );
2015
+
2016
+ return scalar;
2017
+ }
2018
+
2019
+
2020
+ // Returns specifed element of n-D array given linear index
2021
+ CV_IMPL double
2022
+ cvGetReal1D( const CvArr* arr, int idx )
2023
+ {
2024
+ double value = 0;
2025
+ int type = 0;
2026
+ uchar* ptr;
2027
+
2028
+ if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2029
+ {
2030
+ CvMat* mat = (CvMat*)arr;
2031
+
2032
+ type = CV_MAT_TYPE(mat->type);
2033
+ int pix_size = CV_ELEM_SIZE(type);
2034
+
2035
+ // the first part is mul-free sufficient check
2036
+ // that the index is within the matrix
2037
+ if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2038
+ (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2039
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
2040
+
2041
+ ptr = mat->data.ptr + (size_t)idx*pix_size;
2042
+ }
2043
+ else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2044
+ ptr = cvPtr1D( arr, idx, &type );
2045
+ else
2046
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, 0, 0 );
2047
+
2048
+ if( ptr )
2049
+ {
2050
+ if( CV_MAT_CN( type ) > 1 )
2051
+ CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2052
+
2053
+ value = icvGetReal( ptr, type );
2054
+ }
2055
+ return value;
2056
+ }
2057
+
2058
+
2059
+ // Returns specifed element of 2D array
2060
+ CV_IMPL double
2061
+ cvGetReal2D( const CvArr* arr, int y, int x )
2062
+ {
2063
+ double value = 0;
2064
+ int type = 0;
2065
+ uchar* ptr;
2066
+
2067
+ if( CV_IS_MAT( arr ))
2068
+ {
2069
+ CvMat* mat = (CvMat*)arr;
2070
+
2071
+ if( (unsigned)y >= (unsigned)(mat->rows) ||
2072
+ (unsigned)x >= (unsigned)(mat->cols) )
2073
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
2074
+
2075
+ type = CV_MAT_TYPE(mat->type);
2076
+ ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2077
+ }
2078
+ else if( !CV_IS_SPARSE_MAT( arr ))
2079
+ ptr = cvPtr2D( arr, y, x, &type );
2080
+ else
2081
+ {
2082
+ int idx[] = { y, x };
2083
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2084
+ }
2085
+
2086
+ if( ptr )
2087
+ {
2088
+ if( CV_MAT_CN( type ) > 1 )
2089
+ CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2090
+
2091
+ value = icvGetReal( ptr, type );
2092
+ }
2093
+
2094
+ return value;
2095
+ }
2096
+
2097
+
2098
+ // Returns specifed element of 3D array
2099
+ CV_IMPL double
2100
+ cvGetReal3D( const CvArr* arr, int z, int y, int x )
2101
+ {
2102
+ double value = 0;
2103
+ int type = 0;
2104
+ uchar* ptr;
2105
+
2106
+ if( !CV_IS_SPARSE_MAT( arr ))
2107
+ ptr = cvPtr3D( arr, z, y, x, &type );
2108
+ else
2109
+ {
2110
+ int idx[] = { z, y, x };
2111
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2112
+ }
2113
+
2114
+ if( ptr )
2115
+ {
2116
+ if( CV_MAT_CN( type ) > 1 )
2117
+ CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2118
+
2119
+ value = icvGetReal( ptr, type );
2120
+ }
2121
+
2122
+ return value;
2123
+ }
2124
+
2125
+
2126
+ // Returns specifed element of nD array
2127
+ CV_IMPL double
2128
+ cvGetRealND( const CvArr* arr, const int* idx )
2129
+ {
2130
+ double value = 0;
2131
+ int type = 0;
2132
+ uchar* ptr;
2133
+
2134
+ if( !CV_IS_SPARSE_MAT( arr ))
2135
+ ptr = cvPtrND( arr, idx, &type );
2136
+ else
2137
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, 0, 0 );
2138
+
2139
+ if( ptr )
2140
+ {
2141
+ if( CV_MAT_CN( type ) > 1 )
2142
+ CV_Error( CV_BadNumChannels, "cvGetReal* support only single-channel arrays" );
2143
+
2144
+ value = icvGetReal( ptr, type );
2145
+ }
2146
+
2147
+ return value;
2148
+ }
2149
+
2150
+
2151
+ // Assigns new value to specifed element of nD array given linear index
2152
+ CV_IMPL void
2153
+ cvSet1D( CvArr* arr, int idx, CvScalar scalar )
2154
+ {
2155
+ int type = 0;
2156
+ uchar* ptr;
2157
+
2158
+ if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2159
+ {
2160
+ CvMat* mat = (CvMat*)arr;
2161
+
2162
+ type = CV_MAT_TYPE(mat->type);
2163
+ int pix_size = CV_ELEM_SIZE(type);
2164
+
2165
+ // the first part is mul-free sufficient check
2166
+ // that the index is within the matrix
2167
+ if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2168
+ (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2169
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
2170
+
2171
+ ptr = mat->data.ptr + (size_t)idx*pix_size;
2172
+ }
2173
+ else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2174
+ ptr = cvPtr1D( arr, idx, &type );
2175
+ else
2176
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2177
+
2178
+ cvScalarToRawData( &scalar, ptr, type );
2179
+ }
2180
+
2181
+
2182
+ // Assigns new value to specifed element of 2D array
2183
+ CV_IMPL void
2184
+ cvSet2D( CvArr* arr, int y, int x, CvScalar scalar )
2185
+ {
2186
+ int type = 0;
2187
+ uchar* ptr;
2188
+
2189
+ if( CV_IS_MAT( arr ))
2190
+ {
2191
+ CvMat* mat = (CvMat*)arr;
2192
+
2193
+ if( (unsigned)y >= (unsigned)(mat->rows) ||
2194
+ (unsigned)x >= (unsigned)(mat->cols) )
2195
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
2196
+
2197
+ type = CV_MAT_TYPE(mat->type);
2198
+ ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2199
+ }
2200
+ else if( !CV_IS_SPARSE_MAT( arr ))
2201
+ ptr = cvPtr2D( arr, y, x, &type );
2202
+ else
2203
+ {
2204
+ int idx[] = { y, x };
2205
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2206
+ }
2207
+ cvScalarToRawData( &scalar, ptr, type );
2208
+ }
2209
+
2210
+
2211
+ // Assigns new value to specifed element of 3D array
2212
+ CV_IMPL void
2213
+ cvSet3D( CvArr* arr, int z, int y, int x, CvScalar scalar )
2214
+ {
2215
+ int type = 0;
2216
+ uchar* ptr;
2217
+
2218
+ if( !CV_IS_SPARSE_MAT( arr ))
2219
+ ptr = cvPtr3D( arr, z, y, x, &type );
2220
+ else
2221
+ {
2222
+ int idx[] = { z, y, x };
2223
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2224
+ }
2225
+ cvScalarToRawData( &scalar, ptr, type );
2226
+ }
2227
+
2228
+
2229
+ // Assigns new value to specifed element of nD array
2230
+ CV_IMPL void
2231
+ cvSetND( CvArr* arr, const int* idx, CvScalar scalar )
2232
+ {
2233
+ int type = 0;
2234
+ uchar* ptr;
2235
+
2236
+ if( !CV_IS_SPARSE_MAT( arr ))
2237
+ ptr = cvPtrND( arr, idx, &type );
2238
+ else
2239
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2240
+ cvScalarToRawData( &scalar, ptr, type );
2241
+ }
2242
+
2243
+
2244
+ CV_IMPL void
2245
+ cvSetReal1D( CvArr* arr, int idx, double value )
2246
+ {
2247
+ int type = 0;
2248
+ uchar* ptr;
2249
+
2250
+ if( CV_IS_MAT( arr ) && CV_IS_MAT_CONT( ((CvMat*)arr)->type ))
2251
+ {
2252
+ CvMat* mat = (CvMat*)arr;
2253
+
2254
+ type = CV_MAT_TYPE(mat->type);
2255
+ int pix_size = CV_ELEM_SIZE(type);
2256
+
2257
+ // the first part is mul-free sufficient check
2258
+ // that the index is within the matrix
2259
+ if( (unsigned)idx >= (unsigned)(mat->rows + mat->cols - 1) &&
2260
+ (unsigned)idx >= (unsigned)(mat->rows*mat->cols))
2261
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
2262
+
2263
+ ptr = mat->data.ptr + (size_t)idx*pix_size;
2264
+ }
2265
+ else if( !CV_IS_SPARSE_MAT( arr ) || ((CvSparseMat*)arr)->dims > 1 )
2266
+ ptr = cvPtr1D( arr, idx, &type );
2267
+ else
2268
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, &idx, &type, -1, 0 );
2269
+
2270
+ if( CV_MAT_CN( type ) > 1 )
2271
+ CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2272
+
2273
+ if( ptr )
2274
+ icvSetReal( value, ptr, type );
2275
+ }
2276
+
2277
+
2278
+ CV_IMPL void
2279
+ cvSetReal2D( CvArr* arr, int y, int x, double value )
2280
+ {
2281
+ int type = 0;
2282
+ uchar* ptr;
2283
+
2284
+ if( CV_IS_MAT( arr ))
2285
+ {
2286
+ CvMat* mat = (CvMat*)arr;
2287
+
2288
+ if( (unsigned)y >= (unsigned)(mat->rows) ||
2289
+ (unsigned)x >= (unsigned)(mat->cols) )
2290
+ CV_Error( CV_StsOutOfRange, "index is out of range" );
2291
+
2292
+ type = CV_MAT_TYPE(mat->type);
2293
+ ptr = mat->data.ptr + (size_t)y*mat->step + x*CV_ELEM_SIZE(type);
2294
+ }
2295
+ else if( !CV_IS_SPARSE_MAT( arr ))
2296
+ {
2297
+ ptr = cvPtr2D( arr, y, x, &type );
2298
+ }
2299
+ else
2300
+ {
2301
+ int idx[] = { y, x };
2302
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2303
+ }
2304
+ if( CV_MAT_CN( type ) > 1 )
2305
+ CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2306
+
2307
+ if( ptr )
2308
+ icvSetReal( value, ptr, type );
2309
+ }
2310
+
2311
+
2312
+ CV_IMPL void
2313
+ cvSetReal3D( CvArr* arr, int z, int y, int x, double value )
2314
+ {
2315
+ int type = 0;
2316
+ uchar* ptr;
2317
+
2318
+ if( !CV_IS_SPARSE_MAT( arr ))
2319
+ ptr = cvPtr3D( arr, z, y, x, &type );
2320
+ else
2321
+ {
2322
+ int idx[] = { z, y, x };
2323
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2324
+ }
2325
+ if( CV_MAT_CN( type ) > 1 )
2326
+ CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2327
+
2328
+ if( ptr )
2329
+ icvSetReal( value, ptr, type );
2330
+ }
2331
+
2332
+
2333
+ CV_IMPL void
2334
+ cvSetRealND( CvArr* arr, const int* idx, double value )
2335
+ {
2336
+ int type = 0;
2337
+ uchar* ptr;
2338
+
2339
+ if( !CV_IS_SPARSE_MAT( arr ))
2340
+ ptr = cvPtrND( arr, idx, &type );
2341
+ else
2342
+ ptr = icvGetNodePtr( (CvSparseMat*)arr, idx, &type, -1, 0 );
2343
+
2344
+ if( CV_MAT_CN( type ) > 1 )
2345
+ CV_Error( CV_BadNumChannels, "cvSetReal* support only single-channel arrays" );
2346
+
2347
+ if( ptr )
2348
+ icvSetReal( value, ptr, type );
2349
+ }
2350
+
2351
+
2352
+ CV_IMPL void
2353
+ cvClearND( CvArr* arr, const int* idx )
2354
+ {
2355
+ if( !CV_IS_SPARSE_MAT( arr ))
2356
+ {
2357
+ int type;
2358
+ uchar* ptr;
2359
+ ptr = cvPtrND( arr, idx, &type );
2360
+ if( ptr )
2361
+ memset( ptr, 0, CV_ELEM_SIZE(type) );
2362
+ }
2363
+ else
2364
+ icvDeleteNode( (CvSparseMat*)arr, idx, 0 );
2365
+ }
2366
+
2367
+
2368
+ /****************************************************************************************\
2369
+ * Conversion to CvMat or IplImage *
2370
+ \****************************************************************************************/
2371
+
2372
+ // convert array (CvMat or IplImage) to CvMat
2373
+ CV_IMPL CvMat*
2374
+ cvGetMat( const CvArr* array, CvMat* mat,
2375
+ int* pCOI, int allowND )
2376
+ {
2377
+ CvMat* result = 0;
2378
+ CvMat* src = (CvMat*)array;
2379
+ int coi = 0;
2380
+
2381
+ if( !mat || !src )
2382
+ CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
2383
+
2384
+ if( CV_IS_MAT_HDR(src))
2385
+ {
2386
+ if( !src->data.ptr )
2387
+ CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
2388
+
2389
+ result = (CvMat*)src;
2390
+ }
2391
+ else if( CV_IS_IMAGE_HDR(src) )
2392
+ {
2393
+ const IplImage* img = (const IplImage*)src;
2394
+ int depth, order;
2395
+
2396
+ if( img->imageData == 0 )
2397
+ CV_Error( CV_StsNullPtr, "The image has NULL data pointer" );
2398
+
2399
+ depth = IPL2CV_DEPTH( img->depth );
2400
+ if( depth < 0 )
2401
+ CV_Error( CV_BadDepth, "" );
2402
+
2403
+ order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
2404
+
2405
+ if( img->roi )
2406
+ {
2407
+ if( order == IPL_DATA_ORDER_PLANE )
2408
+ {
2409
+ int type = depth;
2410
+
2411
+ if( img->roi->coi == 0 )
2412
+ CV_Error( CV_StsBadFlag,
2413
+ "Images with planar data layout should be used with COI selected" );
2414
+
2415
+ cvInitMatHeader( mat, img->roi->height,
2416
+ img->roi->width, type,
2417
+ img->imageData + (img->roi->coi-1)*img->imageSize +
2418
+ img->roi->yOffset*img->widthStep +
2419
+ img->roi->xOffset*CV_ELEM_SIZE(type),
2420
+ img->widthStep );
2421
+ }
2422
+ else /* pixel order */
2423
+ {
2424
+ int type = CV_MAKETYPE( depth, img->nChannels );
2425
+ coi = img->roi->coi;
2426
+
2427
+ if( img->nChannels > CV_CN_MAX )
2428
+ CV_Error( CV_BadNumChannels,
2429
+ "The image is interleaved and has over CV_CN_MAX channels" );
2430
+
2431
+ cvInitMatHeader( mat, img->roi->height, img->roi->width,
2432
+ type, img->imageData +
2433
+ img->roi->yOffset*img->widthStep +
2434
+ img->roi->xOffset*CV_ELEM_SIZE(type),
2435
+ img->widthStep );
2436
+ }
2437
+ }
2438
+ else
2439
+ {
2440
+ int type = CV_MAKETYPE( depth, img->nChannels );
2441
+
2442
+ if( order != IPL_DATA_ORDER_PIXEL )
2443
+ CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
2444
+
2445
+ cvInitMatHeader( mat, img->height, img->width, type,
2446
+ img->imageData, img->widthStep );
2447
+ }
2448
+
2449
+ result = mat;
2450
+ }
2451
+ else if( allowND && CV_IS_MATND_HDR(src) )
2452
+ {
2453
+ CvMatND* matnd = (CvMatND*)src;
2454
+ int i;
2455
+ int size1 = matnd->dim[0].size, size2 = 1;
2456
+
2457
+ if( !src->data.ptr )
2458
+ CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
2459
+
2460
+ if( !CV_IS_MAT_CONT( matnd->type ))
2461
+ CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
2462
+
2463
+ if( matnd->dims > 2 )
2464
+ for( i = 1; i < matnd->dims; i++ )
2465
+ size2 *= matnd->dim[i].size;
2466
+ else
2467
+ size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
2468
+
2469
+ mat->refcount = 0;
2470
+ mat->hdr_refcount = 0;
2471
+ mat->data.ptr = matnd->data.ptr;
2472
+ mat->rows = size1;
2473
+ mat->cols = size2;
2474
+ mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
2475
+ mat->step = size2*CV_ELEM_SIZE(matnd->type);
2476
+ mat->step &= size1 > 1 ? -1 : 0;
2477
+
2478
+ icvCheckHuge( mat );
2479
+ result = mat;
2480
+ }
2481
+ else
2482
+ CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" );
2483
+
2484
+ if( pCOI )
2485
+ *pCOI = coi;
2486
+
2487
+ return result;
2488
+ }
2489
+
2490
+
2491
+ CV_IMPL CvArr*
2492
+ cvReshapeMatND( const CvArr* arr,
2493
+ int sizeof_header, CvArr* _header,
2494
+ int new_cn, int new_dims, int* new_sizes )
2495
+ {
2496
+ CvArr* result = 0;
2497
+ int dims, coi = 0;
2498
+
2499
+ if( !arr || !_header )
2500
+ CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" );
2501
+
2502
+ if( new_cn == 0 && new_dims == 0 )
2503
+ CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
2504
+
2505
+ dims = cvGetDims( arr );
2506
+
2507
+ if( new_dims == 0 )
2508
+ {
2509
+ new_sizes = 0;
2510
+ new_dims = dims;
2511
+ }
2512
+ else if( new_dims == 1 )
2513
+ {
2514
+ new_sizes = 0;
2515
+ }
2516
+ else
2517
+ {
2518
+ if( new_dims <= 0 || new_dims > CV_MAX_DIM )
2519
+ CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
2520
+ if( !new_sizes )
2521
+ CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" );
2522
+ }
2523
+
2524
+ if( new_dims <= 2 )
2525
+ {
2526
+ CvMat* mat = (CvMat*)arr;
2527
+ CvMat header;
2528
+ int* refcount = 0;
2529
+ int hdr_refcount = 0;
2530
+ int total_width, new_rows, cn;
2531
+
2532
+ if( sizeof_header != sizeof(CvMat) && sizeof_header != sizeof(CvMatND) )
2533
+ CV_Error( CV_StsBadArg, "The output header should be CvMat or CvMatND" );
2534
+
2535
+ if( mat == (CvMat*)_header )
2536
+ {
2537
+ refcount = mat->refcount;
2538
+ hdr_refcount = mat->hdr_refcount;
2539
+ }
2540
+
2541
+ if( !CV_IS_MAT( mat ))
2542
+ mat = cvGetMat( mat, &header, &coi, 1 );
2543
+
2544
+ cn = CV_MAT_CN( mat->type );
2545
+ total_width = mat->cols * cn;
2546
+
2547
+ if( new_cn == 0 )
2548
+ new_cn = cn;
2549
+
2550
+ if( new_sizes )
2551
+ new_rows = new_sizes[0];
2552
+ else if( new_dims == 1 )
2553
+ new_rows = total_width*mat->rows/new_cn;
2554
+ else
2555
+ {
2556
+ new_rows = mat->rows;
2557
+ if( new_cn > total_width )
2558
+ new_rows = mat->rows * total_width / new_cn;
2559
+ }
2560
+
2561
+ if( new_rows != mat->rows )
2562
+ {
2563
+ int total_size = total_width * mat->rows;
2564
+
2565
+ if( !CV_IS_MAT_CONT( mat->type ))
2566
+ CV_Error( CV_BadStep,
2567
+ "The matrix is not continuous so the number of rows can not be changed" );
2568
+
2569
+ total_width = total_size / new_rows;
2570
+
2571
+ if( total_width * new_rows != total_size )
2572
+ CV_Error( CV_StsBadArg, "The total number of matrix elements "
2573
+ "is not divisible by the new number of rows" );
2574
+ }
2575
+
2576
+ header.rows = new_rows;
2577
+ header.cols = total_width / new_cn;
2578
+
2579
+ if( header.cols * new_cn != total_width ||
2580
+ (new_sizes && header.cols != new_sizes[1]) )
2581
+ CV_Error( CV_StsBadArg, "The total matrix width is not "
2582
+ "divisible by the new number of columns" );
2583
+
2584
+ header.type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
2585
+ header.step = header.cols * CV_ELEM_SIZE(mat->type);
2586
+ header.step &= new_rows > 1 ? -1 : 0;
2587
+ header.refcount = refcount;
2588
+ header.hdr_refcount = hdr_refcount;
2589
+
2590
+ if( sizeof_header == sizeof(CvMat) )
2591
+ *(CvMat*)_header = header;
2592
+ else
2593
+ {
2594
+ CvMatND* __header = (CvMatND*)_header;
2595
+ cvGetMatND(&header, __header, 0);
2596
+ if( new_dims > 0 )
2597
+ __header->dims = new_dims;
2598
+ }
2599
+ }
2600
+ else
2601
+ {
2602
+ CvMatND* header = (CvMatND*)_header;
2603
+
2604
+ if( sizeof_header != sizeof(CvMatND))
2605
+ CV_Error( CV_StsBadSize, "The output header should be CvMatND" );
2606
+
2607
+ if( !new_sizes )
2608
+ {
2609
+ if( !CV_IS_MATND( arr ))
2610
+ CV_Error( CV_StsBadArg, "The input array must be CvMatND" );
2611
+
2612
+ {
2613
+ CvMatND* mat = (CvMatND*)arr;
2614
+ assert( new_cn > 0 );
2615
+ int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
2616
+ int new_size = last_dim_size/new_cn;
2617
+
2618
+ if( new_size*new_cn != last_dim_size )
2619
+ CV_Error( CV_StsBadArg,
2620
+ "The last dimension full size is not divisible by new number of channels");
2621
+
2622
+ if( mat != header )
2623
+ {
2624
+ memcpy( header, mat, sizeof(*header));
2625
+ header->refcount = 0;
2626
+ header->hdr_refcount = 0;
2627
+ }
2628
+
2629
+ header->dim[header->dims-1].size = new_size;
2630
+ header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn);
2631
+ }
2632
+ }
2633
+ else
2634
+ {
2635
+ CvMatND stub;
2636
+ CvMatND* mat = (CvMatND*)arr;
2637
+ int i, size1, size2;
2638
+ int step;
2639
+
2640
+ if( new_cn != 0 )
2641
+ CV_Error( CV_StsBadArg,
2642
+ "Simultaneous change of shape and number of channels is not supported. "
2643
+ "Do it by 2 separate calls" );
2644
+
2645
+ if( !CV_IS_MATND( mat ))
2646
+ {
2647
+ cvGetMatND( mat, &stub, &coi );
2648
+ mat = &stub;
2649
+ }
2650
+
2651
+ if( CV_IS_MAT_CONT( mat->type ))
2652
+ CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
2653
+
2654
+ size1 = mat->dim[0].size;
2655
+ for( i = 1; i < dims; i++ )
2656
+ size1 *= mat->dim[i].size;
2657
+
2658
+ size2 = 1;
2659
+ for( i = 0; i < new_dims; i++ )
2660
+ {
2661
+ if( new_sizes[i] <= 0 )
2662
+ CV_Error( CV_StsBadSize,
2663
+ "One of new dimension sizes is non-positive" );
2664
+ size2 *= new_sizes[i];
2665
+ }
2666
+
2667
+ if( size1 != size2 )
2668
+ CV_Error( CV_StsBadSize,
2669
+ "Number of elements in the original and reshaped array is different" );
2670
+
2671
+ if( header != mat )
2672
+ {
2673
+ header->refcount = 0;
2674
+ header->hdr_refcount = 0;
2675
+ }
2676
+
2677
+ header->dims = new_dims;
2678
+ header->type = mat->type;
2679
+ header->data.ptr = mat->data.ptr;
2680
+ step = CV_ELEM_SIZE(header->type);
2681
+
2682
+ for( i = new_dims - 1; i >= 0; i-- )
2683
+ {
2684
+ header->dim[i].size = new_sizes[i];
2685
+ header->dim[i].step = step;
2686
+ step *= new_sizes[i];
2687
+ }
2688
+ }
2689
+ }
2690
+
2691
+ if( coi )
2692
+ CV_Error( CV_BadCOI, "COI is not supported by this operation" );
2693
+
2694
+ result = _header;
2695
+ return result;
2696
+ }
2697
+
2698
+
2699
+ CV_IMPL CvMat*
2700
+ cvReshape( const CvArr* array, CvMat* header,
2701
+ int new_cn, int new_rows )
2702
+ {
2703
+ CvMat* result = 0;
2704
+ CvMat *mat = (CvMat*)array;
2705
+ int total_width, new_width;
2706
+
2707
+ if( !header )
2708
+ CV_Error( CV_StsNullPtr, "" );
2709
+
2710
+ if( !CV_IS_MAT( mat ))
2711
+ {
2712
+ int coi = 0;
2713
+ mat = cvGetMat( mat, header, &coi, 1 );
2714
+ if( coi )
2715
+ CV_Error( CV_BadCOI, "COI is not supported" );
2716
+ }
2717
+
2718
+ if( new_cn == 0 )
2719
+ new_cn = CV_MAT_CN(mat->type);
2720
+ else if( (unsigned)(new_cn - 1) > 3 )
2721
+ CV_Error( CV_BadNumChannels, "" );
2722
+
2723
+ if( mat != header )
2724
+ {
2725
+ int hdr_refcount = header->hdr_refcount;
2726
+ *header = *mat;
2727
+ header->refcount = 0;
2728
+ header->hdr_refcount = hdr_refcount;
2729
+ }
2730
+
2731
+ total_width = mat->cols * CV_MAT_CN( mat->type );
2732
+
2733
+ if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
2734
+ new_rows = mat->rows * total_width / new_cn;
2735
+
2736
+ if( new_rows == 0 || new_rows == mat->rows )
2737
+ {
2738
+ header->rows = mat->rows;
2739
+ header->step = mat->step;
2740
+ }
2741
+ else
2742
+ {
2743
+ int total_size = total_width * mat->rows;
2744
+ if( !CV_IS_MAT_CONT( mat->type ))
2745
+ CV_Error( CV_BadStep,
2746
+ "The matrix is not continuous, thus its number of rows can not be changed" );
2747
+
2748
+ if( (unsigned)new_rows > (unsigned)total_size )
2749
+ CV_Error( CV_StsOutOfRange, "Bad new number of rows" );
2750
+
2751
+ total_width = total_size / new_rows;
2752
+
2753
+ if( total_width * new_rows != total_size )
2754
+ CV_Error( CV_StsBadArg, "The total number of matrix elements "
2755
+ "is not divisible by the new number of rows" );
2756
+
2757
+ header->rows = new_rows;
2758
+ header->step = total_width * CV_ELEM_SIZE1(mat->type);
2759
+ }
2760
+
2761
+ new_width = total_width / new_cn;
2762
+
2763
+ if( new_width * new_cn != total_width )
2764
+ CV_Error( CV_BadNumChannels,
2765
+ "The total width is not divisible by the new number of channels" );
2766
+
2767
+ header->cols = new_width;
2768
+ header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
2769
+
2770
+ result = header;
2771
+ return result;
2772
+ }
2773
+
2774
+
2775
+ // convert array (CvMat or IplImage) to IplImage
2776
+ CV_IMPL IplImage*
2777
+ cvGetImage( const CvArr* array, IplImage* img )
2778
+ {
2779
+ IplImage* result = 0;
2780
+ const IplImage* src = (const IplImage*)array;
2781
+ int depth;
2782
+
2783
+ if( !img )
2784
+ CV_Error( CV_StsNullPtr, "" );
2785
+
2786
+ if( !CV_IS_IMAGE_HDR(src) )
2787
+ {
2788
+ const CvMat* mat = (const CvMat*)src;
2789
+
2790
+ if( !CV_IS_MAT_HDR(mat))
2791
+ CV_Error( CV_StsBadFlag, "" );
2792
+
2793
+ if( mat->data.ptr == 0 )
2794
+ CV_Error( CV_StsNullPtr, "" );
2795
+
2796
+ depth = cvIplDepth(mat->type);
2797
+
2798
+ cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
2799
+ depth, CV_MAT_CN(mat->type) );
2800
+ cvSetData( img, mat->data.ptr, mat->step );
2801
+
2802
+ result = img;
2803
+ }
2804
+ else
2805
+ {
2806
+ result = (IplImage*)src;
2807
+ }
2808
+
2809
+ return result;
2810
+ }
2811
+
2812
+
2813
+ /****************************************************************************************\
2814
+ * IplImage-specific functions *
2815
+ \****************************************************************************************/
2816
+
2817
+ static IplROI* icvCreateROI( int coi, int xOffset, int yOffset, int width, int height )
2818
+ {
2819
+ IplROI *roi = 0;
2820
+ if( !CvIPL.createROI )
2821
+ {
2822
+ roi = (IplROI*)cvAlloc( sizeof(*roi));
2823
+
2824
+ roi->coi = coi;
2825
+ roi->xOffset = xOffset;
2826
+ roi->yOffset = yOffset;
2827
+ roi->width = width;
2828
+ roi->height = height;
2829
+ }
2830
+ else
2831
+ {
2832
+ roi = CvIPL.createROI( coi, xOffset, yOffset, width, height );
2833
+ }
2834
+
2835
+ return roi;
2836
+ }
2837
+
2838
+ static void
2839
+ icvGetColorModel( int nchannels, const char** colorModel, const char** channelSeq )
2840
+ {
2841
+ static const char* tab[][2] =
2842
+ {
2843
+ {"GRAY", "GRAY"},
2844
+ {"",""},
2845
+ {"RGB","BGR"},
2846
+ {"RGB","BGRA"}
2847
+ };
2848
+
2849
+ nchannels--;
2850
+ *colorModel = *channelSeq = "";
2851
+
2852
+ if( (unsigned)nchannels <= 3 )
2853
+ {
2854
+ *colorModel = tab[nchannels][0];
2855
+ *channelSeq = tab[nchannels][1];
2856
+ }
2857
+ }
2858
+
2859
+
2860
+ // create IplImage header
2861
+ CV_IMPL IplImage *
2862
+ cvCreateImageHeader( CvSize size, int depth, int channels )
2863
+ {
2864
+ IplImage *img = 0;
2865
+
2866
+ if( !CvIPL.createHeader )
2867
+ {
2868
+ img = (IplImage *)cvAlloc( sizeof( *img ));
2869
+ cvInitImageHeader( img, size, depth, channels, IPL_ORIGIN_TL,
2870
+ CV_DEFAULT_IMAGE_ROW_ALIGN );
2871
+ }
2872
+ else
2873
+ {
2874
+ const char *colorModel, *channelSeq;
2875
+
2876
+ icvGetColorModel( channels, &colorModel, &channelSeq );
2877
+
2878
+ img = CvIPL.createHeader( channels, 0, depth, (char*)colorModel, (char*)channelSeq,
2879
+ IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL,
2880
+ CV_DEFAULT_IMAGE_ROW_ALIGN,
2881
+ size.width, size.height, 0, 0, 0, 0 );
2882
+ }
2883
+
2884
+ return img;
2885
+ }
2886
+
2887
+
2888
+ // create IplImage header and allocate underlying data
2889
+ CV_IMPL IplImage *
2890
+ cvCreateImage( CvSize size, int depth, int channels )
2891
+ {
2892
+ IplImage *img = cvCreateImageHeader( size, depth, channels );
2893
+ assert( img );
2894
+ cvCreateData( img );
2895
+
2896
+ return img;
2897
+ }
2898
+
2899
+
2900
+ // initalize IplImage header, allocated by the user
2901
+ CV_IMPL IplImage*
2902
+ cvInitImageHeader( IplImage * image, CvSize size, int depth,
2903
+ int channels, int origin, int align )
2904
+ {
2905
+ const char *colorModel, *channelSeq;
2906
+
2907
+ if( !image )
2908
+ CV_Error( CV_HeaderIsNull, "null pointer to header" );
2909
+
2910
+ memset( image, 0, sizeof( *image ));
2911
+ image->nSize = sizeof( *image );
2912
+
2913
+ icvGetColorModel( channels, &colorModel, &channelSeq );
2914
+ strncpy( image->colorModel, colorModel, 4 );
2915
+ strncpy( image->channelSeq, channelSeq, 4 );
2916
+
2917
+ if( size.width < 0 || size.height < 0 )
2918
+ CV_Error( CV_BadROISize, "Bad input roi" );
2919
+
2920
+ if( (depth != (int)IPL_DEPTH_1U && depth != (int)IPL_DEPTH_8U &&
2921
+ depth != (int)IPL_DEPTH_8S && depth != (int)IPL_DEPTH_16U &&
2922
+ depth != (int)IPL_DEPTH_16S && depth != (int)IPL_DEPTH_32S &&
2923
+ depth != (int)IPL_DEPTH_32F && depth != (int)IPL_DEPTH_64F) ||
2924
+ channels < 0 )
2925
+ CV_Error( CV_BadDepth, "Unsupported format" );
2926
+ if( origin != CV_ORIGIN_BL && origin != CV_ORIGIN_TL )
2927
+ CV_Error( CV_BadOrigin, "Bad input origin" );
2928
+
2929
+ if( align != 4 && align != 8 )
2930
+ CV_Error( CV_BadAlign, "Bad input align" );
2931
+
2932
+ image->width = size.width;
2933
+ image->height = size.height;
2934
+
2935
+ if( image->roi )
2936
+ {
2937
+ image->roi->coi = 0;
2938
+ image->roi->xOffset = image->roi->yOffset = 0;
2939
+ image->roi->width = size.width;
2940
+ image->roi->height = size.height;
2941
+ }
2942
+
2943
+ image->nChannels = MAX( channels, 1 );
2944
+ image->depth = depth;
2945
+ image->align = align;
2946
+ image->widthStep = (((image->width * image->nChannels *
2947
+ (image->depth & ~IPL_DEPTH_SIGN) + 7)/8)+ align - 1) & (~(align - 1));
2948
+ image->origin = origin;
2949
+ image->imageSize = image->widthStep * image->height;
2950
+
2951
+ return image;
2952
+ }
2953
+
2954
+
2955
+ CV_IMPL void
2956
+ cvReleaseImageHeader( IplImage** image )
2957
+ {
2958
+ if( !image )
2959
+ CV_Error( CV_StsNullPtr, "" );
2960
+
2961
+ if( *image )
2962
+ {
2963
+ IplImage* img = *image;
2964
+ *image = 0;
2965
+
2966
+ if( !CvIPL.deallocate )
2967
+ {
2968
+ cvFree( &img->roi );
2969
+ cvFree( &img );
2970
+ }
2971
+ else
2972
+ {
2973
+ CvIPL.deallocate( img, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
2974
+ }
2975
+ }
2976
+ }
2977
+
2978
+
2979
+ CV_IMPL void
2980
+ cvReleaseImage( IplImage ** image )
2981
+ {
2982
+ if( !image )
2983
+ CV_Error( CV_StsNullPtr, "" );
2984
+
2985
+ if( *image )
2986
+ {
2987
+ IplImage* img = *image;
2988
+ *image = 0;
2989
+
2990
+ cvReleaseData( img );
2991
+ cvReleaseImageHeader( &img );
2992
+ }
2993
+ }
2994
+
2995
+
2996
+ CV_IMPL void
2997
+ cvSetImageROI( IplImage* image, CvRect rect )
2998
+ {
2999
+ if( !image )
3000
+ CV_Error( CV_HeaderIsNull, "" );
3001
+
3002
+ // allow zero ROI width or height
3003
+ CV_Assert( rect.width >= 0 && rect.height >= 0 &&
3004
+ rect.x < image->width && rect.y < image->height &&
3005
+ rect.x + rect.width >= (int)(rect.width > 0) &&
3006
+ rect.y + rect.height >= (int)(rect.height > 0) );
3007
+
3008
+ rect.width += rect.x;
3009
+ rect.height += rect.y;
3010
+
3011
+ rect.x = std::max(rect.x, 0);
3012
+ rect.y = std::max(rect.y, 0);
3013
+ rect.width = std::min(rect.width, image->width);
3014
+ rect.height = std::min(rect.height, image->height);
3015
+
3016
+ rect.width -= rect.x;
3017
+ rect.height -= rect.y;
3018
+
3019
+ if( image->roi )
3020
+ {
3021
+ image->roi->xOffset = rect.x;
3022
+ image->roi->yOffset = rect.y;
3023
+ image->roi->width = rect.width;
3024
+ image->roi->height = rect.height;
3025
+ }
3026
+ else
3027
+ image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height );
3028
+ }
3029
+
3030
+
3031
+ CV_IMPL void
3032
+ cvResetImageROI( IplImage* image )
3033
+ {
3034
+ if( !image )
3035
+ CV_Error( CV_HeaderIsNull, "" );
3036
+
3037
+ if( image->roi )
3038
+ {
3039
+ if( !CvIPL.deallocate )
3040
+ {
3041
+ cvFree( &image->roi );
3042
+ }
3043
+ else
3044
+ {
3045
+ CvIPL.deallocate( image, IPL_IMAGE_ROI );
3046
+ image->roi = 0;
3047
+ }
3048
+ }
3049
+ }
3050
+
3051
+
3052
+ CV_IMPL CvRect
3053
+ cvGetImageROI( const IplImage* img )
3054
+ {
3055
+ CvRect rect = { 0, 0, 0, 0 };
3056
+ if( !img )
3057
+ CV_Error( CV_StsNullPtr, "Null pointer to image" );
3058
+
3059
+ if( img->roi )
3060
+ rect = cvRect( img->roi->xOffset, img->roi->yOffset,
3061
+ img->roi->width, img->roi->height );
3062
+ else
3063
+ rect = cvRect( 0, 0, img->width, img->height );
3064
+
3065
+ return rect;
3066
+ }
3067
+
3068
+
3069
+ CV_IMPL void
3070
+ cvSetImageCOI( IplImage* image, int coi )
3071
+ {
3072
+ if( !image )
3073
+ CV_Error( CV_HeaderIsNull, "" );
3074
+
3075
+ if( (unsigned)coi > (unsigned)(image->nChannels) )
3076
+ CV_Error( CV_BadCOI, "" );
3077
+
3078
+ if( image->roi || coi != 0 )
3079
+ {
3080
+ if( image->roi )
3081
+ {
3082
+ image->roi->coi = coi;
3083
+ }
3084
+ else
3085
+ {
3086
+ image->roi = icvCreateROI( coi, 0, 0, image->width, image->height );
3087
+ }
3088
+ }
3089
+ }
3090
+
3091
+
3092
+ CV_IMPL int
3093
+ cvGetImageCOI( const IplImage* image )
3094
+ {
3095
+ if( !image )
3096
+ CV_Error( CV_HeaderIsNull, "" );
3097
+
3098
+ return image->roi ? image->roi->coi : 0;
3099
+ }
3100
+
3101
+
3102
+ CV_IMPL IplImage*
3103
+ cvCloneImage( const IplImage* src )
3104
+ {
3105
+ IplImage* dst = 0;
3106
+
3107
+ if( !CV_IS_IMAGE_HDR( src ))
3108
+ CV_Error( CV_StsBadArg, "Bad image header" );
3109
+
3110
+ if( !CvIPL.cloneImage )
3111
+ {
3112
+ dst = (IplImage*)cvAlloc( sizeof(*dst));
3113
+
3114
+ memcpy( dst, src, sizeof(*src));
3115
+ dst->imageData = dst->imageDataOrigin = 0;
3116
+ dst->roi = 0;
3117
+
3118
+ if( src->roi )
3119
+ {
3120
+ dst->roi = icvCreateROI( src->roi->coi, src->roi->xOffset,
3121
+ src->roi->yOffset, src->roi->width, src->roi->height );
3122
+ }
3123
+
3124
+ if( src->imageData )
3125
+ {
3126
+ int size = src->imageSize;
3127
+ cvCreateData( dst );
3128
+ memcpy( dst->imageData, src->imageData, size );
3129
+ }
3130
+ }
3131
+ else
3132
+ dst = CvIPL.cloneImage( src );
3133
+
3134
+ return dst;
3135
+ }
3136
+
3137
+
3138
+ /****************************************************************************************\
3139
+ * Additional operations on CvTermCriteria *
3140
+ \****************************************************************************************/
3141
+
3142
+ CV_IMPL CvTermCriteria
3143
+ cvCheckTermCriteria( CvTermCriteria criteria, double default_eps,
3144
+ int default_max_iters )
3145
+ {
3146
+ CvTermCriteria crit;
3147
+
3148
+ crit.type = CV_TERMCRIT_ITER|CV_TERMCRIT_EPS;
3149
+ crit.max_iter = default_max_iters;
3150
+ crit.epsilon = (float)default_eps;
3151
+
3152
+ if( (criteria.type & ~(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) != 0 )
3153
+ CV_Error( CV_StsBadArg,
3154
+ "Unknown type of term criteria" );
3155
+
3156
+ if( (criteria.type & CV_TERMCRIT_ITER) != 0 )
3157
+ {
3158
+ if( criteria.max_iter <= 0 )
3159
+ CV_Error( CV_StsBadArg,
3160
+ "Iterations flag is set and maximum number of iterations is <= 0" );
3161
+ crit.max_iter = criteria.max_iter;
3162
+ }
3163
+
3164
+ if( (criteria.type & CV_TERMCRIT_EPS) != 0 )
3165
+ {
3166
+ if( criteria.epsilon < 0 )
3167
+ CV_Error( CV_StsBadArg, "Accuracy flag is set and epsilon is < 0" );
3168
+
3169
+ crit.epsilon = criteria.epsilon;
3170
+ }
3171
+
3172
+ if( (criteria.type & (CV_TERMCRIT_EPS | CV_TERMCRIT_ITER)) == 0 )
3173
+ CV_Error( CV_StsBadArg,
3174
+ "Neither accuracy nor maximum iterations "
3175
+ "number flags are set in criteria type" );
3176
+
3177
+ crit.epsilon = (float)MAX( 0, crit.epsilon );
3178
+ crit.max_iter = MAX( 1, crit.max_iter );
3179
+
3180
+ return crit;
3181
+ }
3182
+
3183
+ namespace cv
3184
+ {
3185
+
3186
+ template<> void Ptr<CvMat>::delete_obj()
3187
+ { cvReleaseMat(&obj); }
3188
+
3189
+ template<> void Ptr<IplImage>::delete_obj()
3190
+ { cvReleaseImage(&obj); }
3191
+
3192
+ template<> void Ptr<CvMatND>::delete_obj()
3193
+ { cvReleaseMatND(&obj); }
3194
+
3195
+ template<> void Ptr<CvSparseMat>::delete_obj()
3196
+ { cvReleaseSparseMat(&obj); }
3197
+
3198
+ template<> void Ptr<CvMemStorage>::delete_obj()
3199
+ { cvReleaseMemStorage(&obj); }
3200
+
3201
+ template<> void Ptr<CvFileStorage>::delete_obj()
3202
+ { cvReleaseFileStorage(&obj); }
3203
+
3204
+ }
3205
+
3206
+ /* End of file. */