📄 cxdatastructs.cpp
字号:
CV_CALL( icvGrowSeq( seq, 1 ));
block = seq->first;
assert( block->start_index > 0 );
}
ptr = block->data -= elem_size;
if( element )
CV_MEMCPY_AUTO( 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( CV_StsBadSize, "" );
elem_size = seq->elem_size;
block = seq->first;
if( element )
CV_MEMCPY_AUTO( 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( CV_StsOutOfRange, "" );
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 = (int)(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 */
assert( block != seq->first->prev );
}
before_index = (before_index - block->start_index + delta_index) * elem_size;
memmove( block->data + before_index + elem_size, block->data + before_index,
block_size - before_index - elem_size );
ret_ptr = block->data + before_index;
if( element )
memcpy( ret_ptr, element, elem_size );
seq->ptr = ptr;
}
else
{
block = seq->first;
if( block->start_index == 0 )
{
CV_CALL( icvGrowSeq( seq, 1 ));
block = seq->first;
}
delta_index = block->start_index;
block->count++;
block->start_index--;
block->data -= elem_size;
while( before_index > block->start_index - delta_index + block->count )
{
CvSeqBlock *next_block = block->next;
block_size = block->count * elem_size;
memmove( block->data, block->data + elem_size, block_size - elem_size );
memcpy( block->data + block_size - elem_size, next_block->data, elem_size );
block = next_block;
/* check that we don't fall in the infinite loop */
assert( block != seq->first );
}
before_index = (before_index - block->start_index + delta_index) * elem_size;
memmove( block->data, block->data + elem_size, before_index - elem_size );
ret_ptr = block->data + before_index - elem_size;
if( element )
memcpy( ret_ptr, element, elem_size );
}
seq->total = total + 1;
}
__END__;
return ret_ptr;
}
/* removes element from the sequence */
CV_IMPL void
cvSeqRemove( CvSeq *seq, int index )
{
char *ptr;
int elem_size;
int block_size;
CvSeqBlock *block;
int delta_index;
int total, front = 0;
CV_FUNCNAME( "cvSeqRemove" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
total = seq->total;
index += index < 0 ? total : 0;
index -= index >= total ? total : 0;
if( (unsigned) index >= (unsigned) total )
CV_ERROR( CV_StsOutOfRange, "Invalid index" );
if( index == total - 1 )
{
cvSeqPop( seq, 0 );
}
else if( index == 0 )
{
cvSeqPopFront( seq, 0 );
}
else
{
block = seq->first;
elem_size = seq->elem_size;
delta_index = block->start_index;
while( block->start_index - delta_index + block->count <= index )
block = block->next;
ptr = block->data + (index - block->start_index + delta_index) * elem_size;
front = index < total >> 1;
if( !front )
{
block_size = block->count * elem_size - (int)(ptr - block->data);
while( block != seq->first->prev ) /* while not the last block */
{
CvSeqBlock *next_block = block->next;
memmove( ptr, ptr + elem_size, block_size - elem_size );
memcpy( ptr + block_size - elem_size, next_block->data, elem_size );
block = next_block;
ptr = block->data;
block_size = block->count * elem_size;
}
memmove( ptr, ptr + elem_size, block_size - elem_size );
seq->ptr -= elem_size;
}
else
{
ptr += elem_size;
block_size = (int)(ptr - block->data);
while( block != seq->first )
{
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;
}
memmove( block->data + elem_size, block->data, block_size - elem_size );
block->data += elem_size;
block->start_index++;
}
seq->total = total - 1;
if( --block->count == 0 )
icvFreeSeqBlock( seq, front );
}
__END__;
}
/* adds several elements to the end or in the beginning of sequence */
CV_IMPL void
cvSeqPushMulti( CvSeq *seq, void *_elements, int count, int front )
{
char *elements = (char *) _elements;
CV_FUNCNAME( "cvSeqPushMulti" );
__BEGIN__;
int elem_size;
if( !seq )
CV_ERROR( CV_StsNullPtr, "NULL sequence pointer" );
if( count < 0 )
CV_ERROR( CV_StsBadSize, "number of removed elements is negative" );
elem_size = seq->elem_size;
if( !front )
{
while( count > 0 )
{
int delta = (int)((seq->block_max - seq->ptr) / elem_size);
delta = MIN( delta, count );
if( delta > 0 )
{
seq->first->prev->count += delta;
seq->total += delta;
count -= delta;
delta *= elem_size;
if( elements )
{
memcpy( seq->ptr, elements, delta );
elements += delta;
}
seq->ptr += delta;
}
if( count > 0 )
CV_CALL( icvGrowSeq( seq, 0 ));
}
}
else
{
CvSeqBlock* block = seq->first;
while( count > 0 )
{
int delta;
if( !block || block->start_index == 0 )
{
CV_CALL( icvGrowSeq( seq, 1 ));
block = seq->first;
assert( block->start_index > 0 );
}
delta = MIN( block->start_index, count );
count -= delta;
block->start_index -= delta;
block->count += delta;
seq->total += delta;
delta *= elem_size;
block->data -= delta;
if( elements )
memcpy( block->data, elements + count*elem_size, delta );
}
}
__END__;
}
/* removes several elements from the end of sequence */
CV_IMPL void
cvSeqPopMulti( CvSeq *seq, void *_elements, int count, int front )
{
char *elements = (char *) _elements;
CV_FUNCNAME( "cvSeqPopMulti" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "NULL sequence pointer" );
if( count < 0 )
CV_ERROR( CV_StsBadSize, "number of removed elements is negative" );
count = MIN( count, seq->total );
if( !front )
{
if( elements )
elements += count * seq->elem_size;
while( count > 0 )
{
int delta = seq->first->prev->count;
delta = MIN( delta, count );
assert( delta > 0 );
seq->first->prev->count -= delta;
seq->total -= delta;
count -= delta;
delta *= seq->elem_size;
seq->ptr -= delta;
if( elements )
{
elements -= delta;
memcpy( elements, seq->ptr, delta );
}
if( seq->first->prev->count == 0 )
icvFreeSeqBlock( seq, 0 );
}
}
else
{
while( count > 0 )
{
int delta = seq->first->count;
delta = MIN( delta, count );
assert( delta > 0 );
seq->first->count -= delta;
seq->total -= delta;
count -= delta;
seq->first->start_index += delta;
delta *= seq->elem_size;
if( elements )
{
memcpy( elements, seq->first->data, delta );
elements += delta;
}
seq->first->data += delta;
if( seq->first->count == 0 )
icvFreeSeqBlock( seq, 1 );
}
}
__END__;
}
/* removes all elements from the sequence */
CV_IMPL void
cvClearSeq( CvSeq *seq )
{
CV_FUNCNAME( "cvClearSeq" );
__BEGIN__;
if( !seq )
CV_ERROR( CV_StsNullPtr, "" );
cvSeqPopMulti( seq, 0, seq->total );
__END__;
}
CV_IMPL CvSeq*
cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage, int copy_data )
{
CvSeq* subseq = 0;
CV_FUNCNAME("cvSeqSlice");
__BEGIN__;
int elem_size, count, length;
CvSeqReader reader;
CvSeqBlock *block, *first_block = 0, *last_block = 0;
if( !CV_IS_SEQ(seq) )
CV_ERROR( CV_StsBadArg, "Invalid sequence header" );
if( !storage )
{
storage = seq->storage;
if( !storage )
CV_ERROR( CV_StsNullPtr, "NULL storage pointer" );
}
elem_size = seq->elem_size;
length = cvSliceLength( slice, seq );
if( slice.start_index < 0 )
slice.start_index += seq->total;
else if( slice.start_index >= seq->total )
slice.start_index -= seq->total;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -