📄 cxdatastructs.cpp
字号:
/* initializes sequence writer */
CV_IMPL void
cvStartAppendToSeq( CvSeq *seq, CvSeqWriter * writer )
{
CV_FUNCNAME( "cvStartAppendToSeq" );
__BEGIN__;
if( !seq || !writer )
CV_ERROR( CV_StsNullPtr, "" );
memset( writer, 0, sizeof( *writer ));
writer->header_size = sizeof( CvSeqWriter );
writer->seq = seq;
writer->block = seq->first ? seq->first->prev : 0;
writer->ptr = seq->ptr;
writer->block_max = seq->block_max;
__END__;
}
/* initializes sequence writer */
CV_IMPL void
cvStartWriteSeq( int seq_flags, int header_size,
int elem_size, CvMemStorage * storage, CvSeqWriter * writer )
{
CvSeq *seq = 0;
CV_FUNCNAME( "cvStartWriteSeq" );
__BEGIN__;
if( !storage || !writer )
CV_ERROR( CV_StsNullPtr, "" );
CV_CALL( seq = cvCreateSeq( seq_flags, header_size, elem_size, storage ));
cvStartAppendToSeq( seq, writer );
__END__;
}
/* updates sequence header */
CV_IMPL void
cvFlushSeqWriter( CvSeqWriter * writer )
{
CvSeq *seq = 0;
CV_FUNCNAME( "cvFlushSeqWriter" );
__BEGIN__;
if( !writer )
CV_ERROR( CV_StsNullPtr, "" );
seq = writer->seq;
seq->ptr = writer->ptr;
if( writer->block )
{
int total = 0;
CvSeqBlock *first_block = writer->seq->first;
CvSeqBlock *block = first_block;
writer->block->count = (int)((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 ));
seq = writer->seq;
/* truncate the last block */
if( writer->block && writer->seq->storage )
{
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 = cvAlignLeft((int)(storage_block_max - seq->ptr), CV_STRUCT_ALIGN);
seq->block_max = seq->ptr;
}
}
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" );
if( reader )
{
reader->seq = 0;
reader->block = 0;
reader->ptr = reader->block_max = reader->block_min = 0;
}
__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( void* _reader, int direction )
{
CV_FUNCNAME( "cvChangeSeqBlock" );
__BEGIN__;
CvSeqReader* reader = (CvSeqReader*)_reader;
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 <= ICV_SHIFT_TAB_MAX && (index = icvPower2ShiftTab[elem_size - 1]) >= 0 )
index = (int)((reader->ptr - reader->block_min) >> index);
else
index = (int)((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 )
{
CV_FUNCNAME( "cvSetSeqReaderPos" );
__BEGIN__;
CvSeqBlock *block;
int elem_size, count, total;
if( !reader || !reader->seq )
CV_ERROR( CV_StsNullPtr, "" );
total = reader->seq->total;
elem_size = reader->seq->elem_size;
if( !is_relative )
{
if( index < 0 )
{
if( index < -total )
CV_ERROR( CV_StsOutOfRange, "" );
index += total;
}
else if( index >= total )
{
index -= total;
if( index >= total )
CV_ERROR( CV_StsOutOfRange, "" );
}
block = reader->seq->first;
if( index >= (count = block->count) )
{
if( index + index <= total )
{
do
{
block = block->next;
index -= count;
}
while( index >= (count = block->count) );
}
else
{
do
{
block = block->prev;
total -= block->count;
}
while( index < total );
index -= total;
}
}
reader->ptr = block->data + index * elem_size;
if( reader->block != block )
{
reader->block = block;
reader->block_min = block->data;
reader->block_max = block->data + block->count * elem_size;
}
}
else
{
char* ptr = reader->ptr;
index *= elem_size;
block = reader->block;
if( index > 0 )
{
while( ptr + index >= reader->block_max )
{
int delta = (int)(reader->block_max - ptr);
index -= delta;
reader->block = block = block->next;
reader->block_min = ptr = block->data;
reader->block_max = block->data + block->count*elem_size;
}
reader->ptr = ptr + index;
}
else
{
while( ptr + index < reader->block_min )
{
int delta = (int)(ptr - reader->block_min);
index += delta;
reader->block = block = block->prev;
reader->block_min = block->data;
reader->block_max = ptr = block->data + block->count*elem_size;
}
reader->ptr = ptr + index;
}
}
__END__;
}
/* pushes element to the sequence */
CV_IMPL char*
cvSeqPush( CvSeq *seq, void *element )
{
char *ptr = 0;
size_t 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 )
CV_MEMCPY_AUTO( 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( CV_StsBadSize, "" );
elem_size = seq->elem_size;
seq->ptr = ptr = seq->ptr - elem_size;
if( element )
CV_MEMCPY_AUTO( 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 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -