Update the trunk to the OpenCV's CVS (2008-07-14)
[opencv] / cvaux / src / cvlines.cpp
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
44 CvStatus
45 icvFetchLine8uC3R( 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
123 CvStatus
124 icvDrawLine8uC3R( 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
195 static CvStatus
196 icvPreWarpImage8uC3R( 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
241 static CvStatus
242 icvPostWarpImage8uC3R( 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*/
319 static CvStatus
320 icvDeleteMoire8u( 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*/
370 CV_IMPL void
371 cvDeleteMoire( 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*/
404 CV_IMPL void
405 cvPreWarpImage( 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*/
448 CV_IMPL void
449 cvPostWarpImage( 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