cvdatastructs.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,404 行 · 第 1/5 页
SVN-BASE
2,404 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
#include "_cvdatastructs.h"
#define ICV_FREE_PTR(storage) \
((char*)(storage)->top + (storage)->block_size - (storage)->free_space)
#define ICV_ALIGNED_SEQ_BLOCK_SIZE \
(((int)sizeof(CvSeqBlock) + CV_STRUCT_ALIGN - 1) & -CV_STRUCT_ALIGN)
/****************************************************************************************\
* Functions for manipulating memory storage - list of memory blocks *
\****************************************************************************************/
/* initializes allocated storage */
void
icvInitMemStorage( CvMemStorage* storage, int block_size )
{
CV_FUNCNAME( "icvInitMemStorage " );
__BEGIN__;
if( !storage )
CV_ERROR( CV_StsNullPtr, "" );
if( block_size <= 0 )
block_size = CV_STORAGE_BLOCK_SIZE;
block_size = icvAlign( block_size, CV_STRUCT_ALIGN );
assert( sizeof(CvMemBlock) % CV_STRUCT_ALIGN == 0 );
memset( storage, 0, sizeof( *storage ));
storage->signature = CV_STORAGE_MAGIC_VAL;
storage->block_size = block_size;
__END__;
}
/* initializes child memory storage */
void
icvInitChildMemStorage( CvMemStorage* parent, CvMemStorage* storage )
{
CV_FUNCNAME( "icvInitChildMemStorage" );
__BEGIN__;
if( !storage || !parent )
CV_ERROR( CV_StsNullPtr, "" );
CV_CALL( icvInitMemStorage( storage, parent->block_size ));
storage->parent = parent;
__END__;
}
/* creates root memory storage */
CV_IMPL CvMemStorage*
cvCreateMemStorage( int block_size )
{
CvMemStorage *storage = 0;
CV_FUNCNAME( "cvCreateMemStorage" );
__BEGIN__;
CV_CALL( storage = (CvMemStorage *)cvAlloc( sizeof( CvMemStorage )));
CV_CALL( icvInitMemStorage( storage, block_size ));
__END__;
if( cvGetErrStatus() < 0 )
cvFree( (void**)&storage );
return storage;
}
/* creates child memory storage */
CV_IMPL CvMemStorage *
cvCreateChildMemStorage( CvMemStorage * parent )
{
CvMemStorage *storage = 0;
CV_FUNCNAME( "cvCreateChildMemStorage" );
__BEGIN__;
if( !parent )
CV_ERROR( CV_StsNullPtr, "" );
CV_CALL( storage = cvCreateMemStorage(parent->block_size));
storage->parent = parent;
__END__;
if( cvGetErrStatus() < 0 )
cvFree( (void**)&storage );
return storage;
}
/* releases all blocks of the storage (or returns them to parent if any) */
void
icvDestroyMemStorage( CvMemStorage* storage )
{
CV_FUNCNAME( "icvDestroyMemStorage" );
__BEGIN__;
int k = 0;
CvMemBlock *block;
CvMemBlock *dst_top = 0;
if( !storage )
CV_ERROR( CV_StsNullPtr, "" );
if( storage->parent )
dst_top = storage->parent->top;
for( block = storage->bottom; block != 0; k++ )
{
CvMemBlock *temp = block;
block = block->next;
if( storage->parent )
{
if( dst_top )
{
temp->prev = dst_top;
temp->next = dst_top->next;
if( temp->next )
temp->next->prev = temp;
dst_top = dst_top->next = temp;
}
else
{
dst_top = storage->parent->bottom = storage->parent->top = temp;
temp->prev = temp->next = 0;
storage->free_space = storage->block_size - sizeof( *temp );
}
}
else
{
cvFree( (void**)&temp );
}
}
storage->top = storage->bottom = 0;
storage->free_space = 0;
__END__;
}
/* releases memory storage */
CV_IMPL void
cvReleaseMemStorage( CvMemStorage** storage )
{
CvMemStorage *st;
CV_FUNCNAME( "cvReleaseMemStorage" );
__BEGIN__;
if( !storage )
CV_ERROR( CV_StsNullPtr, "" );
st = *storage;
*storage = 0;
if( st )
{
CV_CALL( icvDestroyMemStorage( st ));
cvFree( (void**)&st );
}
__END__;
}
/* clears memory storage (returns blocks to the parent if any) */
CV_IMPL void
cvClearMemStorage( CvMemStorage * storage )
{
CV_FUNCNAME( "cvClearMemStorage" );
__BEGIN__;
if( !storage )
CV_ERROR( CV_StsNullPtr, "" );
if( storage->parent )
{
icvDestroyMemStorage( storage );
}
else
{
storage->top = storage->bottom;
storage->free_space = storage->bottom ? storage->block_size - sizeof(CvMemBlock) : 0;
}
__END__;
}
/* moves stack pointer to next block.
If no blocks, allocate new one and link it to the storage */
static void
icvGoNextMemBlock( CvMemStorage * storage )
{
CV_FUNCNAME( "icvGoNextMemBlock" );
__BEGIN__;
if( !storage )
CV_ERROR( CV_StsNullPtr, "" );
if( !storage->top || !storage->top->next )
{
CvMemBlock *block;
if( !(storage->parent) )
{
CV_CALL( block = (CvMemBlock *)cvAlloc( storage->block_size ));
}
else
{
CvMemStorage *parent = storage->parent;
CvMemStoragePos parent_pos;
cvSaveMemStoragePos( parent, &parent_pos );
CV_CALL( icvGoNextMemBlock( parent ));
block = parent->top;
cvRestoreMemStoragePos( parent, &parent_pos );
if( block == parent->top ) /* the single allocated block */
{
assert( parent->bottom == block );
parent->top = parent->bottom = 0;
parent->free_space = 0;
}
else
{
/* cut the block from the parent's list of blocks */
parent->top->next = block->next;
if( block->next )
block->next->prev = parent->top;
}
}
/* link block */
block->next = 0;
block->prev = storage->top;
if( storage->top )
storage->top->next = block;
else
storage->top = storage->bottom = block;
}
if( storage->top->next )
storage->top = storage->top->next;
storage->free_space = storage->block_size - sizeof(CvMemBlock);
assert( storage->free_space % CV_STRUCT_ALIGN == 0 );
__END__;
}
/* remembers memory storage position */
CV_IMPL void
cvSaveMemStoragePos( const CvMemStorage * storage, CvMemStoragePos * pos )
{
CV_FUNCNAME( "cvSaveMemStoragePos" );
__BEGIN__;
if( !storage || !pos )
CV_ERROR( CV_StsNullPtr, "" );
pos->top = storage->top;
pos->free_space = storage->free_space;
__END__;
}
/* restores memory storage position */
CV_IMPL void
cvRestoreMemStoragePos( CvMemStorage * storage, CvMemStoragePos * pos )
{
CV_FUNCNAME( "cvRestoreMemStoragePos" );
__BEGIN__;
if( !storage || !pos )
CV_ERROR( CV_StsNullPtr, "" );
if( pos->free_space > storage->block_size )
CV_ERROR_FROM_STATUS( CV_BADSIZE_ERR );
storage->top = pos->top;
storage->free_space = pos->free_space;
if( !storage->top )
{
storage->top = storage->bottom;
storage->free_space = storage->top ? storage->block_size - sizeof(CvMemBlock) : 0;
}
__END__;
}
/* Allocates continuous buffer of the specified size in the storage */
CV_IMPL void*
cvMemStorageAlloc( CvMemStorage* storage, int size )
{
char *ptr = 0;
CV_FUNCNAME( "cvMemStorageAlloc" );
__BEGIN__;
if( !storage )
CV_ERROR( CV_StsNullPtr, "NULL storage pointer" );
assert( storage->free_space % CV_STRUCT_ALIGN == 0 );
if( (unsigned)storage->free_space < (unsigned)size )
{
int max_free_space =
(storage->block_size - (int)sizeof(CvMemBlock)) & -CV_STRUCT_ALIGN;
if( (unsigned)max_free_space < (unsigned)size )
CV_ERROR( CV_StsOutOfRange, "requested size is negative or too big" );
CV_CALL( icvGoNextMemBlock( storage ));
}
ptr = ICV_FREE_PTR(storage);
assert( (long)ptr % CV_STRUCT_ALIGN == 0 );
storage->free_space = (storage->free_space - size) & -CV_STRUCT_ALIGN;
__END__;
return ptr;
}
/****************************************************************************************\
* Sequence implementation *
\****************************************************************************************/
/* creates empty sequence */
CV_IMPL CvSeq *
cvCreateSeq( int seq_flags, int header_size, int elem_size, CvMemStorage * storage )
{
CvSeq *seq = 0;
CV_FUNCNAME( "cvCreateSeq" );
__BEGIN__;
if( !storage )
CV_ERROR( CV_StsNullPtr, "" );
if( header_size < (int)sizeof( CvSeq ) || elem_size <= 0 )
CV_ERROR( CV_StsBadSize, "" );
/* allocate sequence header */
CV_CALL( seq = (CvSeq*)cvMemStorageAlloc( storage, header_size ));
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 = icvPixSize[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->storage = storage;
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 void
cvSetSeqBlockSize( 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 = (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;
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( CvSeq *seq, int index, CvSeqBlock **_block )
{
CvSeqBlock *block;
char *elem = 0;
int count, total;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?