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 logical operations: &, |, ^ ...
45 //
46 // */
47 
48 #include "_cxcore.h"
49 
50 /////////////////////////////////////////////////////////////////////////////////////////
51 //                                                                                     //
52 //                             Macros for logic operations                             //
53 //                                                                                     //
54 /////////////////////////////////////////////////////////////////////////////////////////
55 
56 /* //////////////////////////////////////////////////////////////////////////////////////
57                                 Mat op Mat
58 ////////////////////////////////////////////////////////////////////////////////////// */
59 
60 
61 #define ICV_DEF_BIN_LOG_OP_2D( __op__, name )                                       \
62 IPCVAPI_IMPL( CvStatus, icv##name##_8u_C1R,                                         \
63 ( const uchar* src1, int step1, const uchar* src2, int step2,                       \
64   uchar* dst, int step, CvSize size ), (src1, step1, src2, step2, dst, step, size) )\
65 {                                                                                   \
66     for( ; size.height--; src1 += step1, src2 += step2, dst += step )               \
67     {                                                                               \
68         int i = 0;                                                                  \
69                                                                                     \
70         if( (((size_t)src1 | (size_t)src2 | (size_t)dst) & 3) == 0 )                \
71         {                                                                           \
72             for( ; i <= size.width - 16; i += 16 )                                  \
73             {                                                                       \
74                 int t0 = __op__(((const int*)(src1+i))[0], ((const int*)(src2+i))[0]);\
75                 int t1 = __op__(((const int*)(src1+i))[1], ((const int*)(src2+i))[1]);\
76                                                                                     \
77                 ((int*)(dst+i))[0] = t0;                                            \
78                 ((int*)(dst+i))[1] = t1;                                            \
79                                                                                     \
80                 t0 = __op__(((const int*)(src1+i))[2], ((const int*)(src2+i))[2]);  \
81                 t1 = __op__(((const int*)(src1+i))[3], ((const int*)(src2+i))[3]);  \
82                                                                                     \
83                 ((int*)(dst+i))[2] = t0;                                            \
84                 ((int*)(dst+i))[3] = t1;                                            \
85             }                                                                       \
86                                                                                     \
87             for( ; i <= size.width - 4; i += 4 )                                    \
88             {                                                                       \
89                 int t = __op__(*(const int*)(src1+i), *(const int*)(src2+i));       \
90                 *(int*)(dst+i) = t;                                                 \
91             }                                                                       \
92         }                                                                           \
93                                                                                     \
94         for( ; i < size.width; i++ )                                                \
95         {                                                                           \
96             int t = __op__(((const uchar*)src1)[i],((const uchar*)src2)[i]);        \
97             dst[i] = (uchar)t;                                                      \
98         }                                                                           \
99     }                                                                               \
100                                                                                     \
101     return  CV_OK;                                                                  \
102 }
103 
104 
105 /* //////////////////////////////////////////////////////////////////////////////////////
106                                      Mat op Scalar
107 ////////////////////////////////////////////////////////////////////////////////////// */
108 
109 
110 #define ICV_DEF_UN_LOG_OP_2D( __op__, name )                                            \
111 static CvStatus CV_STDCALL icv##name##_8u_CnR                                           \
112 ( const uchar* src0, int step1, uchar* dst0, int step, CvSize size,                     \
113   const uchar* scalar, int pix_size )                                                   \
114 {                                                                                       \
115     int delta = 12*pix_size;                                                            \
116                                                                                         \
117     for( ; size.height--; src0 += step1, dst0 += step )                                 \
118     {                                                                                   \
119         const uchar* src = (const uchar*)src0;                                          \
120         uchar* dst = dst0;                                                              \
121         int i, len = size.width;                                                        \
122                                                                                         \
123         if( (((size_t)src|(size_t)dst) & 3) == 0 )                                      \
124         {                                                                               \
125             while( (len -= delta) >= 0 )                                                \
126             {                                                                           \
127                 for( i = 0; i < (delta); i += 12 )                                      \
128                 {                                                                       \
129                     int t0 = __op__(((const int*)(src+i))[0], ((const int*)(scalar+i))[0]); \
130                     int t1 = __op__(((const int*)(src+i))[1], ((const int*)(scalar+i))[1]); \
131                     ((int*)(dst+i))[0] = t0;                                            \
132                     ((int*)(dst+i))[1] = t1;                                            \
133                                                                                         \
134                     t0 = __op__(((const int*)(src+i))[2], ((const int*)(scalar+i))[2]); \
135                     ((int*)(dst+i))[2] = t0;                                            \
136                 }                                                                       \
137                 src += delta;                                                           \
138                 dst += delta;                                                           \
139             }                                                                           \
140         }                                                                               \
141         else                                                                            \
142         {                                                                               \
143             while( (len -= delta) >= 0 )                                                \
144             {                                                                           \
145                 for( i = 0; i < (delta); i += 4 )                                       \
146                 {                                                                       \
147                     int t0 = __op__(src[i], scalar[i]);                                 \
148                     int t1 = __op__(src[i+1], scalar[i+1]);                             \
149                     dst[i] = (uchar)t0;                                                 \
150                     dst[i+1] = (uchar)t1;                                               \
151                                                                                         \
152                     t0 = __op__(src[i+2], scalar[i+2]);                                 \
153                     t1 = __op__(src[i+3], scalar[i+3]);                                 \
154                     dst[i+2] = (uchar)t0;                                               \
155                     dst[i+3] = (uchar)t1;                                               \
156                 }                                                                       \
157                 src += delta;                                                           \
158                 dst += delta;                                                           \
159             }                                                                           \
160         }                                                                               \
161                                                                                         \
162         for( len += delta, i = 0; i < len; i++ )                                        \
163         {                                                                               \
164             int t = __op__(src[i],scalar[i]);                                           \
165             dst[i] = (uchar)t;                                                          \
166         }                                                                               \
167     }                                                                                   \
168                                                                                         \
169     return CV_OK;                                                                       \
170 }
171 
172 /////////////////////////////////////////////////////////////////////////////////////////
173 //                                                                                     //
174 //                                LOGIC OPERATIONS                                     //
175 //                                                                                     //
176 /////////////////////////////////////////////////////////////////////////////////////////
177 
178 static void
icvLogicS(const void * srcarr,CvScalar * scalar,void * dstarr,const void * maskarr,CvFunc2D_2A1P1I fn_2d)179 icvLogicS( const void* srcarr, CvScalar* scalar, void* dstarr,
180            const void* maskarr, CvFunc2D_2A1P1I fn_2d )
181 {
182     uchar* buffer = 0;
183     int local_alloc = 1;
184 
185     CV_FUNCNAME( "icvLogicS" );
186 
187     __BEGIN__;
188 
189     CvMat srcstub, *src = (CvMat*)srcarr;
190     CvMat dststub, *dst = (CvMat*)dstarr;
191     CvMat maskstub, *mask = (CvMat*)maskarr;
192     CvMat dstbuf, *tdst;
193     CvCopyMaskFunc copym_func = 0;
194 
195     int y, dy;
196     int coi1 = 0, coi2 = 0;
197     int is_nd = 0, cont_flag = 0;
198     int elem_size, elem_size1, type, depth;
199     double buf[12];
200     CvSize size, tsize;
201     int src_step, dst_step, tdst_step, mask_step;
202 
203     if( !CV_IS_MAT(src))
204     {
205         if( CV_IS_MATND(src) )
206             is_nd = 1;
207         else
208             CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
209     }
210 
211     if( !CV_IS_MAT(dst))
212     {
213         if( CV_IS_MATND(dst) )
214             is_nd = 1;
215         else
216             CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
217     }
218 
219     if( is_nd )
220     {
221         CvArr* arrs[] = { src, dst };
222         CvMatND stubs[2];
223         CvNArrayIterator iterator;
224 
225         if( maskarr )
226             CV_ERROR( CV_StsBadMask,
227             "This operation on multi-dimensional arrays does not support mask" );
228 
229         CV_CALL( cvInitNArrayIterator( 2, arrs, 0, stubs, &iterator ));
230 
231         type = CV_MAT_TYPE(iterator.hdr[0]->type);
232         depth = CV_MAT_DEPTH(type);
233         iterator.size.width *= CV_ELEM_SIZE(type);
234         elem_size1 = CV_ELEM_SIZE1(depth);
235 
236         CV_CALL( cvScalarToRawData( scalar, buf, type, 1 ));
237 
238         do
239         {
240             IPPI_CALL( fn_2d( iterator.ptr[0], CV_STUB_STEP,
241                               iterator.ptr[1], CV_STUB_STEP,
242                               iterator.size, buf, elem_size1 ));
243         }
244         while( cvNextNArraySlice( &iterator ));
245         EXIT;
246     }
247 
248     if( coi1 != 0 || coi2 != 0 )
249         CV_ERROR( CV_BadCOI, "" );
250 
251     if( !CV_ARE_TYPES_EQ( src, dst ) )
252         CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
253 
254     if( !CV_ARE_SIZES_EQ( src, dst ) )
255         CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
256 
257     size = cvGetMatSize( src );
258     type = CV_MAT_TYPE(src->type);
259     depth = CV_MAT_DEPTH(type);
260     elem_size = CV_ELEM_SIZE(type);
261     elem_size1 = CV_ELEM_SIZE1(depth);
262 
263     if( !mask )
264     {
265         cont_flag = CV_IS_MAT_CONT( src->type & dst->type );
266         dy = size.height;
267         tdst = dst;
268     }
269     else
270     {
271         int buf_size;
272 
273         if( !CV_IS_MAT(mask) )
274             CV_CALL( mask = cvGetMat( mask, &maskstub ));
275 
276         if( !CV_IS_MASK_ARR(mask))
277             CV_ERROR( CV_StsBadMask, "" );
278 
279         if( !CV_ARE_SIZES_EQ( mask, dst ))
280             CV_ERROR( CV_StsUnmatchedSizes, "" );
281 
282         cont_flag = CV_IS_MAT_CONT( src->type & dst->type & mask->type );
283         dy = CV_MAX_LOCAL_SIZE/(elem_size*size.height);
284         dy = MAX(dy,1);
285         dy = MIN(dy,size.height);
286         dstbuf = cvMat( dy, size.width, type );
287         if( !cont_flag )
288             dstbuf.step = cvAlign( dstbuf.step, 8 );
289         buf_size = dstbuf.step ? dstbuf.step*dy : size.width*elem_size;
290         if( buf_size > CV_MAX_LOCAL_SIZE )
291         {
292             CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
293             local_alloc = 0;
294         }
295         else
296             buffer = (uchar*)cvStackAlloc( buf_size );
297         dstbuf.data.ptr = buffer;
298         tdst = &dstbuf;
299 
300         copym_func = icvGetCopyMaskFunc( elem_size );
301     }
302 
303     src_step = src->step;
304     dst_step = dst->step;
305     tdst_step = tdst->step;
306     mask_step = mask ? mask->step : 0;
307     CV_CALL( cvScalarToRawData( scalar, buf, type, 1 ));
308 
309     for( y = 0; y < size.height; y += dy )
310     {
311         tsize.width = size.width;
312         tsize.height = dy;
313         if( y + dy > size.height )
314             tsize.height = size.height - y;
315         if( cont_flag || tsize.height == 1 )
316         {
317             tsize.width *= tsize.height;
318             tsize.height = 1;
319             src_step = tdst_step = dst_step = mask_step = CV_STUB_STEP;
320         }
321         IPPI_CALL( fn_2d( src->data.ptr + y*src->step, src_step, tdst->data.ptr, tdst_step,
322                           cvSize(tsize.width*elem_size, tsize.height), buf, elem_size1 ));
323         if( mask )
324         {
325             IPPI_CALL( copym_func( tdst->data.ptr, tdst_step, dst->data.ptr + y*dst->step,
326                                    dst_step, tsize, mask->data.ptr + y*mask->step, mask_step ));
327         }
328     }
329 
330     __END__;
331 
332     if( !local_alloc )
333         cvFree( &buffer );
334 }
335 
336 
337 static void
icvLogic(const void * srcarr1,const void * srcarr2,void * dstarr,const void * maskarr,CvFunc2D_3A fn_2d)338 icvLogic( const void* srcarr1, const void* srcarr2, void* dstarr,
339           const void* maskarr, CvFunc2D_3A fn_2d )
340 {
341     uchar* buffer = 0;
342     int local_alloc = 1;
343 
344     CV_FUNCNAME( "icvLogic" );
345 
346     __BEGIN__;
347 
348     int y, dy;
349     int coi1 = 0, coi2 = 0, coi3 = 0;
350     int type, elem_size;
351     int is_nd = 0, cont_flag = 0;
352     CvMat  srcstub1, *src1 = (CvMat*)srcarr1;
353     CvMat  srcstub2, *src2 = (CvMat*)srcarr2;
354     CvMat  dststub,  *dst = (CvMat*)dstarr;
355     CvMat  maskstub, *mask = (CvMat*)maskarr;
356     CvMat  dstbuf, *tdst;
357     int src1_step, src2_step, tdst_step, dst_step, mask_step;
358     CvSize size, tsize;
359     CvCopyMaskFunc copym_func = 0;
360 
361     if( !CV_IS_MAT(src1))
362     {
363         if( CV_IS_MATND(src1) )
364             is_nd = 1;
365         else
366             CV_CALL( src1 = cvGetMat( src1, &srcstub1, &coi1 ));
367     }
368 
369     if( !CV_IS_MAT(src2))
370     {
371         if( CV_IS_MATND(src2) )
372             is_nd = 1;
373         else
374             CV_CALL( src2 = cvGetMat( src2, &srcstub2, &coi2 ));
375     }
376 
377     if( !CV_IS_MAT(dst))
378     {
379         if( CV_IS_MATND(dst) )
380             is_nd = 1;
381         else
382             CV_CALL( dst = cvGetMat( dst, &dststub, &coi3 ));
383     }
384 
385     if( is_nd )
386     {
387         CvArr* arrs[] = { src1, src2, dst };
388         CvMatND stubs[3];
389         CvNArrayIterator iterator;
390 
391         if( maskarr )
392             CV_ERROR( CV_StsBadMask,
393             "This operation on multi-dimensional arrays does not support mask" );
394 
395         CV_CALL( cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ));
396 
397         type = CV_MAT_TYPE(iterator.hdr[0]->type);
398         iterator.size.width *= CV_ELEM_SIZE(type);
399 
400         do
401         {
402             IPPI_CALL( fn_2d( iterator.ptr[0], CV_STUB_STEP,
403                               iterator.ptr[1], CV_STUB_STEP,
404                               iterator.ptr[2], CV_STUB_STEP,
405                               iterator.size ));
406         }
407         while( cvNextNArraySlice( &iterator ));
408         EXIT;
409     }
410 
411     if( coi1 != 0 || coi2 != 0 || coi3 != 0 )
412         CV_ERROR_FROM_CODE( CV_BadCOI );
413 
414     if( !CV_ARE_TYPES_EQ( src1, src2 ) )
415         CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
416 
417     if( !CV_ARE_SIZES_EQ( src1, src2 ) )
418         CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
419 
420     if( !CV_ARE_TYPES_EQ( src1, dst ) )
421         CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
422 
423     if( !CV_ARE_SIZES_EQ( src1, dst ) )
424         CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
425 
426     size = cvGetMatSize( src1 );
427     type = CV_MAT_TYPE( src1->type );
428     elem_size = CV_ELEM_SIZE(type);
429 
430     if( !mask )
431     {
432         cont_flag = CV_IS_MAT_CONT( src1->type & src2->type & dst->type );
433         dy = size.height;
434         tdst = dst;
435     }
436     else
437     {
438         int buf_size;
439 
440         if( !CV_IS_MAT(mask) )
441             CV_CALL( mask = cvGetMat( mask, &maskstub ));
442 
443         if( !CV_IS_MASK_ARR(mask))
444             CV_ERROR( CV_StsBadMask, "" );
445 
446         if( !CV_ARE_SIZES_EQ( mask, dst ))
447             CV_ERROR( CV_StsUnmatchedSizes, "" );
448 
449         cont_flag = CV_IS_MAT_CONT( src1->type & src2->type & dst->type & mask->type );
450         dy = CV_MAX_LOCAL_SIZE/(elem_size*size.height);
451         dy = MAX(dy,1);
452         dy = MIN(dy,size.height);
453         dstbuf = cvMat( dy, size.width, type );
454         if( !cont_flag )
455             dstbuf.step = cvAlign( dstbuf.step, 8 );
456         buf_size = dstbuf.step ? dstbuf.step*dy : size.width*elem_size;
457         if( buf_size > CV_MAX_LOCAL_SIZE )
458         {
459             CV_CALL( buffer = (uchar*)cvAlloc( buf_size ));
460             local_alloc = 0;
461         }
462         else
463             buffer = (uchar*)cvStackAlloc( buf_size );
464         dstbuf.data.ptr = buffer;
465         tdst = &dstbuf;
466 
467         copym_func = icvGetCopyMaskFunc( elem_size );
468     }
469 
470     src1_step = src1->step;
471     src2_step = src2->step;
472     dst_step = dst->step;
473     tdst_step = tdst->step;
474     mask_step = mask ? mask->step : 0;
475 
476     for( y = 0; y < size.height; y += dy )
477     {
478         tsize.width = size.width;
479         tsize.height = dy;
480         if( y + dy > size.height )
481             tsize.height = size.height - y;
482         if( cont_flag || tsize.height == 1 )
483         {
484             tsize.width *= tsize.height;
485             tsize.height = 1;
486             src1_step = src2_step = tdst_step = dst_step = mask_step = CV_STUB_STEP;
487         }
488         IPPI_CALL( fn_2d( src1->data.ptr + y*src1->step, src1_step,
489                           src2->data.ptr + y*src2->step, src2_step,
490                           tdst->data.ptr, tdst_step,
491                           cvSize(tsize.width*elem_size, tsize.height) ));
492         if( mask )
493         {
494             IPPI_CALL( copym_func( tdst->data.ptr, tdst_step, dst->data.ptr + y*dst->step,
495                                    dst_step, tsize, mask->data.ptr + y*mask->step, mask_step ));
496         }
497     }
498 
499     __END__;
500 
501     if( !local_alloc )
502         cvFree( &buffer );
503 }
504 
ICV_DEF_BIN_LOG_OP_2D(CV_XOR,Xor)505 ICV_DEF_BIN_LOG_OP_2D( CV_XOR, Xor )
506 ICV_DEF_UN_LOG_OP_2D( CV_XOR, XorC )
507 
508 ICV_DEF_BIN_LOG_OP_2D( CV_AND, And )
509 ICV_DEF_UN_LOG_OP_2D( CV_AND, AndC )
510 
511 ICV_DEF_BIN_LOG_OP_2D( CV_OR, Or )
512 ICV_DEF_UN_LOG_OP_2D( CV_OR, OrC )
513 
514 
515 /////////////////////////////////////////////////////////////////////////////////////////
516 //                                    X O R                                            //
517 /////////////////////////////////////////////////////////////////////////////////////////
518 
519 CV_IMPL void
520 cvXorS( const void* src, CvScalar scalar, void* dst, const void* mask )
521 {
522     icvLogicS( src, &scalar, dst, mask, (CvFunc2D_2A1P1I)icvXorC_8u_CnR );
523 }
524 
525 
526 CV_IMPL void
cvXor(const void * src1,const void * src2,void * dst,const void * mask)527 cvXor( const void* src1, const void* src2, void* dst, const void* mask )
528 {
529     icvLogic( src1, src2, dst, mask, (CvFunc2D_3A)icvXor_8u_C1R );
530 }
531 
532 /////////////////////////////////////////////////////////////////////////////////////////
533 //                                    A N D                                            //
534 /////////////////////////////////////////////////////////////////////////////////////////
535 
536 CV_IMPL void
cvAndS(const void * src,CvScalar scalar,void * dst,const void * mask)537 cvAndS( const void* src, CvScalar scalar, void* dst, const void* mask )
538 {
539     icvLogicS( src, &scalar, dst, mask, (CvFunc2D_2A1P1I)icvAndC_8u_CnR );
540 }
541 
542 
543 CV_IMPL void
cvAnd(const void * src1,const void * src2,void * dst,const void * mask)544 cvAnd( const void* src1, const void* src2, void* dst, const void* mask )
545 {
546     icvLogic( src1, src2, dst, mask, (CvFunc2D_3A)icvAnd_8u_C1R );
547 }
548 
549 
550 /////////////////////////////////////////////////////////////////////////////////////////
551 //                                      O R                                            //
552 /////////////////////////////////////////////////////////////////////////////////////////
553 
554 CV_IMPL void
cvOrS(const void * src,CvScalar scalar,void * dst,const void * mask)555 cvOrS( const void* src, CvScalar scalar, void* dst, const void* mask )
556 {
557     icvLogicS( src, &scalar, dst, mask, (CvFunc2D_2A1P1I)icvOrC_8u_CnR );
558 }
559 
560 
561 CV_IMPL void
cvOr(const void * src1,const void * src2,void * dst,const void * mask)562 cvOr( const void* src1, const void* src2, void* dst, const void* mask )
563 {
564     icvLogic( src1, src2, dst, mask, (CvFunc2D_3A)icvOr_8u_C1R );
565 }
566 
567 
568 /////////////////////////////////////////////////////////////////////////////////////////
569 //                                      N O T                                          //
570 /////////////////////////////////////////////////////////////////////////////////////////
571 
572 
573 IPCVAPI_IMPL( CvStatus, icvNot_8u_C1R,
574 ( const uchar* src1, int step1, uchar* dst, int step, CvSize size ),
575   (src1, step1, dst, step, size) )
576 {
577     for( ; size.height--; src1 += step1, dst += step )
578     {
579         int i = 0;
580 
581         if( (((size_t)src1 | (size_t)dst) & 3) == 0 )
582         {
583             for( ; i <= size.width - 16; i += 16 )
584             {
585                 int t0 = ~((const int*)(src1+i))[0];
586                 int t1 = ~((const int*)(src1+i))[1];
587 
588                 ((int*)(dst+i))[0] = t0;
589                 ((int*)(dst+i))[1] = t1;
590 
591                 t0 = ~((const int*)(src1+i))[2];
592                 t1 = ~((const int*)(src1+i))[3];
593 
594                 ((int*)(dst+i))[2] = t0;
595                 ((int*)(dst+i))[3] = t1;
596             }
597 
598             for( ; i <= size.width - 4; i += 4 )
599             {
600                 int t = ~*(const int*)(src1+i);
601                 *(int*)(dst+i) = t;
602             }
603         }
604 
605         for( ; i < size.width; i++ )
606         {
607             int t = ~((const uchar*)src1)[i];
608             dst[i] = (uchar)t;
609         }
610     }
611 
612     return  CV_OK;
613 }
614 
615 
616 CV_IMPL void
cvNot(const void * srcarr,void * dstarr)617 cvNot( const void* srcarr, void* dstarr )
618 {
619     CV_FUNCNAME( "cvNot" );
620 
621     __BEGIN__;
622 
623     CvMat srcstub, *src = (CvMat*)srcarr;
624     CvMat dststub, *dst = (CvMat*)dstarr;
625 
626     int coi1 = 0, coi2 = 0;
627     int type, is_nd = 0;
628     CvSize size;
629     int src_step, dst_step;
630 
631     if( !CV_IS_MAT(src))
632     {
633         if( CV_IS_MATND(src) )
634             is_nd = 1;
635         else
636             CV_CALL( src = cvGetMat( src, &srcstub, &coi1 ));
637     }
638 
639     if( !CV_IS_MAT(dst))
640     {
641         if( CV_IS_MATND(src) )
642             is_nd = 1;
643         else
644             CV_CALL( dst = cvGetMat( dst, &dststub, &coi2 ));
645     }
646 
647     if( is_nd )
648     {
649         CvArr* arrs[] = { src, dst };
650         CvMatND stubs[2];
651         CvNArrayIterator iterator;
652 
653         CV_CALL( cvInitNArrayIterator( 2, arrs, 0, stubs, &iterator ));
654 
655         type = CV_MAT_TYPE(iterator.hdr[0]->type);
656         iterator.size.width *= CV_ELEM_SIZE(type);
657 
658         do
659         {
660             IPPI_CALL( icvNot_8u_C1R( iterator.ptr[0], CV_STUB_STEP,
661                                       iterator.ptr[1], CV_STUB_STEP,
662                                       iterator.size ));
663         }
664         while( cvNextNArraySlice( &iterator ));
665         EXIT;
666     }
667 
668     if( coi1 != 0 || coi2 != 0 )
669         CV_ERROR( CV_BadCOI, "" );
670 
671     if( !CV_ARE_TYPES_EQ( src, dst ) )
672         CV_ERROR_FROM_CODE( CV_StsUnmatchedFormats );
673 
674     if( !CV_ARE_SIZES_EQ( src, dst ) )
675         CV_ERROR_FROM_CODE( CV_StsUnmatchedSizes );
676 
677     size = cvGetMatSize( src );
678     src_step = src->step;
679     dst_step = dst->step;
680 
681     if( CV_IS_MAT_CONT( src->type & dst->type ))
682     {
683         size.width *= size.height;
684         src_step = dst_step = CV_STUB_STEP;
685         size.height = 1;
686     }
687 
688     type = CV_MAT_TYPE( src->type );
689     size.width *= CV_ELEM_SIZE(type);
690 
691     IPPI_CALL( icvNot_8u_C1R( src->data.ptr, src_step, dst->data.ptr, dst_step, size ));
692 
693     __END__;
694 }
695 
696 /* End of file. */
697