16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M/////////////////////////////////////////////////////////////////////////////////////// 26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By downloading, copying, installing or using the software you agree to this license. 66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// If you do not agree to this license, do not download, install, 76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// copy or use the software. 86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Intel License Agreement 116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// For Open Source Computer Vision Library 126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved. 146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners. 156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification, 176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met: 186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's of source code must retain the above copyright notice, 206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer. 216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's in binary form must reproduce the above copyright notice, 236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer in the documentation 246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and/or other materials provided with the distribution. 256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * The name of Intel Corporation may not be used to endorse or promote products 276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// derived from this software without specific prior written permission. 286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and 306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied 316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed. 326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct, 336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages 346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services; 356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused 366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability, 376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of 386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage. 396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/ 416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h" 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvFFillSegment 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ushort y; 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ushort l; 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ushort r; 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ushort prevl; 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ushort prevr; 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn short dir; 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvFFillSegment; 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define UP 1 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DOWN -1 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_PUSH( Y, L, R, PREV_L, PREV_R, DIR )\ 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ \ 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail->y = (ushort)(Y); \ 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail->l = (ushort)(L); \ 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail->r = (ushort)(R); \ 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail->prevl = (ushort)(PREV_L); \ 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail->prevr = (ushort)(PREV_R); \ 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail->dir = (short)(DIR); \ 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ++tail >= buffer_end ) \ 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tail = buffer; \ 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_POP( Y, L, R, PREV_L, PREV_R, DIR ) \ 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ \ 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Y = head->y; \ 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn L = head->l; \ 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn R = head->r; \ 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PREV_L = head->prevl; \ 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn PREV_R = head->prevr; \ 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIR = head->dir; \ 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ++head >= buffer_end ) \ 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn head = buffer; \ 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_EQ_C3( p1, p2 ) \ 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((p1)[0] == (p2)[0] && (p1)[1] == (p2)[1] && (p1)[2] == (p2)[2]) 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_SET_C3( p, q ) \ 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((p)[0] = (q)[0], (p)[1] = (q)[1], (p)[2] = (q)[2]) 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Simple Floodfill (repainting single-color connected component) * 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFloodFill_8u_CnIR( uchar* pImage, int step, CvSize roi, CvPoint seed, 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* _newVal, CvConnectedComp* region, int flags, 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer, int buffer_size, int cn ) 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* img = pImage + step * seed.y; 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, L, R; 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int area = 0; 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int val0[] = {0,0,0}; 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar newVal[] = {0,0,0}; 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int XMin, XMax, YMin = seed.y, YMax = seed.y; 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _8_connectivity = (flags & 255) == 8; 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer_end = buffer + buffer_size, *head = buffer, *tail = buffer; 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn L = R = XMin = XMax = seed.x; 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val0[0] = img[L]; 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn newVal[0] = _newVal[0]; 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[L] = newVal[0]; 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++R < roi.width && img[R] == val0[0] ) 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[R] = newVal[0]; 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --L >= 0 && img[L] == val0[0] ) 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[L] = newVal[0]; 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( cn == 3 ); 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( val0, img + L*3 ); 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( newVal, _newVal ); 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + L*3, newVal ); 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --L >= 0 && ICV_EQ_C3( img + L*3, val0 )) 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + L*3, newVal ); 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++R < roi.width && ICV_EQ_C3( img + R*3, val0 )) 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + R*3, newVal ); 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMax = --R; 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMin = ++L; 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( seed.y, L, R, R + 1, R, UP ); 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( head != tail ) 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, YC, PL, PR, dir; 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_POP( YC, L, R, PL, PR, dir ); 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int data[][3] = 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {-dir, L - _8_connectivity, R + _8_connectivity}, 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, L - _8_connectivity, PL - 1}, 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, PR + 1, R + _8_connectivity} 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn }; 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn area += R - L + 1; 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMax < R ) XMax = R; 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMin > L ) XMin = L; 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMax < YC ) YMax = YC; 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMin > YC ) YMin = YC; 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0/*(unsigned)(YC - dir) >= (unsigned)roi.height*/; k < 3; k++ ) 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dir = data[k][0]; 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + (YC + dir) * step; 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = data[k][1]; 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int right = data[k][2]; 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)(YC + dir) >= (unsigned)roi.height ) 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn continue; 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)i < (unsigned)roi.width && img[i] == val0[0] ) 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i] = newVal[0]; 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --j >= 0 && img[j] == val0[0] ) 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[j] = newVal[0]; 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++i < roi.width && img[i] == val0[0] ) 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i] = newVal[0]; 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)i < (unsigned)roi.width && ICV_EQ_C3( img + i*3, val0 )) 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + i*3, newVal ); 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --j >= 0 && ICV_EQ_C3( img + j*3, val0 )) 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + j*3, newVal ); 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++i < roi.width && ICV_EQ_C3( img + i*3, val0 )) 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + i*3, newVal ); 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->area = area; 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.x = XMin; 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.y = YMin; 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.width = XMax - XMin + 1; 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.height = YMax - YMin + 1; 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->value = cvScalar(newVal[0], newVal[1], newVal[2], 0); 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* because all the operations on floats that are done during non-gradient floodfill 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn are just copying and comparison on equality, 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn we can do the whole op on 32-bit integers instead */ 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFloodFill_32f_CnIR( int* pImage, int step, CvSize roi, CvPoint seed, 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* _newVal, CvConnectedComp* region, int flags, 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer, int buffer_size, int cn ) 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* img = pImage + (step /= sizeof(pImage[0])) * seed.y; 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, L, R; 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int area = 0; 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int val0[] = {0,0,0}; 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int newVal[] = {0,0,0}; 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int XMin, XMax, YMin = seed.y, YMax = seed.y; 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _8_connectivity = (flags & 255) == 8; 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer_end = buffer + buffer_size, *head = buffer, *tail = buffer; 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn L = R = XMin = XMax = seed.x; 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val0[0] = img[L]; 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn newVal[0] = _newVal[0]; 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[L] = newVal[0]; 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++R < roi.width && img[R] == val0[0] ) 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[R] = newVal[0]; 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --L >= 0 && img[L] == val0[0] ) 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[L] = newVal[0]; 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( cn == 3 ); 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( val0, img + L*3 ); 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( newVal, _newVal ); 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + L*3, newVal ); 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --L >= 0 && ICV_EQ_C3( img + L*3, val0 )) 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + L*3, newVal ); 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++R < roi.width && ICV_EQ_C3( img + R*3, val0 )) 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + R*3, newVal ); 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMax = --R; 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMin = ++L; 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( seed.y, L, R, R + 1, R, UP ); 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( head != tail ) 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, YC, PL, PR, dir; 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_POP( YC, L, R, PL, PR, dir ); 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int data[][3] = 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {-dir, L - _8_connectivity, R + _8_connectivity}, 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, L - _8_connectivity, PL - 1}, 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, PR + 1, R + _8_connectivity} 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn }; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn area += R - L + 1; 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMax < R ) XMax = R; 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMin > L ) XMin = L; 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMax < YC ) YMax = YC; 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMin > YC ) YMin = YC; 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0/*(unsigned)(YC - dir) >= (unsigned)roi.height*/; k < 3; k++ ) 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dir = data[k][0]; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + (YC + dir) * step; 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = data[k][1]; 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int right = data[k][2]; 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)(YC + dir) >= (unsigned)roi.height ) 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn continue; 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)i < (unsigned)roi.width && img[i] == val0[0] ) 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i] = newVal[0]; 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --j >= 0 && img[j] == val0[0] ) 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[j] = newVal[0]; 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++i < roi.width && img[i] == val0[0] ) 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i] = newVal[0]; 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)i < (unsigned)roi.width && ICV_EQ_C3( img + i*3, val0 )) 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + i*3, newVal ); 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( --j >= 0 && ICV_EQ_C3( img + j*3, val0 )) 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + j*3, newVal ); 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ++i < roi.width && ICV_EQ_C3( img + i*3, val0 )) 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + i*3, newVal ); 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Cv32suf v0, v1, v2; 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->area = area; 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.x = XMin; 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.y = YMin; 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.width = XMax - XMin + 1; 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.height = YMax - YMin + 1; 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v0.i = newVal[0]; v1.i = newVal[1]; v2.i = newVal[2]; 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->value = cvScalar( v0.f, v1.f, v2.f ); 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Gradient Floodfill * 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DIFF_INT_C1(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw[0]) <= interval[0]) 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DIFF_INT_C3(p1,p2) ((unsigned)((p1)[0] - (p2)[0] + d_lw[0])<= interval[0] && \ 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)((p1)[1] - (p2)[1] + d_lw[1])<= interval[1] && \ 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)((p1)[2] - (p2)[2] + d_lw[2])<= interval[2]) 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DIFF_FLT_C1(p1,p2) (fabs((p1)[0] - (p2)[0] + d_lw[0]) <= interval[0]) 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DIFF_FLT_C3(p1,p2) (fabs((p1)[0] - (p2)[0] + d_lw[0]) <= interval[0] && \ 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fabs((p1)[1] - (p2)[1] + d_lw[1]) <= interval[1] && \ 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn fabs((p1)[2] - (p2)[2] + d_lw[2]) <= interval[2]) 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFloodFill_Grad_8u_CnIR( uchar* pImage, int step, uchar* pMask, int maskStep, 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize /*roi*/, CvPoint seed, uchar* _newVal, uchar* _d_lw, 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* _d_up, CvConnectedComp* region, int flags, 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer, int buffer_size, int cn ) 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* img = pImage + step*seed.y; 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y; 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, L, R; 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int area = 0; 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sum[] = {0,0,0}, val0[] = {0,0,0}; 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar newVal[] = {0,0,0}; 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int d_lw[] = {0,0,0}; 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn unsigned interval[] = {0,0,0}; 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int XMin, XMax, YMin = seed.y, YMax = seed.y; 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _8_connectivity = (flags & 255) == 8; 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE; 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0; 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1); 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer_end = buffer + buffer_size, *head = buffer, *tail = buffer; 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn L = R = seed.x; 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mask[L] ) 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[L] = newMaskVal; 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < cn; i++ ) 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn newVal[i] = _newVal[i]; 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d_lw[i] = _d_lw[i]; 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn interval[i] = (unsigned)(_d_up[i] + _d_lw[i]); 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val0[i] = img[L*cn+i]; 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_INT_C1( img + (R+1), val0 )) 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_INT_C1( img + (L-1), val0 )) 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_INT_C1( img + (R+1), img + R )) 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_INT_C1( img + (L-1), img + L )) 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_INT_C3( img + (R+1)*3, val0 )) 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_INT_C3( img + (L-1)*3, val0 )) 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_INT_C3( img + (R+1)*3, img + R*3 )) 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_INT_C3( img + (L-1)*3, img + L*3 )) 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMax = R; 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMin = L; 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( seed.y, L, R, R + 1, R, UP ); 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( head != tail ) 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, YC, PL, PR, dir, curstep; 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_POP( YC, L, R, PL, PR, dir ); 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int data[][3] = 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {-dir, L - _8_connectivity, R + _8_connectivity}, 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, L - _8_connectivity, PL - 1}, 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, PR + 1, R + _8_connectivity} 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn }; 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn unsigned length = (unsigned)(R-L); 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn area += (int)length + 1; 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMax < R ) XMax = R; 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMin > L ) XMin = L; 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMax < YC ) YMax = YC; 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMin > YC ) YMin = YC; 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < 3; k++ ) 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dir = data[k][0]; 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn curstep = dir * step; 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + (YC + dir) * step; 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask = pMask + (YC + dir) * maskStep; 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = data[k][1]; 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int right = data[k][2]; 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_INT_C1( img + i, val0 )) 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_INT_C1( img + j, val0 )) 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && DIFF_INT_C1( img + i, val0 )) 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( !_8_connectivity ) 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_INT_C1( img + i, img - curstep + i )) 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_INT_C1( img + j, img + (j+1) )) 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_INT_C1( img + i, img + (i-1) ) || 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_INT_C1( img + i, img + i - curstep) && i <= R))) 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int idx, val[1]; 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((val[0] = img[i], 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)(idx = i-L-1) <= length) && 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img - curstep + (i-1))) || 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img - curstep + i )) || 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img - curstep + (i+1) )))) 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_INT_C1( img + j, img + (j+1) )) 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((val[0] = img[i], 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img + (i-1) )) || 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((unsigned)(idx = i-L-1) <= length && 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img - curstep + (i-1) ))) || 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img - curstep + i )) || 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C1( val, img - curstep + (i+1) )))) 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + YC * step; 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fillImage ) 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i] = newVal[0]; 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( region ) 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[0] += img[i]; 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < 3; k++ ) 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dir = data[k][0]; 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn curstep = dir * step; 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + (YC + dir) * step; 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask = pMask + (YC + dir) * maskStep; 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = data[k][1]; 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int right = data[k][2]; 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_INT_C3( img + i*3, val0 )) 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_INT_C3( img + j*3, val0 )) 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && DIFF_INT_C3( img + i*3, val0 )) 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( !_8_connectivity ) 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_INT_C3( img + i*3, img - curstep + i*3 )) 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_INT_C3( img + j*3, img + (j+1)*3 )) 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_INT_C3( img + i*3, img + (i-1)*3 ) || 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_INT_C3( img + i*3, img + i*3 - curstep) && i <= R))) 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int idx, val[3]; 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((ICV_SET_C3( val, img+i*3 ), 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)(idx = i-L-1) <= length) && 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img - curstep + (i-1)*3 )) || 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img - curstep + i*3 )) || 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img - curstep + (i+1)*3 )))) 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_INT_C3( img + j*3, img + (j+1)*3 )) 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((ICV_SET_C3( val, img + i*3 ), 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img + (i-1)*3 )) || 6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((unsigned)(idx = i-L-1) <= length && 6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img - curstep + (i-1)*3 ))) || 6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img - curstep + i*3 )) || 6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_INT_C3( val, img - curstep + (i+1)*3 )))) 6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + YC * step; 6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fillImage ) 6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + i*3, newVal ); 6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( region ) 6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[0] += img[i*3]; 6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[1] += img[i*3+1]; 6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[2] += img[i*3+2]; 6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->area = area; 6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.x = XMin; 6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.y = YMin; 6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.width = XMax - XMin + 1; 6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.height = YMax - YMin + 1; 6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fillImage ) 6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->value = cvScalar(newVal[0], newVal[1], newVal[2]); 6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double iarea = area ? 1./area : 0; 6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->value = cvScalar(sum[0]*iarea, sum[1]*iarea, sum[2]*iarea); 6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus 6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFloodFill_Grad_32f_CnIR( float* pImage, int step, uchar* pMask, int maskStep, 6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize /*roi*/, CvPoint seed, float* _newVal, float* _d_lw, 6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* _d_up, CvConnectedComp* region, int flags, 6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer, int buffer_size, int cn ) 6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* img = pImage + (step /= sizeof(float))*seed.y; 6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* mask = (pMask += maskStep + 1) + maskStep*seed.y; 6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, L, R; 6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int area = 0; 6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double sum[] = {0,0,0}, val0[] = {0,0,0}; 6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float newVal[] = {0,0,0}; 6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float d_lw[] = {0,0,0}; 6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float interval[] = {0,0,0}; 6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int XMin, XMax, YMin = seed.y, YMax = seed.y; 6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _8_connectivity = (flags & 255) == 8; 6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int fixedRange = flags & CV_FLOODFILL_FIXED_RANGE; 6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int fillImage = (flags & CV_FLOODFILL_MASK_ONLY) == 0; 6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar newMaskVal = (uchar)(flags & 0xff00 ? flags >> 8 : 1); 6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer_end = buffer + buffer_size, *head = buffer, *tail = buffer; 6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn L = R = seed.x; 7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mask[L] ) 7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[L] = newMaskVal; 7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < cn; i++ ) 7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn newVal[i] = _newVal[i]; 7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d_lw[i] = 0.5f*(_d_lw[i] - _d_up[i]); 7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn interval[i] = 0.5f*(_d_lw[i] + _d_up[i]); 7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn val0[i] = img[L*cn+i]; 7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_FLT_C1( img + (R+1), val0 )) 7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_FLT_C1( img + (L-1), val0 )) 7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_FLT_C1( img + (R+1), img + R )) 7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_FLT_C1( img + (L-1), img + L )) 7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_FLT_C3( img + (R+1)*3, val0 )) 7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_FLT_C3( img + (L-1)*3, val0 )) 7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[R + 1] && DIFF_FLT_C3( img + (R+1)*3, img + R*3 )) 7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[++R] = newMaskVal; 7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[L - 1] && DIFF_FLT_C3( img + (L-1)*3, img + L*3 )) 7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[--L] = newMaskVal; 7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMax = R; 7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn XMin = L; 7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( seed.y, L, R, R + 1, R, UP ); 7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( head != tail ) 7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, YC, PL, PR, dir, curstep; 7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_POP( YC, L, R, PL, PR, dir ); 7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int data[][3] = 7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {-dir, L - _8_connectivity, R + _8_connectivity}, 7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, L - _8_connectivity, PL - 1}, 7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn {dir, PR + 1, R + _8_connectivity} 7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn }; 7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn unsigned length = (unsigned)(R-L); 7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn area += (int)length + 1; 7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMax < R ) XMax = R; 7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( XMin > L ) XMin = L; 7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMax < YC ) YMax = YC; 7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( YMin > YC ) YMin = YC; 7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cn == 1 ) 7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < 3; k++ ) 7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dir = data[k][0]; 7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn curstep = dir * step; 7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + (YC + dir) * step; 7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask = pMask + (YC + dir) * maskStep; 7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = data[k][1]; 7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int right = data[k][2]; 7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_FLT_C1( img + i, val0 )) 7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_FLT_C1( img + j, val0 )) 8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && DIFF_FLT_C1( img + i, val0 )) 8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( !_8_connectivity ) 8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_FLT_C1( img + i, img - curstep + i )) 8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_FLT_C1( img + j, img + (j+1) )) 8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_FLT_C1( img + i, img + (i-1) ) || 8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_FLT_C1( img + i, img + i - curstep) && i <= R))) 8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int idx; 8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float val[1]; 8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && 8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((val[0] = img[i], 8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)(idx = i-L-1) <= length) && 8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img - curstep + (i-1) )) || 8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img - curstep + i )) || 8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img - curstep + (i+1) )))) 8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_FLT_C1( img + j, img + (j+1) )) 8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((val[0] = img[i], 8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img + (i-1) )) || 8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((unsigned)(idx = i-L-1) <= length && 8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img - curstep + (i-1) ))) || 8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img - curstep + i )) || 8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C1( val, img - curstep + (i+1) )))) 8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + YC * step; 8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fillImage ) 8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i] = newVal[0]; 8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( region ) 8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[0] += img[i]; 8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < 3; k++ ) 8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dir = data[k][0]; 8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn curstep = dir * step; 8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + (YC + dir) * step; 8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask = pMask + (YC + dir) * maskStep; 8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int left = data[k][1]; 8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int right = data[k][2]; 8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fixedRange ) 8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_FLT_C3( img + i*3, val0 )) 8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_FLT_C3( img + j*3, val0 )) 8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && DIFF_FLT_C3( img + i*3, val0 )) 8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( !_8_connectivity ) 8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && DIFF_FLT_C3( img + i*3, img - curstep + i*3 )) 9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_FLT_C3( img + j*3, img + (j+1)*3 )) 9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_FLT_C3( img + i*3, img + (i-1)*3 ) || 9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (DIFF_FLT_C3( img + i*3, img + i*3 - curstep) && i <= R))) 9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = left; i <= right; i++ ) 9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int idx; 9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float val[3]; 9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask[i] && 9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((ICV_SET_C3( val, img+i*3 ), 9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)(idx = i-L-1) <= length) && 9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img - curstep + (i-1)*3 )) || 9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img - curstep + i*3 )) || 9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img - curstep + (i+1)*3 )))) 9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j = i; 9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[--j] && DIFF_FLT_C3( img + j*3, img + (j+1)*3 )) 9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[j] = newMaskVal; 9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( !mask[++i] && 9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((ICV_SET_C3( val, img + i*3 ), 9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img + (i-1)*3 )) || 9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (((unsigned)(idx = i-L-1) <= length && 9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img - curstep + (i-1)*3 ))) || 9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img - curstep + i*3 )) || 9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)(++idx) <= length && 9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn DIFF_FLT_C3( val, img - curstep + (i+1)*3 )))) 9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask[i] = newMaskVal; 9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_PUSH( YC + dir, j+1, i-1, L, R, -dir ); 9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img = pImage + YC * step; 9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fillImage ) 9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_SET_C3( img + i*3, newVal ); 9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( region ) 9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = L; i <= R; i++ ) 9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[0] += img[i*3]; 9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[1] += img[i*3+1]; 9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sum[2] += img[i*3+2]; 9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( region ) 9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->area = area; 9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.x = XMin; 9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.y = YMin; 9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.width = XMax - XMin + 1; 9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->rect.height = YMax - YMin + 1; 9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( fillImage ) 9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->value = cvScalar(newVal[0], newVal[1], newVal[2]); 9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double iarea = area ? 1./area : 0; 9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn region->value = cvScalar(sum[0]*iarea, sum[1]*iarea, sum[2]*iarea); 9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* External Functions * 9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_CDECL* CvFloodFillFunc)( 9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void* img, int step, CvSize size, CvPoint seed, void* newval, 9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvConnectedComp* comp, int flags, void* buffer, int buffer_size, int cn ); 9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_CDECL* CvFloodFillGradFunc)( 9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void* img, int step, uchar* mask, int maskStep, CvSize size, 9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint seed, void* newval, void* d_lw, void* d_up, void* ccomp, 9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int flags, void* buffer, int buffer_size, int cn ); 9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvInitFloodFill( void** ffill_tab, 10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void** ffillgrad_tab ) 10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ffill_tab[0] = (void*)icvFloodFill_8u_CnIR; 10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ffill_tab[1] = (void*)icvFloodFill_32f_CnIR; 10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ffillgrad_tab[0] = (void*)icvFloodFill_Grad_8u_CnIR; 10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ffillgrad_tab[1] = (void*)icvFloodFill_Grad_32f_CnIR; 10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFloodFill( CvArr* arr, CvPoint seed_point, 10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvScalar newVal, CvScalar lo_diff, CvScalar up_diff, 10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvConnectedComp* comp, int flags, CvArr* maskarr ) 10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn static void* ffill_tab[4]; 10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn static void* ffillgrad_tab[4]; 10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn static int inittab = 0; 10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* tempMask = 0; 10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFFillSegment* buffer = 0; 10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvFloodFill" ); 10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( comp ) 10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( comp, 0, sizeof(*comp) ); 10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, type, depth, cn, is_simple, idx; 10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int buffer_size, connectivity = flags & 255; 10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double nv_buf[4] = {0,0,0,0}; 10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn union { uchar b[4]; float f[4]; } ld_buf, ud_buf; 10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat stub, *img = (CvMat*)arr; 10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat maskstub, *mask = (CvMat*)maskarr; 10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size; 10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !inittab ) 10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvInitFloodFill( ffill_tab, ffillgrad_tab ); 10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inittab = 1; 10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( img = cvGetMat( img, &stub )); 10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn type = CV_MAT_TYPE( img->type ); 10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn depth = CV_MAT_DEPTH(type); 10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cn = CV_MAT_CN(type); 10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn idx = type == CV_8UC1 || type == CV_8UC3 ? 0 : 10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn type == CV_32FC1 || type == CV_32FC3 ? 1 : -1; 10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( idx < 0 ) 10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, "" ); 10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( connectivity == 0 ) 10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn connectivity = 4; 10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( connectivity != 4 && connectivity != 8 ) 10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadFlag, "Connectivity must be 4, 0(=4) or 8" ); 10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn is_simple = mask == 0 && (flags & CV_FLOODFILL_MASK_ONLY) == 0; 10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < cn; i++ ) 10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( lo_diff.val[i] < 0 || up_diff.val[i] < 0 ) 10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "lo_diff and up_diff must be non-negative" ); 10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn is_simple &= fabs(lo_diff.val[i]) < DBL_EPSILON && fabs(up_diff.val[i]) < DBL_EPSILON; 10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size = cvGetMatSize( img ); 10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)seed_point.x >= (unsigned)size.width || 10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (unsigned)seed_point.y >= (unsigned)size.height ) 10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "Seed point is outside of image" ); 10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvScalarToRawData( &newVal, &nv_buf, type, 0 ); 10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer_size = MAX( size.width, size.height )*2; 10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( buffer = (CvFFillSegment*)cvAlloc( buffer_size*sizeof(buffer[0]))); 10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( is_simple ) 10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size = CV_ELEM_SIZE(type); 10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const uchar* seed_ptr = img->data.ptr + img->step*seed_point.y + elem_size*seed_point.x; 10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFloodFillFunc func = (CvFloodFillFunc)ffill_tab[idx]; 10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !func ) 10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, "" ); 10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // check if the new value is different from the current value at the seed point. 10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // if they are exactly the same, use the generic version with mask to avoid infinite loops. 10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < elem_size; i++ ) 10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seed_ptr[i] != ((uchar*)nv_buf)[i] ) 10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( i < elem_size ) 10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( func( img->data.ptr, img->step, size, 10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seed_point, &nv_buf, comp, flags, 10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer, buffer_size, cn )); 10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvFloodFillGradFunc func = (CvFloodFillGradFunc)ffillgrad_tab[idx]; 11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !func ) 11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, "" ); 11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask ) 11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* created mask will be 8-byte aligned */ 11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tempMask = cvCreateMat( size.height + 2, (size.width + 9) & -8, CV_8UC1 ); 11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask = tempMask; 11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( mask = cvGetMat( mask, &maskstub )); 11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MASK_ARR( mask )) 11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadMask, "" ); 11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( mask->width != size.width + 2 || mask->height != size.height + 2 ) 11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "mask must be 2 pixel wider " 11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "and 2 pixel taller than filled image" ); 11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int width = tempMask ? mask->step : size.width + 2; 11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar* mask_row = mask->data.ptr + mask->step; 11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( mask_row - mask->step, 1, width ); 11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 1; i <= size.height; i++, mask_row += mask->step ) 11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( tempMask ) 11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( mask_row, 0, width ); 11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mask_row[0] = mask_row[size.width+1] = (uchar)1; 11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( mask_row, 1, width ); 11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( depth == CV_8U ) 11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < cn; i++ ) 11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = cvFloor(lo_diff.val[i]); 11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ld_buf.b[i] = CV_CAST_8U(t); 11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = cvFloor(up_diff.val[i]); 11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ud_buf.b[i] = CV_CAST_8U(t); 11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < cn; i++ ) 11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ld_buf.f[i] = (float)lo_diff.val[i]; 11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ud_buf.f[i] = (float)up_diff.val[i]; 11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( func( img->data.ptr, img->step, mask->data.ptr, mask->step, 11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size, seed_point, &nv_buf, ld_buf.f, ud_buf.f, 11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn comp, flags, buffer, buffer_size, cn )); 11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &buffer ); 11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &tempMask ); 11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */ 1161