?? cxdatastructs.cpp
字號:
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 voidcvSeqRemove( 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 voidcvSeqPushMulti( 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 voidcvSeqPopMulti( 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 voidcvClearSeq( 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; if( (unsigned)length > (unsigned)seq->total || ((unsigned)slice.start_index >= (unsigned)seq->total && length != 0) ) CV_ERROR( CV_StsOutOfRange, "Bad sequence slice" ); CV_CALL( subseq = cvCreateSeq( seq->flags, seq->header_size, elem_size, storage )); if( length > 0 ) { cvStartReadSeq( seq, &reader, 0 ); cvSetSeqReaderPos( &reader, slice.start_index, 0 ); count = (int)((reader.block_max - reader.ptr)/elem_size); do { int bl = MIN( count, length ); if( !copy_data ) { block = (CvSeqBlock*)cvMemStorageAlloc( storage, sizeof(*block) ); if( !first_block ) { first_block = subseq->first = block->prev = block->next = block; block->start_index = 0; } else { block->prev = last_block; block->next = first_block; last_block->next = first_block->prev = block; block->start_index = last_block->start_index + last_block->count; } last_block = block; block->data = reader.ptr; block->count = bl; subseq->total += bl; } else cvSeqPushMulti( subseq, reader.ptr, bl, 0 ); length -= bl; reader.block = reader.block->next; reader.ptr = reader.block->data; count = reader.block->count; } while( length > 0 ); } __END__; return subseq;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -