blob: 4fece72d5c0db8c7c19610ef6131c7ffb94c6087 [file] [log] [blame]
/*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 */