Update to 2.0.0 tree from current Fremantle build
[opencv] / src / cvaux / cvlines.cpp
diff --git a/src/cvaux/cvlines.cpp b/src/cvaux/cvlines.cpp
new file mode 100644 (file)
index 0000000..4fece72
--- /dev/null
@@ -0,0 +1,483 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                        Intel License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of Intel Corporation may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+#include "_cvaux.h"
+
+#if 0
+CvStatus
+icvFetchLine8uC3R( uchar * src, int src_step,
+                   uchar * dst, int *dst_num, CvSize src_size, CvPoint start, CvPoint end )
+{
+    int i;
+    int dx = end.x - start.x, dy = end.y - start.y;
+    int err;
+
+    if( !src || !dst || (src_size.width | src_size.height) < 0 ||
+        src_step < src_size.width * 3 ||
+        (unsigned) start.x >= (unsigned) src_size.width ||
+        (unsigned) start.y >= (unsigned) src_size.height ||
+        (unsigned) end.x >= (unsigned) src_size.width ||
+        (unsigned) end.y >= (unsigned) src_size.height )
+        return CV_BADFACTOR_ERR;
+
+    if( dx < 0 )
+    {
+        dx = -dx;
+        dy = -dy;
+        start.x = end.x;
+        start.y = end.y;
+    }
+
+    src += start.y * src_step + start.x * 3;
+
+    i = dy >> 31;
+    dy = (dy ^ i) - i;
+    src_step = (src_step ^ i) - i;
+
+    if( dx > dy )
+    {
+        if( dst_num )
+        {
+            if( *dst_num <= dx )
+                return CV_BADSIZE_ERR;
+            *dst_num = dx + 1;
+        }
+        err = dx;
+        dx += dx;
+        dy += dy;
+        for( i = dx; i >= 0; i -= 2, dst += 3 )
+        {
+            int mask = (err -= dy) < 0 ? -1 : 0;
+            
+            dst[0] = src[0];
+            dst[1] = src[1];
+            dst[2] = src[2];
+
+            err += dx & mask;
+            src += (src_step & mask) + 3;
+        }
+    }
+    else
+    {
+        if( dst_num )
+        {
+            if( *dst_num <= dy )
+                return CV_BADSIZE_ERR;
+            *dst_num = dy + 1;
+        }
+        err = dy;
+        dx += dx;
+        dy += dy;
+        for( i = dy; i >= 0; i -= 2, dst += 3 )
+        {
+            int mask = (err -= dx) < 0 ? -1 : 0;
+
+            dst[0] = src[0];
+            dst[1] = src[1];
+            dst[2] = src[2];
+
+            err += dy & mask;
+            src += src_step + (mask & 3);
+        }
+    }
+    return CV_NO_ERR;
+}
+
+CvStatus
+icvDrawLine8uC3R( uchar * src, int src_num,
+                  uchar * dst, int dst_step, CvSize dst_size, CvPoint start, CvPoint end )
+{
+    int i;
+    int dx = end.x - start.x, dy = end.y - start.y;
+    int err;
+
+    if( !src || !dst || (dst_size.width | dst_size.height) < 0 ||
+        dst_step < dst_size.width * 3 ||
+        (unsigned) start.x >= (unsigned) dst_size.width ||
+        (unsigned) start.y >= (unsigned) dst_size.height ||
+        (unsigned) end.x >= (unsigned) dst_size.width ||
+        (unsigned) end.y >= (unsigned) dst_size.height )
+        return CV_BADFACTOR_ERR;
+
+    if( dx < 0 )
+    {
+        dx = -dx;
+        dy = -dy;
+        start.x = end.x;
+        start.y = end.y;
+    }
+
+    dst += start.y * dst_step + start.x * 3;
+
+    i = dy >> 31;
+    dy = (dy ^ i) - i;
+    dst_step = (dst_step ^ i) - i;
+
+    if( dx > dy )
+    {
+        if( (unsigned) (src_num - 1) < (unsigned) dx )
+            return CV_BADSIZE_ERR;
+        err = dx;
+        dx += dx;
+        dy += dy;
+        for( i = dx; i >= 0; i -= 2, src += 3 )
+        {
+            int mask = (err -= dy) < 0 ? -1 : 0;
+
+            dst[0] = src[0];
+            dst[1] = src[1];
+            dst[2] = src[2];
+            err += dx & mask;
+            dst += (dst_step & mask) + 3;
+        }
+    }
+    else
+    {
+        if( (unsigned) (src_num - 1) < (unsigned) dy )
+            return CV_BADSIZE_ERR;
+        err = dy;
+        dx += dx;
+        dy += dy;
+        for( i = dy; i >= 0; i -= 2, src += 3 )
+        {
+            int mask = (err -= dx) < 0 ? -1 : 0;
+
+            dst[0] = src[0];
+            dst[1] = src[1];
+            dst[2] = src[2];
+            err += dy & mask;
+            dst += dst_step + (mask & 3);
+        }
+    }
+    return CV_NO_ERR;
+}
+#endif
+
+/*======================================================================================*/
+
+static CvStatus
+icvPreWarpImage8uC3R( int numLines,     /* number of scanlines   */
+                      uchar * src,      /* source image          */
+                      int src_step,     /* line step         */
+                      uchar * dst,      /* dest buffers          */
+                      int *dst_nums,    /* lens of buffer        */
+                      CvSize src_size,  /* image size in pixels */
+                      int *scanlines )  /* scanlines array       */
+{
+    int k;
+    CvPoint start;
+    CvPoint end;
+    int curr;
+    int curr_dst;
+    CvMat mat;
+
+    curr = 0;
+    curr_dst = 0;
+
+    cvInitMatHeader( &mat, src_size.height, src_size.width, CV_8UC3, src, src_step );
+
+    for( k = 0; k < numLines; k++ )
+    {
+        start.x = scanlines[curr++];
+        start.y = scanlines[curr++];
+
+        end.x = scanlines[curr++];
+        end.y = scanlines[curr++];
+
+#ifdef _DEBUG
+        {
+        CvLineIterator iterator;
+        assert( cvInitLineIterator( &mat, start, end, &iterator, 8 ) == dst_nums[k] );
+        }
+#endif
+        cvSampleLine( &mat, start, end, dst + curr_dst, 8 );
+        curr_dst += dst_nums[k] * 3;
+
+    }
+
+    return CV_NO_ERR;
+}
+
+
+/*======================================================================================*/
+
+static CvStatus
+icvPostWarpImage8uC3R( int numLines,    /* number of scanlines  */
+                       uchar * src,     /* source buffers       */
+                       int *src_nums,   /* lens of buffers      */
+                       uchar * dst,     /* dest image           */
+                       int dst_step,    /* dest image step      */
+                       CvSize dst_size, /* dest image size      */
+                       int *scanlines ) /* scanline             */
+{
+    int i, k;
+    CvPoint start;
+    CvPoint end;
+    int curr;
+    int src_num;
+    int curr_src;
+    CvMat mat;
+    CvLineIterator iterator;
+
+    curr = 0;
+    curr_src = 0;
+
+    cvInitMatHeader( &mat, dst_size.height, dst_size.width, CV_8UC3, dst, dst_step );
+
+    for( k = 0; k < numLines; k++ )
+    {
+        start.x = scanlines[curr++];
+        start.y = scanlines[curr++];
+
+        end.x = scanlines[curr++];
+        end.y = scanlines[curr++];
+
+        src_num = src_nums[k];
+
+        if( cvInitLineIterator( &mat, start, end, &iterator, 8 ) != src_num )
+        {
+            assert(0);
+            return CV_NOTDEFINED_ERR;
+        }
+
+        for( i = 0; i < src_num; i++ )
+        {
+            memcpy( iterator.ptr, src + curr_src, 3 );
+            CV_NEXT_LINE_POINT( iterator );
+            curr_src += 3;
+        }
+
+#if 0
+        err = icvDrawLine8uC3R( src + curr_src, /* sourse buffer    */
+                                src_num,        /* len of buffer    */
+                                dst,    /* dest image       */
+                                dst_step,       /* dest image step  */
+                                dst_size,       /* dest image size  */
+                                start,  /* start point      */
+                                end );  /* end point        */
+        curr_src += src_num * 3;
+#endif
+    }
+
+    return CV_NO_ERR;
+
+}
+
+
+/*======================================================================================*/
+
+/*F///////////////////////////////////////////////////////////////////////////////////////
+//    Name:    icvDeleteMoire8uC3R
+//    Purpose:
+//      Function deletes moire - replaces black uncovered pixels with their neighboors.
+//    Context:
+//    Parameters:
+//      img       - image data
+//      img_step  - distance between lines in bytes
+//      img_size  - width and height of the image in pixels
+//    Returns:
+//      CV_NO_ERR if all Ok or error code
+//    Notes:
+//F*/
+static CvStatus
+icvDeleteMoire8u( uchar * img, int img_step, CvSize img_size, int cn )
+{
+    int x, y;
+    uchar *src = img, *dst = img + img_step;
+
+    if( !img || img_size.width <= 0 || img_size.height <= 0 || img_step < img_size.width * 3 )
+        return CV_BADFACTOR_ERR;
+
+    img_size.width *= cn;
+
+    for( y = 1; y < img_size.height; y++, src = dst, dst += img_step )
+    {
+        switch( cn )
+        {
+        case 1:
+            for( x = 0; x < img_size.width; x++ )
+            {
+                if( dst[x] == 0 )
+                    dst[x] = src[x];
+            }
+            break;
+        case 3:
+            for( x = 0; x < img_size.width; x += 3 )
+            {
+                if( dst[x] == 0 && dst[x + 1] == 0 && dst[x + 2] == 0 )
+                {
+                    dst[x] = src[x];
+                    dst[x + 1] = src[x + 1];
+                    dst[x + 2] = src[x + 2];
+                }
+            }
+            break;
+        default:
+            assert(0);
+            break;
+        }
+    }
+
+    return CV_NO_ERR;
+}
+
+
+/*F///////////////////////////////////////////////////////////////////////////////////////
+//    Name: cvDeleteMoire
+//    Purpose: The functions delete moire on the image after ViewMorphing
+//    Context:
+//    Parameters:  img        - image on which will delete moire
+//
+//    Notes:
+//F*/
+CV_IMPL void
+cvDeleteMoire( IplImage * img )
+{
+    uchar *img_data = 0;
+    int img_step = 0;
+    CvSize img_size;
+
+    CV_FUNCNAME( "cvDeleteMoire" );
+
+    __BEGIN__;
+
+    cvGetImageRawData( img, &img_data, &img_step, &img_size );
+
+    if( img->nChannels != 1 && img->nChannels != 3 )
+        CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
+    if( img->depth != IPL_DEPTH_8U )
+        CV_ERROR( CV_BadDepth, "Channel depth of source image must be 8." );
+
+    CV_CALL( icvDeleteMoire8u( img_data, img_step, img_size, img->nChannels ));
+
+    __CLEANUP__;
+    __END__;
+
+}
+
+
+/*F///////////////////////////////////////////////////////////////////////////////////////
+//    Name: cvPreWarpImage
+//    Purpose: The functions warp image for next stage of ViewMorphing
+//    Context:
+//    Parameters:  img        - initial image (in the beginning)
+//
+//    Notes:
+//F*/
+CV_IMPL void
+cvPreWarpImage( int numLines,   /* number of scanlines */
+                IplImage * img, /* Source Image       */
+                uchar * dst,    /* dest buffers       */
+                int *dst_nums,  /* lens of buffer     */
+                int *scanlines /* scanlines array    */  )
+{
+    uchar *img_data = 0;
+    int img_step = 0;
+    CvSize img_size;
+
+    CV_FUNCNAME( "cvPreWarpImage" );
+
+    __BEGIN__;
+
+    cvGetImageRawData( img, &img_data, &img_step, &img_size );
+
+    if( img->nChannels != 3 )
+        CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
+    if( img->depth != IPL_DEPTH_8U )
+        CV_ERROR( CV_BadDepth, "Channel depth of image must be 8." );
+
+    CV_CALL( icvPreWarpImage8uC3R( numLines,    /* number of scanlines  */
+                                   img_data,    /* source image         */
+                                   img_step,    /* line step            */
+                                   dst, /* dest buffers         */
+                                   dst_nums,    /* lens of buffer       */
+                                   img_size,    /* image size in pixels */
+                                   scanlines /* scanlines array      */  ));
+
+    __CLEANUP__;
+    __END__;
+
+}
+
+
+/*F///////////////////////////////////////////////////////////////////////////////////////
+//    Name: cvPostWarpImage
+//    Purpose: The functions postwarp the image after morphing
+//    Context:
+//    Parameters:  img        - initial image (in the beginning)
+//
+//    Notes:   
+//F*/
+CV_IMPL void
+cvPostWarpImage( int numLines,  /* number of scanlines  */
+                 uchar * src,   /* source buffers       */
+                 int *src_nums, /* lens of buffers      */
+                 IplImage * img,        /* dest image           */
+                 int *scanlines /* scanline             */  )
+{
+    uchar *img_data = 0;
+    int img_step = 0;
+    CvSize img_size;
+
+    CV_FUNCNAME( "cvPostWarpImage" );
+
+    __BEGIN__;
+
+    cvGetImageRawData( img, &img_data, &img_step, &img_size );
+
+    if( img->nChannels != 3 )
+        CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
+    if( img->depth != IPL_DEPTH_8U )
+        CV_ERROR( CV_BadDepth, "Channel depth of image must be 8." );
+
+    CV_CALL( icvPostWarpImage8uC3R( numLines,   /* number of scanlines   */
+                                    src,        /* source buffers       */
+                                    src_nums,   /* lens of buffers      */
+                                    img_data,   /* dest image           */
+                                    img_step,   /* dest image step      */
+                                    img_size,   /* dest image size      */
+                                    scanlines /* scanline             */  ));
+
+    __CLEANUP__;
+    __END__;
+}
+
+/* End of file */
+