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#include "_cvaux.h"
42
43#if 0
44CvStatus
45icvFetchLine8uC3R( uchar * src, int src_step,
46                   uchar * dst, int *dst_num, CvSize src_size, CvPoint start, CvPoint end )
47{
48    int i;
49    int dx = end.x - start.x, dy = end.y - start.y;
50    int err;
51
52    if( !src || !dst || (src_size.width | src_size.height) < 0 ||
53        src_step < src_size.width * 3 ||
54        (unsigned) start.x >= (unsigned) src_size.width ||
55        (unsigned) start.y >= (unsigned) src_size.height ||
56        (unsigned) end.x >= (unsigned) src_size.width ||
57        (unsigned) end.y >= (unsigned) src_size.height )
58        return CV_BADFACTOR_ERR;
59
60    if( dx < 0 )
61    {
62        dx = -dx;
63        dy = -dy;
64        start.x = end.x;
65        start.y = end.y;
66    }
67
68    src += start.y * src_step + start.x * 3;
69
70    i = dy >> 31;
71    dy = (dy ^ i) - i;
72    src_step = (src_step ^ i) - i;
73
74    if( dx > dy )
75    {
76        if( dst_num )
77        {
78            if( *dst_num <= dx )
79                return CV_BADSIZE_ERR;
80            *dst_num = dx + 1;
81        }
82        err = dx;
83        dx += dx;
84        dy += dy;
85        for( i = dx; i >= 0; i -= 2, dst += 3 )
86        {
87            int mask = (err -= dy) < 0 ? -1 : 0;
88
89            dst[0] = src[0];
90            dst[1] = src[1];
91            dst[2] = src[2];
92
93            err += dx & mask;
94            src += (src_step & mask) + 3;
95        }
96    }
97    else
98    {
99        if( dst_num )
100        {
101            if( *dst_num <= dy )
102                return CV_BADSIZE_ERR;
103            *dst_num = dy + 1;
104        }
105        err = dy;
106        dx += dx;
107        dy += dy;
108        for( i = dy; i >= 0; i -= 2, dst += 3 )
109        {
110            int mask = (err -= dx) < 0 ? -1 : 0;
111
112            dst[0] = src[0];
113            dst[1] = src[1];
114            dst[2] = src[2];
115
116            err += dy & mask;
117            src += src_step + (mask & 3);
118        }
119    }
120    return CV_NO_ERR;
121}
122
123CvStatus
124icvDrawLine8uC3R( uchar * src, int src_num,
125                  uchar * dst, int dst_step, CvSize dst_size, CvPoint start, CvPoint end )
126{
127    int i;
128    int dx = end.x - start.x, dy = end.y - start.y;
129    int err;
130
131    if( !src || !dst || (dst_size.width | dst_size.height) < 0 ||
132        dst_step < dst_size.width * 3 ||
133        (unsigned) start.x >= (unsigned) dst_size.width ||
134        (unsigned) start.y >= (unsigned) dst_size.height ||
135        (unsigned) end.x >= (unsigned) dst_size.width ||
136        (unsigned) end.y >= (unsigned) dst_size.height )
137        return CV_BADFACTOR_ERR;
138
139    if( dx < 0 )
140    {
141        dx = -dx;
142        dy = -dy;
143        start.x = end.x;
144        start.y = end.y;
145    }
146
147    dst += start.y * dst_step + start.x * 3;
148
149    i = dy >> 31;
150    dy = (dy ^ i) - i;
151    dst_step = (dst_step ^ i) - i;
152
153    if( dx > dy )
154    {
155        if( (unsigned) (src_num - 1) < (unsigned) dx )
156            return CV_BADSIZE_ERR;
157        err = dx;
158        dx += dx;
159        dy += dy;
160        for( i = dx; i >= 0; i -= 2, src += 3 )
161        {
162            int mask = (err -= dy) < 0 ? -1 : 0;
163
164            dst[0] = src[0];
165            dst[1] = src[1];
166            dst[2] = src[2];
167            err += dx & mask;
168            dst += (dst_step & mask) + 3;
169        }
170    }
171    else
172    {
173        if( (unsigned) (src_num - 1) < (unsigned) dy )
174            return CV_BADSIZE_ERR;
175        err = dy;
176        dx += dx;
177        dy += dy;
178        for( i = dy; i >= 0; i -= 2, src += 3 )
179        {
180            int mask = (err -= dx) < 0 ? -1 : 0;
181
182            dst[0] = src[0];
183            dst[1] = src[1];
184            dst[2] = src[2];
185            err += dy & mask;
186            dst += dst_step + (mask & 3);
187        }
188    }
189    return CV_NO_ERR;
190}
191#endif
192
193/*======================================================================================*/
194
195static CvStatus
196icvPreWarpImage8uC3R( int numLines,     /* number of scanlines   */
197                      uchar * src,      /* source image          */
198                      int src_step,     /* line step         */
199                      uchar * dst,      /* dest buffers          */
200                      int *dst_nums,    /* lens of buffer        */
201                      CvSize src_size,  /* image size in pixels */
202                      int *scanlines )  /* scanlines array       */
203{
204    int k;
205    CvPoint start;
206    CvPoint end;
207    int curr;
208    int curr_dst;
209    CvMat mat;
210
211    curr = 0;
212    curr_dst = 0;
213
214    cvInitMatHeader( &mat, src_size.height, src_size.width, CV_8UC3, src, src_step );
215
216    for( k = 0; k < numLines; k++ )
217    {
218        start.x = scanlines[curr++];
219        start.y = scanlines[curr++];
220
221        end.x = scanlines[curr++];
222        end.y = scanlines[curr++];
223
224#ifdef _DEBUG
225        {
226        CvLineIterator iterator;
227        assert( cvInitLineIterator( &mat, start, end, &iterator, 8 ) == dst_nums[k] );
228        }
229#endif
230        cvSampleLine( &mat, start, end, dst + curr_dst, 8 );
231        curr_dst += dst_nums[k] * 3;
232
233    }
234
235    return CV_NO_ERR;
236}
237
238
239/*======================================================================================*/
240
241static CvStatus
242icvPostWarpImage8uC3R( int numLines,    /* number of scanlines  */
243                       uchar * src,     /* source buffers       */
244                       int *src_nums,   /* lens of buffers      */
245                       uchar * dst,     /* dest image           */
246                       int dst_step,    /* dest image step      */
247                       CvSize dst_size, /* dest image size      */
248                       int *scanlines ) /* scanline             */
249{
250    int i, k;
251    CvPoint start;
252    CvPoint end;
253    int curr;
254    int src_num;
255    int curr_src;
256    CvMat mat;
257    CvLineIterator iterator;
258
259    curr = 0;
260    curr_src = 0;
261
262    cvInitMatHeader( &mat, dst_size.height, dst_size.width, CV_8UC3, dst, dst_step );
263
264    for( k = 0; k < numLines; k++ )
265    {
266        start.x = scanlines[curr++];
267        start.y = scanlines[curr++];
268
269        end.x = scanlines[curr++];
270        end.y = scanlines[curr++];
271
272        src_num = src_nums[k];
273
274        if( cvInitLineIterator( &mat, start, end, &iterator, 8 ) != src_num )
275        {
276            assert(0);
277            return CV_NOTDEFINED_ERR;
278        }
279
280        for( i = 0; i < src_num; i++ )
281        {
282            memcpy( iterator.ptr, src + curr_src, 3 );
283            CV_NEXT_LINE_POINT( iterator );
284            curr_src += 3;
285        }
286
287#if 0
288        err = icvDrawLine8uC3R( src + curr_src, /* sourse buffer    */
289                                src_num,        /* len of buffer    */
290                                dst,    /* dest image       */
291                                dst_step,       /* dest image step  */
292                                dst_size,       /* dest image size  */
293                                start,  /* start point      */
294                                end );  /* end point        */
295        curr_src += src_num * 3;
296#endif
297    }
298
299    return CV_NO_ERR;
300
301}
302
303
304/*======================================================================================*/
305
306/*F///////////////////////////////////////////////////////////////////////////////////////
307//    Name:    icvDeleteMoire8uC3R
308//    Purpose:
309//      Function deletes moire - replaces black uncovered pixels with their neighboors.
310//    Context:
311//    Parameters:
312//      img       - image data
313//      img_step  - distance between lines in bytes
314//      img_size  - width and height of the image in pixels
315//    Returns:
316//      CV_NO_ERR if all Ok or error code
317//    Notes:
318//F*/
319static CvStatus
320icvDeleteMoire8u( uchar * img, int img_step, CvSize img_size, int cn )
321{
322    int x, y;
323    uchar *src = img, *dst = img + img_step;
324
325    if( !img || img_size.width <= 0 || img_size.height <= 0 || img_step < img_size.width * 3 )
326        return CV_BADFACTOR_ERR;
327
328    img_size.width *= cn;
329
330    for( y = 1; y < img_size.height; y++, src = dst, dst += img_step )
331    {
332        switch( cn )
333        {
334        case 1:
335            for( x = 0; x < img_size.width; x++ )
336            {
337                if( dst[x] == 0 )
338                    dst[x] = src[x];
339            }
340            break;
341        case 3:
342            for( x = 0; x < img_size.width; x += 3 )
343            {
344                if( dst[x] == 0 && dst[x + 1] == 0 && dst[x + 2] == 0 )
345                {
346                    dst[x] = src[x];
347                    dst[x + 1] = src[x + 1];
348                    dst[x + 2] = src[x + 2];
349                }
350            }
351            break;
352        default:
353            assert(0);
354            break;
355        }
356    }
357
358    return CV_NO_ERR;
359}
360
361
362/*F///////////////////////////////////////////////////////////////////////////////////////
363//    Name: cvDeleteMoire
364//    Purpose: The functions delete moire on the image after ViewMorphing
365//    Context:
366//    Parameters:  img        - image on which will delete moire
367//
368//    Notes:
369//F*/
370CV_IMPL void
371cvDeleteMoire( IplImage * img )
372{
373    uchar *img_data = 0;
374    int img_step = 0;
375    CvSize img_size;
376
377    CV_FUNCNAME( "cvDeleteMoire" );
378
379    __BEGIN__;
380
381    cvGetImageRawData( img, &img_data, &img_step, &img_size );
382
383    if( img->nChannels != 1 && img->nChannels != 3 )
384        CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
385    if( img->depth != IPL_DEPTH_8U )
386        CV_ERROR( CV_BadDepth, "Channel depth of source image must be 8." );
387
388    CV_CALL( icvDeleteMoire8u( img_data, img_step, img_size, img->nChannels ));
389
390    __CLEANUP__;
391    __END__;
392
393}
394
395
396/*F///////////////////////////////////////////////////////////////////////////////////////
397//    Name: cvPreWarpImage
398//    Purpose: The functions warp image for next stage of ViewMorphing
399//    Context:
400//    Parameters:  img        - initial image (in the beginning)
401//
402//    Notes:
403//F*/
404CV_IMPL void
405cvPreWarpImage( int numLines,   /* number of scanlines */
406                IplImage * img, /* Source Image       */
407                uchar * dst,    /* dest buffers       */
408                int *dst_nums,  /* lens of buffer     */
409                int *scanlines /* scanlines array    */  )
410{
411    uchar *img_data = 0;
412    int img_step = 0;
413    CvSize img_size;
414
415    CV_FUNCNAME( "cvPreWarpImage" );
416
417    __BEGIN__;
418
419    cvGetImageRawData( img, &img_data, &img_step, &img_size );
420
421    if( img->nChannels != 3 )
422        CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
423    if( img->depth != IPL_DEPTH_8U )
424        CV_ERROR( CV_BadDepth, "Channel depth of image must be 8." );
425
426    CV_CALL( icvPreWarpImage8uC3R( numLines,    /* number of scanlines  */
427                                   img_data,    /* source image         */
428                                   img_step,    /* line step            */
429                                   dst, /* dest buffers         */
430                                   dst_nums,    /* lens of buffer       */
431                                   img_size,    /* image size in pixels */
432                                   scanlines /* scanlines array      */  ));
433
434    __CLEANUP__;
435    __END__;
436
437}
438
439
440/*F///////////////////////////////////////////////////////////////////////////////////////
441//    Name: cvPostWarpImage
442//    Purpose: The functions postwarp the image after morphing
443//    Context:
444//    Parameters:  img        - initial image (in the beginning)
445//
446//    Notes:
447//F*/
448CV_IMPL void
449cvPostWarpImage( int numLines,  /* number of scanlines  */
450                 uchar * src,   /* source buffers       */
451                 int *src_nums, /* lens of buffers      */
452                 IplImage * img,        /* dest image           */
453                 int *scanlines /* scanline             */  )
454{
455    uchar *img_data = 0;
456    int img_step = 0;
457    CvSize img_size;
458
459    CV_FUNCNAME( "cvPostWarpImage" );
460
461    __BEGIN__;
462
463    cvGetImageRawData( img, &img_data, &img_step, &img_size );
464
465    if( img->nChannels != 3 )
466        CV_ERROR( CV_BadNumChannels, "Source image must have 3 channel." );
467    if( img->depth != IPL_DEPTH_8U )
468        CV_ERROR( CV_BadDepth, "Channel depth of image must be 8." );
469
470    CV_CALL( icvPostWarpImage8uC3R( numLines,   /* number of scanlines   */
471                                    src,        /* source buffers       */
472                                    src_nums,   /* lens of buffers      */
473                                    img_data,   /* dest image           */
474                                    img_step,   /* dest image step      */
475                                    img_size,   /* dest image size      */
476                                    scanlines /* scanline             */  ));
477
478    __CLEANUP__;
479    __END__;
480}
481
482/* End of file */
483
484