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