cvpersistence.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 2,051 行 · 第 1/5 页
SVN-BASE
2,051 行
buffer[0] = '\0';
is_id = strcmp( name_start, "id" ) == 0;
if( free_attr == 0 )
{
// allocate another chunk of attributes
CvAttrList* new_attr;
CV_CALL( new_attr = (CvAttrList*)cvMemStorageAlloc(
storage->memstorage,
sizeof(*new_attr) + (chunk_size+1)*2*sizeof(char*)));
new_attr->attr = (char**)(new_attr+1);
new_attr->next = 0;
if( !last_attr )
node->attr = new_attr;
else
{
*attr_arr = 0;
last_attr->next = new_attr;
}
last_attr = new_attr;
attr_arr = new_attr->attr;
free_attr = chunk_size;
}
*attr_arr++ = name_start;
if( c == '=' )
need = ICV_NEED_ATTRVAL;
else
{
if( !isspace(c))
EXIT;
need = ICV_NEED_EQSIGN;
goto skip_read;
}
}
}
else if( c == '=' )
{
if( need != ICV_NEED_EQSIGN )
EXIT; // unexpected character
else
need = ICV_NEED_ATTRVAL;
}
else if( c == '\"' || c == '\'' )
{
if( need != ICV_NEED_ATTRVAL )
EXIT; // unexpected character
else
{
int quot_char = c;
char* val_start = ++buffer;
char* val_end = 0;
for( ; buffer < storage->buffer_end; buffer++ )
{
c = buffer[0];
if( isspace(c))
{
process_space();
continue;
}
if( c == quot_char )
{
val_end = buffer;
*val_end = '\0';
break;
}
}
if( !val_end )
EXIT; // the attribute value is not closed
*attr_arr++ = val_start;
if( is_id )
{
if( node->name )
EXIT; // repeated 'id = "..."'
else
node->name = val_start;
}
need = ICV_NEED_ATTRNAME;
}
}
else if( c == '/' )
{
if( need != ICV_NEED_ATTRNAME )
EXIT; // unexpected character
else if( buffer[1] != '>' )
EXIT; // '>' is expected after '/'
else
{
is_empty = 1;
buffer += 2;
break;
}
}
else if( c == '>' )
{
if( need != ICV_NEED_ATTRNAME )
EXIT; // unexpected character
else
{
buffer++;
break;
}
}
else
EXIT; // unexpected character;
}
if( attr_arr )
*attr_arr++ = 0;
if( !node->tagname )
EXIT; // dummy empty tag (e.g. <>)
if( tag == ICV_CLOSING_TAG )
{
if( attr_arr )
EXIT; // closing tag has attributes
if( !storage->parent || !storage->parent->tagname ||
strcmp( storage->parent->tagname, node->tagname ) != 0 )
EXIT; // unmatched names in the opening and closing tags
storage->parent = storage->parent->v_prev;
if( storage->parent == 0 )
{
result = 1; // XML has been read completely and
// its structure seems to be correct
break;
}
}
else
{
char* type_name;
if( node->name )
if( icvQueryName( storage, node->name, node ) != node )
EXIT; // duplicated id
type_name = (char*)cvAttrValue( node->attr, "type" );
if( type_name )
CV_CALL( node->typeinfo = cvFindType( type_name ));
if( !storage->root )
{
storage->root = node;
if( is_empty )
EXIT; // the first tag (<opencv_storage>) must be non-empty
}
else
cvInsertNodeIntoTree( node, storage->parent, 0 );
if( !is_empty )
storage->parent = node;
node->body = buffer;
}
}
__END__;
return result;
}
/************************ standard types *************************/
/*********************** CvMat or CvMatND ************************/
static int
icvIsMat( const void* ptr )
{
return CV_IS_MAT(ptr);
}
static int
icvIsMatND( const void* ptr )
{
return CV_IS_MATND(ptr);
}
static void
icvWriteArray( CvFileStorage* storage, const char* name,
const void* struct_ptr, CvAttrList attr, int /*flags*/ )
{
CV_FUNCNAME( "icvWriteArray" );
__BEGIN__;
char dt_buf[16];
char size_buf[10*CV_MAX_DIM];
int format;
char* new_attr[10];
int idx = 0;
CvMat* mat = (CvMat*)struct_ptr;
CvMatND header;
CvMatNDIterator iterator;
if( !icvIsMat(mat) && !icvIsMatND(mat))
CV_ERROR( CV_StsBadArg, "The input structure is not an array" );
new_attr[idx++] = "dt";
sprintf( dt_buf, "%d%c", CV_MAT_CN(mat->type),
icvTypeSymbol[CV_MAT_DEPTH(mat->type)] );
new_attr[idx++] = dt_buf + ICV_DT_SHIFT(dt_buf);
new_attr[idx++] = "size";
if( CV_IS_MAT(mat))
sprintf( size_buf, "%d %d", mat->rows, mat->cols );
else
{
CvMatND* matnd = (CvMatND*)struct_ptr;
int i, size_buf_len = 0;
for( i = 0; i < matnd->dims; i++ )
{
int dl = 0;
sprintf( size_buf + size_buf_len, "%s%d%n", i == 0 ? "" : " ",
matnd->dim[i].size, &dl );
size_buf_len += dl;
}
}
new_attr[idx++] = size_buf;
new_attr[idx++] = "format";
if( ICV_IS_BINARY(storage) )
{
format = ICV_FORMAT_BINARY;
new_attr[idx++] = "xdr.base64";
}
else
{
format = ICV_FORMAT_TEXT;
new_attr[idx++] = "text";
}
new_attr[idx++] = 0;
CV_CALL( cvStartWriteStruct( storage, name, CV_IS_MAT(mat) ? "CvMat" : "CvMatND",
struct_ptr, cvAttrList(new_attr, &attr)));
CV_CALL( icvPrepareArrayOp( 1, (void**)&struct_ptr, 0, &header, &iterator ));
iterator.size.width *= CV_MAT_CN(mat->type);
do
{
CV_CALL( icvWriteRawData( storage, dt_buf + 1, format,
iterator.ptr[0], iterator.size.width ));
}
while( icvNextMatNDSlice( &iterator ));
CV_CALL( cvEndWriteStruct( storage ));
__END__;
}
static void*
icvReadArray( CvFileStorage* storage, CvFileNode* node )
{
void* ptr = 0;
CV_FUNCNAME( "icvReadArray" );
__BEGIN__;
int size[CV_MAX_DIM+1], dims;
int pl, type = 0, format;
CvMatND header;
CvMatNDIterator iterator;
const char* size_buf;
const char* dt;
const char* format_buf;
const char* pos;
int is_matnd;
assert( node && node->tagname && strcmp( node->tagname, "struct" ) == 0 && node->typeinfo &&
(strcmp( node->typeinfo->type_name, "CvMat") == 0 ||
strcmp( node->typeinfo->type_name, "CvMatND") == 0));
is_matnd = strcmp( node->typeinfo->type_name, "CvMatND") == 0;
size_buf = cvAttrValue( node->attr, "size" );
format_buf = cvAttrValue( node->attr, "format" );
dt = cvAttrValue( node->attr, "dt" );
if( !size_buf || !format_buf || !dt )
EXIT;
pl = strlen(dt);
if( pl != 1 && (pl != 2 || !isdigit(dt[0])))
EXIT;
pos = strchr( icvTypeSymbol, dt[pl-1] );
if( !pos )
EXIT;
type = pos - icvTypeSymbol;
if( pl == 2 )
{
if( dt[0] - '0' < 1 || dt[0] - '0' > 4 )
EXIT;
type += (dt[0] - '0')*8;
}
memset( size, 0, sizeof(size));
storage->buffer = (char*)size_buf;
icvReadRawData( storage, "i", ICV_FORMAT_TEXT, size, CV_MAX_DIM );
for( dims = 0; size[dims] != 0; dims++ )
if( size[dims] < 0 )
EXIT;
if( dims < 1 )
EXIT;
if( strcmp( format_buf, "text" ) == 0 )
format = ICV_FORMAT_TEXT;
else if( strcmp( format_buf, "xdr.base64" ) == 0 )
format = ICV_FORMAT_BINARY;
else
EXIT;
if( is_matnd )
{
CV_CALL( node->content = cvCreateMatND( dims, size, type ));
}
else
{
CV_CALL( node->content = cvCreateMat( size[0], dims > 1 ? size[1] : 1, type ));
}
CV_CALL( icvPrepareArrayOp( 1, (void**)&node->content, 0, &header, &iterator ));
iterator.size.width *= CV_MAT_CN(type);
storage->buffer = (char*)node->body;
storage->base64_buffer_read = storage->base64_buffer = storage->base64_buffer_start;
do
{
if( !icvReadRawData( storage, dt + pl - 1, format,
iterator.ptr[0], iterator.size.width ))
EXIT;
}
while( icvNextMatNDSlice( &iterator ));
ptr = (void*)node->content;
__END__;
if( !ptr && node )
cvRelease( (void**)&node->content );
return ptr;
}
/******************************* IplImage ******************************/
static int
icvIsImage( const void* ptr )
{
return CV_IS_IMAGE(ptr);
}
static void
icvWriteImage( CvFileStorage* storage, const char* name,
const void* struct_ptr, CvAttrList attr, int /*flags*/ )
{
CV_FUNCNAME( "icvWriteImage" );
__BEGIN__;
char dt_buf[16];
char width_buf[16];
char height_buf[16];
char roi_buf[32];
int format, depth;
int y, width_n;
const char* new_attr[20];
int idx = 0;
IplImage* img = (IplImage*)struct_ptr;
if( !icvIsImage(img) )
CV_ERROR( CV_StsBadArg, "The input structure is not an IplImage" );
if( img->nChannels > 1 && img->dataOrder == IPL_DATA_ORDER_PLANE )
CV_ERROR( CV_StsBadArg, "Planar IplImage data layout is not supported" );
if( img->nChannels > 4 )
CV_ERROR( CV_BadDepth, "Unsupported number of channels" );
depth = icvIplToCvDepth(img->depth);
if( depth < 0 )
CV_ERROR( CV_BadDepth, "Unsupported image depth" );
new_attr[idx++] = "dt";
sprintf( dt_buf, "%d%c", img->nChannels, icvTypeSymbol[depth] );
new_attr[idx++] = dt_buf + ICV_DT_SHIFT(dt_buf);
new_attr[idx++] = "width";
sprintf( width_buf, "%d", img->width );
new_attr[idx++] = width_buf;
new_attr[idx++] = "
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?