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 + -
显示快捷键?