?? cxdatastructs.cpp
字號:
CV_CALL( cvSetSeqBlockSize( seq, (1 << 10)/elem_size )); __END__; return seq;}/* adjusts <delta_elems> field of sequence. It determines how much the sequence grows if there are no free space inside the sequence buffers */CV_IMPL voidcvSetSeqBlockSize( CvSeq *seq, int delta_elements ){ int elem_size; int useful_block_size; CV_FUNCNAME( "cvSetSeqBlockSize" ); __BEGIN__; if( !seq || !seq->storage ) CV_ERROR( CV_StsNullPtr, "" ); if( delta_elements < 0 ) CV_ERROR( CV_StsOutOfRange, "" ); useful_block_size = cvAlignLeft(seq->storage->block_size - sizeof(CvMemBlock) - sizeof(CvSeqBlock), CV_STRUCT_ALIGN); elem_size = seq->elem_size; if( delta_elements == 0 ) { delta_elements = (1 << 10) / elem_size; delta_elements = MAX( delta_elements, 1 ); } if( delta_elements * elem_size > useful_block_size ) { delta_elements = useful_block_size / elem_size; if( delta_elements == 0 ) CV_ERROR( CV_StsOutOfRange, "Storage block size is too small " "to fit the sequence elements" ); } seq->delta_elems = delta_elements; __END__;}/* finds sequence element by its index */CV_IMPL char*cvGetSeqElem( const CvSeq *seq, int index ){ CvSeqBlock *block; int count, total = seq->total; if( (unsigned)index >= (unsigned)total ) { index += index < 0 ? total : 0; index -= index >= total ? total : 0; if( (unsigned)index >= (unsigned)total ) return 0; } block = seq->first; if( index + index <= total ) { while( index >= (count = block->count) ) { block = block->next; index -= count; } } else { do { block = block->prev; total -= block->count; } while( index < total ); index -= total; } return block->data + index * seq->elem_size;}/* calculates index of sequence element */CV_IMPL intcvSeqElemIdx( const CvSeq* seq, const void* _element, CvSeqBlock** _block ){ const char *element = (const char *)_element; int elem_size; int id = -1; CvSeqBlock *first_block; CvSeqBlock *block; CV_FUNCNAME( "cvSeqElemIdx" ); __BEGIN__; if( !seq || !element ) CV_ERROR( CV_StsNullPtr, "" ); block = first_block = seq->first; elem_size = seq->elem_size; for( ;; ) { if( (unsigned)(element - block->data) < (unsigned) (block->count * elem_size) ) { if( _block ) *_block = block; if( elem_size <= ICV_SHIFT_TAB_MAX && (id = icvPower2ShiftTab[elem_size - 1]) >= 0 ) id = (int)((size_t)(element - block->data) >> id); else id = (int)((size_t)(element - block->data) / elem_size); id += block->start_index - seq->first->start_index; break; } block = block->next; if( block == first_block ) break; } __END__; return id;}CV_IMPL intcvSliceLength( CvSlice slice, const CvSeq* seq ){ int total = seq->total; int length = slice.end_index - slice.start_index; if( length != 0 ) { if( slice.start_index < 0 ) slice.start_index += total; if( slice.end_index <= 0 ) slice.end_index += total; length = slice.end_index - slice.start_index; } if( length < 0 ) { length += total; /*if( length < 0 ) length += total;*/ } else if( length > total ) length = total; return length;}/* copies all the sequence elements into single continuous array */CV_IMPL void*cvCvtSeqToArray( const CvSeq *seq, void *array, CvSlice slice ){ CV_FUNCNAME( "cvCvtSeqToArray" ); __BEGIN__; int elem_size, total; CvSeqReader reader; char *dst = (char*)array; if( !seq || !array ) CV_ERROR( CV_StsNullPtr, "" ); elem_size = seq->elem_size; total = cvSliceLength( slice, seq )*elem_size; if( total == 0 ) EXIT; cvStartReadSeq( seq, &reader, 0 ); CV_CALL( cvSetSeqReaderPos( &reader, slice.start_index, 0 )); do { int count = (int)(reader.block_max - reader.ptr); if( count > total ) count = total; memcpy( dst, reader.ptr, count ); dst += count; reader.block = reader.block->next; reader.ptr = reader.block->data; reader.block_max = reader.ptr + reader.block->count*elem_size; total -= count; } while( total > 0 ); __END__; return array;}/* constructs sequence from array without copying any data. the resultant sequence can't grow above its initial size */CV_IMPL CvSeq*cvMakeSeqHeaderForArray( int seq_flags, int header_size, int elem_size, void *array, int total, CvSeq *seq, CvSeqBlock * block ){ CvSeq* result = 0; CV_FUNCNAME( "cvMakeSeqHeaderForArray" ); __BEGIN__; if( elem_size <= 0 || header_size < (int)sizeof( CvSeq ) || total < 0 ) CV_ERROR( CV_StsBadSize, "" ); if( !seq || ((!array || !block) && total > 0) ) CV_ERROR( CV_StsNullPtr, "" ); memset( seq, 0, header_size ); seq->header_size = header_size; seq->flags = (seq_flags & ~CV_MAGIC_MASK) | CV_SEQ_MAGIC_VAL; { int elemtype = CV_MAT_TYPE(seq_flags); int typesize = CV_ELEM_SIZE(elemtype); if( elemtype != CV_SEQ_ELTYPE_GENERIC && typesize != 0 && typesize != elem_size ) CV_ERROR( CV_StsBadSize, "Element size doesn't match to the size of predefined element type " "(try to use 0 for sequence element type)" ); } seq->elem_size = elem_size; seq->total = total; seq->block_max = seq->ptr = (char *) array + total * elem_size; if( total > 0 ) { seq->first = block; block->prev = block->next = block; block->start_index = 0; block->count = total; block->data = (char *) array; } result = seq; __END__; return result;}/* the function allocates space for at least one more sequence element. if there are free sequence blocks (seq->free_blocks != 0), they are reused, otherwise the space is allocated in the storage */static voidicvGrowSeq( CvSeq *seq, int in_front_of ){ CV_FUNCNAME( "icvGrowSeq" ); __BEGIN__; CvSeqBlock *block; if( !seq ) CV_ERROR( CV_StsNullPtr, "" ); block = seq->free_blocks; if( !block ) { int elem_size = seq->elem_size; int delta_elems = seq->delta_elems; CvMemStorage *storage = seq->storage; if( seq->total >= delta_elems*4 ) cvSetSeqBlockSize( seq, delta_elems*2 ); if( !storage ) CV_ERROR( CV_StsNullPtr, "The sequence has NULL storage pointer" ); /* if there is a free space just after last allocated block and it's big enough then enlarge the last block (this can happen only if the new block is added to the end of sequence */ if( (unsigned)(ICV_FREE_PTR(storage) - seq->block_max) < CV_STRUCT_ALIGN && storage->free_space >= seq->elem_size && !in_front_of ) { int delta = storage->free_space / elem_size; delta = MIN( delta, delta_elems ) * elem_size; seq->block_max += delta; storage->free_space = cvAlignLeft((int)(((char*)storage->top + storage->block_size) - seq->block_max), CV_STRUCT_ALIGN ); EXIT; } else { int delta = elem_size * delta_elems + ICV_ALIGNED_SEQ_BLOCK_SIZE; /* try to allocate <delta_elements> elements */ if( storage->free_space < delta ) { int small_block_size = MAX(1, delta_elems/3)*elem_size + ICV_ALIGNED_SEQ_BLOCK_SIZE; /* try to allocate smaller part */ if( storage->free_space >= small_block_size + CV_STRUCT_ALIGN ) { delta = (storage->free_space - ICV_ALIGNED_SEQ_BLOCK_SIZE)/seq->elem_size; delta = delta*seq->elem_size + ICV_ALIGNED_SEQ_BLOCK_SIZE; } else { CV_CALL( icvGoNextMemBlock( storage )); assert( storage->free_space >= delta ); } } CV_CALL( block = (CvSeqBlock*)cvMemStorageAlloc( storage, delta )); block->data = (char*)cvAlignPtr( block + 1, CV_STRUCT_ALIGN ); block->count = delta - ICV_ALIGNED_SEQ_BLOCK_SIZE; block->prev = block->next = 0; } } else { seq->free_blocks = block->next; } if( !(seq->first) ) { seq->first = block; block->prev = block->next = block; } else { block->prev = seq->first->prev; block->next = seq->first; block->prev->next = block->next->prev = block; } /* for free blocks the <count> field means total number of bytes in the block. And for used blocks it means a current number of sequence elements in the block */ assert( block->count % seq->elem_size == 0 && block->count > 0 ); if( !in_front_of ) { seq->ptr = block->data; seq->block_max = block->data + block->count; block->start_index = block == block->prev ? 0 : block->prev->start_index + block->prev->count; } else { int delta = block->count / seq->elem_size; block->data += block->count; if( block != block->prev ) { assert( seq->first->start_index == 0 ); seq->first = block; } else { seq->block_max = seq->ptr = block->data; } block->start_index = 0; for( ;; ) { block->start_index += delta; block = block->next; if( block == seq->first ) break; } } block->count = 0; __END__;}/* recycles a sequence block for the further use */static voidicvFreeSeqBlock( CvSeq *seq, int in_front_of ){ /*CV_FUNCNAME( "icvFreeSeqBlock" );*/ __BEGIN__; CvSeqBlock *block = seq->first; assert( (in_front_of ? block : block->prev)->count == 0 ); if( block == block->prev ) /* single block case */ { block->count = (int)(seq->block_max - block->data) + block->start_index * seq->elem_size; block->data = seq->block_max - block->count; seq->first = 0; seq->ptr = seq->block_max = 0; seq->total = 0; } else { if( !in_front_of ) { block = block->prev; assert( seq->ptr == block->data ); block->count = (int)(seq->block_max - seq->ptr); seq->block_max = seq->ptr = block->prev->data + block->prev->count * seq->elem_size; } else { int delta = block->start_index; block->count = delta * seq->elem_size; block->data -= block->count; /* update start indices of sequence blocks */ for( ;; ) { block->start_index -= delta; block = block->next; if( block == seq->first ) break; } seq->first = block->next; } block->prev->next = block->next; block->next->prev = block->prev; } assert( block->count > 0 && block->count % seq->elem_size == 0 ); block->next = seq->free_blocks; seq->free_blocks = block; __END__;}/****************************************************************************************\* Sequence Writer implementation *\****************************************************************************************//* initializes sequence writer */CV_IMPL voidcvStartAppendToSeq( 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 */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -