cvdatastructs.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,404 行 · 第 1/5 页
SVN-BASE
2,404 行
seq->ptr = writer->ptr;
if( writer->block )
{
int total = 0;
CvSeqBlock *first_block = writer->seq->first;
CvSeqBlock *block = first_block;
writer->block->count = (writer->ptr - writer->block->data) / seq->elem_size;
assert( writer->block->count > 0 );
do
{
total += block->count;
block = block->next;
}
while( block != first_block );
writer->seq->total = total;
}
__END__;
}
/* calls icvFlushSeqWriter and finishes writing process */
CV_IMPL CvSeq *
cvEndWriteSeq( CvSeqWriter * writer )
{
CvSeq *seq = 0;
CV_FUNCNAME( "cvEndWriteSeq" );
__BEGIN__;
if( !writer )
CV_ERROR( CV_StsNullPtr, "" );
CV_CALL( cvFlushSeqWriter( writer ));
/* truncate the last block */
if( writer->block && writer->seq->storage )
{
CvSeq *seq = writer->seq;
CvMemStorage *storage = seq->storage;
char *storage_block_max = (char *) storage->top + storage->block_size;
assert( writer->block->count > 0 );
if( (unsigned)((storage_block_max - storage->free_space)
- seq->block_max) < CV_STRUCT_ALIGN )
{
storage->free_space = (storage_block_max - seq->ptr) & -CV_STRUCT_ALIGN;
seq->block_max = seq->ptr;
}
}
seq = writer->seq;
/*writer->seq = 0; */
writer->ptr = 0;
__END__;
return seq;
}
/* creates new sequence block */
CV_IMPL void
cvCreateSeqBlock( CvSeqWriter * writer )
{
CV_FUNCNAME( "cvCreateSeqBlock" );
__BEGIN__;
CvSeq *seq;
if( !writer || !writer->seq )
CV_ERROR( CV_StsNullPtr, "" );
seq = writer->seq;
cvFlushSeqWriter( writer );
CV_CALL( icvGrowSeq( seq, 0 ));
writer->block = seq->first->prev;
writer->ptr = seq->ptr;
writer->block_max = seq->block_max;
__END__;
}
/****************************************************************************************\
* Sequence Reader implementation *
\****************************************************************************************/
/* initializes sequence reader */
CV_IMPL void
cvStartReadSeq( const CvSeq *seq, CvSeqReader * reader, int reverse )
{
CvSeqBlock *first_block;
CvSeqBlock *last_block;
CV_FUNCNAME( "cvStartReadSeq" );
__BEGIN__;
if( !seq || !reader )
CV_ERROR( CV_StsNullPtr, "" );
reader->header_size = sizeof( CvSeqReader );
reader->seq = (CvSeq*)seq;
first_block = seq->first;
if( first_block )
{
last_block = first_block->prev;
reader->ptr = first_block->data;
reader->prev_elem = _CV_GET_LAST_ELEM( seq, last_block );
reader->delta_index = seq->first->start_index;
if( reverse )
{
char *temp = reader->ptr;
reader->ptr = reader->prev_elem;
reader->prev_elem = temp;
reader->block = last_block;
}
else
{
reader->block = first_block;
}
reader->block_min = reader->block->data;
reader->block_max = reader->block_min + reader->block->count * seq->elem_size;
}
else
{
reader->delta_index = 0;
reader->block = 0;
reader->ptr = reader->prev_elem = reader->block_min = reader->block_max = 0;
}
__END__;
}
/* changes the current reading block to the previous or to the next */
CV_IMPL void
cvChangeSeqBlock( CvSeqReader * reader, int direction )
{
CV_FUNCNAME( "cvChangeSeqBlock" );
__BEGIN__;
if( !reader )
CV_ERROR( CV_StsNullPtr, "" );
if( direction > 0 )
{
reader->block = reader->block->next;
reader->ptr = reader->block->data;
}
else
{
reader->block = reader->block->prev;
reader->ptr = _CV_GET_LAST_ELEM( reader->seq, reader->block );
}
reader->block_min = reader->block->data;
reader->block_max = reader->block_min + reader->block->count * reader->seq->elem_size;
__END__;
}
/* returns the current reader position */
CV_IMPL int
cvGetSeqReaderPos( CvSeqReader * reader )
{
int elem_size;
int index = -1;
CV_FUNCNAME( "cvGetSeqReaderPos" );
__BEGIN__;
if( !reader || !reader->ptr )
CV_ERROR( CV_StsNullPtr, "" );
elem_size = reader->seq->elem_size;
if( elem_size == 8 )
{
index = (reader->ptr - reader->block_min) >> 3;
}
else if( elem_size == 4 )
{
index = (reader->ptr - reader->block_min) >> 2;
}
else if( elem_size == 1 )
{
index = reader->ptr - reader->block_min;
}
else
{
index = (reader->ptr - reader->block_min) / elem_size;
}
index += reader->block->start_index - reader->delta_index;
__END__;
return index;
}
/* sets reader position to given absolute or relative
(relatively to the current one) position */
CV_IMPL void
cvSetSeqReaderPos( CvSeqReader * reader, int index, int is_relative )
{
int total;
CvSeqBlock *block;
int idx, elem_size;
CV_FUNCNAME( "cvSetSeqReaderPos" );
__BEGIN__;
if( !reader )
CV_ERROR( CV_StsNullPtr, "" );
total = reader->seq->total;
if( is_relative )
index += cvGetSeqReaderPos( reader );
if( index < 0 )
index += total;
if( index >= total )
index -= total;
if( (unsigned) index >= (unsigned) total )
CV_ERROR_FROM_STATUS( CV_BADRANGE_ERR );
elem_size = reader->seq->elem_size;
block = reader->block;
idx = index - block->start_index + reader->delta_index;
if( (unsigned) idx < (unsigned) block->count )
{
reader->ptr = block->data + idx * elem_size;
}
else
{
reader->ptr = cvGetSeqElem( reader->seq, index, &block );
assert( reader->ptr && block );
reader->block = block;
reader->block_min = block->data;
reader->block_max = _CV_GET_LAST_ELEM( reader->seq, block ) + elem_size;
}
__END__;
}
/* pushes element to the sequence */
CV_IMPL char*
cvSeqPush( CvSeq *seq, void *element )
{
char *ptr = 0;
int elem_size;
CV_FUNCNAME( "cvSeqPush" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
elem_size = seq->elem_size;
ptr = seq->ptr;
if( ptr >= seq->block_max )
{
CV_CALL( icvGrowSeq( seq, 0 ));
ptr = seq->ptr;
assert( ptr + elem_size <= seq->block_max /*&& ptr == seq->block_min */ );
}
if( element )
memcpy( ptr, element, elem_size );
seq->first->prev->count++;
seq->total++;
seq->ptr = ptr + elem_size;
__END__;
return ptr;
}
/* pops the last element out of the sequence */
CV_IMPL void
cvSeqPop( CvSeq *seq, void *element )
{
char *ptr;
int elem_size;
CV_FUNCNAME( "cvSeqPop" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
if( seq->total <= 0 )
CV_ERROR_FROM_STATUS( CV_BADSIZE_ERR );
elem_size = seq->elem_size;
seq->ptr = ptr = seq->ptr - elem_size;
if( element )
memcpy( element, ptr, elem_size );
seq->ptr = ptr;
seq->total--;
if( --(seq->first->prev->count) == 0 )
{
icvFreeSeqBlock( seq, 0 );
assert( seq->ptr == seq->block_max );
}
__END__;
}
/* pushes element to the front of the sequence */
CV_IMPL char*
cvSeqPushFront( CvSeq *seq, void *element )
{
char* ptr = 0;
int elem_size;
CvSeqBlock *block;
CV_FUNCNAME( "cvSeqPushFront" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
elem_size = seq->elem_size;
block = seq->first;
if( !block || block->start_index == 0 )
{
CV_CALL( icvGrowSeq( seq, 1 ));
block = seq->first;
assert( block->start_index > 0 );
}
ptr = block->data -= elem_size;
if( element )
memcpy( ptr, element, elem_size );
block->count++;
block->start_index--;
seq->total++;
__END__;
return ptr;
}
/* pulls out the first element of the sequence */
CV_IMPL void
cvSeqPopFront( CvSeq *seq, void *element )
{
int elem_size;
CvSeqBlock *block;
CV_FUNCNAME( "cvSeqPopFront" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
if( seq->total <= 0 )
CV_ERROR_FROM_STATUS( CV_BADSIZE_ERR );
elem_size = seq->elem_size;
block = seq->first;
if( element )
memcpy( element, block->data, elem_size );
block->data += elem_size;
block->start_index++;
seq->total--;
if( --(block->count) == 0 )
{
icvFreeSeqBlock( seq, 1 );
}
__END__;
}
/* inserts new element in the middle of the sequence */
CV_IMPL char*
cvSeqInsert( CvSeq *seq, int before_index, void *element )
{
int elem_size;
int block_size;
CvSeqBlock *block;
int delta_index;
int total;
char* ret_ptr = 0;
CV_FUNCNAME( "cvSeqInsert" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
total = seq->total;
before_index += before_index < 0 ? total : 0;
before_index -= before_index > total ? total : 0;
if( (unsigned)before_index > (unsigned)total )
CV_ERROR_FROM_STATUS( CV_BADRANGE_ERR );
if( before_index == total )
{
CV_CALL( ret_ptr = cvSeqPush( seq, element ));
}
else if( before_index == 0 )
{
CV_CALL( ret_ptr = cvSeqPushFront( seq, element ));
}
else
{
elem_size = seq->elem_size;
if( before_index >= total >> 1 )
{
char *ptr = seq->ptr + elem_size;
if( ptr > seq->block_max )
{
CV_CALL( icvGrowSeq( seq, 0 ));
ptr = seq->ptr + elem_size;
assert( ptr <= seq->block_max );
}
delta_index = seq->first->start_index;
block = seq->first->prev;
block->count++;
block_size = ptr - block->data;
while( before_index < block->start_index - delta_index )
{
CvSeqBlock *prev_block = block->prev;
memmove( block->data + elem_size, block->data, block_size - elem_size );
block_size = prev_block->count * elem_size;
memcpy( block->data, prev_block->data + block_size - elem_size, elem_size );
block = prev_block;
/* check that we don't fall in the infinite loop */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?