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 )                                       \
62IPCVAPI_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 )                                            \
111static 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
178static void
179icvLogicS( 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
337static void
338icvLogic( 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
505ICV_DEF_BIN_LOG_OP_2D( CV_XOR, Xor )
506ICV_DEF_UN_LOG_OP_2D( CV_XOR, XorC )
507
508ICV_DEF_BIN_LOG_OP_2D( CV_AND, And )
509ICV_DEF_UN_LOG_OP_2D( CV_AND, AndC )
510
511ICV_DEF_BIN_LOG_OP_2D( CV_OR, Or )
512ICV_DEF_UN_LOG_OP_2D( CV_OR, OrC )
513
514
515/////////////////////////////////////////////////////////////////////////////////////////
516//                                    X O R                                            //
517/////////////////////////////////////////////////////////////////////////////////////////
518
519CV_IMPL void
520cvXorS( 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
526CV_IMPL void
527cvXor( 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
536CV_IMPL void
537cvAndS( 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
543CV_IMPL void
544cvAnd( 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
554CV_IMPL void
555cvOrS( 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
561CV_IMPL void
562cvOr( 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
573IPCVAPI_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
616CV_IMPL void
617cvNot( 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