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 ICV_FREE_PTR(storage) \ 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((schar*)(storage)->top + (storage)->block_size - (storage)->free_space) 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_ALIGNED_SEQ_BLOCK_SIZE \ 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (int)cvAlign(sizeof(CvSeqBlock), CV_STRUCT_ALIGN) 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_INLINE int 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvAlignLeft( int size, int align ) 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return size & -align; 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_GET_LAST_ELEM( seq, block ) \ 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((block)->data + ((block)->count - 1)*((seq)->elem_size)) 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_SWAP_ELEMS(a,b,elem_size) \ 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ \ 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k; \ 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < elem_size; k++ ) \ 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { \ 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char t0 = (a)[k]; \ 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char t1 = (b)[k]; \ 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (a)[k] = t1; \ 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (b)[k] = t0; \ 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } \ 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_SHIFT_TAB_MAX 32 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const schar icvPower2ShiftTab[] = 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, 4, 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}; 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Functions for manipulating memory storage - list of memory blocks * 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Initialize allocated storage: */ 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvInitMemStorage( CvMemStorage* storage, int block_size ) 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "icvInitMemStorage " ); 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block_size <= 0 ) 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = CV_STORAGE_BLOCK_SIZE; 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = cvAlign( block_size, CV_STRUCT_ALIGN ); 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( sizeof(CvMemBlock) % CV_STRUCT_ALIGN == 0 ); 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( storage, 0, sizeof( *storage )); 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->signature = CV_STORAGE_MAGIC_VAL; 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->block_size = block_size; 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Create root memory storage: */ 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvMemStorage* 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateMemStorage( int block_size ) 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage *storage = 0; 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreateMemStorage" ); 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( storage = (CvMemStorage *)cvAlloc( sizeof( CvMemStorage ))); 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvInitMemStorage( storage, block_size )); 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 ) 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &storage ); 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return storage; 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Create child memory storage: */ 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvMemStorage * 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateChildMemStorage( CvMemStorage * parent ) 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage *storage = 0; 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreateChildMemStorage" ); 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !parent ) 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( storage = cvCreateMemStorage(parent->block_size)); 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->parent = parent; 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 ) 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &storage ); 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return storage; 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Release all blocks of the storage (or return them to parent, if any): */ 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDestroyMemStorage( CvMemStorage* storage ) 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "icvDestroyMemStorage" ); 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k = 0; 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemBlock *block; 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemBlock *dst_top = 0; 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->parent ) 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst_top = storage->parent->top; 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( block = storage->bottom; block != 0; k++ ) 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemBlock *temp = block; 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->parent ) 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( dst_top ) 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp->prev = dst_top; 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp->next = dst_top->next; 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( temp->next ) 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp->next->prev = temp; 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst_top = dst_top->next = temp; 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst_top = storage->parent->bottom = storage->parent->top = temp; 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp->prev = temp->next = 0; 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = storage->block_size - sizeof( *temp ); 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &temp ); 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top = storage->bottom = 0; 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = 0; 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Release memory storage: */ 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvReleaseMemStorage( CvMemStorage** storage ) 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage *st; 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvReleaseMemStorage" ); 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn st = *storage; 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *storage = 0; 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( st ) 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvDestroyMemStorage( st )); 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &st ); 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Clears memory storage (return blocks to the parent, if any): */ 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvClearMemStorage( CvMemStorage * storage ) 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvClearMemStorage" ); 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->parent ) 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDestroyMemStorage( storage ); 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top = storage->bottom; 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = storage->bottom ? storage->block_size - sizeof(CvMemBlock) : 0; 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Moves stack pointer to next block. 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn If no blocks, allocate new one and link it to the storage: */ 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvGoNextMemBlock( CvMemStorage * storage ) 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "icvGoNextMemBlock" ); 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage->top || !storage->top->next ) 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemBlock *block; 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(storage->parent) ) 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( block = (CvMemBlock *)cvAlloc( storage->block_size )); 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage *parent = storage->parent; 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStoragePos parent_pos; 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSaveMemStoragePos( parent, &parent_pos ); 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGoNextMemBlock( parent )); 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = parent->top; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvRestoreMemStoragePos( parent, &parent_pos ); 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block == parent->top ) /* the single allocated block */ 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( parent->bottom == block ); 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent->top = parent->bottom = 0; 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent->free_space = 0; 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* cut the block from the parent's list of blocks */ 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent->top->next = block->next; 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block->next ) 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->next->prev = parent->top; 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* link block */ 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->next = 0; 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev = storage->top; 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->top ) 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top->next = block; 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top = storage->bottom = block; 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->top->next ) 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top = storage->top->next; 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = storage->block_size - sizeof(CvMemBlock); 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( storage->free_space % CV_STRUCT_ALIGN == 0 ); 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remember memory storage position: */ 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSaveMemStoragePos( const CvMemStorage * storage, CvMemStoragePos * pos ) 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSaveMemStoragePos" ); 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage || !pos ) 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pos->top = storage->top; 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pos->free_space = storage->free_space; 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Restore memory storage position: */ 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos ) 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvRestoreMemStoragePos" ); 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage || !pos ) 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pos->free_space > storage->block_size ) 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // this breaks icvGoNextMemBlock, so comment it off for now 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->parent && (!pos->top || pos->top->next) ) 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemBlock* save_bottom; 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !pos->top ) 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn save_bottom = 0; 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn save_bottom = storage->bottom; 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->bottom = pos->top->next; 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pos->top->next = 0; 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->bottom->prev = 0; 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDestroyMemStorage( storage ); 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->bottom = save_bottom; 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn }*/ 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top = pos->top; 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = pos->free_space; 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage->top ) 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->top = storage->bottom; 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = storage->top ? storage->block_size - sizeof(CvMemBlock) : 0; 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Allocate continuous buffer of the specified size in the storage: */ 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void* 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMemStorageAlloc( CvMemStorage* storage, size_t size ) 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *ptr = 0; 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvMemStorageAlloc" ); 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL storage pointer" ); 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( size > INT_MAX ) 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "Too large memory block is requested" ); 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( storage->free_space % CV_STRUCT_ALIGN == 0 ); 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (size_t)storage->free_space < size ) 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size_t max_free_space = cvAlignLeft(storage->block_size - sizeof(CvMemBlock), CV_STRUCT_ALIGN); 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_free_space < size ) 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "requested size is negative or too big" ); 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGoNextMemBlock( storage )); 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = ICV_FREE_PTR(storage); 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( (size_t)ptr % CV_STRUCT_ALIGN == 0 ); 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = cvAlignLeft(storage->free_space - (int)size, CV_STRUCT_ALIGN ); 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ptr; 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvString 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len ) 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvString str; 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvMemStorageAllocString" ); 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn str.len = len >= 0 ? len : (int)strlen(ptr); 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( str.ptr = (char*)cvMemStorageAlloc( storage, str.len + 1 )); 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( str.ptr, ptr, str.len ); 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn str.ptr[str.len] = '\0'; 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return str; 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Sequence implementation * 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Create empty sequence: */ 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSeq * 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateSeq( int seq_flags, int header_size, int elem_size, CvMemStorage * storage ) 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq *seq = 0; 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreateSeq" ); 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( header_size < (int)sizeof( CvSeq ) || elem_size <= 0 ) 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* allocate sequence header */ 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( seq = (CvSeq*)cvMemStorageAlloc( storage, header_size )); 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( seq, 0, header_size ); 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->header_size = header_size; 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->flags = (seq_flags & ~CV_MAGIC_MASK) | CV_SEQ_MAGIC_VAL; 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elemtype = CV_MAT_TYPE(seq_flags); 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int typesize = CV_ELEM_SIZE(elemtype); 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elemtype != CV_SEQ_ELTYPE_GENERIC && 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn typesize != 0 && typesize != elem_size ) 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "Specified element size doesn't match to the size of the specified element type " 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "(try to use 0 for element type)" ); 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->elem_size = elem_size; 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->storage = storage; 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvSetSeqBlockSize( seq, (1 << 10)/elem_size )); 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return seq; 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* adjusts <delta_elems> field of sequence. It determines how much the sequence 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn grows if there are no free space inside the sequence buffers */ 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSetSeqBlockSize( CvSeq *seq, int delta_elements ) 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int useful_block_size; 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSetSeqBlockSize" ); 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !seq->storage ) 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta_elements < 0 ) 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "" ); 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn useful_block_size = cvAlignLeft(seq->storage->block_size - sizeof(CvMemBlock) - 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(CvSeqBlock), CV_STRUCT_ALIGN); 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta_elements == 0 ) 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_elements = (1 << 10) / elem_size; 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_elements = MAX( delta_elements, 1 ); 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta_elements * elem_size > useful_block_size ) 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_elements = useful_block_size / elem_size; 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta_elements == 0 ) 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "Storage block size is too small " 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "to fit the sequence elements" ); 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->delta_elems = delta_elements; 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Find a sequence element by its index: */ 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL schar* 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetSeqElem( const CvSeq *seq, int index ) 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count, total = seq->total; 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)index >= (unsigned)total ) 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += index < 0 ? total : 0; 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= index >= total ? total : 0; 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)index >= (unsigned)total ) 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return 0; 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index + index <= total ) 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( index >= (count = block->count) ) 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= count; 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->prev; 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total -= block->count; 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( index < total ); 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= total; 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return block->data + index * seq->elem_size; 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calculate index of a sequence element: */ 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqElemIdx( const CvSeq* seq, const void* _element, CvSeqBlock** _block ) 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const schar *element = (const schar *)_element; 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int id = -1; 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *first_block; 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqElemIdx" ); 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !element ) 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = first_block = seq->first; 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ;; ) 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)(element - block->data) < (unsigned) (block->count * elem_size) ) 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _block ) 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *_block = block; 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elem_size <= ICV_SHIFT_TAB_MAX && (id = icvPower2ShiftTab[elem_size - 1]) >= 0 ) 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn id = (int)((size_t)(element - block->data) >> id); 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn id = (int)((size_t)(element - block->data) / elem_size); 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn id += block->start_index - seq->first->start_index; 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block == first_block ) 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return id; 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSliceLength( CvSlice slice, const CvSeq* seq ) 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total = seq->total; 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int length = slice.end_index - slice.start_index; 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( length != 0 ) 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( slice.start_index < 0 ) 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.start_index += total; 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( slice.end_index <= 0 ) 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.end_index += total; 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length = slice.end_index - slice.start_index; 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( length < 0 ) 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length += total; 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*if( length < 0 ) 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length += total;*/ 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( length > total ) 6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length = total; 6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return length; 6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Copy all sequence elements into single continuous array: */ 6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void* 6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCvtSeqToArray( const CvSeq *seq, void *array, CvSlice slice ) 6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCvtSeqToArray" ); 6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size, total; 6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char *dst = (char*)array; 6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !array ) 6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = cvSliceLength( slice, seq )*elem_size; 6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( total == 0 ) 6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader, 0 ); 6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvSetSeqReaderPos( &reader, slice.start_index, 0 )); 6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = (int)(reader.block_max - reader.ptr); 6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count > total ) 6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = total; 6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( dst, reader.ptr, count ); 6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst += count; 6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader.block = reader.block->next; 6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader.ptr = reader.block->data; 6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader.block_max = reader.ptr + reader.block->count*elem_size; 6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total -= count; 6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( total > 0 ); 6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return array; 6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Construct a sequence from an array without copying any data. 6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn NB: The resultant sequence cannot grow beyond its initial size: */ 6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSeq* 6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, 6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void *array, int total, CvSeq *seq, CvSeqBlock * block ) 6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* result = 0; 6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvMakeSeqHeaderForArray" ); 6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elem_size <= 0 || header_size < (int)sizeof( CvSeq ) || total < 0 ) 6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || ((!array || !block) && total > 0) ) 6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( seq, 0, header_size ); 7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->header_size = header_size; 7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->flags = (seq_flags & ~CV_MAGIC_MASK) | CV_SEQ_MAGIC_VAL; 7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elemtype = CV_MAT_TYPE(seq_flags); 7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int typesize = CV_ELEM_SIZE(elemtype); 7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elemtype != CV_SEQ_ELTYPE_GENERIC && 7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn typesize != 0 && typesize != elem_size ) 7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, 7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "Element size doesn't match to the size of predefined element type " 7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "(try to use 0 for sequence element type)" ); 7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->elem_size = elem_size; 7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total = total; 7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max = seq->ptr = (schar *) array + total * elem_size; 7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( total > 0 ) 7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first = block; 7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev = block->next = block; 7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index = 0; 7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = total; 7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data = (schar *) array; 7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = seq; 7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* The function allocates space for at least one more sequence element. 7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn If there are free sequence blocks (seq->free_blocks != 0) 7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn they are reused, otherwise the space is allocated in the storage: */ 7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvGrowSeq( CvSeq *seq, int in_front_of ) 7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "icvGrowSeq" ); 7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->free_blocks; 7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !block ) 7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size = seq->elem_size; 7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta_elems = seq->delta_elems; 7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage *storage = seq->storage; 7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->total >= delta_elems*4 ) 7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqBlockSize( seq, delta_elems*2 ); 7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "The sequence has NULL storage pointer" ); 7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* If there is a free space just after last allocated block 7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn and it is big enough then enlarge the last block. 7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn This can happen only if the new block is added to the end of sequence: */ 7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)(ICV_FREE_PTR(storage) - seq->block_max) < CV_STRUCT_ALIGN && 7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space >= seq->elem_size && !in_front_of ) 7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = storage->free_space / elem_size; 7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = MIN( delta, delta_elems ) * elem_size; 7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max += delta; 7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = cvAlignLeft((int)(((schar*)storage->top + storage->block_size) - 7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max), CV_STRUCT_ALIGN ); 7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = elem_size * delta_elems + ICV_ALIGNED_SEQ_BLOCK_SIZE; 7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Try to allocate <delta_elements> elements: */ 7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->free_space < delta ) 7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int small_block_size = MAX(1, delta_elems/3)*elem_size + 7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ICV_ALIGNED_SEQ_BLOCK_SIZE; 7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* try to allocate smaller part */ 7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( storage->free_space >= small_block_size + CV_STRUCT_ALIGN ) 7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = (storage->free_space - ICV_ALIGNED_SEQ_BLOCK_SIZE)/seq->elem_size; 7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = delta*seq->elem_size + ICV_ALIGNED_SEQ_BLOCK_SIZE; 7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGoNextMemBlock( storage )); 7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( storage->free_space >= delta ); 7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( block = (CvSeqBlock*)cvMemStorageAlloc( storage, delta )); 8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data = (schar*)cvAlignPtr( block + 1, CV_STRUCT_ALIGN ); 8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = delta - ICV_ALIGNED_SEQ_BLOCK_SIZE; 8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev = block->next = 0; 8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->free_blocks = block->next; 8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(seq->first) ) 8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first = block; 8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev = block->next = block; 8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev = seq->first->prev; 8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->next = seq->first; 8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev->next = block->next->prev = block; 8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* For free blocks the <count> field means 8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * total number of bytes in the block. 8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * 8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * For used blocks it means current number 8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * of sequence elements in the block: 8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( block->count % seq->elem_size == 0 && block->count > 0 ); 8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !in_front_of ) 8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = block->data; 8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max = block->data + block->count; 8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index = block == block->prev ? 0 : 8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev->start_index + block->prev->count; 8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = block->count / seq->elem_size; 8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data += block->count; 8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block != block->prev ) 8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( seq->first->start_index == 0 ); 8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first = block; 8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max = seq->ptr = block->data; 8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index = 0; 8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ;; ) 8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index += delta; 8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block == seq->first ) 8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = 0; 8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Recycle a sequence block: */ 8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvFreeSeqBlock( CvSeq *seq, int in_front_of ) 8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*CV_FUNCNAME( "icvFreeSeqBlock" );*/ 8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block = seq->first; 8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( (in_front_of ? block : block->prev)->count == 0 ); 8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block == block->prev ) /* single block case */ 8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = (int)(seq->block_max - block->data) + block->start_index * seq->elem_size; 8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data = seq->block_max - block->count; 8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first = 0; 8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = seq->block_max = 0; 8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total = 0; 8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !in_front_of ) 8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->prev; 8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( seq->ptr == block->data ); 8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = (int)(seq->block_max - seq->ptr); 8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max = seq->ptr = block->prev->data + 8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev->count * seq->elem_size; 8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = block->start_index; 9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = delta * seq->elem_size; 9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data -= block->count; 9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Update start indices of sequence blocks: */ 9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ;; ) 9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index -= delta; 9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block == seq->first ) 9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first = block->next; 9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev->next = block->next; 9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->next->prev = block->prev; 9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( block->count > 0 && block->count % seq->elem_size == 0 ); 9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->next = seq->free_blocks; 9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->free_blocks = block; 9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Sequence Writer implementation * 9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Initialize sequence writer: */ 9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvStartAppendToSeq( CvSeq *seq, CvSeqWriter * writer ) 9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvStartAppendToSeq" ); 9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !writer ) 9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( writer, 0, sizeof( *writer )); 9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->header_size = sizeof( CvSeqWriter ); 9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->seq = seq; 9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->block = seq->first ? seq->first->prev : 0; 9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->ptr = seq->ptr; 9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->block_max = seq->block_max; 9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Initialize sequence writer: */ 9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvStartWriteSeq( int seq_flags, int header_size, 9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size, CvMemStorage * storage, CvSeqWriter * writer ) 9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq *seq = 0; 9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvStartWriteSeq" ); 9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage || !writer ) 9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( seq = cvCreateSeq( seq_flags, header_size, elem_size, storage )); 9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartAppendToSeq( seq, writer ); 9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Update sequence header: */ 9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFlushSeqWriter( CvSeqWriter * writer ) 9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq *seq = 0; 9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvFlushSeqWriter" ); 9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !writer ) 9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq = writer->seq; 9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = writer->ptr; 9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( writer->block ) 9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total = 0; 9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *first_block = writer->seq->first; 9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block = first_block; 9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->block->count = (int)((writer->ptr - writer->block->data) / seq->elem_size); 10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( writer->block->count > 0 ); 10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total += block->count; 10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( block != first_block ); 10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->seq->total = total; 10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calls icvFlushSeqWriter and finishes writing process: */ 10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSeq * 10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEndWriteSeq( CvSeqWriter * writer ) 10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq *seq = 0; 10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvEndWriteSeq" ); 10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !writer ) 10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvFlushSeqWriter( writer )); 10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq = writer->seq; 10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Truncate the last block: */ 10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( writer->block && writer->seq->storage ) 10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage *storage = seq->storage; 10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *storage_block_max = (schar *) storage->top + storage->block_size; 10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( writer->block->count > 0 ); 10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)((storage_block_max - storage->free_space) 10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn - seq->block_max) < CV_STRUCT_ALIGN ) 10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage->free_space = cvAlignLeft((int)(storage_block_max - seq->ptr), CV_STRUCT_ALIGN); 10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->block_max = seq->ptr; 10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->ptr = 0; 10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return seq; 10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Create new sequence block: */ 10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateSeqBlock( CvSeqWriter * writer ) 10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreateSeqBlock" ); 10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq *seq; 10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !writer || !writer->seq ) 10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq = writer->seq; 10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFlushSeqWriter( writer ); 10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 0 )); 10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->block = seq->first->prev; 10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->ptr = seq->ptr; 10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn writer->block_max = seq->block_max; 10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Sequence Reader implementation * 10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Initialize sequence reader: */ 10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvStartReadSeq( const CvSeq *seq, CvSeqReader * reader, int reverse ) 10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *first_block; 10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *last_block; 10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvStartReadSeq" ); 10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( reader ) 10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->seq = 0; 11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = 0; 11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = reader->block_max = reader->block_min = 0; 11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !reader ) 11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->header_size = sizeof( CvSeqReader ); 11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->seq = (CvSeq*)seq; 11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn first_block = seq->first; 11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( first_block ) 11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn last_block = first_block->prev; 11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = first_block->data; 11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->prev_elem = CV_GET_LAST_ELEM( seq, last_block ); 11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->delta_index = seq->first->start_index; 11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( reverse ) 11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *temp = reader->ptr; 11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = reader->prev_elem; 11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->prev_elem = temp; 11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = last_block; 11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = first_block; 11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_min = reader->block->data; 11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_max = reader->block_min + reader->block->count * seq->elem_size; 11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->delta_index = 0; 11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = 0; 11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = reader->prev_elem = reader->block_min = reader->block_max = 0; 11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Change the current reading block 11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * to the previous or to the next: 11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvChangeSeqBlock( void* _reader, int direction ) 11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvChangeSeqBlock" ); 11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader* reader = (CvSeqReader*)_reader; 11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !reader ) 11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( direction > 0 ) 11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = reader->block->next; 11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = reader->block->data; 11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = reader->block->prev; 11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = CV_GET_LAST_ELEM( reader->seq, reader->block ); 11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_min = reader->block->data; 11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_max = reader->block_min + reader->block->count * reader->seq->elem_size; 11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Return the current reader position: */ 11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetSeqReaderPos( CvSeqReader* reader ) 11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int index = -1; 11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGetSeqReaderPos" ); 11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !reader || !reader->ptr ) 11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = reader->seq->elem_size; 11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elem_size <= ICV_SHIFT_TAB_MAX && (index = icvPower2ShiftTab[elem_size - 1]) >= 0 ) 11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index = (int)((reader->ptr - reader->block_min) >> index); 11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index = (int)((reader->ptr - reader->block_min) / elem_size); 12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += reader->block->start_index - reader->delta_index; 12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return index; 12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Set reader position to given position, 12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * either absolute or relative to the 12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * current one: 12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative ) 12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSetSeqReaderPos" ); 12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size, count, total; 12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !reader || !reader->seq ) 12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = reader->seq->total; 12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = reader->seq->elem_size; 12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_relative ) 12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index < 0 ) 12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index < -total ) 12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "" ); 12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += total; 12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( index >= total ) 12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= total; 12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index >= total ) 12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "" ); 12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = reader->seq->first; 12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index >= (count = block->count) ) 12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index + index <= total ) 12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= count; 12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( index >= (count = block->count) ); 12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->prev; 12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total -= block->count; 12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( index < total ); 12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= total; 12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = block->data + index * elem_size; 12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( reader->block != block ) 12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = block; 12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_min = block->data; 12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_max = block->data + block->count * elem_size; 12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* ptr = reader->ptr; 12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index *= elem_size; 12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = reader->block; 12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index > 0 ) 12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ptr + index >= reader->block_max ) 12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = (int)(reader->block_max - ptr); 12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= delta; 12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = block = block->next; 12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_min = ptr = block->data; 12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_max = block->data + block->count*elem_size; 12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = ptr + index; 12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ptr + index < reader->block_min ) 12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = (int)(ptr - reader->block_min); 12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += delta; 13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block = block = block->prev; 13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_min = block->data; 13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->block_max = ptr = block->data + block->count*elem_size; 13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader->ptr = ptr + index; 13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Push element onto the sequence: */ 13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL schar* 13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPush( CvSeq *seq, void *element ) 13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *ptr = 0; 13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size_t elem_size; 13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPush" ); 13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = seq->ptr; 13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ptr >= seq->block_max ) 13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 0 )); 13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = seq->ptr; 13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( ptr + elem_size <= seq->block_max /*&& ptr == seq->block_min */ ); 13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( ptr, element, elem_size ); 13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first->prev->count++; 13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total++; 13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = ptr + elem_size; 13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ptr; 13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Pop last element off of the sequence: */ 13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPop( CvSeq *seq, void *element ) 13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *ptr; 13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPop" ); 13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->total <= 0 ) 13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = ptr = seq->ptr - elem_size; 13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( element, ptr, elem_size ); 13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = ptr; 13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total--; 13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( --(seq->first->prev->count) == 0 ) 13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvFreeSeqBlock( seq, 0 ); 13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( seq->ptr == seq->block_max ); 13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Push element onto the front of the sequence: */ 13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL schar* 13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPushFront( CvSeq *seq, void *element ) 13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* ptr = 0; 13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPushFront" ); 13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !block || block->start_index == 0 ) 14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 1 )); 14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( block->start_index > 0 ); 14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = block->data -= elem_size; 14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( ptr, element, elem_size ); 14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count++; 14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index--; 14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total++; 14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ptr; 14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Shift out first element of the sequence: */ 14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPopFront( CvSeq *seq, void *element ) 14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPopFront" ); 14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->total <= 0 ) 14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( element, block->data, elem_size ); 14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data += elem_size; 14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index++; 14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total--; 14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( --(block->count) == 0 ) 14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvFreeSeqBlock( seq, 1 ); 14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Insert new element in middle of sequence: */ 14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL schar* 14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqInsert( CvSeq *seq, int before_index, void *element ) 14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int block_size; 14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta_index; 14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total; 14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* ret_ptr = 0; 14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqInsert" ); 14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn before_index += before_index < 0 ? total : 0; 14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn before_index -= before_index > total ? total : 0; 14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)before_index > (unsigned)total ) 14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "" ); 14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( before_index == total ) 14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ret_ptr = cvSeqPush( seq, element )); 14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( before_index == 0 ) 14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ret_ptr = cvSeqPushFront( seq, element )); 14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( before_index >= total >> 1 ) 14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *ptr = seq->ptr + elem_size; 14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ptr > seq->block_max ) 14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 0 )); 15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = seq->ptr + elem_size; 15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( ptr <= seq->block_max ); 15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_index = seq->first->start_index; 15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first->prev; 15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count++; 15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = (int)(ptr - block->data); 15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( before_index < block->start_index - delta_index ) 15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *prev_block = block->prev; 15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( block->data + elem_size, block->data, block_size - elem_size ); 15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = prev_block->count * elem_size; 15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( block->data, prev_block->data + block_size - elem_size, elem_size ); 15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = prev_block; 15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Check that we don't fall into an infinite loop: */ 15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( block != seq->first->prev ); 15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn before_index = (before_index - block->start_index + delta_index) * elem_size; 15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( block->data + before_index + elem_size, block->data + before_index, 15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size - before_index - elem_size ); 15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ret_ptr = block->data + before_index; 15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( ret_ptr, element, elem_size ); 15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr = ptr; 15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( block->start_index == 0 ) 15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 1 )); 15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_index = block->start_index; 15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count++; 15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index--; 15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data -= elem_size; 15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( before_index > block->start_index - delta_index + block->count ) 15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *next_block = block->next; 15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = block->count * elem_size; 15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( block->data, block->data + elem_size, block_size - elem_size ); 15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( block->data + block_size - elem_size, next_block->data, elem_size ); 15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = next_block; 15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Check that we don't fall into an infinite loop: */ 15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( block != seq->first ); 15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn before_index = (before_index - block->start_index + delta_index) * elem_size; 15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( block->data, block->data + elem_size, before_index - elem_size ); 15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ret_ptr = block->data + before_index - elem_size; 15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( ret_ptr, element, elem_size ); 15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total = total + 1; 15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return ret_ptr; 15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Removes element from sequence: */ 15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqRemove( CvSeq *seq, int index ) 15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *ptr; 15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int block_size; 15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block; 15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta_index; 15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total, front = 0; 15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqRemove" ); 15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += index < 0 ? total : 0; 16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= index >= total ? total : 0; 16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned) index >= (unsigned) total ) 16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "Invalid index" ); 16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index == total - 1 ) 16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPop( seq, 0 ); 16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( index == 0 ) 16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPopFront( seq, 0 ); 16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta_index = block->start_index; 16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( block->start_index - delta_index + block->count <= index ) 16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = block->next; 16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = block->data + (index - block->start_index + delta_index) * elem_size; 16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn front = index < total >> 1; 16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !front ) 16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = block->count * elem_size - (int)(ptr - block->data); 16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( block != seq->first->prev ) /* while not the last block */ 16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *next_block = block->next; 16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( ptr, ptr + elem_size, block_size - elem_size ); 16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( ptr + block_size - elem_size, next_block->data, elem_size ); 16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = next_block; 16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = block->data; 16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = block->count * elem_size; 16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( ptr, ptr + elem_size, block_size - elem_size ); 16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr -= elem_size; 16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr += elem_size; 16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = (int)(ptr - block->data); 16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( block != seq->first ) 16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *prev_block = block->prev; 16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( block->data + elem_size, block->data, block_size - elem_size ); 16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block_size = prev_block->count * elem_size; 16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( block->data, prev_block->data + block_size - elem_size, elem_size ); 16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = prev_block; 16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memmove( block->data + elem_size, block->data, block_size - elem_size ); 16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data += elem_size; 16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index++; 16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total = total - 1; 16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( --block->count == 0 ) 16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvFreeSeqBlock( seq, front ); 16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Add several elements to the beginning or end of a sequence: */ 16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPushMulti( CvSeq *seq, void *_elements, int count, int front ) 16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char *elements = (char *) _elements; 16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPushMulti" ); 16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL sequence pointer" ); 16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count < 0 ) 16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "number of removed elements is negative" ); 16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !front ) 16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( count > 0 ) 16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = (int)((seq->block_max - seq->ptr) / elem_size); 16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = MIN( delta, count ); 16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta > 0 ) 16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first->prev->count += delta; 17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total += delta; 17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count -= delta; 17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta *= elem_size; 17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elements ) 17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( seq->ptr, elements, delta ); 17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elements += delta; 17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr += delta; 17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count > 0 ) 17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 0 )); 17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock* block = seq->first; 17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( count > 0 ) 17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta; 17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !block || block->start_index == 0 ) 17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( seq, 1 )); 17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = seq->first; 17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( block->start_index > 0 ); 17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = MIN( block->start_index, count ); 17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count -= delta; 17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index -= delta; 17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count += delta; 17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total += delta; 17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta *= elem_size; 17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data -= delta; 17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elements ) 17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( block->data, elements + count*elem_size, delta ); 17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove several elements from the end of sequence: */ 17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPopMulti( CvSeq *seq, void *_elements, int count, int front ) 17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn char *elements = (char *) _elements; 17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPopMulti" ); 17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL sequence pointer" ); 17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( count < 0 ) 17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "number of removed elements is negative" ); 17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = MIN( count, seq->total ); 17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !front ) 17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elements ) 17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elements += count * seq->elem_size; 17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( count > 0 ) 17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = seq->first->prev->count; 17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = MIN( delta, count ); 17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( delta > 0 ); 17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first->prev->count -= delta; 17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total -= delta; 17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count -= delta; 17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta *= seq->elem_size; 17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->ptr -= delta; 17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elements ) 17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elements -= delta; 17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( elements, seq->ptr, delta ); 17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->first->prev->count == 0 ) 17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvFreeSeqBlock( seq, 0 ); 17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( count > 0 ) 17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta = seq->first->count; 17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = MIN( delta, count ); 18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( delta > 0 ); 18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first->count -= delta; 18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->total -= delta; 18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count -= delta; 18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first->start_index += delta; 18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta *= seq->elem_size; 18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elements ) 18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( elements, seq->first->data, delta ); 18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elements += delta; 18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn seq->first->data += delta; 18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->first->count == 0 ) 18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvFreeSeqBlock( seq, 1 ); 18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove all elements from a sequence: */ 18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvClearSeq( CvSeq *seq ) 18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvClearSeq" ); 18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPopMulti( seq, 0, seq->total ); 18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSeq* 18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_data ) 18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* subseq = 0; 18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvSeqSlice"); 18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size, count, length; 18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock *block, *first_block = 0, *last_block = 0; 18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(seq) ) 18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Invalid sequence header" ); 18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = seq->storage; 18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL storage pointer" ); 18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length = cvSliceLength( slice, seq ); 18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( slice.start_index < 0 ) 18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.start_index += seq->total; 18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( slice.start_index >= seq->total ) 18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.start_index -= seq->total; 18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)length > (unsigned)seq->total || 18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((unsigned)slice.start_index >= (unsigned)seq->total && length != 0) ) 18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "Bad sequence slice" ); 18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( subseq = cvCreateSeq( seq->flags, seq->header_size, elem_size, storage )); 18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( length > 0 ) 18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader, 0 ); 18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader, slice.start_index, 0 ); 18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = (int)((reader.block_max - reader.ptr)/elem_size); 18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn do 18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int bl = MIN( count, length ); 18846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 18856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !copy_data ) 18866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block = (CvSeqBlock*)cvMemStorageAlloc( storage, sizeof(*block) ); 18886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !first_block ) 18896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn first_block = subseq->first = block->prev = block->next = block; 18916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index = 0; 18926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 18936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 18946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 18956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->prev = last_block; 18966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->next = first_block; 18976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn last_block->next = first_block->prev = block; 18986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->start_index = last_block->start_index + last_block->count; 18996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn last_block = block; 19016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->data = reader.ptr; 19026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn block->count = bl; 19036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn subseq->total += bl; 19046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 19066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPushMulti( subseq, reader.ptr, bl, 0 ); 19076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length -= bl; 19086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader.block = reader.block->next; 19096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn reader.ptr = reader.block->data; 19106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = reader.block->count; 19116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( length > 0 ); 19136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 19166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return subseq; 19186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 19196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Remove slice from the middle of the sequence. 19226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// !!! TODO !!! Implement more efficient algorithm 19236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 19246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) 19256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 19266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvSeqRemoveSlice"); 19276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 19296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total, length; 19316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(seq) ) 19336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Invalid sequence header" ); 19346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn length = cvSliceLength( slice, seq ); 19366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 19376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( slice.start_index < 0 ) 19396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.start_index += total; 19406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( slice.start_index >= total ) 19416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.start_index -= total; 19426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)slice.start_index >= (unsigned)total ) 19446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "start slice index is out of range" ); 19456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn slice.end_index = slice.start_index + length; 19476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( slice.end_index < total ) 19496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader_to, reader_from; 19516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size = seq->elem_size; 19526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader_to ); 19546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader_from ); 19556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( slice.start_index > total - slice.end_index ) 19576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, count = seq->total - slice.end_index; 19596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_to, slice.start_index ); 19606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_from, slice.end_index ); 19616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 19636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size ); 19656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader_to ); 19666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader_from ); 19676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPopMulti( seq, 0, slice.end_index - slice.start_index ); 19706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 19726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, count = slice.start_index; 19746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_to, slice.end_index ); 19756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_from, slice.start_index ); 19766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 19786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, reader_to ); 19806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, reader_from ); 19816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size ); 19836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPopMulti( seq, 0, slice.end_index - slice.start_index, 1 ); 19866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 19896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 19906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPopMulti( seq, 0, total - slice.start_index ); 19916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPopMulti( seq, 0, slice.end_index - total, 1 ); 19926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 19936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 19956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 19966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 19986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Insert a sequence into the middle of another sequence: 19996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// !!! TODO !!! Implement more efficient algorithm 20006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 20016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqInsertSlice( CvSeq* seq, int index, const CvArr* from_arr ) 20026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 20036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader_to, reader_from; 20046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, elem_size, total, from_total; 20056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvSeqInsertSlice"); 20076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 20096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq from_header, *from = (CvSeq*)from_arr; 20116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock block; 20126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(seq) ) 20146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Invalid destination sequence header" ); 20156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(from)) 20176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* mat = (CvMat*)from; 20196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MAT(mat)) 20206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Source is not a sequence nor matrix" ); 20216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MAT_CONT(mat->type) || (mat->rows != 1 && mat->cols != 1) ) 20236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "The source array must be 1d coninuous vector" ); 20246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( from = cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(from_header), 20266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ELEM_SIZE(mat->type), 20276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mat->data.ptr, mat->cols + mat->rows - 1, 20286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &from_header, &block )); 20296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->elem_size != from->elem_size ) 20326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, 20336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "Source and destination sequence element sizes are different." ); 20346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn from_total = from->total; 20366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( from_total == 0 ) 20386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 20396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 20416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += index < 0 ? total : 0; 20426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index -= index > total ? total : 0; 20436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)index > (unsigned)total ) 20456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "" ); 20466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 20486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index < (total >> 1) ) 20506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPushMulti( seq, 0, from_total, 1 ); 20526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader_to ); 20546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader_from ); 20556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_from, from_total ); 20566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < index; i++ ) 20586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size ); 20606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader_to ); 20616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader_from ); 20626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 20656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPushMulti( seq, 0, from_total ); 20676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader_to ); 20696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader_from ); 20706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_from, total ); 20716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_to, seq->total ); 20726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total - index; i++ ) 20746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, reader_to ); 20766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, reader_from ); 20776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size ); 20786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( from, &reader_from ); 20826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &reader_to, index ); 20836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < from_total; i++ ) 20856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 20866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_AUTO( reader_to.ptr, reader_from.ptr, elem_size ); 20876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader_to ); 20886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader_from ); 20896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 20906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 20926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 20936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 20946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Sort the sequence using user-specified comparison function. 20956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// The semantics is similar to qsort() function. 20966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// The code is based on BSD system qsort(): 20976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Copyright (c) 1992, 1993 20986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * The Regents of the University of California. All rights reserved. 20996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * 21006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution and use in source and binary forms, with or without 21016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * modification, are permitted provided that the following conditions 21026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * are met: 21036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * 1. Redistributions of source code must retain the above copyright 21046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * notice, this list of conditions and the following disclaimer. 21056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * 2. Redistributions in binary form must reproduce the above copyright 21066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * notice, this list of conditions and the following disclaimer in the 21076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * documentation and/or other materials provided with the distribution. 21086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * 3. All advertising materials mentioning features or use of this software 21096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * must display the following acknowledgement: 21106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * This product includes software developed by the University of 21116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * California, Berkeley and its contributors. 21126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * 4. Neither the name of the University nor the names of its contributors 21136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * may be used to endorse or promote products derived from this software 21146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * without specific prior written permission. 21156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * 21166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 21266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * SUCH DAMAGE. 21276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvSeqReaderPos 21296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 21306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqBlock* block; 21316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* ptr; 21326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* block_min; 21336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* block_max; 21346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 21356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvSeqReaderPos; 21366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_SAVE_READER_POS( reader, pos ) \ 21386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ \ 21396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (pos).block = (reader).block; \ 21406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (pos).ptr = (reader).ptr; \ 21416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (pos).block_min = (reader).block_min; \ 21426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (pos).block_max = (reader).block_max; \ 21436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 21446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_RESTORE_READER_POS( reader, pos )\ 21466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ \ 21476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (reader).block = (pos).block; \ 21486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (reader).ptr = (pos).ptr; \ 21496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (reader).block_min = (pos).block_min; \ 21506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (reader).block_max = (pos).block_max; \ 21516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 21526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renninline schar* 21546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMed3( schar* a, schar* b, schar* c, CvCmpFunc cmp_func, void* aux ) 21556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 21566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return cmp_func(a, b, aux) < 0 ? 21576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (cmp_func(b, c, aux) < 0 ? b : cmp_func(a, c, aux) < 0 ? c : a) 21586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn :(cmp_func(b, c, aux) > 0 ? b : cmp_func(a, c, aux) < 0 ? a : c); 21596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 21606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 21626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqSort( CvSeq* seq, CvCmpFunc cmp_func, void* aux ) 21636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 21646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 21656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int isort_thresh = 7; 21666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader left, right; 21676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sp = 0; 21686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn struct 21706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 21716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReaderPos lb; 21726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReaderPos ub; 21736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 21746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn stack[48]; 21756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqSort" ); 21776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 21796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(seq) ) 21816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); 21826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !cmp_func ) 21846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "Null compare function" ); 21856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( seq->total <= 1 ) 21876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 21886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 21906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn isort_thresh *= elem_size; 21916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &left, 0 ); 21936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn right = left; 21946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SAVE_READER_POS( left, stack[0].lb ); 21956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, right ); 21966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SAVE_READER_POS( right, stack[0].ub ); 21976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 21986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( sp >= 0 ) 21996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_RESTORE_READER_POS( left, stack[sp].lb ); 22016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_RESTORE_READER_POS( right, stack[sp].ub ); 22026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sp--; 22036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;) 22056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, n, m; 22076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader ptr, ptr2; 22086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( left.block == right.block ) 22106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = (int)(right.ptr - left.ptr) + elem_size; 22116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 22126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = cvGetSeqReaderPos( &right ); 22146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = (n - cvGetSeqReaderPos( &left ) + 1)*elem_size; 22156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n <= isort_thresh ) 22186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn insert_sort: 22206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr = ptr2 = left; 22216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, ptr ); 22226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, right ); 22236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ptr.ptr != right.ptr ) 22246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr2.ptr = ptr.ptr; 22266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ptr2.block != ptr.block ) 22276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr2.block = ptr.block; 22296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr2.block_min = ptr.block_min; 22306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr2.block_max = ptr.block_max; 22316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( ptr2.ptr != left.ptr ) 22336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* cur = ptr2.ptr; 22356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, ptr2 ); 22366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cmp_func( ptr2.ptr, cur, aux ) <= 0 ) 22376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 22386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( ptr2.ptr, cur, elem_size ); 22396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, ptr ); 22416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 22436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 22456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader left0, left1, right0, right1; 22476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader tmp0, tmp1; 22486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *m1, *m2, *m3, *pivot; 22496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int swap_cnt = 0; 22506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int l, l0, l1, r, r0, r1; 22516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left0 = tmp0 = left; 22536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn right0 = right1 = right; 22546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n /= elem_size; 22556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n > 40 ) 22576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int d = n / 8; 22596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *p1, *p2, *p3; 22606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p1 = tmp0.ptr; 22616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, d, 1 ); 22626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p2 = tmp0.ptr; 22636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, d, 1 ); 22646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p3 = tmp0.ptr; 22656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m1 = icvMed3( p1, p2, p3, cmp_func, aux ); 22666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, (n/2) - d*3, 1 ); 22676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p1 = tmp0.ptr; 22686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, d, 1 ); 22696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p2 = tmp0.ptr; 22706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, d, 1 ); 22716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p3 = tmp0.ptr; 22726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m2 = icvMed3( p1, p2, p3, cmp_func, aux ); 22736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, n - 1 - d*3 - n/2, 1 ); 22746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p1 = tmp0.ptr; 22756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, d, 1 ); 22766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p2 = tmp0.ptr; 22776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, d, 1 ); 22786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p3 = tmp0.ptr; 22796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m3 = icvMed3( p1, p2, p3, cmp_func, aux ); 22806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 22826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m1 = tmp0.ptr; 22846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, n/2, 1 ); 22856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m2 = tmp0.ptr; 22866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp0, n - 1 - n/2, 1 ); 22876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m3 = tmp0.ptr; 22886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 22906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pivot = icvMed3( m1, m2, m3, cmp_func, aux ); 22916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left = left0; 22926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( pivot != left.ptr ) 22936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 22946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( pivot, left.ptr, elem_size ); 22956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pivot = left.ptr; 22966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 22976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left ); 22986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left1 = left; 22996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;) 23016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( left.ptr != right.ptr && (r = cmp_func(left.ptr, pivot, aux)) <= 0 ) 23036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( r == 0 ) 23056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( left1.ptr != left.ptr ) 23076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( left1.ptr, left.ptr, elem_size ); 23086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn swap_cnt = 1; 23096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left1 ); 23106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left ); 23126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( left.ptr != right.ptr && (r = cmp_func(right.ptr,pivot, aux)) >= 0 ) 23156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( r == 0 ) 23176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( right1.ptr != right.ptr ) 23196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( right1.ptr, right.ptr, elem_size ); 23206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn swap_cnt = 1; 23216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, right1 ); 23226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, right ); 23246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( left.ptr == right.ptr ) 23276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r = cmp_func(left.ptr, pivot, aux); 23296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( r == 0 ) 23306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( left1.ptr != left.ptr ) 23326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( left1.ptr, left.ptr, elem_size ); 23336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn swap_cnt = 1; 23346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left1 ); 23356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( r <= 0 ) 23376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left ); 23396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 23416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, right ); 23436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 23456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( left.ptr, right.ptr, elem_size ); 23486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left ); 23496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r = left.ptr == right.ptr; 23506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, right ); 23516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn swap_cnt = 1; 23526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( r ) 23536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 23546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( swap_cnt == 0 ) 23576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left = left0, right = right0; 23596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn goto insert_sort; 23606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l = cvGetSeqReaderPos( &left ); 23636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( l == 0 ) 23646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l = seq->total; 23656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = cvGetSeqReaderPos( &left0 ); 23666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l1 = cvGetSeqReaderPos( &left1 ); 23676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( l1 == 0 ) 23686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l1 = seq->total; 23696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = MIN( l - l1, l1 - l0 ); 23716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n > 0 ) 23726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp0 = left0; 23746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp1 = left; 23756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp1, 0-n, 1 ); 23766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < n; i++ ) 23776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( tmp0.ptr, tmp1.ptr, elem_size ); 23796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, tmp0 ); 23806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, tmp1 ); 23816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 23846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r = cvGetSeqReaderPos( &right ); 23856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r0 = cvGetSeqReaderPos( &right0 ); 23866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn r1 = cvGetSeqReaderPos( &right1 ); 23876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m = MIN( r0 - r1, r1 - r ); 23886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m > 0 ) 23896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp0 = left; 23916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp1 = right0; 23926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &tmp1, 1-m, 1 ); 23936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < m; i++ ) 23946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 23956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( tmp0.ptr, tmp1.ptr, elem_size ); 23966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, tmp0 ); 23976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, tmp1 ); 23986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 23996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = l - l1; 24026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m = r1 - r; 24036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n > 1 ) 24046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m > 1 ) 24066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( n > m ) 24086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sp++; 24106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SAVE_READER_POS( left0, stack[sp].lb ); 24116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &left0, n - 1, 1 ); 24126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SAVE_READER_POS( left0, stack[sp].ub ); 24136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left = right = right0; 24146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &left, 1 - m, 1 ); 24156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 24176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sp++; 24196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SAVE_READER_POS( right0, stack[sp].ub ); 24206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &right0, 1 - m, 1 ); 24216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SAVE_READER_POS( right0, stack[sp].lb ); 24226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left = right = left0; 24236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &right, n - 1, 1 ); 24246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 24276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left = right = left0; 24296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &right, n - 1, 1 ); 24306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( m > 1 ) 24336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn left = right = right0; 24356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetSeqReaderPos( &left, 1 - m, 1 ); 24366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 24386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 24396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 24446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 24456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL schar* 24486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqSearch( CvSeq* seq, const void* _elem, CvCmpFunc cmp_func, 24496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int is_sorted, int* _idx, void* userdata ) 24506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 24516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* result = 0; 24526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const schar* elem = (const schar*)_elem; 24536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int idx = -1; 24546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvSeqSearch"); 24566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 24586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size, i, j, total; 24606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SEQ(seq) ) 24626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( !seq ? CV_StsNullPtr : CV_StsBadArg, "Bad input sequence" ); 24636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !elem ) 24656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "Null element pointer" ); 24666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 24686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 24696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( total == 0 ) 24716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 24726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_sorted ) 24746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 24766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader, 0 ); 24776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 24786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cmp_func ) 24796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total; i++ ) 24816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cmp_func( elem, reader.ptr, userdata ) == 0 ) 24836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 24846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader ); 24856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( (elem_size & (sizeof(int)-1)) == 0 ) 24886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total; i++ ) 24906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < elem_size; j += sizeof(int) ) 24926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 24936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( *(const int*)(reader.ptr + j) != *(const int*)(elem + j) ) 24946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 24956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 24966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( j == elem_size ) 24976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 24986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader ); 24996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total; i++ ) 25046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < elem_size; j++ ) 25066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( reader.ptr[j] != elem[j] ) 25086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 25096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( j == elem_size ) 25116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 25126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader ); 25136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn idx = i; 25176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( i < total ) 25186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = reader.ptr; 25196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !cmp_func ) 25236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "Null compare function" ); 25246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn i = 0, j = total; 25266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( j > i ) 25286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k = (i+j)>>1, code; 25306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* ptr = cvGetSeqElem( seq, k ); 25316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = cmp_func( elem, ptr, userdata ); 25326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !code ) 25336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = ptr; 25356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn idx = k; 25366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 25376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( code < 0 ) 25396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn j = k; 25406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 25416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn i = k+1; 25426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn idx = j; 25446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 25476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _idx ) 25496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *_idx = idx; 25506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 25526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 25536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 25566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqInvert( CvSeq* seq ) 25576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 25586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqInvert" ); 25596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 25616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader left_reader, right_reader; 25636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size; 25646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, count; 25656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvStartReadSeq( seq, &left_reader, 0 )); 25676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvStartReadSeq( seq, &right_reader, 1 )); 25686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 25696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = seq->total >> 1; 25706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < count; i++ ) 25726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 25736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP_ELEMS( left_reader.ptr, right_reader.ptr, elem_size ); 25746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, left_reader ); 25756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_PREV_SEQ_ELEM( elem_size, right_reader ); 25766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 25776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 25796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 25806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvPTreeNode 25836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 25846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn struct CvPTreeNode* parent; 25856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* element; 25866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int rank; 25876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 25886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvPTreeNode; 25896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 25916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This function splits the input sequence or set into one or more equivalence classes. 25926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// is_equal(a,b,...) returns non-zero if the two sequence elements 25936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// belong to the same class. The function returns sequence of integers - 25946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 0-based class indexes for each element. 25956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 25966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// The algorithm is described in "Introduction to Algorithms" 25976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// by Cormen, Leiserson and Rivest, chapter "Data structures for disjoint sets" 25986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 25996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, 26006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvCmpFunc is_equal, void* userdata ) 26016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 26026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* result = 0; 26036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* temp_storage = 0; 26046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int class_idx = 0; 26056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSeqPartition" ); 26076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 26096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqWriter writer; 26116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader, reader0; 26126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* nodes; 26136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 26146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int is_set; 26156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !labels ) 26176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 26186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !is_equal ) 26206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 26216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 26236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = seq->storage; 26246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 26266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 26276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn is_set = CV_IS_SET(seq); 26296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp_storage = cvCreateChildMemStorage( storage ); 26316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nodes = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPTreeNode), temp_storage ); 26336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( seq, &reader ); 26356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( &writer, 0, sizeof(writer)); 26366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartAppendToSeq( nodes, &writer ); 26376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Initial O(N) pass. Make a forest of single-vertex trees. 26396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < seq->total; i++ ) 26406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode node = { 0, 0, 0 }; 26426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !is_set || CV_IS_SET_ELEM( reader.ptr )) 26436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node.element = reader.ptr; 26446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_WRITE_SEQ_ELEM( node, writer ); 26456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); 26466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteSeq( &writer ); 26496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Because in the next loop we will iterate 26516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // through all the sequence nodes each time, 26526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // we do not need to initialize reader every time: 26536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( nodes, &reader ); 26546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( nodes, &reader0 ); 26556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // The main O(N^2) pass. Merge connected components. 26576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < nodes->total; i++ ) 26586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* node = (CvPTreeNode*)(reader0.ptr); 26606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* root = node; 26616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( nodes->elem_size, reader0 ); 26626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !node->element ) 26646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn continue; 26656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // find root 26676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( root->parent ) 26686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn root = root->parent; 26696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < nodes->total; j++ ) 26716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* node2 = (CvPTreeNode*)reader.ptr; 26736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node2->element && node2 != node && 26756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn is_equal( node->element, node2->element, userdata )) 26766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* root2 = node2; 26786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // unite both trees 26806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( root2->parent ) 26816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn root2 = root2->parent; 26826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( root2 != root ) 26846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( root->rank > root2->rank ) 26866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn root2->parent = root; 26876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 26886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn root->parent = root2; 26906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn root2->rank += root->rank == root2->rank; 26916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn root = root2; 26926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 26936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( root->parent == 0 ); 26946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 26956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Compress path from node2 to the root: 26966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( node2->parent ) 26976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 26986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* temp = node2; 26996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node2 = node2->parent; 27006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp->parent = root; 27016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Compress path from node to the root: 27046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node2 = node; 27056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( node2->parent ) 27066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 27076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* temp = node2; 27086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node2 = node2->parent; 27096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn temp->parent = root; 27106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( sizeof(*node), reader ); 27156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Final O(N) pass (Enumerate classes) 27196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Reuse reader one more time 27206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = cvCreateSeq( 0, sizeof(CvSeq), sizeof(int), storage ); 27216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartAppendToSeq( result, &writer ); 27226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < nodes->total; i++ ) 27246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 27256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPTreeNode* node = (CvPTreeNode*)reader.ptr; 27266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int idx = -1; 27276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node->element ) 27296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 27306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( node->parent ) 27316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->parent; 27326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node->rank >= 0 ) 27336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node->rank = ~class_idx++; 27346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn idx = ~node->rank; 27356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( sizeof(*node), reader ); 27386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_WRITE_SEQ_ELEM( idx, writer ); 27396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 27406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvEndWriteSeq( &writer ); 27426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 27446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( labels ) 27466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *labels = result; 27476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &temp_storage ); 27496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return class_idx; 27506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 27516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 27546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Set implementation * 27556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 27566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Creates empty set: */ 27586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSet* 27596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage * storage ) 27606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 27616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSet *set = 0; 27626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreateSet" ); 27646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 27666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 27686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 27696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( header_size < (int)sizeof( CvSet ) || 27706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size < (int)sizeof(void*)*2 || 27716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (elem_size & (sizeof(void*)-1)) != 0 ) 27726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 27736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set = (CvSet*) cvCreateSeq( set_flags, header_size, elem_size, storage ); 27756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->flags = (set->flags & ~CV_MAGIC_MASK) | CV_SET_MAGIC_VAL; 27766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 27786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return set; 27806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 27816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Add new element to the set: */ 27846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 27856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSetAdd( CvSet* set, CvSetElem* element, CvSetElem** inserted_element ) 27866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 27876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int id = -1; 27886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSetAdd" ); 27906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 27926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSetElem *free_elem; 27946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !set ) 27966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 27976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 27986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !(set->free_elems) ) 27996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 28006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = set->total; 28016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int elem_size = set->elem_size; 28026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar *ptr; 28036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvGrowSeq( (CvSeq *) set, 0 )); 28046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->free_elems = (CvSetElem*) (ptr = set->ptr); 28066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; ptr + elem_size <= set->block_max; ptr += elem_size, count++ ) 28076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 28086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((CvSetElem*)ptr)->flags = count | CV_SET_ELEM_FREE_FLAG; 28096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((CvSetElem*)ptr)->next_free = (CvSetElem*)(ptr + elem_size); 28106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 28116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( count <= CV_SET_ELEM_IDX_MASK+1 ); 28126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((CvSetElem*)(ptr - elem_size))->next_free = 0; 28136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->first->prev->count += count - set->total; 28146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->total = count; 28156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->ptr = set->block_max; 28166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 28176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free_elem = set->free_elems; 28196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->free_elems = free_elem->next_free; 28206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn id = free_elem->flags & CV_SET_ELEM_IDX_MASK; 28226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( element ) 28236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_INT( free_elem, element, (size_t)set->elem_size/sizeof(int) ); 28246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn free_elem->flags = id; 28266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->active_count++; 28276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( inserted_element ) 28296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *inserted_element = free_elem; 28306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 28326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return id; 28346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 28356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove element from a set given element index: */ 28386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 28396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvSetRemove( CvSet* set, int index ) 28406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 28416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvSetRemove" ); 28426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 28446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSetElem* elem = cvGetSetElem( set, index ); 28466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( elem ) 28476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetRemoveByPtr( set, elem ); 28486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( !set ) 28496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 28506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 28526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 28536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove all elements from a set: */ 28566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 28576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvClearSet( CvSet* set ) 28586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 28596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvClearSet" ); 28606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 28626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvClearSeq( (CvSeq*)set )); 28646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->free_elems = 0; 28656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn set->active_count = 0; 28666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 28686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 28696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 28726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Graph implementation * 28736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 28746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Create a new graph: */ 28766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvGraph * 28776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateGraph( int graph_type, int header_size, 28786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vtx_size, int edge_size, CvMemStorage * storage ) 28796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 28806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraph *graph = 0; 28816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSet *edges = 0; 28826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCleateGraph" ); 28846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 28866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSet *vertices = 0; 28886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( header_size < (int) sizeof( CvGraph ) 28906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn || edge_size < (int) sizeof( CvGraphEdge ) 28916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn || vtx_size < (int) sizeof( CvGraphVtx ) 28926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ){ 28936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "" ); 28946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 28956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 28966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( vertices = cvCreateSet( graph_type, header_size, vtx_size, storage )); 28976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( edges = cvCreateSet( CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_GRAPH_EDGE, 28986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof( CvSet ), edge_size, storage )); 28996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn graph = (CvGraph*)vertices; 29016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn graph->edges = edges; 29026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 29046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return graph; 29066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 29076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove all vertices and edges from a graph: */ 29106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 29116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvClearGraph( CvGraph * graph ) 29126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 29136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvClearGraph" ); 29146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 29166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 29186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 29196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvClearSet( graph->edges ); 29216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvClearSet( (CvSet*)graph ); 29226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 29246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 29256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Add a vertex to a graph: */ 29286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 29296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphAddVtx( CvGraph* graph, const CvGraphVtx* _vertex, CvGraphVtx** _inserted_vertex ) 29306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 29316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *vertex = 0; 29326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int index = -1; 29336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphAddVtx" ); 29356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 29376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 29396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 29406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vertex = (CvGraphVtx*)cvSetNew((CvSet*)graph); 29426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( vertex ) 29436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 29446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _vertex ) 29456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_INT( vertex + 1, _vertex + 1, 29466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (size_t)(graph->elem_size - sizeof(CvGraphVtx))/sizeof(int) ); 29476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vertex->first = 0; 29486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index = vertex->flags; 29496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 29506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _inserted_vertex ) 29526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *_inserted_vertex = vertex; 29536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 29556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return index; 29576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 29586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove a vertex from the graph together with its incident edges: */ 29616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 29626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) 29636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 29646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = -1; 29656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphRemoveVtxByPtr" ); 29676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 29696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph || !vtx ) 29716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 29726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_SET_ELEM(vtx)) 29746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "The vertex does not belong to the graph" ); 29756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = graph->edges->active_count; 29776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ;; ) 29786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 29796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge = vtx->first; 29806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !edge ) 29816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 29826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGraphRemoveEdgeByPtr( graph, edge->vtx[0], edge->vtx[1] ); 29836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 29846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count -= graph->edges->active_count; 29856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetRemoveByPtr( (CvSet*)graph, vtx ); 29866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 29886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return count; 29906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 29916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 29936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove a vertex from the graph together with its incident edges: */ 29946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 29956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphRemoveVtx( CvGraph* graph, int index ) 29966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 29976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = -1; 29986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *vtx = 0; 29996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphRemoveVtx" ); 30016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 30036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 30056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 30066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx = cvGetGraphVtx( graph, index ); 30086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !vtx ) 30096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "The vertex is not found" ); 30106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count = graph->edges->active_count; 30126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ;; ) 30136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 30146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge = vtx->first; 30156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count++; 30166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !edge ) 30186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 30196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGraphRemoveEdgeByPtr( graph, edge->vtx[0], edge->vtx[1] ); 30206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 30216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count -= graph->edges->active_count; 30226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetRemoveByPtr( (CvSet*)graph, vtx ); 30236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 30256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return count; 30276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 30286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Find a graph edge given pointers to the ending vertices: */ 30316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvGraphEdge* 30326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFindGraphEdgeByPtr( const CvGraph* graph, 30336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvGraphVtx* start_vtx, 30346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvGraphVtx* end_vtx ) 30356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 30366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge = 0; 30376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvFindGraphEdgeByPtr" ); 30386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 30406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ofs = 0; 30426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph || !start_vtx || !end_vtx ) 30446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 30456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( start_vtx == end_vtx ) 30476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 30486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH_ORIENTED( graph ) && 30506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) 30516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 30526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvGraphVtx* t; 30536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( start_vtx, end_vtx, t ); 30546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 30556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = start_vtx->first; 30576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; edge; edge = edge->next[ofs] ) 30586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 30596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ofs = start_vtx == edge->vtx[1]; 30606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( ofs == 1 || start_vtx == edge->vtx[0] ); 30616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edge->vtx[1] == end_vtx ) 30626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 30636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 30646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 30666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return edge; 30686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 30696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Find an edge in the graph given indices of the ending vertices: */ 30726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvGraphEdge * 30736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) 30746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 30756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge = 0; 30766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *start_vtx; 30776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *end_vtx; 30786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvFindGraphEdge" ); 30806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 30826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 30846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "graph pointer is NULL" ); 30856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn start_vtx = cvGetGraphVtx( graph, start_idx ); 30876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn end_vtx = cvGetGraphVtx( graph, end_idx ); 30886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = cvFindGraphEdgeByPtr( graph, start_vtx, end_vtx ); 30906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 30926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return edge; 30946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 30956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 30976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Given two vertices, return the edge 30986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * connecting them, creating it if it 30996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * did not already exist: 31006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 31016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 31026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphAddEdgeByPtr( CvGraph* graph, 31036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, 31046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvGraphEdge* _edge, 31056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge ** _inserted_edge ) 31066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 31076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge = 0; 31086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int result = -1; 31096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphAddEdgeByPtr" ); 31116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 31136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int delta; 31156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 31176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "graph pointer is NULL" ); 31186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH_ORIENTED( graph ) && 31206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) 31216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 31226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* t; 31236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( start_vtx, end_vtx, t ); 31246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 31256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( edge = cvFindGraphEdgeByPtr( graph, start_vtx, end_vtx )); 31276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edge ) 31286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 31296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = 0; 31306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 31316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 31326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( start_vtx == end_vtx ) 31346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( start_vtx ? CV_StsBadArg : CV_StsNullPtr, 31356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "vertex pointers coinside (or set to NULL)" ); 31366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( edge = (CvGraphEdge*)cvSetNew( (CvSet*)(graph->edges) )); 31386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( edge->flags >= 0 ); 31396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->vtx[0] = start_vtx; 31416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->vtx[1] = end_vtx; 31426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->next[0] = start_vtx->first; 31436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->next[1] = end_vtx->first; 31446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn start_vtx->first = end_vtx->first = edge; 31456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn delta = (graph->edges->elem_size - sizeof(*edge))/sizeof(int); 31476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _edge ) 31486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 31496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta > 0 ) 31506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MEMCPY_INT( edge + 1, _edge + 1, delta ); 31516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->weight = _edge->weight; 31526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 31536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 31546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 31556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( delta > 0 ) 31566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ZERO_INT( edge + 1, delta ); 31576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->weight = 1.f; 31586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 31596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = 1; 31616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 31636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( _inserted_edge ) 31656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *_inserted_edge = edge; 31666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 31686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 31696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Given two vertices, return the edge 31716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * connecting them, creating it if it 31726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * did not already exist: 31736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 31746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 31756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphAddEdge( CvGraph* graph, 31766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int start_idx, int end_idx, 31776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const CvGraphEdge* _edge, 31786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge ** _inserted_edge ) 31796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 31806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *start_vtx; 31816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *end_vtx; 31826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int result = -1; 31836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphAddEdge" ); 31856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 31876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 31896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 31906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn start_vtx = cvGetGraphVtx( graph, start_idx ); 31926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn end_vtx = cvGetGraphVtx( graph, end_idx ); 31936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = cvGraphAddEdgeByPtr( graph, start_vtx, end_vtx, _edge, _inserted_edge ); 31956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 31976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 31986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 31996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 32006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove the graph edge connecting two given vertices: */ 32036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 32046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx ) 32056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 32066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphRemoveEdgeByPtr" ); 32076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 32096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ofs, prev_ofs; 32116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge, *next_edge, *prev_edge; 32126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph || !start_vtx || !end_vtx ) 32146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 32156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( start_vtx == end_vtx ) 32176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 32186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH_ORIENTED( graph ) && 32206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (start_vtx->flags & CV_SET_ELEM_IDX_MASK) > (end_vtx->flags & CV_SET_ELEM_IDX_MASK) ) 32216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 32226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* t; 32236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_SWAP( start_vtx, end_vtx, t ); 32246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 32256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ofs = prev_ofs = 0, prev_edge = 0, edge = start_vtx->first; edge != 0; 32276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prev_ofs = ofs, prev_edge = edge, edge = edge->next[ofs] ) 32286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 32296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ofs = start_vtx == edge->vtx[1]; 32306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( ofs == 1 || start_vtx == edge->vtx[0] ); 32316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edge->vtx[1] == end_vtx ) 32326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 32336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 32346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !edge ) 32366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 32376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn next_edge = edge->next[ofs]; 32396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( prev_edge ) 32406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prev_edge->next[prev_ofs] = next_edge; 32416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 32426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn start_vtx->first = next_edge; 32436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ofs = prev_ofs = 0, prev_edge = 0, edge = end_vtx->first; edge != 0; 32456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prev_ofs = ofs, prev_edge = edge, edge = edge->next[ofs] ) 32466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 32476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ofs = end_vtx == edge->vtx[1]; 32486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( ofs == 1 || end_vtx == edge->vtx[0] ); 32496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( edge->vtx[0] == start_vtx ) 32506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 32516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 32526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( edge != 0 ); 32546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn next_edge = edge->next[ofs]; 32566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( prev_edge ) 32576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prev_edge->next[prev_ofs] = next_edge; 32586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 32596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn end_vtx->first = next_edge; 32606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSetRemoveByPtr( graph->edges, edge ); 32626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 32646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 32656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Remove the graph edge connecting two given vertices: */ 32686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 32696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) 32706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 32716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *start_vtx; 32726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *end_vtx; 32736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphRemoveEdge" ); 32756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 32776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 32796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 32806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn start_vtx = cvGetGraphVtx( graph, start_idx ); 32826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn end_vtx = cvGetGraphVtx( graph, end_idx ); 32836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvGraphRemoveEdgeByPtr( graph, start_vtx, end_vtx ); 32856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 32876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 32886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Count number of edges incident to a given vertex: */ 32916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 32926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vertex ) 32936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 32946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge; 32956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = -1; 32966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphVtxDegreeByPtr" ); 32986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 32996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 33006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph || !vertex ) 33026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 33036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( edge = vertex->first, count = 0; edge; ) 33056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 33066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count++; 33076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); 33086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 33096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 33116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return count; 33136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 33146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Count number of edges incident to a given vertex: */ 33176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 33186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGraphVtxDegree( const CvGraph* graph, int vtx_idx ) 33196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 33206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx *vertex; 33216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge *edge; 33226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = -1; 33236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvGraphVtxDegree" ); 33256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 33276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 33296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 33306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vertex = cvGetGraphVtx( graph, vtx_idx ); 33326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !vertex ) 33336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsObjectNotFound, "" ); 33346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( edge = vertex->first, count = 0; edge; ) 33366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 33376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn count++; 33386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); 33396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 33406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 33426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return count; 33446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 33456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvGraphItem 33486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 33496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* vtx; 33506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge* edge; 33516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 33526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvGraphItem; 33536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 33566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvSeqElemsClearFlags( CvSeq* seq, int offset, int clear_mask ) 33576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 33586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("icvStartScanGraph"); 33596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 33616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 33636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, total, elem_size; 33646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq ) 33666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 33676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 33696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 33706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)offset > (unsigned)elem_size ) 33726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "" ); 33736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvStartReadSeq( seq, &reader )); 33756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total; i++ ) 33776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 33786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* flag_ptr = (int*)(reader.ptr + offset); 33796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *flag_ptr &= ~clear_mask; 33806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader ); 33826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 33836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 33856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 33866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic schar* 33896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvSeqFindNextElem( CvSeq* seq, int offset, int mask, 33906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int value, int* start_index ) 33916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 33926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn schar* elem_ptr = 0; 33936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("icvStartScanGraph"); 33956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 33976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 33986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 33996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total, elem_size, index; 34006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !seq || !start_index ) 34026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 34036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_size = seq->elem_size; 34056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total = seq->total; 34066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index = *start_index; 34076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)offset > (unsigned)elem_size ) 34096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "" ); 34106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( total == 0 ) 34126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 34136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (unsigned)index >= (unsigned)total ) 34156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 34166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index %= total; 34176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn index += index < 0 ? total : 0; 34186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 34196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvStartReadSeq( seq, &reader )); 34216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index != 0 ) 34236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvSetSeqReaderPos( &reader, index )); 34246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( index = 0; index < total; index++ ) 34266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 34276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* flag_ptr = (int*)(reader.ptr + offset); 34286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (*flag_ptr & mask) == value ) 34296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 34306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( elem_size, reader ); 34326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 34336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( index < total ) 34356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 34366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn elem_ptr = reader.ptr; 34376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *start_index = index; 34386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 34396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 34416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return elem_ptr; 34436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 34446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_FIELD_OFFSET( field, structtype ) ((int)(size_t)&((structtype*)0)->field) 34466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvGraphScanner* 34486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx, int mask ) 34496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 34506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphScanner* scanner = 0; 34516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* child_storage = 0; 34526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvCreateGraphScanner"); 34546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 34566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !graph ) 34586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "Null graph pointer" ); 34596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( graph->storage != 0 ); 34616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( scanner = (CvGraphScanner*)cvAlloc( sizeof(*scanner) )); 34636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( scanner, 0, sizeof(*scanner)); 34646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->graph = graph; 34666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->mask = mask; 34676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = vtx; 34686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->index = vtx == 0 ? 0 : -1; 34696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( child_storage = cvCreateChildMemStorage( graph->storage )); 34716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( scanner->stack = cvCreateSeq( 0, sizeof(CvSet), 34736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(CvGraphItem), child_storage )); 34746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvSeqElemsClearFlags( (CvSeq*)graph, 34766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FIELD_OFFSET( flags, CvGraphVtx), 34776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_ITEM_VISITED_FLAG| 34786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_SEARCH_TREE_NODE_FLAG )); 34796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvSeqElemsClearFlags( (CvSeq*)(graph->edges), 34816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FIELD_OFFSET( flags, CvGraphEdge), 34826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_ITEM_VISITED_FLAG )); 34836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 34856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 ) 34876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 34886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &child_storage ); 34896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &scanner ); 34906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 34916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return scanner; 34936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 34946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 34966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 34976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvReleaseGraphScanner( CvGraphScanner** scanner ) 34986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 34996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvReleaseGraphScanner"); 35006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 35026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !scanner ) 35046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "Null double pointer to graph scanner" ); 35056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( *scanner ) 35076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (*scanner)->stack ) 35096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvReleaseMemStorage( &((*scanner)->stack->storage))); 35106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( scanner ); 35116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 35126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 35146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 35156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int 35186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvNextGraphItem( CvGraphScanner* scanner ) 35196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 35206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int code = -1; 35216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvNextGraphItem"); 35236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 35256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* vtx; 35276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* dst; 35286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge* edge; 35296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphItem item; 35306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !scanner || !(scanner->stack)) 35326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "Null graph scanner" ); 35336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst = scanner->dst; 35356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx = scanner->vtx; 35366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = scanner->edge; 35376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;) 35396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;) 35416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( dst && !CV_IS_GRAPH_VERTEX_VISITED(dst) ) 35436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = vtx = dst; 35456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = vtx->first; 35466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->flags |= CV_GRAPH_ITEM_VISITED_FLAG; 35476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if((scanner->mask & CV_GRAPH_VERTEX)) 35496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = vtx; 35516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->edge = vtx->first; 35526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->dst = 0; 35536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = CV_GRAPH_VERTEX; 35546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 35556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 35566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 35576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( edge ) 35596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst = edge->vtx[vtx == edge->vtx[0]]; 35616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH_EDGE_VISITED(edge) ) 35636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Check that the edge is outgoing: 35656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH_ORIENTED( scanner->graph ) || dst != edge->vtx[0] ) 35666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->flags |= CV_GRAPH_ITEM_VISITED_FLAG; 35686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH_VERTEX_VISITED(dst) ) 35706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn item.vtx = vtx; 35726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn item.edge = edge; 35736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx->flags |= CV_GRAPH_SEARCH_TREE_NODE_FLAG; 35756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPush( scanner->stack, &item ); 35776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 35786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->mask & CV_GRAPH_TREE_EDGE ) 35796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = CV_GRAPH_TREE_EDGE; 35816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = vtx; 35826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->dst = dst; 35836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->edge = edge; 35846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 35856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 35866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 35876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 35886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 35896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->mask & (CV_GRAPH_BACK_EDGE| 35916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_CROSS_EDGE| 35926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_FORWARD_EDGE) ) 35936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 35946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = (dst->flags & CV_GRAPH_SEARCH_TREE_NODE_FLAG) ? 35956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_BACK_EDGE : 35966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (edge->flags & CV_GRAPH_FORWARD_EDGE_FLAG) ? 35976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_FORWARD_EDGE : CV_GRAPH_CROSS_EDGE; 35986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->flags &= ~CV_GRAPH_FORWARD_EDGE_FLAG; 35996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->mask & code ) 36006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = vtx; 36026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->dst = dst; 36036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->edge = edge; 36046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 36056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( (dst->flags & (CV_GRAPH_ITEM_VISITED_FLAG| 36106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_SEARCH_TREE_NODE_FLAG)) == 36116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (CV_GRAPH_ITEM_VISITED_FLAG| 36126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_GRAPH_SEARCH_TREE_NODE_FLAG)) 36136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge->flags |= CV_GRAPH_FORWARD_EDGE_FLAG; 36156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = CV_NEXT_GRAPH_EDGE( edge, vtx ); 36196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !edge ) /* need to backtrack */ 36226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->stack->total == 0 ) 36246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->index >= 0 ) 36266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx = 0; 36276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 36286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->index = 0; 36296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 36306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPop( scanner->stack, &item ); 36326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx = item.vtx; 36336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx->flags &= ~CV_GRAPH_SEARCH_TREE_NODE_FLAG; 36346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge = item.edge; 36356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst = 0; 36366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->mask & CV_GRAPH_BACKTRACKING ) 36386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = vtx; 36406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->edge = edge; 36416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->dst = edge->vtx[vtx == edge->vtx[0]]; 36426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = CV_GRAPH_BACKTRACKING; 36436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 36446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !vtx ) 36496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx = (CvGraphVtx*)icvSeqFindNextElem( (CvSeq*)(scanner->graph), 36516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FIELD_OFFSET( flags, CvGraphVtx ), CV_GRAPH_ITEM_VISITED_FLAG|INT_MIN, 36526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 0, &(scanner->index) ); 36536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !vtx ) 36556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = CV_GRAPH_OVER; 36576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 36586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst = vtx; 36626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( scanner->mask & CV_GRAPH_NEW_TREE ) 36636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 36646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->dst = dst; 36656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->edge = 0; 36666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn scanner->vtx = 0; 36676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn code = CV_GRAPH_NEW_TREE; 36686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 36696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 36716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 36736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return code; 36756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 36766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvGraph* 36796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) 36806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 36816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* flag_buffer = 0; 36826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx** ptr_buffer = 0; 36836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraph* result = 0; 36846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCloneGraph" ); 36866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 36886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, k; 36906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vtx_size, edge_size; 36916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeqReader reader; 36926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_GRAPH(graph)) 36946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "Invalid graph pointer" ); 36956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 36976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn storage = graph->storage; 36986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 36996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 37006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL storage pointer" ); 37016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx_size = graph->elem_size; 37036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn edge_size = graph->edges->elem_size; 37046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( flag_buffer = (int*)cvAlloc( graph->total*sizeof(flag_buffer[0]))); 37066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( ptr_buffer = (CvGraphVtx**)cvAlloc( graph->total*sizeof(ptr_buffer[0]))); 37076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( result = cvCreateGraph( graph->flags, graph->header_size, 37086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx_size, edge_size, storage )); 37096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( result + sizeof(CvGraph), graph + sizeof(CvGraph), 37106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn graph->header_size - sizeof(CvGraph)); 37116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Pass 1. Save flags, copy vertices: 37136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( (CvSeq*)graph, &reader ); 37146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0, k = 0; i < graph->total; i++ ) 37156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_IS_SET_ELEM( reader.ptr )) 37176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* vtx = (CvGraphVtx*)reader.ptr; 37196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* dstvtx = 0; 37206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvGraphAddVtx( result, vtx, &dstvtx )); 37216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn flag_buffer[k] = dstvtx->flags = vtx->flags; 37226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx->flags = k; 37236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ptr_buffer[k++] = dstvtx; 37246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 37256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( vtx_size, reader ); 37266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 37276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Pass 2. Copy edges: 37296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( (CvSeq*)graph->edges, &reader ); 37306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < graph->edges->total; i++ ) 37316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_IS_SET_ELEM( reader.ptr )) 37336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge* edge = (CvGraphEdge*)reader.ptr; 37356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphEdge* dstedge = 0; 37366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* new_org = ptr_buffer[edge->vtx[0]->flags]; 37376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* new_dst = ptr_buffer[edge->vtx[1]->flags]; 37386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvGraphAddEdgeByPtr( result, new_org, new_dst, edge, &dstedge )); 37396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dstedge->flags = edge->flags; 37406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 37416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( edge_size, reader ); 37426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 37436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // Pass 3. Restore flags: 37456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvStartReadSeq( (CvSeq*)graph, &reader ); 37466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0, k = 0; i < graph->edges->total; i++ ) 37476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_IS_SET_ELEM( reader.ptr )) 37496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvGraphVtx* vtx = (CvGraphVtx*)reader.ptr; 37516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vtx->flags = flag_buffer[k++]; 37526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 37536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_NEXT_SEQ_ELEM( vtx_size, reader ); 37546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 37556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 37576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &flag_buffer ); 37596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &ptr_buffer ); 37606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( cvGetErrStatus() < 0 ) 37626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = 0; 37636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 37656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 37666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 37696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn* Working with sequence tree * 37706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 37716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Gather pointers to all the sequences, accessible from the <first>, to the single sequence. 37736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvSeq* 37746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) 37756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 37766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq* allseq = 0; 37776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvTreeToNodeSeq"); 37796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 37816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNodeIterator iterator; 37836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !storage ) 37856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL storage pointer" ); 37866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( allseq = cvCreateSeq( 0, header_size, sizeof(first), storage )); 37886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( first ) 37906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( cvInitTreeNodeIterator( &iterator, first, INT_MAX )); 37926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 37936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;) 37946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 37956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void* node = cvNextTreeNode( &iterator ); 37966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !node ) 37976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 37986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvSeqPush( allseq, &node ); 37996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 38006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 38016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 38036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return allseq; 38056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 38066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvTreeNode 38096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 38106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int flags; /* micsellaneous flags */ 38116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int header_size; /* size of sequence header */ 38126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn struct CvTreeNode* h_prev; /* previous sequence */ 38136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn struct CvTreeNode* h_next; /* next sequence */ 38146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn struct CvTreeNode* v_prev; /* 2nd previous sequence */ 38156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn struct CvTreeNode* v_next; /* 2nd next sequence */ 38166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 38176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvTreeNode; 38186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Insert contour into tree given certain parent sequence. 38226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// If parent is equal to frame (the most external contour), 38236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// then added contour will have null pointer to parent: 38246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 38256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvInsertNodeIntoTree( void* _node, void* _parent, void* _frame ) 38266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 38276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvInsertNodeIntoTree" ); 38286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 38306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* node = (CvTreeNode*)_node; 38326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* parent = (CvTreeNode*)_parent; 38336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !node || !parent ) 38356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 38366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node->v_prev = _parent != _frame ? parent : 0; 38386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node->h_next = parent->v_next; 38396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( parent->v_next != node ); 38416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( parent->v_next ) 38436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent->v_next->h_prev = node; 38446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent->v_next = node; 38456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 38476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 38486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Remove contour from tree, together with the contour's children: 38516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 38526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvRemoveNodeFromTree( void* _node, void* _frame ) 38536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 38546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvRemoveNodeFromTree" ); 38556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 38576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* node = (CvTreeNode*)_node; 38596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* frame = (CvTreeNode*)_frame; 38606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !node ) 38626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR_FROM_CODE( CV_StsNullPtr ); 38636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node == frame ) 38656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadArg, "frame node could not be deleted" ); 38666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node->h_next ) 38686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node->h_next->h_prev = node->h_prev; 38696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node->h_prev ) 38716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node->h_prev->h_next = node->h_next; 38726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 38736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 38746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* parent = node->v_prev; 38756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !parent ) 38766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent = frame; 38776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( parent ) 38796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 38806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( parent->v_next == node ); 38816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn parent->v_next = node->h_next; 38826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 38836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 38846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 38866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 38876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 38906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvInitTreeNodeIterator( CvTreeNodeIterator* treeIterator, 38916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const void* first, int max_level ) 38926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 38936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("icvInitTreeNodeIterator"); 38946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 38966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 38976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !treeIterator || !first ) 38986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 38996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_level < 0 ) 39016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsOutOfRange, "" ); 39026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->node = (void*)first; 39046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->level = 0; 39056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->max_level = max_level; 39066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 39086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 39096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void* 39126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvNextTreeNode( CvTreeNodeIterator* treeIterator ) 39136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 39146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* prevNode = 0; 39156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvNextTreeNode"); 39176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 39196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* node; 39216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int level; 39226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !treeIterator ) 39246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "NULL iterator pointer" ); 39256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prevNode = node = (CvTreeNode*)treeIterator->node; 39276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn level = treeIterator->level; 39286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node ) 39306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node->v_next && level+1 < treeIterator->max_level ) 39326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->v_next; 39346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn level++; 39356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 39376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( node->h_next == 0 ) 39396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->v_prev; 39416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( --level < 0 ) 39426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = 0; 39446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 39456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node && treeIterator->max_level != 0 ? node->h_next : 0; 39486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->node = node; 39526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->level = level; 39536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 39556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return prevNode; 39576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 39586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void* 39616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvPrevTreeNode( CvTreeNodeIterator* treeIterator ) 39626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 39636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* prevNode = 0; 39646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME("cvPrevTreeNode"); 39666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 39686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTreeNode* node; 39706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int level; 39716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !treeIterator ) 39736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 39746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prevNode = node = (CvTreeNode*)treeIterator->node; 39766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn level = treeIterator->level; 39776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( node ) 39796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !node->h_prev ) 39816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->v_prev; 39836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( --level < 0 ) 39846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = 0; 39856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 39876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->h_prev; 39896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( node->v_next && level < treeIterator->max_level ) 39916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 39926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->v_next; 39936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn level++; 39946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 39956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( node->h_next ) 39966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn node = node->h_next; 39976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 39996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 40006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 40016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->node = node; 40026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn treeIterator->level = level; 40036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 40046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 40056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 40066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return prevNode; 40076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 40086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 40096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */ 4010