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#include "_cxcore.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  XY_SHIFT  16
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  XY_ONE    (1 << XY_SHIFT)
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_DRAWING_STORAGE_BLOCK ((1 << 12) - 256)
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvPolyEdge
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x, dx;
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    union
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        struct CvPolyEdge *next;
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int y0;
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    };
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y1;
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvPolyEdge;
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCollectPolyEdges( CvMat* img, CvSeq* v, CvContour* edges,
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const void* color, int line_type,
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int shift, CvPoint offset=cvPoint(0,0) );
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFillEdgeCollection( CvMat* img, CvContour* edges, const void* color );
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPolyLine( CvMat* img, CvPoint *v, int count, int closed,
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             const void* color, int thickness, int line_type, int shift );
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFillConvexPoly( CvMat* img, CvPoint* v, int npts,
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   const void* color, int line_type, int shift );
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                   Lines                                                *
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 )
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int result = 0;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvClipLine" );
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x1, y1, x2, y2;
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int c1, c2;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int right = img_size.width-1, bottom = img_size.height-1;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !pt1 || !pt2 )
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "One of point pointers is NULL" );
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( right < 0 || bottom < 0 )
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "Image width or height are negative" );
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    x1 = pt1->x; y1 = pt1->y; x2 = pt2->x; y2 = pt2->y;
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    c1 = (x1 < 0) + (x1 > right) * 2 + (y1 < 0) * 4 + (y1 > bottom) * 8;
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    c2 = (x2 < 0) + (x2 > right) * 2 + (y2 < 0) * 4 + (y2 > bottom) * 8;
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (c1 & c2) == 0 && (c1 | c2) != 0 )
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int a;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( c1 & 12 )
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            a = c1 < 8 ? 0 : bottom;
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x1 += (int) (((int64) (a - y1)) * (x2 - x1) / (y2 - y1));
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y1 = a;
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c1 = (x1 < 0) + (x1 > right) * 2;
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( c2 & 12 )
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            a = c2 < 8 ? 0 : bottom;
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x2 += (int) (((int64) (a - y2)) * (x2 - x1) / (y2 - y1));
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            y2 = a;
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c2 = (x2 < 0) + (x2 > right) * 2;
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (c1 & c2) == 0 && (c1 | c2) != 0 )
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c1 )
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = c1 == 1 ? 0 : right;
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y1 += (int) (((int64) (a - x1)) * (y2 - y1) / (x2 - x1));
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x1 = a;
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c1 = 0;
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( c2 )
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = c2 == 1 ? 0 : right;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                y2 += (int) (((int64) (a - x2)) * (y2 - y1) / (x2 - x1));
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x2 = a;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                c2 = 0;
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( (c1 & c2) != 0 || (x1 | y1 | x2 | y2) >= 0 );
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1->x = x1;
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1->y = y1;
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2->x = x2;
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2->y = y2;
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    result = ( c1 | c2 ) == 0;
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return result;
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   Initializes line iterator.
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   Returns number of points on the line or negative number if error.
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvInitLineIterator( const CvArr* img, CvPoint pt1, CvPoint pt2,
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvLineIterator* iterator, int connectivity,
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int left_to_right )
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int count = -1;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvInitLineIterator" );
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dx, dy, s;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int bt_pix, bt_pix0, step;
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(mat) )
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( mat = cvGetMat( mat, &stub ));
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !iterator )
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "Pointer to the iterator state is NULL" );
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( connectivity != 8 && connectivity != 4 )
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Connectivity must be 8 or 4" );
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)pt1.x >= (unsigned)(mat->width) ||
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned)pt2.x >= (unsigned)(mat->width) ||
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned)pt1.y >= (unsigned)(mat->height) ||
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (unsigned)pt2.y >= (unsigned)(mat->height) )
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadPoint,
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "One of the ending points is outside of the image, use cvClipLine" );
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bt_pix0 = bt_pix = CV_ELEM_SIZE(mat->type);
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step = mat->step;
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dx = pt2.x - pt1.x;
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dy = pt2.y - pt1.y;
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    s = dx < 0 ? -1 : 0;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( left_to_right )
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = (dx ^ s) - s;
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy = (dy ^ s) - s;
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= (pt1.x ^ pt2.x) & s;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= (pt1.y ^ pt2.y) & s;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = (dx ^ s) - s;
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bt_pix = (bt_pix ^ s) - s;
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    iterator->ptr = (uchar*)(mat->data.ptr + pt1.y * step + pt1.x * bt_pix0);
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    s = dy < 0 ? -1 : 0;
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dy = (dy ^ s) - s;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step = (step ^ s) - s;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    s = dy > dx ? -1 : 0;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* conditional swaps */
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dx ^= dy & s;
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dy ^= dx & s;
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dx ^= dy & s;
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bt_pix ^= step & s;
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    step ^= bt_pix & s;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bt_pix ^= step & s;
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( connectivity == 8 )
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( dx >= 0 && dy >= 0 );
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->err = dx - (dy + dy);
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->plus_delta = dx + dx;
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->minus_delta = -(dy + dy);
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->plus_step = step;
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->minus_step = bt_pix;
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        count = dx + 1;
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else /* connectivity == 4 */
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( dx >= 0 && dy >= 0 );
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->err = 0;
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->plus_delta = (dx + dx) + (dy + dy);
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->minus_delta = -(dy + dy);
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->plus_step = step - bt_pix;
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iterator->minus_step = bt_pix;
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        count = dx + dy + 1;
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return count;
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvLine( CvMat* mat, CvPoint pt1, CvPoint pt2,
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         const void* color, int connectivity = 8 )
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvClipLine( cvGetMatSize(mat), &pt1, &pt2 ))
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvLineIterator iterator;
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int pix_size = CV_ELEM_SIZE(mat->type);
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i, count;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( connectivity == 0 )
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            connectivity = 8;
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( connectivity == 1 )
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            connectivity = 4;
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        count = cvInitLineIterator( mat, pt1, pt2, &iterator, connectivity, 1 );
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < count; i++ )
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_MEMCPY_AUTO( iterator.ptr, color, pix_size );
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_NEXT_LINE_POINT( iterator );
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Correction table depent on the slope */
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const uchar icvSlopeCorrTable[] = {
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    181, 181, 181, 182, 182, 183, 184, 185, 187, 188, 190, 192, 194, 196, 198, 201,
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    203, 206, 209, 211, 214, 218, 221, 224, 227, 231, 235, 238, 242, 246, 250, 254
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Gaussian for antialiasing filter */
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvFilterTable[] = {
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    168, 177, 185, 194, 202, 210, 218, 224, 231, 236, 241, 246, 249, 252, 254, 254,
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    254, 254, 252, 249, 246, 241, 236, 231, 224, 218, 210, 202, 194, 185, 177, 168,
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    158, 149, 140, 131, 122, 114, 105, 97, 89, 82, 75, 68, 62, 56, 50, 45,
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    40, 36, 32, 28, 25, 22, 19, 16, 14, 12, 11, 9, 8, 7, 5, 5
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvLineAA( CvMat* img, CvPoint pt1, CvPoint pt2,
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           const void* color )
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dx, dy;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ecount, scount = 0;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int slope;
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ax, ay;
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x_step, y_step;
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ep_table[9];
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cb = ((uchar*)color)[0], cg = ((uchar*)color)[1], cr = ((uchar*)color)[2];
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int _cb, _cg, _cr;
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nch = CV_MAT_CN( img->type );
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* ptr = (uchar*)(img->data.ptr);
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step = img->step;
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size = cvGetMatSize( img );
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( img && (nch == 1 || nch == 3) && CV_MAT_DEPTH(img->type) == CV_8U );
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt1.x -= XY_ONE*2;
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt1.y -= XY_ONE*2;
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt2.x -= XY_ONE*2;
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt2.y -= XY_ONE*2;
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ptr += img->step*2 + 2*nch;
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.width = ((size.width - 5) << XY_SHIFT) + 1;
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.height = ((size.height - 5) << XY_SHIFT) + 1;
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !cvClipLine( size, &pt1, &pt2 ))
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dx = pt2.x - pt1.x;
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dy = pt2.y - pt1.y;
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j = dx < 0 ? -1 : 0;
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ax = (dx ^ j) - j;
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    i = dy < 0 ? -1 : 0;
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ay = (dy ^ i) - i;
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ax > ay )
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = ax;
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy = (dy ^ j) - j;
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & j;
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.x ^= pt1.x & j;
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & j;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & j;
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.y ^= pt1.y & j;
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & j;
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x_step = XY_ONE;
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.x += XY_ONE;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ecount = (pt2.x >> XY_SHIFT) - (pt1.x >> XY_SHIFT);
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        j = -(pt1.x & (XY_ONE - 1));
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y += (int) ((((int64) y_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        slope = (y_step >> (XY_SHIFT - 5)) & 0x3f;
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        slope ^= (y_step < 0 ? 0x3f : 0);
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* Get 4-bit fractions for end-point adjustments */
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        i = (pt1.x >> (XY_SHIFT - 7)) & 0x78;
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        j = (pt2.x >> (XY_SHIFT - 7)) & 0x78;
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy = ay;
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = (dx ^ i) - i;
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & i;
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.x ^= pt1.x & i;
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & i;
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & i;
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.y ^= pt1.y & i;
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & i;
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y_step = XY_ONE;
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.y += XY_ONE;
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ecount = (pt2.y >> XY_SHIFT) - (pt1.y >> XY_SHIFT);
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        j = -(pt1.y & (XY_ONE - 1));
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x += (int) ((((int64) x_step) * j) >> XY_SHIFT) + (XY_ONE >> 1);
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        slope = (x_step >> (XY_SHIFT - 5)) & 0x3f;
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        slope ^= (x_step < 0 ? 0x3f : 0);
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* Get 4-bit fractions for end-point adjustments */
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        i = (pt1.y >> (XY_SHIFT - 7)) & 0x78;
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        j = (pt2.y >> (XY_SHIFT - 7)) & 0x78;
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    slope = (slope & 0x20) ? 0x100 : icvSlopeCorrTable[slope];
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Calc end point correction table */
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int t0 = slope << 7;
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int t1 = ((0x78 - i) | 4) * slope;
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int t2 = (j | 4) * slope;
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[0] = 0;
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[8] = slope;
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[1] = ep_table[3] = ((((j - i) & 0x78) | 4) * slope >> 8) & 0x1ff;
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[2] = (t1 >> 8) & 0x1ff;
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[4] = ((((j - i) + 0x80) | 4) * slope >> 8) & 0x1ff;
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[5] = ((t1 + t0) >> 8) & 0x1ff;
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[6] = (t2 >> 8) & 0x1ff;
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ep_table[7] = ((t2 + t0) >> 8) & 0x1ff;
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( nch == 3 )
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define  ICV_PUT_POINT()            \
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                   \
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cb = tptr[0];                  \
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cb += ((cb - _cb)*a + 127)>> 8;\
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cg = tptr[1];                  \
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cg += ((cg - _cg)*a + 127)>> 8;\
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cr = tptr[2];                  \
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cr += ((cr - _cr)*a + 127)>> 8;\
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[0] = (uchar)_cb;           \
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[1] = (uchar)_cg;           \
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[2] = (uchar)_cr;           \
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ax > ay )
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.x >> XY_SHIFT) * 3;
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       (((ecount >= 2) + 1) & (ecount | 2))];
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist + 32] >> 8) & 0xff;
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr += step;
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr += step;
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.y += y_step;
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += 3;
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scount++;
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.y >> XY_SHIFT) * step;
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1) * 3;
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       (((ecount >= 2) + 1) & (ecount | 2))];
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist + 32] >> 8) & 0xff;
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr += 3;
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr += 3;
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.x += x_step;
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += step;
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scount++;
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #undef ICV_PUT_POINT
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define  ICV_PUT_POINT()            \
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                   \
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cb = tptr[0];                  \
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _cb += ((cb - _cb)*a + 127)>> 8;\
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[0] = (uchar)_cb;           \
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ax > ay )
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.x >> XY_SHIFT);
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *tptr = ptr + ((pt1.y >> XY_SHIFT) - 1) * step;
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       (((ecount >= 2) + 1) & (ecount | 2))];
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int a, dist = (pt1.y >> (XY_SHIFT - 5)) & 31;
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist + 32] >> 8) & 0xff;
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr += step;
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr += step;
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.y += y_step;
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr++;
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scount++;
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.y >> XY_SHIFT) * step;
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *tptr = ptr + ((pt1.x >> XY_SHIFT) - 1);
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ep_corr = ep_table[(((scount >= 2) + 1) & (scount | 2)) * 3 +
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       (((ecount >= 2) + 1) & (ecount | 2))];
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int a, dist = (pt1.x >> (XY_SHIFT - 5)) & 31;
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist + 32] >> 8) & 0xff;
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr++;
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[dist] >> 8) & 0xff;
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr++;
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = (ep_corr * icvFilterTable[63 - dist] >> 8) & 0xff;
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.x += x_step;
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += step;
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scount++;
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #undef ICV_PUT_POINT
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvLine2( CvMat* img, CvPoint pt1, CvPoint pt2, const void* color )
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dx, dy;
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ecount;
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ax, ay;
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j;
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int x_step, y_step;
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cb = ((uchar*)color)[0];
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cg = ((uchar*)color)[1];
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int cr = ((uchar*)color)[2];
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pix_size = CV_ELEM_SIZE( img->type );
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *ptr = (uchar*)(img->data.ptr), *tptr;
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step = img->step;
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size = cvGetMatSize( img );
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //assert( img && (nch == 1 || nch == 3) && CV_MAT_DEPTH(img->type) == CV_8U );
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt1.x -= XY_ONE*2;
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt1.y -= XY_ONE*2;
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt2.x -= XY_ONE*2;
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt2.y -= XY_ONE*2;
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ptr += img->step*2 + 2*pix_size;
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.width = ((size.width - 5) << XY_SHIFT) + 1;
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size.height = ((size.height - 5) << XY_SHIFT) + 1;
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !cvClipLine( size, &pt1, &pt2 ))
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dx = pt2.x - pt1.x;
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dy = pt2.y - pt1.y;
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j = dx < 0 ? -1 : 0;
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ax = (dx ^ j) - j;
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    i = dy < 0 ? -1 : 0;
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ay = (dy ^ i) - i;
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ax > ay )
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = ax;
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy = (dy ^ j) - j;
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & j;
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.x ^= pt1.x & j;
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & j;
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & j;
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.y ^= pt1.y & j;
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & j;
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x_step = XY_ONE;
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y_step = (int) (((int64) dy << XY_SHIFT) / (ax | 1));
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ecount = (pt2.x - pt1.x) >> XY_SHIFT;
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy = ay;
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = (dx ^ i) - i;
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & i;
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.x ^= pt1.x & i;
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.x ^= pt2.x & i;
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & i;
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt2.y ^= pt1.y & i;
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt1.y ^= pt2.y & i;
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x_step = (int) (((int64) dx << XY_SHIFT) / (ay | 1));
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y_step = XY_ONE;
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ecount = (pt2.y - pt1.y) >> XY_SHIFT;
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt1.x += (XY_ONE >> 1);
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt1.y += (XY_ONE >> 1);
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( pix_size == 3 )
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define  ICV_PUT_POINT()    \
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                           \
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[0] = (uchar)cb;    \
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[1] = (uchar)cg;    \
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[2] = (uchar)cr;    \
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT)*3 +
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ICV_PUT_POINT();
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ax > ay )
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.x >> XY_SHIFT) * 3;
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr = ptr + (pt1.y >> XY_SHIFT) * step;
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.y += y_step;
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += 3;
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.y >> XY_SHIFT) * step;
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr = ptr + (pt1.x >> XY_SHIFT) * 3;
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.x += x_step;
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += step;
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #undef ICV_PUT_POINT
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( pix_size == 1 )
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define  ICV_PUT_POINT()            \
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                   \
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr[0] = (uchar)cb;            \
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT) +
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ICV_PUT_POINT();
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ax > ay )
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.x >> XY_SHIFT);
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr = ptr + (pt1.y >> XY_SHIFT) * step;
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.y += y_step;
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr++;
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.y >> XY_SHIFT) * step;
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr = ptr + (pt1.x >> XY_SHIFT);
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.x += x_step;
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += step;
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #undef ICV_PUT_POINT
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define  ICV_PUT_POINT()                \
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < pix_size; j++ )     \
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr[j] = ((uchar*)color)[j];
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        tptr = ptr + ((pt2.x + (XY_ONE >> 1))>> XY_SHIFT)*pix_size +
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ((pt2.y + (XY_ONE >> 1)) >> XY_SHIFT)*step;
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ICV_PUT_POINT();
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ax > ay )
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.x >> XY_SHIFT) * pix_size;
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr = ptr + (pt1.y >> XY_SHIFT) * step;
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.y += y_step;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += pix_size;
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (pt1.y >> XY_SHIFT) * step;
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( ecount >= 0 )
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tptr = ptr + (pt1.x >> XY_SHIFT) * pix_size;
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT();
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.x += x_step;
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += step;
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ecount--;
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #undef ICV_PUT_POINT
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                   Antialiazed Elliptic Arcs via Antialiazed Lines                      *
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const float icvSinTable[] =
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    { 0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    1.0000000f, 0.9998477f, 0.9993908f, 0.9986295f, 0.9975641f, 0.9961947f,
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9945219f, 0.9925462f, 0.9902681f, 0.9876883f, 0.9848078f, 0.9816272f,
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9781476f, 0.9743701f, 0.9702957f, 0.9659258f, 0.9612617f, 0.9563048f,
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9510565f, 0.9455186f, 0.9396926f, 0.9335804f, 0.9271839f, 0.9205049f,
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9135455f, 0.9063078f, 0.8987940f, 0.8910065f, 0.8829476f, 0.8746197f,
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.8660254f, 0.8571673f, 0.8480481f, 0.8386706f, 0.8290376f, 0.8191520f,
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.8090170f, 0.7986355f, 0.7880108f, 0.7771460f, 0.7660444f, 0.7547096f,
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.7431448f, 0.7313537f, 0.7193398f, 0.7071068f, 0.6946584f, 0.6819984f,
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.6691306f, 0.6560590f, 0.6427876f, 0.6293204f, 0.6156615f, 0.6018150f,
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.5877853f, 0.5735764f, 0.5591929f, 0.5446390f, 0.5299193f, 0.5150381f,
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.5000000f, 0.4848096f, 0.4694716f, 0.4539905f, 0.4383711f, 0.4226183f,
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.4067366f, 0.3907311f, 0.3746066f, 0.3583679f, 0.3420201f, 0.3255682f,
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.3090170f, 0.2923717f, 0.2756374f, 0.2588190f, 0.2419219f, 0.2249511f,
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.2079117f, 0.1908090f, 0.1736482f, 0.1564345f, 0.1391731f, 0.1218693f,
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.1045285f, 0.0871557f, 0.0697565f, 0.0523360f, 0.0348995f, 0.0174524f,
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.0000000f, -0.0174524f, -0.0348995f, -0.0523360f, -0.0697565f, -0.0871557f,
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.1045285f, -0.1218693f, -0.1391731f, -0.1564345f, -0.1736482f, -0.1908090f,
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.2079117f, -0.2249511f, -0.2419219f, -0.2588190f, -0.2756374f, -0.2923717f,
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.3090170f, -0.3255682f, -0.3420201f, -0.3583679f, -0.3746066f, -0.3907311f,
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.4067366f, -0.4226183f, -0.4383711f, -0.4539905f, -0.4694716f, -0.4848096f,
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.5000000f, -0.5150381f, -0.5299193f, -0.5446390f, -0.5591929f, -0.5735764f,
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.5877853f, -0.6018150f, -0.6156615f, -0.6293204f, -0.6427876f, -0.6560590f,
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.6691306f, -0.6819984f, -0.6946584f, -0.7071068f, -0.7193398f, -0.7313537f,
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.7431448f, -0.7547096f, -0.7660444f, -0.7771460f, -0.7880108f, -0.7986355f,
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.8090170f, -0.8191520f, -0.8290376f, -0.8386706f, -0.8480481f, -0.8571673f,
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.8660254f, -0.8746197f, -0.8829476f, -0.8910065f, -0.8987940f, -0.9063078f,
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9135455f, -0.9205049f, -0.9271839f, -0.9335804f, -0.9396926f, -0.9455186f,
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9510565f, -0.9563048f, -0.9612617f, -0.9659258f, -0.9702957f, -0.9743701f,
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9781476f, -0.9816272f, -0.9848078f, -0.9876883f, -0.9902681f, -0.9925462f,
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9945219f, -0.9961947f, -0.9975641f, -0.9986295f, -0.9993908f, -0.9998477f,
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -1.0000000f, -0.9998477f, -0.9993908f, -0.9986295f, -0.9975641f, -0.9961947f,
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9945219f, -0.9925462f, -0.9902681f, -0.9876883f, -0.9848078f, -0.9816272f,
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9781476f, -0.9743701f, -0.9702957f, -0.9659258f, -0.9612617f, -0.9563048f,
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9510565f, -0.9455186f, -0.9396926f, -0.9335804f, -0.9271839f, -0.9205049f,
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.9135455f, -0.9063078f, -0.8987940f, -0.8910065f, -0.8829476f, -0.8746197f,
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.8660254f, -0.8571673f, -0.8480481f, -0.8386706f, -0.8290376f, -0.8191520f,
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.8090170f, -0.7986355f, -0.7880108f, -0.7771460f, -0.7660444f, -0.7547096f,
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.7431448f, -0.7313537f, -0.7193398f, -0.7071068f, -0.6946584f, -0.6819984f,
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.6691306f, -0.6560590f, -0.6427876f, -0.6293204f, -0.6156615f, -0.6018150f,
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.5877853f, -0.5735764f, -0.5591929f, -0.5446390f, -0.5299193f, -0.5150381f,
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.5000000f, -0.4848096f, -0.4694716f, -0.4539905f, -0.4383711f, -0.4226183f,
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.4067366f, -0.3907311f, -0.3746066f, -0.3583679f, -0.3420201f, -0.3255682f,
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.3090170f, -0.2923717f, -0.2756374f, -0.2588190f, -0.2419219f, -0.2249511f,
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.2079117f, -0.1908090f, -0.1736482f, -0.1564345f, -0.1391731f, -0.1218693f,
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.1045285f, -0.0871557f, -0.0697565f, -0.0523360f, -0.0348995f, -0.0174524f,
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    -0.0000000f, 0.0174524f, 0.0348995f, 0.0523360f, 0.0697565f, 0.0871557f,
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.1045285f, 0.1218693f, 0.1391731f, 0.1564345f, 0.1736482f, 0.1908090f,
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.2079117f, 0.2249511f, 0.2419219f, 0.2588190f, 0.2756374f, 0.2923717f,
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.3090170f, 0.3255682f, 0.3420201f, 0.3583679f, 0.3746066f, 0.3907311f,
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.4067366f, 0.4226183f, 0.4383711f, 0.4539905f, 0.4694716f, 0.4848096f,
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.5000000f, 0.5150381f, 0.5299193f, 0.5446390f, 0.5591929f, 0.5735764f,
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.5877853f, 0.6018150f, 0.6156615f, 0.6293204f, 0.6427876f, 0.6560590f,
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.6691306f, 0.6819984f, 0.6946584f, 0.7071068f, 0.7193398f, 0.7313537f,
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.7431448f, 0.7547096f, 0.7660444f, 0.7771460f, 0.7880108f, 0.7986355f,
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.8090170f, 0.8191520f, 0.8290376f, 0.8386706f, 0.8480481f, 0.8571673f,
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.8660254f, 0.8746197f, 0.8829476f, 0.8910065f, 0.8987940f, 0.9063078f,
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9135455f, 0.9205049f, 0.9271839f, 0.9335804f, 0.9396926f, 0.9455186f,
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9510565f, 0.9563048f, 0.9612617f, 0.9659258f, 0.9702957f, 0.9743701f,
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9781476f, 0.9816272f, 0.9848078f, 0.9876883f, 0.9902681f, 0.9925462f,
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.9945219f, 0.9961947f, 0.9975641f, 0.9986295f, 0.9993908f, 0.9998477f,
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    1.0000000f
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvSinCos( int angle, float *cosval, float *sinval )
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    angle += (angle < 0 ? 360 : 0);
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *sinval = icvSinTable[angle];
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *cosval = icvSinTable[450 - angle];
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   constructs polygon that represents elliptic arc.
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEllipse2Poly( CvPoint center, CvSize axes, int angle,
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int arc_start, int arc_end, CvPoint* pts, int delta )
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float alpha, beta;
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double size_a = axes.width, size_b = axes.height;
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double cx = center.x, cy = center.y;
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint *pts_origin = pts;
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( angle < 0 )
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        angle += 360;
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( angle > 360 )
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        angle -= 360;
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( arc_start > arc_end )
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        i = arc_start;
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_start = arc_end;
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_end = i;
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( arc_start < 0 )
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_start += 360;
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_end += 360;
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( arc_end > 360 )
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_end -= 360;
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_start -= 360;
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( arc_end - arc_start > 360 )
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_start = 0;
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        arc_end = 360;
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvSinCos( angle, &alpha, &beta );
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = arc_start; i < arc_end + delta; i += delta )
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double x, y;
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        angle = i;
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( angle > arc_end )
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            angle = arc_end;
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( angle < 0 )
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            angle += 360;
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x = size_a * icvSinTable[450-angle];
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y = size_b * icvSinTable[angle];
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pts->x = cvRound( cx + x * alpha - y * beta );
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pts->y = cvRound( cy - x * beta - y * alpha );
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pts += i == arc_start || pts->x != pts[-1].x || pts->y != pts[-1].y;
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    i = (int)(pts - pts_origin);
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; i < 2; i++ )
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pts_origin[i] = pts_origin[i-1];
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return i;
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvEllipseEx( CvMat* img, CvPoint center, CvSize axes,
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int angle, int arc_start, int arc_end,
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              const void* color, int thickness, int line_type )
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStorage* st = 0;
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "icvEllipseEx" );
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint v[1 << 8];
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int count, delta;
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( axes.width < 0 || axes.height < 0 )
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadSize, "" );
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    delta = (MAX(axes.width,axes.height)+(XY_ONE>>1))>>XY_SHIFT;
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    delta = delta < 3 ? 90 : delta < 10 ? 30 : delta < 15 ? 18 : 5;
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    count = cvEllipse2Poly( center, axes, angle, arc_start, arc_end, v, delta );
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness >= 0 )
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvPolyLine( img, v, count, 0, color, thickness, line_type, XY_SHIFT );
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( arc_end - arc_start >= 360 )
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFillConvexPoly( img, v, count, color, line_type, XY_SHIFT );
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvContour* edges;
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSeq vtx;
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSeqBlock block;
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( st = cvCreateMemStorage( CV_DRAWING_STORAGE_BLOCK ));
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( edges = (CvContour*)cvCreateSeq( 0, sizeof(CvContour), sizeof(CvPolyEdge), st ));
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        v[count++] = center;
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvMakeSeqHeaderForArray( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint),
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                          v, count, &vtx, &block ));
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvCollectPolyEdges( img, &vtx, edges, color, line_type, XY_SHIFT ));
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvFillEdgeCollection( img, edges, color ));
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( st )
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvReleaseMemStorage( &st );
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                                Polygons filling                                        *
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* helper macros: filling horizontal row */
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_HLINE( ptr, xl, xr, color, pix_size )            \
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                            \
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* hline_ptr = (uchar*)(ptr) + (xl)*(pix_size);      \
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* hline_max_ptr = (uchar*)(ptr) + (xr)*(pix_size);  \
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                             \
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; hline_ptr <= hline_max_ptr; hline_ptr += (pix_size))\
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                        \
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int hline_j;                                         \
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( hline_j = 0; hline_j < (pix_size); hline_j++ )  \
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                    \
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            hline_ptr[hline_j] = ((uchar*)color)[hline_j];   \
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                    \
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                        \
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* filling convex polygon. v - array of vertices, ntps - number of points */
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFillConvexPoly( CvMat* img, CvPoint *v, int npts, const void* color, int line_type, int shift )
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    struct
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int idx, di;
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x, dx, ye;
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edge[2];
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int delta = shift ? 1 << (shift - 1) : 0;
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, y, imin = 0, left = 0, right = 1, x1, x2;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int edges = npts;
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int xmin, xmax, ymin, ymax;
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* ptr = img->data.ptr;
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size = cvGetMatSize( img );
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pix_size = CV_ELEM_SIZE(img->type);
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint p0;
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int delta1, delta2;
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type < CV_AA )
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        delta1 = delta2 = XY_ONE >> 1;
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //delta1 = 0, delta2 = XY_ONE - 1;
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        delta1 = XY_ONE - 1, delta2 = 0;
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p0 = v[npts - 1];
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p0.x <<= XY_SHIFT - shift;
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p0.y <<= XY_SHIFT - shift;
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( 0 <= shift && shift <= XY_SHIFT );
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    xmin = xmax = v[0].x;
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ymin = ymax = v[0].y;
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < npts; i++ )
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint p = v[i];
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( p.y < ymin )
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ymin = p.y;
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            imin = i;
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ymax = MAX( ymax, p.y );
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        xmax = MAX( xmax, p.x );
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        xmin = MIN( xmin, p.x );
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p.x <<= XY_SHIFT - shift;
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p.y <<= XY_SHIFT - shift;
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( line_type <= 8 )
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( shift == 0 )
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvPoint pt0, pt1;
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt0.x = p0.x >> XY_SHIFT;
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt0.y = p0.y >> XY_SHIFT;
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.x = p.x >> XY_SHIFT;
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt1.y = p.y >> XY_SHIFT;
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvLine( img, pt0, pt1, color, line_type );
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvLine2( img, p0, p, color );
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvLineAA( img, p0, p, color );
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p0 = p;
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    xmin = (xmin + delta) >> shift;
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    xmax = (xmax + delta) >> shift;
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ymin = (ymin + delta) >> shift;
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ymax = (ymax + delta) >> shift;
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( npts < 3 || xmax < 0 || ymax < 0 || xmin >= size.width || ymin >= size.height )
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ymax = MIN( ymax, size.height - 1 );
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edge[0].idx = edge[1].idx = imin;
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edge[0].ye = edge[1].ye = y = ymin;
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edge[0].di = 1;
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edge[1].di = npts - 1;
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ptr += img->step*y;
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    do
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( line_type < CV_AA || y < ymax || y == ymin )
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < 2; i++ )
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( y >= edge[i].ye )
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int idx = edge[i].idx, di = edge[i].di;
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int xs = 0, xe, ye, ty = 0;
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for(;;)
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ty = (v[idx].y + delta) >> shift;
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( ty > y || edges == 0 )
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            break;
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        xs = v[idx].x;
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        idx += di;
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        idx -= ((idx < npts) - 1) & npts;   /* idx -= idx >= npts ? npts : 0 */
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        edges--;
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ye = ty;
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    xs <<= XY_SHIFT - shift;
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    xe = v[idx].x << (XY_SHIFT - shift);
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* no more edges */
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( y >= ye )
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        return;
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    edge[i].ye = ye;
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    edge[i].dx = ((xe - xs)*2 + (ye - y)) / (2 * (ye - y));
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    edge[i].x = xs;
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    edge[i].idx = idx;
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( edge[left].x > edge[right].x )
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            left ^= 1;
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            right ^= 1;
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x1 = edge[left].x;
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x2 = edge[right].x;
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( y >= 0 )
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int xx1 = (x1 + delta1) >> XY_SHIFT;
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int xx2 = (x2 + delta2) >> XY_SHIFT;
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( xx2 >= 0 && xx1 < size.width )
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( xx1 < 0 )
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    xx1 = 0;
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( xx2 >= size.width )
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    xx2 = size.width - 1;
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_HLINE( ptr, xx1, xx2, color, pix_size );
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x1 += edge[left].dx;
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        x2 += edge[right].dx;
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edge[left].x = x1;
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edge[right].x = x2;
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ptr += img->step;
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( ++y <= ymax );
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/******** Arbitrary polygon **********/
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCollectPolyEdges( CvMat* img, CvSeq* v, CvContour* edges,
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const void* color, int line_type, int shift,
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     CvPoint offset )
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  i, count = v->total;
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvRect bounds = edges->rect;
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int delta = offset.y + (shift ? 1 << (shift - 1) : 0);
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int elem_type = CV_MAT_TYPE(v->flags);
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( v, &reader );
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartAppendToSeq( (CvSeq*)edges, &writer );
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < count; i++ )
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint pt0, pt1, t0, t1;
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPolyEdge edge;
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_READ_EDGE( pt0, pt1, reader );
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( elem_type == CV_32SC2 )
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt0.x = (pt0.x + offset.x) << (XY_SHIFT - shift);
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt0.y = (pt0.y + delta) >> shift;
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt1.y = (pt1.y + delta) >> shift;
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            Cv32suf x, y;
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( shift == 0 );
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x.i = pt0.x; y.i = pt0.y;
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt0.x = cvRound((x.f + offset.x) * XY_ONE);
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt0.y = cvRound(y.f + offset.y);
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            x.i = pt1.x; y.i = pt1.y;
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt1.x = cvRound((x.f + offset.x) * XY_ONE);
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pt1.y = cvRound(y.f + offset.y);
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( line_type < CV_AA )
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0.y = pt0.y; t1.y = pt1.y;
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvLine( img, t0, t1, color, line_type );
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0.x = pt0.x; t1.x = pt1.x;
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0.y = pt0.y << XY_SHIFT;
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t1.y = pt1.y << XY_SHIFT;
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvLineAA( img, t0, t1, color );
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( pt0.y == pt1.y )
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            continue;
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( pt0.y > pt1.y )
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_SWAP( pt0, pt1, t0 );
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bounds.y = MIN( bounds.y, pt0.y );
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bounds.height = MAX( bounds.height, pt1.y );
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( pt0.x < pt1.x )
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bounds.x = MIN( bounds.x, pt0.x );
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bounds.width = MAX( bounds.width, pt1.x );
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bounds.x = MIN( bounds.x, pt1.x );
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bounds.width = MAX( bounds.width, pt0.x );
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edge.y0 = pt0.y;
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edge.y1 = pt1.y;
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edge.x = pt0.x;
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( edge.y0 < edge.y1 );
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_WRITE_SEQ_ELEM( edge, writer );
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    edges->rect = bounds;
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvEndWriteSeq( &writer );
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCmpEdges( const void* _e1, const void* _e2, void* /*userdata*/ )
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPolyEdge *e1 = (CvPolyEdge*)_e1, *e2 = (CvPolyEdge*)_e2;
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return e1->y0 - e2->y0 ? e1->y0 - e2->y0 :
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           e1->x - e2->x ? e1->x - e2->x : e1->dx - e2->dx;
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/**************** helper macros and functions for sequence/contour processing ***********/
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFillEdgeCollection( CvMat* img, CvContour* edges, const void* color )
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPolyEdge tmp;
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, y, total = edges->total;
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqReader reader;
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size = cvGetMatSize(img);
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPolyEdge* e;
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y_max = INT_MIN;
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pix_size = CV_ELEM_SIZE(img->type);
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( &tmp, 0, sizeof(tmp));
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* check parameters */
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( edges->total < 2 || edges->rect.height < 0 || edges->rect.y >= size.height ||
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edges->rect.width < 0 || edges->rect.x >= size.width )
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSeqSort( (CvSeq*)edges, icvCmpEdges, 0 );
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( (CvSeq*)edges, &reader );
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _DEBUG
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    e = &tmp;
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp.y0 = INT_MIN;
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < total; i++ )
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPolyEdge* e1 = (CvPolyEdge*)(reader.ptr);
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _DEBUG
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( e1->y0 < e1->y1 && (i == 0 || icvCmpEdges( e, e1, 0 ) <= 0) );
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        e = e1;
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        y_max = MAX( y_max, e1->y1 );
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_NEXT_SEQ_ELEM( sizeof(CvPolyEdge), reader );
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* start drawing */
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp.y0 = INT_MAX;
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvSeqPush( (CvSeq*)edges, &tmp );
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    i = 0;
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tmp.next = 0;
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvStartReadSeq( (CvSeq*)edges, &reader );
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    e = (CvPolyEdge*)(reader.ptr);
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    y_max = MIN( y_max, size.height );
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = e->y0; y < y_max; y++ )
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPolyEdge *last, *prelast, *keep_prelast;
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int sort_flag = 0;
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int draw = 0;
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int clipline = y < 0;
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prelast = &tmp;
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        last = tmp.next;
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( last || e->y0 == y )
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( last && last->y1 == y )
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* exlude edge if y reachs its lower point */
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prelast->next = last->next;
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                last = last->next;
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            keep_prelast = prelast;
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( last && (e->y0 > y || last->x < e->x) )
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* go to the next edge in active list */
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prelast = last;
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                last = last->next;
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( i < total )
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* insert new edge into active list if y reachs its upper point */
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prelast->next = e;
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e->next = last;
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prelast = e;
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_NEXT_SEQ_ELEM( edges->elem_size, reader );
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                e = (CvPolyEdge*)(reader.ptr);
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i++;
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( draw )
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !clipline )
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* convert x's from fixed-point to image coordinates */
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    uchar *timg = (uchar*)(img->data.ptr) + y * img->step;
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int x1 = keep_prelast->x;
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int x2 = prelast->x;
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( x1 > x2 )
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int t = x1;
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        x1 = x2;
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        x2 = t;
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x1 = (x1 + XY_ONE - 1) >> XY_SHIFT;
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x2 = x2 >> XY_SHIFT;
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* clip and draw the line */
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( x1 < size.width && x2 >= 0 )
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( x1 < 0 )
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            x1 = 0;
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( x2 >= size.width )
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            x2 = size.width - 1;
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_HLINE( timg, x1, x2, color, pix_size );
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                keep_prelast->x += keep_prelast->dx;
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prelast->x += prelast->dx;
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            draw ^= 1;
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* sort edges (bubble sort on list) */
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        keep_prelast = 0;
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        do
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prelast = &tmp;
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            last = tmp.next;
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            while( last != keep_prelast && last->next != 0 )
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvPolyEdge *te = last->next;
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* swap edges */
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( last->x > te->x )
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prelast->next = te;
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    last->next = te->next;
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    te->next = last;
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prelast = te;
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sort_flag = 1;
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prelast = last;
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    last = te;
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            keep_prelast = prelast;
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( sort_flag && keep_prelast != tmp.next && keep_prelast != &tmp );
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* draws simple or filled circle */
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCircle( CvMat* img, CvPoint center, int radius, const void* color, int fill )
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize size = cvGetMatSize( img );
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int step = img->step;
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int pix_size = CV_ELEM_SIZE(img->type);
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* ptr = (uchar*)(img->data.ptr);
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int err = 0, dx = radius, dy = 0, plus = 1, minus = (radius << 1) - 1;
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int inside = center.x >= radius && center.x < size.width - radius &&
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        center.y >= radius && center.y < size.height - radius;
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #define ICV_PUT_POINT( ptr, x )     \
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_MEMCPY_CHAR( ptr + (x)*pix_size, color, pix_size );
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( dx >= dy )
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int mask;
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int y11 = center.y - dy, y12 = center.y + dy, y21 = center.y - dx, y22 = center.y + dx;
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x11 = center.x - dx, x12 = center.x + dx, x21 = center.x - dy, x22 = center.x + dy;
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( inside )
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *tptr0 = ptr + y11 * step;
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *tptr1 = ptr + y12 * step;
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !fill )
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr0, x11 );
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr1, x11 );
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr0, x12 );
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr1, x12 );
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_HLINE( tptr0, x11, x12, color, pix_size );
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_HLINE( tptr1, x11, x12, color, pix_size );
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr0 = ptr + y21 * step;
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tptr1 = ptr + y22 * step;
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !fill )
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr0, x21 );
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr1, x21 );
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr0, x22 );
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PUT_POINT( tptr1, x22 );
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_HLINE( tptr0, x21, x22, color, pix_size );
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_HLINE( tptr1, x21, x22, color, pix_size );
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( x11 < size.width && x12 >= 0 && y21 < size.height && y22 >= 0 )
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( fill )
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x11 = MAX( x11, 0 );
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                x12 = MIN( x12, size.width - 1 );
14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (unsigned)y11 < (unsigned)size.height )
14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *tptr = ptr + y11 * step;
14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !fill )
14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( x11 >= 0 )
14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_PUT_POINT( tptr, x11 );
14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( x12 < size.width )
14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_PUT_POINT( tptr, x12 );
14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ICV_HLINE( tptr, x11, x12, color, pix_size );
14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (unsigned)y12 < (unsigned)size.height )
14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *tptr = ptr + y12 * step;
14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !fill )
14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( x11 >= 0 )
14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_PUT_POINT( tptr, x11 );
14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( x12 < size.width )
14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_PUT_POINT( tptr, x12 );
14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ICV_HLINE( tptr, x11, x12, color, pix_size );
15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( x21 < size.width && x22 >= 0 )
15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( fill )
15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x21 = MAX( x21, 0 );
15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x22 = MIN( x22, size.width - 1 );
15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)y21 < (unsigned)size.height )
15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    uchar *tptr = ptr + y21 * step;
15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !fill )
15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( x21 >= 0 )
15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ICV_PUT_POINT( tptr, x21 );
15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( x22 < size.width )
15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ICV_PUT_POINT( tptr, x22 );
15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_HLINE( tptr, x21, x22, color, pix_size );
15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (unsigned)y22 < (unsigned)size.height )
15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    uchar *tptr = ptr + y22 * step;
15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !fill )
15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( x21 >= 0 )
15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ICV_PUT_POINT( tptr, x21 );
15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( x22 < size.width )
15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            ICV_PUT_POINT( tptr, x22 );
15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        ICV_HLINE( tptr, x21, x22, color, pix_size );
15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dy++;
15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        err += plus;
15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        plus += 2;
15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        mask = (err <= 0) - 1;
15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        err -= minus & mask;
15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx += mask;
15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        minus -= mask & 2;
15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #undef  ICV_PUT_POINT
15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvThickLine( CvMat* img, CvPoint p0, CvPoint p1, const void* color,
15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn              int thickness, int line_type, int flags, int shift )
15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const double INV_XY_ONE = 1./XY_ONE;
15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p0.x <<= XY_SHIFT - shift;
15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p0.y <<= XY_SHIFT - shift;
15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p1.x <<= XY_SHIFT - shift;
15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p1.y <<= XY_SHIFT - shift;
15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness <= 1 )
15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( line_type < CV_AA )
15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( line_type == 1 || line_type == 4 || shift == 0 )
15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p0.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p0.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p1.x = (p1.x + (XY_ONE>>1)) >> XY_SHIFT;
15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p1.y = (p1.y + (XY_ONE>>1)) >> XY_SHIFT;
15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvLine( img, p0, p1, color, line_type );
15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvLine2( img, p0, p1, color );
15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvLineAA( img, p0, p1, color );
15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint pt[4], dp = {0,0};
15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double dx = (p0.x - p1.x)*INV_XY_ONE, dy = (p1.y - p0.y)*INV_XY_ONE;
15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double r = dx * dx + dy * dy;
15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i;
15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        thickness <<= XY_SHIFT - 1;
15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( fabs(r) > DBL_EPSILON )
15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            r = thickness * cvInvSqrt( (float) r );
15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dp.x = cvRound( dy * r );
15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dp.y = cvRound( dx * r );
15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[0].x = p0.x + dp.x;
16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[0].y = p0.y + dp.y;
16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[1].x = p0.x - dp.x;
16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[1].y = p0.y - dp.y;
16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[2].x = p1.x - dp.x;
16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[2].y = p1.y - dp.y;
16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[3].x = p1.x + dp.x;
16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        pt[3].y = p1.y + dp.y;
16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFillConvexPoly( img, pt, 4, color, line_type, XY_SHIFT );
16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < 2; i++ )
16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( flags & (i+1) )
16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( line_type < CV_AA )
16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvPoint center;
16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    center.x = (p0.x + (XY_ONE>>1)) >> XY_SHIFT;
16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    center.y = (p0.y + (XY_ONE>>1)) >> XY_SHIFT;
16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCircle( img, center, thickness >> XY_SHIFT, color, 1 );
16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvEllipseEx( img, p0, cvSize(thickness, thickness),
16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                  0, 0, 360, color, -1, line_type );
16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p0 = p1;
16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvPolyLine( CvMat* img, CvPoint *v, int count, int is_closed,
16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             const void* color, int thickness,
16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             int line_type, int shift )
16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("icvPolyLine");
16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( count > 0 )
16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i = is_closed ? count - 1 : 0;
16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int flags = 2 + !is_closed;
16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint p0;
16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( 0 <= shift && shift <= XY_SHIFT );
16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( img && thickness >= 0 );
16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( v && count >= 0 );
16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !v )
16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsNullPtr, "" );
16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p0 = v[i];
16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = !is_closed; i < count; i++ )
16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvPoint p = v[i];
16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvThickLine( img, p0, p, color, thickness, line_type, flags, shift );
16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p0 = p;
16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            flags = 2;
16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*                              External functions                                        *
16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvScalar cvColorToScalar( double packed_color, int type )
16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvScalar scalar;
16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_MAT_DEPTH( type ) == CV_8U )
16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int icolor = cvRound( packed_color );
16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_CN( type ) > 1 )
16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = icolor & 255;
16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[1] = (icolor >> 8) & 255;
16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[2] = (icolor >> 16) & 255;
16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[3] = (icolor >> 24) & 255;
16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = CV_CAST_8U( icolor );
16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( CV_MAT_DEPTH( type ) == CV_8S )
16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int icolor = cvRound( packed_color );
16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_CN( type ) > 1 )
16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = (char)icolor;
16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[1] = (char)(icolor >> 8);
16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[2] = (char)(icolor >> 16);
17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[3] = (char)(icolor >> 24);
17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = CV_CAST_8S( icolor );
17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int cn = CV_MAT_CN( type );
17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        switch( cn )
17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 1:
17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = packed_color;
17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[1] = scalar.val[2] = scalar.val[3] = 0;
17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 2:
17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = scalar.val[1] = packed_color;
17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[2] = scalar.val[3] = 0;
17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        case 3:
17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = scalar.val[1] = scalar.val[2] = packed_color;
17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[3] = 0;
17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        default:
17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scalar.val[0] = scalar.val[1] =
17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scalar.val[2] = scalar.val[3] = packed_color;
17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return scalar;
17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvLine( void* img, CvPoint pt1, CvPoint pt2, CvScalar color,
17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int thickness, int line_type, int shift )
17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvLine" );
17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( img, &stub, &coi ));
17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)thickness > 255  )
17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvThickLine( mat, pt1, pt2, buf, thickness, line_type, 3, shift );
17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvRectangle( void* img, CvPoint pt1, CvPoint pt2,
17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             CvScalar color, int thickness,
17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             int line_type, int shift )
17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint pt[4];
17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME("cvRectangle");
17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness > 255 )
17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( img, &stub, &coi ));
17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt[0] = pt1;
18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt[1].x = pt2.x;
18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt[1].y = pt1.y;
18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt[2] = pt2;
18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt[3].x = pt1.x;
18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pt[3].y = pt2.y;
18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness >= 0 )
18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvPolyLine( mat, pt, 4, 1, buf, thickness, line_type, shift );
18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFillConvexPoly( mat, pt, 4, buf, line_type, shift );
18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCircle( void *img, CvPoint center, int radius,
18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn          CvScalar color, int thickness, int line_type, int shift )
18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCircle" );
18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( radius < 0 )
18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness > 255 )
18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness > 1 || line_type >= CV_AA )
18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        center.x <<= XY_SHIFT - shift;
18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        center.y <<= XY_SHIFT - shift;
18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        radius <<= XY_SHIFT - shift;
18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvEllipseEx( mat, center, cvSize( radius, radius ),
18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      0, 0, 360, buf, thickness, line_type );
18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvCircle( mat, center, radius, buf, thickness < 0 );
18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEllipse( void *img, CvPoint center, CvSize axes,
18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           double angle, double start_angle, double end_angle,
18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           CvScalar color, int thickness, int line_type, int shift )
18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvEllipse" );
18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
18846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( axes.width < 0 || axes.height < 0 )
18866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
18876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness > 255 )
18896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
18906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
18926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
18936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
18956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int _angle = cvRound(angle);
18986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int _start_angle = cvRound(start_angle);
18996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int _end_angle = cvRound(end_angle);
19006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        center.x <<= XY_SHIFT - shift;
19016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        center.y <<= XY_SHIFT - shift;
19026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        axes.width <<= XY_SHIFT - shift;
19036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        axes.height <<= XY_SHIFT - shift;
19046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvEllipseEx( mat, center, axes, _angle, _start_angle,
19066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               _end_angle, buf, thickness, line_type ));
19076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
19086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
19106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
19116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
19146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFillConvexPoly( void *img, CvPoint *pts, int npts, CvScalar color, int line_type, int shift )
19156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
19166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvFillConvexPoly" );
19176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
19196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
19216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
19226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
19236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
19256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
19276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
19286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
19306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
19316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !pts )
19336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
19346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( npts <= 0 )
19366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
19376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
19396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
19406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
19426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFillConvexPoly( mat, pts, npts, buf, line_type, shift );
19436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
19456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
19466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
19496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFillPoly( void *img, CvPoint **pts, int *npts, int contours,
19506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvScalar color, int line_type, int shift )
19516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
19526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStorage* st = 0;
19536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvFillPoly" );
19556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
19576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
19596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
19606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
19616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
19636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
19656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
19666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
19686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
19696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( contours <= 0 )
19716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "" );
19726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !pts )
19746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
19756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( npts <= 0 )
19776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
19786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
19806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
19816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
19836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
19856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvContour* edges = 0;
19866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSeq vtx;
19876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSeqBlock block;
19886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( st = cvCreateMemStorage( CV_DRAWING_STORAGE_BLOCK ));
19906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( edges = (CvContour*)cvCreateSeq( 0, sizeof(CvContour),
19916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                  sizeof(CvPolyEdge), st ));
19926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( int i = 0; i < contours; i++ )
19946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !pts[i] )
19966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsNullPtr, "" );
19976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( npts[i] < 0 )
19996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsOutOfRange, "" );
20006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvMakeSeqHeaderForArray( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint),
20026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     pts[i], npts[i], &vtx, &block );
20036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( icvCollectPolyEdges( mat, &vtx, edges, buf, line_type, shift ));
20056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
20066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvFillEdgeCollection( mat, edges, buf ));
20086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
20096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
20116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMemStorage( &st );
20136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
20146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
20186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPolyLine( void *img, CvPoint **pts, int *npts,
20196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int contours, int closed, CvScalar color,
20206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int thickness, int line_type, int shift )
20216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
20226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPolyLine" );
20236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
20256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0, i;
20276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
20286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
20296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
20316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
20336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
20346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
20366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
20376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( contours <= 0 )
20396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "" );
20406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness < -1 || thickness > 255 )
20426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "" );
20436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !pts )
20456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
20466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( npts <= 0 )
20486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
20496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( shift < 0 || XY_SHIFT < shift )
20516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "shift must be between 0 and 16" );
20526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
20546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < contours; i++ )
20566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvPolyLine( mat, pts[i], npts[i], closed, buf, thickness, line_type, shift );
20576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
20596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
20606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_SIZE_SHIFT     8
20636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_ITALIC_ALPHA   (1 << 8)
20646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_ITALIC_DIGIT   (2 << 8)
20656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_ITALIC_PUNCT   (4 << 8)
20666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_ITALIC_BRACES  (8 << 8)
20676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_HAVE_GREEK     (16 << 8)
20686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FONT_HAVE_CYRILLIC  (32 << 8)
20696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyPlain[] = {
20716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(5 + 4*16) + CV_FONT_HAVE_GREEK,
20726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
20736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
20746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn215, 190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
20756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 193, 84,
20766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn194, 85, 86, 87, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
20776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
20786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn195, 223, 196, 88 };
20796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyPlainItalic[] = {
20816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(5 + 4*16) + CV_FONT_ITALIC_ALPHA + CV_FONT_HAVE_GREEK,
20826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
20836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
20846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn215, 190, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
20856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 193, 84,
20866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn194, 85, 86, 87, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
20876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
20886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn195, 223, 196, 88 };
20896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyComplexSmall[] = {
20916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(6 + 7*16) + CV_FONT_HAVE_GREEK,
20926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
20936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 2213, 1241, 1238, 1242,
20946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1215, 1273, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013,
20956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1223, 1084,
20966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1224, 1247, 586, 1249, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
20976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126,
20986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1225, 1229, 1226, 1246 };
20996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyComplexSmallItalic[] = {
21016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(6 + 7*16) + CV_FONT_ITALIC_ALPHA + CV_FONT_HAVE_GREEK,
21026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
21036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1241, 1238, 1242,
21046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1215, 1273, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
21056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1223, 1084,
21066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1224, 1247, 586, 1249, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161,
21076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
21086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1225, 1229, 1226, 1246 };
21096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheySimplex[] = {
21116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_HAVE_GREEK,
21126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
21136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
21146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn715, 690, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513,
21156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 693, 584,
21166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn694, 2247, 586, 2249, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611,
21176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626,
21186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn695, 723, 696, 2246 };
21196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyDuplex[] = {
21216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_HAVE_GREEK,
21226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 2714, 2728, 2732, 2719, 2733, 2718, 2727, 2721, 2722, 2723, 2725, 2711, 2724, 2710, 2720,
21236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2712, 2713, 2730, 2726, 2731,
21246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2715, 2734, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513,
21256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2223, 2084,
21266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2224, 2247, 587, 2249, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611,
21276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626,
21286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2225, 2229, 2226, 2246 };
21296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyComplex[] = {
21316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_HAVE_GREEK + CV_FONT_HAVE_CYRILLIC,
21326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 2214, 2217, 2275, 2274, 2271, 2272, 2216, 2221, 2222, 2219, 2232, 2211, 2231, 2210, 2220,
21336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2212, 2213, 2241, 2238, 2242,
21346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2215, 2273, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
21356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084,
21366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111,
21376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126,
21386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2225, 2229, 2226, 2246 };
21396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyComplexItalic[] = {
21416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_ITALIC_ALPHA + CV_FONT_ITALIC_DIGIT + CV_FONT_ITALIC_PUNCT +
21426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_FONT_HAVE_GREEK + CV_FONT_HAVE_CYRILLIC,
21436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
21446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
21456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2765, 2273, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063,
21466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2223, 2084,
21476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2224, 2247, 587, 2249, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161,
21486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176,
21496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2225, 2229, 2226, 2246 };
21506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyTriplex[] = {
21526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_HAVE_GREEK,
21536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 3214, 3228, 3232, 3219, 3233, 3218, 3227, 3221, 3222, 3223, 3225, 3211, 3224, 3210, 3220,
21546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3212, 3213, 3230, 3226, 3231,
21556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3215, 3234, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013,
21566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 2223, 2084,
21576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2224, 2247, 587, 2249, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111,
21586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126,
21596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2225, 2229, 2226, 2246 };
21606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyTriplexItalic[] = {
21626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_ITALIC_ALPHA + CV_FONT_ITALIC_DIGIT +
21636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_FONT_ITALIC_PUNCT + CV_FONT_HAVE_GREEK,
21646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 3264, 3278, 3282, 3269, 3233, 3268, 3277, 3271, 3272, 3223, 3225, 3261, 3224, 3260, 3270,
21656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3262, 3263, 3230, 3226, 3231,
21666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3265, 3234, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063,
21676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 2223, 2084,
21686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2224, 2247, 587, 2249, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161,
21696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176,
21706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2225, 2229, 2226, 2246 };
21716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyScriptSimplex[] = {
21736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_ITALIC_ALPHA + CV_FONT_HAVE_GREEK,
21746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
21756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
21766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn715, 690, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
21776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 693, 584,
21786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn694, 2247, 586, 2249, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
21796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676,
21806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn695, 723, 696, 2246 };
21816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvHersheyScriptComplex[] = {
21836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn(9 + 12*16) + CV_FONT_ITALIC_ALPHA + CV_FONT_ITALIC_DIGIT + CV_FONT_ITALIC_PUNCT + CV_FONT_HAVE_GREEK,
21846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
21856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
21866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2215, 2273, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563,
21876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2223, 2084,
21886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2224, 2247, 586, 2249, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661,
21896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676,
21906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2225, 2229, 2226, 2246 };
21916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
21946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPutText( void *img, const char *text, CvPoint org, const CvFont *font, CvScalar color )
21956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
21966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvPutText" );
21976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
21996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int view_x, view_y;
22016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
22026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int top_bottom = 0, base_line;
22036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int hscale, vscale, default_shear, italic_shear;
22046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int thickness, line_type;
22056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
22066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double buf[4];
22076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvPoint pt[1 << 10];
22086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int count;
22096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
22116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const char **faces = icvHersheyGlyphs;
22126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
22146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
22166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
22176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->origin )
22196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        top_bottom = 1;
22206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !text || !font || !font->ascii )
22226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
22236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &color, buf, mat->type, 0 ));
22256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    base_line = -(font->ascii[0] & 15);
22266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hscale = cvRound(font->hscale*XY_ONE);
22276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    vscale = cvRound(font->vscale*XY_ONE);
22286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default_shear = cvRound(font->shear*font->vscale*XY_ONE);
22296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    italic_shear = !(font->font_face & CV_FONT_ITALIC) ? 0 : cvRound(font->vscale*.25*XY_ONE);
22306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    thickness = font->thickness;
22316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    line_type = font->line_type;
22326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
22346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
22356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( top_bottom )
22376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        vscale = -vscale;
22386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    view_x = org.x << XY_SHIFT;
22406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    view_y = (org.y << XY_SHIFT) + base_line*vscale;
22416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; text[i] != '\0'; i++ )
22436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
22446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int c = (uchar)text[i];
22456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int dx, shear = default_shear;
22466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const char* ptr;
22476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint p;
22486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( c > 128 || c < ' ' )
22506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c = '?';
22516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( italic_shear )
22536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
22546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
22556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(font->ascii[0] & CV_FONT_ITALIC_ALPHA) )
22576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    shear += italic_shear;
22586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( '0' <= c && c <= '9' )
22606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(font->ascii[0] & CV_FONT_ITALIC_DIGIT) )
22626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    shear += italic_shear;
22636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( c < 'A' )
22656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(font->ascii[0] & CV_FONT_ITALIC_PUNCT) )
22676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    shear += italic_shear;
22686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
22706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                shear += italic_shear;
22726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
22746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ptr = faces[font->ascii[(c-' ')+1]];
22766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p.x = (unsigned char)ptr[0] - 'R';
22776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p.y = (unsigned char)ptr[1] - 'R';
22786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dx = p.y*hscale;
22796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        view_x -= p.x*hscale;
22806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        count = 0;
22816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ptr += 2;; )
22836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
22846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( *ptr == ' ' || !*ptr )
22856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( count > 1 )
22876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvPolyLine( mat, pt, count, 0, buf, thickness, line_type, XY_SHIFT );
22886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !*ptr++ )
22896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
22906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                count = 0;
22916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
22936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p.x = (unsigned char)ptr[0] - 'R';
22956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                p.y = (unsigned char)ptr[1] - 'R';
22966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += 2;
22976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt[count].x = p.x*hscale - p.y*shear + view_x;
22986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt[count++].y = p.y*vscale + view_y;
22996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
23006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
23016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        view_x += dx;
23026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
23036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
23056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
23066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
23086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvInitFont( CvFont *font, int font_face, double hscale, double vscale,
23096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double shear, int thickness, int line_type )
23106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
23116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvInitFont" );
23126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
23146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int is_italic = font_face & CV_FONT_ITALIC;
23166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !font )
23186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
23196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( hscale <= 0 || vscale <= 0 || thickness < 0 )
23216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
23226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch( (font_face & 7) )
23246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
23256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_SIMPLEX:
23266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = icvHersheySimplex;
23276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_PLAIN:
23296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = !is_italic ? icvHersheyPlain : icvHersheyPlainItalic;
23306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_DUPLEX:
23326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = icvHersheyDuplex;
23336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_COMPLEX:
23356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = !is_italic ? icvHersheyComplex : icvHersheyComplexItalic;
23366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_TRIPLEX:
23386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = !is_italic ? icvHersheyTriplex : icvHersheyTriplexItalic;
23396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_COMPLEX_SMALL:
23416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = !is_italic ? icvHersheyComplexSmall : icvHersheyComplexSmallItalic;
23426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_SCRIPT_SIMPLEX:
23446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = icvHersheyScriptSimplex;
23456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_FONT_HERSHEY_SCRIPT_COMPLEX:
23476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        font->ascii = icvHersheyScriptComplex;
23486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
23496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
23506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "Unknown font type" );
23516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
23526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->font_face = font_face;
23546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->hscale = (float)hscale;
23556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->vscale = (float)vscale;
23566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->thickness = thickness;
23576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->shear = (float)shear;
23586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->greek = font->cyrillic = 0;
23596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    font->line_type = line_type;
23606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
23626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
23636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
23666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetTextSize( const char *text, const CvFont *font, CvSize *size, int *_base_line )
23676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
23686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvGetTextSize" );
23696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
23716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float view_x = 0;
23736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int base_line, cap_line;
23746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
23766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const char **faces = icvHersheyGlyphs;
23776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !text || !font || !font->ascii || !size )
23796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNullPtr, "" );
23806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    base_line = (font->ascii[0] & 15);
23826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cap_line = (font->ascii[0] >> 4) & 15;
23836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( _base_line )
23846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *_base_line = cvRound(base_line*font->vscale);
23856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size->height = cvRound((cap_line + base_line)*font->vscale + font->thickness);
23866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; text[i] != '\0'; i++ )
23886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
23896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int c = (uchar)text[i];
23906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const char* ptr;
23916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvPoint p;
23926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( c > 128 || c < ' ' )
23946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            c = '?';
23956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ptr = faces[font->ascii[(c-' ')+1]];
23976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p.x = (unsigned char)ptr[0] - 'R';
23986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        p.y = (unsigned char)ptr[1] - 'R';
23996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        view_x += (p.y - p.x)*font->hscale;
24006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
24016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size->width = cvRound(view_x + font->thickness);
24036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
24056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
24066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const CvPoint icvCodeDeltas[8] =
24096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
24106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_ADJUST_EDGE_COUNT( count, seq )  \
24126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ((count) -= ((count) == (seq)->total && !CV_IS_SEQ_CLOSED(seq)))
24136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
24156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvDrawContours( void*  img,  CvSeq*  contour,
24166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvScalar externalColor, CvScalar holeColor,
24176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int  maxLevel, int thickness,
24186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int line_type, CvPoint offset )
24196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
24206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeq *contour0 = contour, *h_next = 0;
24216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMemStorage* st = 0;
24226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeq* tseq = 0;
24236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvContour* edges = 0;
24246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSeqWriter writer;
24256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvTreeNodeIterator iterator;
24266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvDrawContours" );
24286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
24306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int coi = 0;
24326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)img;
24336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double ext_buf[4], hole_buf[4];
24346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( mat, &stub, &coi ));
24366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( line_type == CV_AA && CV_MAT_DEPTH(mat->type) != CV_8U )
24386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        line_type = 8;
24396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !contour )
24416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        EXIT;
24426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( coi != 0 )
24446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadCOI, cvUnsupportedFormat );
24456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness < -1 || thickness > 255 )
24476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsOutOfRange, "" );
24486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &externalColor, ext_buf, mat->type, 0 ));
24506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( cvScalarToRawData( &holeColor, hole_buf, mat->type, 0 ));
24516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( maxLevel < 0 )
24536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
24546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        h_next = contour->h_next;
24556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        contour->h_next = 0;
24566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        maxLevel = -maxLevel+1;
24576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
24586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness < 0 )
24606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
24616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( contour->storage )
24626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            st = cvCreateChildMemStorage( contour->storage );
24636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
24646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            st = cvCreateMemStorage( CV_DRAWING_STORAGE_BLOCK );
24656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        tseq = cvCreateSeq( 0, sizeof(CvContour), sizeof(CvPoint), st );
24666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        edges = (CvContour*)cvCreateSeq( 0, sizeof(CvContour), sizeof(CvPolyEdge), st );
24676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
24686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( &writer, 0, sizeof(writer));
24706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvInitTreeNodeIterator( &iterator, contour, maxLevel );
24726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( (contour = (CvSeq*)cvNextTreeNode( &iterator )) != 0 )
24746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
24756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSeqReader reader;
24766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i, count = contour->total;
24776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int elem_type = CV_MAT_TYPE(contour->flags);
24786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        void* clr = (contour->flags & CV_SEQ_FLAG_HOLE) == 0 ? ext_buf : hole_buf;
24796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvStartReadSeq( contour, &reader, 0 );
24816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_IS_SEQ_CHAIN_CONTOUR( contour ))
24836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
24846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvPoint pt = ((CvChain*)contour)->origin;
24856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvPoint prev_pt = pt;
24866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            char prev_code = reader.ptr ? reader.ptr[0] : '\0';
24876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( thickness < 0 )
24896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
24906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvClearSeq( tseq );
24916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvStartAppendToSeq( tseq, &writer );
24926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_WRITE_SEQ_ELEM( pt, writer );
24936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
24946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev_pt.x += offset.x;
24966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev_pt.y += offset.y;
24976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < count; i++ )
24996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
25006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                char code;
25016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_READ_SEQ_ELEM( code, reader );
25026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( (code & ~7) == 0 );
25046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( code != prev_code )
25066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
25076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev_code = code;
25086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( thickness >= 0 )
25096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
25106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvThickLine( mat, prev_pt, pt, clr, thickness, line_type, 2, 0 );
25116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
25126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
25136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
25146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_WRITE_SEQ_ELEM( pt, writer );
25156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
25166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    prev_pt = pt;
25176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
25186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt.x += icvCodeDeltas[(int)code].x;
25206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                pt.y += icvCodeDeltas[(int)code].y;
25216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
25226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( thickness >= 0 )
25246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
25256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvThickLine( mat, prev_pt, ((CvChain*)contour)->origin,
25266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              clr, thickness, line_type, 2, 0 );
25276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
25286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
25296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
25306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_WRITE_SEQ_ELEM( pt, writer );
25316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvEndWriteSeq( &writer );
25326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_CALL( icvCollectPolyEdges( mat, tseq, edges, ext_buf, line_type, 0 ));
25336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
25346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
25356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( CV_IS_SEQ_POLYLINE( contour ))
25366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
25376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( thickness >= 0 )
25386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
25396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvPoint pt1, pt2;
25406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int shift = 0;
25416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                count -= !CV_IS_SEQ_CLOSED(contour);
25436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( elem_type == CV_32SC2 )
25446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
25456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_READ_SEQ_ELEM( pt1, reader );
25466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    pt1.x += offset.x;
25476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    pt1.y += offset.y;
25486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
25496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
25506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
25516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvPoint2D32f pt1f;
25526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_READ_SEQ_ELEM( pt1f, reader );
25536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    pt1.x = cvRound( (pt1f.x + offset.x) * XY_ONE );
25546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    pt1.y = cvRound( (pt1f.y + offset.y) * XY_ONE );
25556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    shift = XY_SHIFT;
25566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
25576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < count; i++ )
25596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
25606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( elem_type == CV_32SC2 )
25616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
25626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_READ_SEQ_ELEM( pt2, reader );
25636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        pt2.x += offset.x;
25646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        pt2.y += offset.y;
25656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
25666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
25676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
25686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvPoint2D32f pt2f;
25696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_READ_SEQ_ELEM( pt2f, reader );
25706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        pt2.x = cvRound( pt2f.x * XY_ONE );
25716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        pt2.y = cvRound( pt2f.y * XY_ONE );
25726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
25736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvThickLine( mat, pt1, pt2, clr, thickness, line_type, 2, shift );
25746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    pt1 = pt2;
25756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
25766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
25776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
25786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
25796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_CALL( icvCollectPolyEdges( mat, contour, edges, ext_buf, line_type, 0, offset ));
25806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
25816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
25826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
25836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( thickness < 0 )
25856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
25866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvFillEdgeCollection( mat, edges, ext_buf ));
25876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
25886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
25906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( h_next && contour0 )
25926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        contour0->h_next = h_next;
25936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvReleaseMemStorage( &st );
25956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
25966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
2598