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 basic operations: cvCopy, cvSet
45 //
46 // */
47
48 #include "_cxcore.h"
49
50 /////////////////////////////////////////////////////////////////////////////////////////
51 // //
52 // L/L COPY & SET FUNCTIONS //
53 // //
54 /////////////////////////////////////////////////////////////////////////////////////////
55
56
57 IPCVAPI_IMPL( CvStatus, icvCopy_8u_C1R, ( const uchar* src, int srcstep,
58 uchar* dst, int dststep, CvSize size ),
59 (src, srcstep, dst, dststep, size) )
60 {
61 for( ; size.height--; src += srcstep, dst += dststep )
62 memcpy( dst, src, size.width );
63
64 return CV_OK;
65 }
66
67
68 static CvStatus CV_STDCALL
icvSet_8u_C1R(uchar * dst,int dst_step,CvSize size,const void * scalar,int pix_size)69 icvSet_8u_C1R( uchar* dst, int dst_step, CvSize size,
70 const void* scalar, int pix_size )
71 {
72 int copy_len = 12*pix_size;
73 uchar* dst_limit = dst + size.width;
74
75 if( size.height-- )
76 {
77 while( dst + copy_len <= dst_limit )
78 {
79 memcpy( dst, scalar, copy_len );
80 dst += copy_len;
81 }
82
83 memcpy( dst, scalar, dst_limit - dst );
84 }
85
86 if( size.height )
87 {
88 dst = dst_limit - size.width + dst_step;
89
90 for( ; size.height--; dst += dst_step )
91 memcpy( dst, dst - dst_step, size.width );
92 }
93
94 return CV_OK;
95 }
96
97
98 /////////////////////////////////////////////////////////////////////////////////////////
99 // //
100 // L/L COPY WITH MASK FUNCTIONS //
101 // //
102 /////////////////////////////////////////////////////////////////////////////////////////
103
104
105 #define ICV_DEF_COPY_MASK_C1_CASE( type ) \
106 for( i = 0; i <= size.width-2; i += 2 ) \
107 { \
108 if( mask[i] ) \
109 dst[i] = src[i]; \
110 if( mask[i+1] ) \
111 dst[i+1] = src[i+1]; \
112 } \
113 \
114 for( ; i < size.width; i++ ) \
115 { \
116 if( mask[i] ) \
117 dst[i] = src[i]; \
118 }
119
120 #define ICV_DEF_COPY_MASK_C3_CASE( type ) \
121 for( i = 0; i < size.width; i++ ) \
122 if( mask[i] ) \
123 { \
124 type t0 = src[i*3]; \
125 type t1 = src[i*3+1]; \
126 type t2 = src[i*3+2]; \
127 \
128 dst[i*3] = t0; \
129 dst[i*3+1] = t1; \
130 dst[i*3+2] = t2; \
131 }
132
133
134
135 #define ICV_DEF_COPY_MASK_C4_CASE( type ) \
136 for( i = 0; i < size.width; i++ ) \
137 if( mask[i] ) \
138 { \
139 type t0 = src[i*4]; \
140 type t1 = src[i*4+1]; \
141 dst[i*4] = t0; \
142 dst[i*4+1] = t1; \
143 \
144 t0 = src[i*4+2]; \
145 t1 = src[i*4+3]; \
146 dst[i*4+2] = t0; \
147 dst[i*4+3] = t1; \
148 }
149
150
151 #define ICV_DEF_COPY_MASK_2D( name, type, cn ) \
152 IPCVAPI_IMPL( CvStatus, \
153 name,( const type* src, int srcstep, type* dst, int dststep,\
154 CvSize size, const uchar* mask, int maskstep ), \
155 (src, srcstep, dst, dststep, size, mask, maskstep)) \
156 { \
157 srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]); \
158 for( ; size.height--; src += srcstep, \
159 dst += dststep, mask += maskstep ) \
160 { \
161 int i; \
162 ICV_DEF_COPY_MASK_C##cn##_CASE( type ) \
163 } \
164 \
165 return CV_OK; \
166 }
167
168
169 #define ICV_DEF_SET_MASK_C1_CASE( type ) \
170 for( i = 0; i <= size.width-2; i += 2 ) \
171 { \
172 if( mask[i] ) \
173 dst[i] = s0; \
174 if( mask[i+1] ) \
175 dst[i+1] = s0; \
176 } \
177 \
178 for( ; i < size.width; i++ ) \
179 { \
180 if( mask[i] ) \
181 dst[i] = s0; \
182 }
183
184
185 #define ICV_DEF_SET_MASK_C3_CASE( type ) \
186 for( i = 0; i < size.width; i++ ) \
187 if( mask[i] ) \
188 { \
189 dst[i*3] = s0; \
190 dst[i*3+1] = s1; \
191 dst[i*3+2] = s2; \
192 }
193
194 #define ICV_DEF_SET_MASK_C4_CASE( type ) \
195 for( i = 0; i < size.width; i++ ) \
196 if( mask[i] ) \
197 { \
198 dst[i*4] = s0; \
199 dst[i*4+1] = s1; \
200 dst[i*4+2] = s2; \
201 dst[i*4+3] = s3; \
202 }
203
204 #define ICV_DEF_SET_MASK_2D( name, type, cn ) \
205 IPCVAPI_IMPL( CvStatus, \
206 name,( type* dst, int dststep, \
207 const uchar* mask, int maskstep, \
208 CvSize size, const type* scalar ), \
209 (dst, dststep, mask, maskstep, size, scalar))\
210 { \
211 CV_UN_ENTRY_C##cn( type ); \
212 dststep /= sizeof(dst[0]); \
213 \
214 for( ; size.height--; mask += maskstep, \
215 dst += dststep ) \
216 { \
217 int i; \
218 ICV_DEF_SET_MASK_C##cn##_CASE( type ) \
219 } \
220 \
221 return CV_OK; \
222 }
223
224
225 ICV_DEF_SET_MASK_2D( icvSet_8u_C1MR, uchar, 1 )
226 ICV_DEF_SET_MASK_2D( icvSet_16s_C1MR, ushort, 1 )
227 ICV_DEF_SET_MASK_2D( icvSet_8u_C3MR, uchar, 3 )
228 ICV_DEF_SET_MASK_2D( icvSet_8u_C4MR, int, 1 )
229 ICV_DEF_SET_MASK_2D( icvSet_16s_C3MR, ushort, 3 )
230 ICV_DEF_SET_MASK_2D( icvSet_16s_C4MR, int64, 1 )
231 ICV_DEF_SET_MASK_2D( icvSet_32f_C3MR, int, 3 )
232 ICV_DEF_SET_MASK_2D( icvSet_32f_C4MR, int, 4 )
233 ICV_DEF_SET_MASK_2D( icvSet_64s_C3MR, int64, 3 )
234 ICV_DEF_SET_MASK_2D( icvSet_64s_C4MR, int64, 4 )
235
236 ICV_DEF_COPY_MASK_2D( icvCopy_8u_C1MR, uchar, 1 )
237 ICV_DEF_COPY_MASK_2D( icvCopy_16s_C1MR, ushort, 1 )
238 ICV_DEF_COPY_MASK_2D( icvCopy_8u_C3MR, uchar, 3 )
239 ICV_DEF_COPY_MASK_2D( icvCopy_8u_C4MR, int, 1 )
240 ICV_DEF_COPY_MASK_2D( icvCopy_16s_C3MR, ushort, 3 )
241 ICV_DEF_COPY_MASK_2D( icvCopy_16s_C4MR, int64, 1 )
242 ICV_DEF_COPY_MASK_2D( icvCopy_32f_C3MR, int, 3 )
243 ICV_DEF_COPY_MASK_2D( icvCopy_32f_C4MR, int, 4 )
244 ICV_DEF_COPY_MASK_2D( icvCopy_64s_C3MR, int64, 3 )
245 ICV_DEF_COPY_MASK_2D( icvCopy_64s_C4MR, int64, 4 )
246
247 #define CV_DEF_INIT_COPYSET_TAB_2D( FUNCNAME, FLAG ) \
248 static void icvInit##FUNCNAME##FLAG##Table( CvBtFuncTable* table ) \
249 { \
250 table->fn_2d[1] = (void*)icv##FUNCNAME##_8u_C1##FLAG; \
251 table->fn_2d[2] = (void*)icv##FUNCNAME##_16s_C1##FLAG; \
252 table->fn_2d[3] = (void*)icv##FUNCNAME##_8u_C3##FLAG; \
253 table->fn_2d[4] = (void*)icv##FUNCNAME##_8u_C4##FLAG; \
254 table->fn_2d[6] = (void*)icv##FUNCNAME##_16s_C3##FLAG; \
255 table->fn_2d[8] = (void*)icv##FUNCNAME##_16s_C4##FLAG; \
256 table->fn_2d[12] = (void*)icv##FUNCNAME##_32f_C3##FLAG; \
257 table->fn_2d[16] = (void*)icv##FUNCNAME##_32f_C4##FLAG; \
258 table->fn_2d[24] = (void*)icv##FUNCNAME##_64s_C3##FLAG; \
259 table->fn_2d[32] = (void*)icv##FUNCNAME##_64s_C4##FLAG; \
260 }
261
CV_DEF_INIT_COPYSET_TAB_2D(Set,MR)262 CV_DEF_INIT_COPYSET_TAB_2D( Set, MR )
263 CV_DEF_INIT_COPYSET_TAB_2D( Copy, MR )
264
265 /////////////////////////////////////////////////////////////////////////////////////////
266 // //
267 // H/L COPY & SET FUNCTIONS //
268 // //
269 /////////////////////////////////////////////////////////////////////////////////////////
270
271
272 CvCopyMaskFunc
273 icvGetCopyMaskFunc( int elem_size )
274 {
275 static CvBtFuncTable copym_tab;
276 static int inittab = 0;
277
278 if( !inittab )
279 {
280 icvInitCopyMRTable( ©m_tab );
281 inittab = 1;
282 }
283 return (CvCopyMaskFunc)copym_tab.fn_2d[elem_size];
284 }
285
286
287 /* dst = src */
288 CV_IMPL void
cvCopy(const void * srcarr,void * dstarr,const void * maskarr)289 cvCopy( const void* srcarr, void* dstarr, const void* maskarr )
290 {
291 CV_FUNCNAME( "cvCopy" );
292
293 __BEGIN__;
294
295 int pix_size;
296 CvMat srcstub, *src = (CvMat*)srcarr;
297 CvMat dststub, *dst = (CvMat*)dstarr;
298 CvSize size;
299
300 if( !CV_IS_MAT(src) || !CV_IS_MAT(dst) )
301 {
302 if( CV_IS_SPARSE_MAT(src) && CV_IS_SPARSE_MAT(dst))
303 {
304 CvSparseMat* src1 = (CvSparseMat*)src;
305 CvSparseMat* dst1 = (CvSparseMat*)dst;
306 CvSparseMatIterator iterator;
307 CvSparseNode* node;
308
309 dst1->dims = src1->dims;
310 memcpy( dst1->size, src1->size, src1->dims*sizeof(src1->size[0]));
311 dst1->valoffset = src1->valoffset;
312 dst1->idxoffset = src1->idxoffset;
313 cvClearSet( dst1->heap );
314
315 if( src1->heap->active_count >= dst1->hashsize*CV_SPARSE_HASH_RATIO )
316 {
317 CV_CALL( cvFree( &dst1->hashtable ));
318 dst1->hashsize = src1->hashsize;
319 CV_CALL( dst1->hashtable =
320 (void**)cvAlloc( dst1->hashsize*sizeof(dst1->hashtable[0])));
321 }
322
323 memset( dst1->hashtable, 0, dst1->hashsize*sizeof(dst1->hashtable[0]));
324
325 for( node = cvInitSparseMatIterator( src1, &iterator );
326 node != 0; node = cvGetNextSparseNode( &iterator ))
327 {
328 CvSparseNode* node_copy = (CvSparseNode*)cvSetNew( dst1->heap );
329 int tabidx = node->hashval & (dst1->hashsize - 1);
330 CV_MEMCPY_AUTO( node_copy, node, dst1->heap->elem_size );
331 node_copy->next = (CvSparseNode*)dst1->hashtable[tabidx];
332 dst1->hashtable[tabidx] = node_copy;
333 }
334 EXIT;
335 }
336 else if( CV_IS_MATND(src) || CV_IS_MATND(dst) )
337 {
338 CvArr* arrs[] = { src, dst };
339 CvMatND stubs[3];
340 CvNArrayIterator iterator;
341
342 CV_CALL( cvInitNArrayIterator( 2, arrs, maskarr, stubs, &iterator ));
343 pix_size = CV_ELEM_SIZE(iterator.hdr[0]->type);
344
345 if( !maskarr )
346 {
347 iterator.size.width *= pix_size;
348 if( iterator.size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double))
349 {
350 do
351 {
352 memcpy( iterator.ptr[1], iterator.ptr[0], iterator.size.width );
353 }
354 while( cvNextNArraySlice( &iterator ));
355 }
356 else
357 {
358 do
359 {
360 icvCopy_8u_C1R( iterator.ptr[0], CV_STUB_STEP,
361 iterator.ptr[1], CV_STUB_STEP, iterator.size );
362 }
363 while( cvNextNArraySlice( &iterator ));
364 }
365 }
366 else
367 {
368 CvCopyMaskFunc func = icvGetCopyMaskFunc( pix_size );
369 if( !func )
370 CV_ERROR( CV_StsUnsupportedFormat, "" );
371
372 do
373 {
374 func( iterator.ptr[0], CV_STUB_STEP,
375 iterator.ptr[1], CV_STUB_STEP,
376 iterator.size,
377 iterator.ptr[2], CV_STUB_STEP );
378 }
379 while( cvNextNArraySlice( &iterator ));
380 }
381 EXIT;
382 }
383 else
384 {
385 int coi1 = 0, coi2 = 0;
386 CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
387 CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
388
389 if( coi1 )
390 {
391 CvArr* planes[] = { 0, 0, 0, 0 };
392
393 if( maskarr )
394 CV_ERROR( CV_StsBadArg, "COI + mask are not supported" );
395
396 planes[coi1-1] = dst;
397 CV_CALL( cvSplit( src, planes[0], planes[1], planes[2], planes[3] ));
398 EXIT;
399 }
400 else if( coi2 )
401 {
402 CvArr* planes[] = { 0, 0, 0, 0 };
403
404 if( maskarr )
405 CV_ERROR( CV_StsBadArg, "COI + mask are not supported" );
406
407 planes[coi2-1] = src;
408 CV_CALL( cvMerge( planes[0], planes[1], planes[2], planes[3], dst ));
409 EXIT;
410 }
411 }
412 }
413
414 if( !CV_ARE_TYPES_EQ( src, dst ))
415 CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
416
417 if( !CV_ARE_SIZES_EQ( src, dst ))
418 CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
419
420 size = cvGetMatSize( src );
421 pix_size = CV_ELEM_SIZE(src->type);
422
423 if( !maskarr )
424 {
425 int src_step = src->step, dst_step = dst->step;
426 size.width *= pix_size;
427 if( CV_IS_MAT_CONT( src->type & dst->type ) && (src_step == dst_step) && (src_step == src->width * pix_size))
428 {
429 size.width *= size.height;
430
431 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE*
432 CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double))
433 {
434 memcpy( dst->data.ptr, src->data.ptr, size.width );
435 EXIT;
436 }
437
438 size.height = 1;
439 src_step = dst_step = CV_STUB_STEP;
440 }
441
442 if( src->data.ptr != dst->data.ptr )
443 icvCopy_8u_C1R( src->data.ptr, src_step,
444 dst->data.ptr, dst_step, size );
445 }
446 else
447 {
448 CvCopyMaskFunc func = icvGetCopyMaskFunc(pix_size);
449 CvMat maskstub, *mask = (CvMat*)maskarr;
450 int src_step = src->step;
451 int dst_step = dst->step;
452 int mask_step;
453
454 if( !CV_IS_MAT( mask ))
455 CV_CALL( mask = cvGetMat( mask, &maskstub ));
456 if( !CV_IS_MASK_ARR( mask ))
457 CV_ERROR( CV_StsBadMask, "" );
458
459 if( !CV_ARE_SIZES_EQ( src, mask ))
460 CV_ERROR( CV_StsUnmatchedSizes, "" );
461
462 mask_step = mask->step;
463
464 if( CV_IS_MAT_CONT( src->type & dst->type & mask->type ))
465 {
466 size.width *= size.height;
467 size.height = 1;
468 src_step = dst_step = mask_step = CV_STUB_STEP;
469 }
470
471 if( !func )
472 CV_ERROR( CV_StsUnsupportedFormat, "" );
473
474 IPPI_CALL( func( src->data.ptr, src_step, dst->data.ptr, dst_step,
475 size, mask->data.ptr, mask_step ));
476 }
477
478 __END__;
479 }
480
481
482 /* dst(idx) = value */
483 CV_IMPL void
cvSet(void * arr,CvScalar value,const void * maskarr)484 cvSet( void* arr, CvScalar value, const void* maskarr )
485 {
486 static CvBtFuncTable setm_tab;
487 static int inittab = 0;
488
489 CV_FUNCNAME( "cvSet" );
490
491 __BEGIN__;
492
493 CvMat stub, *mat = (CvMat*)arr;
494 int pix_size, type;
495 double buf[12];
496 int mat_step;
497 CvSize size;
498
499 if( !value.val[0] && !value.val[1] &&
500 !value.val[2] && !value.val[3] && !maskarr )
501 {
502 cvZero( arr );
503 EXIT;
504 }
505
506 if( !CV_IS_MAT(mat))
507 {
508 if( CV_IS_MATND(mat))
509 {
510 CvMatND nstub;
511 CvNArrayIterator iterator;
512 int pix_size1;
513
514 CV_CALL( cvInitNArrayIterator( 1, &arr, maskarr, &nstub, &iterator ));
515
516 type = CV_MAT_TYPE(iterator.hdr[0]->type);
517 pix_size1 = CV_ELEM_SIZE1(type);
518 pix_size = pix_size1*CV_MAT_CN(type);
519
520 CV_CALL( cvScalarToRawData( &value, buf, type, maskarr == 0 ));
521
522 if( !maskarr )
523 {
524 iterator.size.width *= pix_size;
525 do
526 {
527 icvSet_8u_C1R( iterator.ptr[0], CV_STUB_STEP,
528 iterator.size, buf, pix_size1 );
529 }
530 while( cvNextNArraySlice( &iterator ));
531 }
532 else
533 {
534 CvFunc2D_2A1P func = (CvFunc2D_2A1P)(setm_tab.fn_2d[pix_size]);
535 if( !func )
536 CV_ERROR( CV_StsUnsupportedFormat, "" );
537
538 do
539 {
540 func( iterator.ptr[0], CV_STUB_STEP,
541 iterator.ptr[1], CV_STUB_STEP,
542 iterator.size, buf );
543 }
544 while( cvNextNArraySlice( &iterator ));
545 }
546 EXIT;
547 }
548 else
549 {
550 int coi = 0;
551 CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
552
553 if( coi != 0 )
554 CV_ERROR( CV_BadCOI, "" );
555 }
556 }
557
558 type = CV_MAT_TYPE( mat->type );
559 pix_size = CV_ELEM_SIZE(type);
560 size = cvGetMatSize( mat );
561 mat_step = mat->step;
562
563 if( !maskarr )
564 {
565 if( CV_IS_MAT_CONT( mat->type ))
566 {
567 size.width *= size.height;
568
569 if( size.width <= (int)(CV_MAX_INLINE_MAT_OP_SIZE*sizeof(double)))
570 {
571 if( type == CV_32FC1 )
572 {
573 float* dstdata = (float*)(mat->data.ptr);
574 float val = (float)value.val[0];
575
576 do
577 {
578 dstdata[size.width-1] = val;
579 }
580 while( --size.width );
581
582 EXIT;
583 }
584
585 if( type == CV_64FC1 )
586 {
587 double* dstdata = (double*)(mat->data.ptr);
588 double val = value.val[0];
589
590 do
591 {
592 dstdata[size.width-1] = val;
593 }
594 while( --size.width );
595
596 EXIT;
597 }
598 }
599
600 mat_step = CV_STUB_STEP;
601 size.height = 1;
602 }
603
604 size.width *= pix_size;
605 CV_CALL( cvScalarToRawData( &value, buf, type, 1 ));
606
607 IPPI_CALL( icvSet_8u_C1R( mat->data.ptr, mat_step, size, buf,
608 CV_ELEM_SIZE1(type)));
609 }
610 else
611 {
612 CvFunc2D_2A1P func;
613 CvMat maskstub, *mask = (CvMat*)maskarr;
614 int mask_step;
615
616 CV_CALL( mask = cvGetMat( mask, &maskstub ));
617
618 if( !CV_IS_MASK_ARR( mask ))
619 CV_ERROR( CV_StsBadMask, "" );
620
621 if( !inittab )
622 {
623 icvInitSetMRTable( &setm_tab );
624 inittab = 1;
625 }
626
627 if( !CV_ARE_SIZES_EQ( mat, mask ))
628 CV_ERROR( CV_StsUnmatchedSizes, "" );
629
630 mask_step = mask->step;
631
632 if( CV_IS_MAT_CONT( mat->type & mask->type ))
633 {
634 size.width *= size.height;
635 mat_step = mask_step = CV_STUB_STEP;
636 size.height = 1;
637 }
638
639 func = (CvFunc2D_2A1P)(setm_tab.fn_2d[pix_size]);
640 if( !func )
641 CV_ERROR( CV_StsUnsupportedFormat, "" );
642
643 CV_CALL( cvScalarToRawData( &value, buf, type, 0 ));
644
645 IPPI_CALL( func( mat->data.ptr, mat_step, mask->data.ptr,
646 mask_step, size, buf ));
647 }
648
649 __END__;
650 }
651
652
653 /****************************************************************************************\
654 * Clearing *
655 \****************************************************************************************/
656
657 icvSetByte_8u_C1R_t icvSetByte_8u_C1R_p = 0;
658
659 CvStatus CV_STDCALL
icvSetZero_8u_C1R(uchar * dst,int dststep,CvSize size)660 icvSetZero_8u_C1R( uchar* dst, int dststep, CvSize size )
661 {
662 if( size.width + size.height > 256 && icvSetByte_8u_C1R_p )
663 return icvSetByte_8u_C1R_p( 0, dst, dststep, size );
664
665 for( ; size.height--; dst += dststep )
666 memset( dst, 0, size.width );
667
668 return CV_OK;
669 }
670
671 CV_IMPL void
cvSetZero(CvArr * arr)672 cvSetZero( CvArr* arr )
673 {
674 CV_FUNCNAME( "cvSetZero" );
675
676 __BEGIN__;
677
678 CvMat stub, *mat = (CvMat*)arr;
679 CvSize size;
680 int mat_step;
681
682 if( !CV_IS_MAT( mat ))
683 {
684 if( CV_IS_MATND(mat))
685 {
686 CvMatND nstub;
687 CvNArrayIterator iterator;
688
689 CV_CALL( cvInitNArrayIterator( 1, &arr, 0, &nstub, &iterator ));
690 iterator.size.width *= CV_ELEM_SIZE(iterator.hdr[0]->type);
691
692 if( iterator.size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double) )
693 {
694 do
695 {
696 memset( iterator.ptr[0], 0, iterator.size.width );
697 }
698 while( cvNextNArraySlice( &iterator ));
699 }
700 else
701 {
702 do
703 {
704 icvSetZero_8u_C1R( iterator.ptr[0], CV_STUB_STEP, iterator.size );
705 }
706 while( cvNextNArraySlice( &iterator ));
707 }
708 EXIT;
709 }
710 else if( CV_IS_SPARSE_MAT(mat))
711 {
712 CvSparseMat* mat1 = (CvSparseMat*)mat;
713 cvClearSet( mat1->heap );
714 if( mat1->hashtable )
715 memset( mat1->hashtable, 0, mat1->hashsize*sizeof(mat1->hashtable[0]));
716 EXIT;
717 }
718 else
719 {
720 int coi = 0;
721 CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
722 if( coi != 0 )
723 CV_ERROR( CV_BadCOI, "coi is not supported" );
724 }
725 }
726
727 size = cvGetMatSize( mat );
728 size.width *= CV_ELEM_SIZE(mat->type);
729 mat_step = mat->step;
730
731 if( CV_IS_MAT_CONT( mat->type ))
732 {
733 size.width *= size.height;
734
735 if( size.width <= CV_MAX_INLINE_MAT_OP_SIZE*(int)sizeof(double) )
736 {
737 memset( mat->data.ptr, 0, size.width );
738 EXIT;
739 }
740
741 mat_step = CV_STUB_STEP;
742 size.height = 1;
743 }
744
745 IPPI_CALL( icvSetZero_8u_C1R( mat->data.ptr, mat_step, size ));
746
747 __END__;
748 }
749
750
751 /****************************************************************************************\
752 * Flipping *
753 \****************************************************************************************/
754
755 #define ICV_DEF_FLIP_HZ_CASE_C1( type ) \
756 for( i = 0; i < (len+1)/2; i++ ) \
757 { \
758 type t0 = src[i]; \
759 type t1 = src[len - i - 1]; \
760 dst[i] = t1; \
761 dst[len - i - 1] = t0; \
762 }
763
764
765 #define ICV_DEF_FLIP_HZ_CASE_C3( type ) \
766 for( i = 0; i < (len+1)/2; i++ ) \
767 { \
768 type t0 = src[i*3]; \
769 type t1 = src[(len - i)*3 - 3]; \
770 dst[i*3] = t1; \
771 dst[(len - i)*3 - 3] = t0; \
772 t0 = src[i*3 + 1]; \
773 t1 = src[(len - i)*3 - 2]; \
774 dst[i*3 + 1] = t1; \
775 dst[(len - i)*3 - 2] = t0; \
776 t0 = src[i*3 + 2]; \
777 t1 = src[(len - i)*3 - 1]; \
778 dst[i*3 + 2] = t1; \
779 dst[(len - i)*3 - 1] = t0; \
780 }
781
782
783 #define ICV_DEF_FLIP_HZ_CASE_C4( type ) \
784 for( i = 0; i < (len+1)/2; i++ ) \
785 { \
786 type t0 = src[i*4]; \
787 type t1 = src[(len - i)*4 - 4]; \
788 dst[i*4] = t1; \
789 dst[(len - i)*4 - 4] = t0; \
790 t0 = src[i*4 + 1]; \
791 t1 = src[(len - i)*4 - 3]; \
792 dst[i*4 + 1] = t1; \
793 dst[(len - i)*4 - 3] = t0; \
794 t0 = src[i*4 + 2]; \
795 t1 = src[(len - i)*4 - 2]; \
796 dst[i*4 + 2] = t1; \
797 dst[(len - i)*4 - 2] = t0; \
798 t0 = src[i*4 + 3]; \
799 t1 = src[(len - i)*4 - 1]; \
800 dst[i*4 + 3] = t1; \
801 dst[(len - i)*4 - 1] = t0; \
802 }
803
804
805 #define ICV_DEF_FLIP_HZ_FUNC( flavor, arrtype, cn ) \
806 static CvStatus CV_STDCALL \
807 icvFlipHorz_##flavor( const arrtype* src, int srcstep, \
808 arrtype* dst, int dststep, CvSize size ) \
809 { \
810 int i, len = size.width; \
811 srcstep /= sizeof(src[0]); dststep /= sizeof(dst[0]); \
812 \
813 for( ; size.height--; src += srcstep, dst += dststep ) \
814 { \
815 ICV_DEF_FLIP_HZ_CASE_C##cn( arrtype ) \
816 } \
817 \
818 return CV_OK; \
819 }
820
821
822 ICV_DEF_FLIP_HZ_FUNC( 8u_C1R, uchar, 1 )
823 ICV_DEF_FLIP_HZ_FUNC( 8u_C2R, ushort, 1 )
824 ICV_DEF_FLIP_HZ_FUNC( 8u_C3R, uchar, 3 )
825 ICV_DEF_FLIP_HZ_FUNC( 16u_C2R, int, 1 )
826 ICV_DEF_FLIP_HZ_FUNC( 16u_C3R, ushort, 3 )
827 ICV_DEF_FLIP_HZ_FUNC( 32s_C2R, int64, 1 )
828 ICV_DEF_FLIP_HZ_FUNC( 32s_C3R, int, 3 )
829 ICV_DEF_FLIP_HZ_FUNC( 64s_C2R, int, 4 )
830 ICV_DEF_FLIP_HZ_FUNC( 64s_C3R, int64, 3 )
831 ICV_DEF_FLIP_HZ_FUNC( 64s_C4R, int64, 4 )
832
CV_DEF_INIT_PIXSIZE_TAB_2D(FlipHorz,R)833 CV_DEF_INIT_PIXSIZE_TAB_2D( FlipHorz, R )
834
835
836 static CvStatus
837 icvFlipVert_8u_C1R( const uchar* src, int srcstep,
838 uchar* dst, int dststep, CvSize size )
839 {
840 int y, i;
841 const uchar* src1 = src + (size.height - 1)*srcstep;
842 uchar* dst1 = dst + (size.height - 1)*dststep;
843
844 for( y = 0; y < (size.height + 1)/2; y++, src += srcstep, src1 -= srcstep,
845 dst += dststep, dst1 -= dststep )
846 {
847 i = 0;
848 if( ((size_t)(src)|(size_t)(dst)|(size_t)src1|(size_t)dst1) % sizeof(int) == 0 )
849 {
850 for( ; i <= size.width - 16; i += 16 )
851 {
852 int t0 = ((int*)(src + i))[0];
853 int t1 = ((int*)(src1 + i))[0];
854
855 ((int*)(dst + i))[0] = t1;
856 ((int*)(dst1 + i))[0] = t0;
857
858 t0 = ((int*)(src + i))[1];
859 t1 = ((int*)(src1 + i))[1];
860
861 ((int*)(dst + i))[1] = t1;
862 ((int*)(dst1 + i))[1] = t0;
863
864 t0 = ((int*)(src + i))[2];
865 t1 = ((int*)(src1 + i))[2];
866
867 ((int*)(dst + i))[2] = t1;
868 ((int*)(dst1 + i))[2] = t0;
869
870 t0 = ((int*)(src + i))[3];
871 t1 = ((int*)(src1 + i))[3];
872
873 ((int*)(dst + i))[3] = t1;
874 ((int*)(dst1 + i))[3] = t0;
875 }
876
877 for( ; i <= size.width - 4; i += 4 )
878 {
879 int t0 = ((int*)(src + i))[0];
880 int t1 = ((int*)(src1 + i))[0];
881
882 ((int*)(dst + i))[0] = t1;
883 ((int*)(dst1 + i))[0] = t0;
884 }
885 }
886
887 for( ; i < size.width; i++ )
888 {
889 uchar t0 = src[i];
890 uchar t1 = src1[i];
891
892 dst[i] = t1;
893 dst1[i] = t0;
894 }
895 }
896
897 return CV_OK;
898 }
899
900
901 CV_IMPL void
cvFlip(const CvArr * srcarr,CvArr * dstarr,int flip_mode)902 cvFlip( const CvArr* srcarr, CvArr* dstarr, int flip_mode )
903 {
904 static CvBtFuncTable tab;
905 static int inittab = 0;
906
907 CV_FUNCNAME( "cvFlip" );
908
909 __BEGIN__;
910
911 CvMat sstub, *src = (CvMat*)srcarr;
912 CvMat dstub, *dst = (CvMat*)dstarr;
913 CvSize size;
914 CvFunc2D_2A func = 0;
915 int pix_size;
916
917 if( !inittab )
918 {
919 icvInitFlipHorzRTable( &tab );
920 inittab = 1;
921 }
922
923 if( !CV_IS_MAT( src ))
924 {
925 int coi = 0;
926 CV_CALL( src = cvGetMat( src, &sstub, &coi ));
927 if( coi != 0 )
928 CV_ERROR( CV_BadCOI, "coi is not supported" );
929 }
930
931 if( !dst )
932 dst = src;
933 else if( !CV_IS_MAT( dst ))
934 {
935 int coi = 0;
936 CV_CALL( dst = cvGetMat( dst, &dstub, &coi ));
937 if( coi != 0 )
938 CV_ERROR( CV_BadCOI, "coi is not supported" );
939 }
940
941 if( !CV_ARE_TYPES_EQ( src, dst ))
942 CV_ERROR( CV_StsUnmatchedFormats, "" );
943
944 if( !CV_ARE_SIZES_EQ( src, dst ))
945 CV_ERROR( CV_StsUnmatchedSizes, "" );
946
947 size = cvGetMatSize( src );
948 pix_size = CV_ELEM_SIZE( src->type );
949
950 if( flip_mode == 0 )
951 {
952 size.width *= pix_size;
953
954 IPPI_CALL( icvFlipVert_8u_C1R( src->data.ptr, src->step,
955 dst->data.ptr, dst->step, size ));
956 }
957 else
958 {
959 int inplace = src->data.ptr == dst->data.ptr;
960 uchar* dst_data = dst->data.ptr;
961 int dst_step = dst->step;
962
963 func = (CvFunc2D_2A)(tab.fn_2d[pix_size]);
964
965 if( !func )
966 CV_ERROR( CV_StsUnsupportedFormat, "" );
967
968 if( flip_mode < 0 && !inplace )
969 {
970 dst_data += dst_step * (dst->height - 1);
971 dst_step = -dst_step;
972 }
973
974 IPPI_CALL( func( src->data.ptr, src->step, dst_data, dst_step, size ));
975
976 if( flip_mode < 0 && inplace )
977 {
978 size.width *= pix_size;
979 IPPI_CALL( icvFlipVert_8u_C1R( dst->data.ptr, dst->step,
980 dst->data.ptr, dst->step, size ));
981 }
982 }
983
984 __END__;
985 }
986
987
988 CV_IMPL void
cvRepeat(const CvArr * srcarr,CvArr * dstarr)989 cvRepeat( const CvArr* srcarr, CvArr* dstarr )
990 {
991 CV_FUNCNAME( "cvRepeat" );
992
993 __BEGIN__;
994
995 CvMat sstub, *src = (CvMat*)srcarr;
996 CvMat dstub, *dst = (CvMat*)dstarr;
997 CvSize srcsize, dstsize;
998 int pix_size;
999 int x, y, k, l;
1000
1001 if( !CV_IS_MAT( src ))
1002 {
1003 int coi = 0;
1004 CV_CALL( src = cvGetMat( src, &sstub, &coi ));
1005 if( coi != 0 )
1006 CV_ERROR( CV_BadCOI, "coi is not supported" );
1007 }
1008
1009 if( !CV_IS_MAT( dst ))
1010 {
1011 int coi = 0;
1012 CV_CALL( dst = cvGetMat( dst, &dstub, &coi ));
1013 if( coi != 0 )
1014 CV_ERROR( CV_BadCOI, "coi is not supported" );
1015 }
1016
1017 if( !CV_ARE_TYPES_EQ( src, dst ))
1018 CV_ERROR( CV_StsUnmatchedFormats, "" );
1019
1020 srcsize = cvGetMatSize( src );
1021 dstsize = cvGetMatSize( dst );
1022 pix_size = CV_ELEM_SIZE( src->type );
1023
1024 for( y = 0, k = 0; y < dstsize.height; y++ )
1025 {
1026 for( x = 0; x < dstsize.width; x += srcsize.width )
1027 {
1028 l = srcsize.width;
1029 if( l > dstsize.width - x )
1030 l = dstsize.width - x;
1031 memcpy( dst->data.ptr + y*dst->step + x*pix_size,
1032 src->data.ptr + k*src->step, l*pix_size );
1033 }
1034 if( ++k == srcsize.height )
1035 k = 0;
1036 }
1037
1038 __END__;
1039 }
1040
1041 /* End of file. */
1042
1043