Update to 2.0.0 tree from current Fremantle build
[opencv] / cv / src / cvhistogram.cpp
diff --git a/cv/src/cvhistogram.cpp b/cv/src/cvhistogram.cpp
deleted file mode 100644 (file)
index be90e45..0000000
+++ /dev/null
@@ -1,2513 +0,0 @@
-/*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"
-
-/* Creates new histogram */
-CvHistogram *
-cvCreateHist( int dims, int *sizes, CvHistType type, float** ranges, int uniform )
-{
-    CvHistogram *hist = 0;
-
-    CV_FUNCNAME( "cvCreateHist" );
-    __BEGIN__;
-
-    if( (unsigned)dims > CV_MAX_DIM )
-        CV_ERROR( CV_BadOrder, "Number of dimensions is out of range" );
-
-    if( !sizes )
-        CV_ERROR( CV_HeaderIsNull, "Null <sizes> pointer" );
-
-    CV_CALL( hist = (CvHistogram *)cvAlloc( sizeof( CvHistogram )));
-
-    hist->type = CV_HIST_MAGIC_VAL;
-    hist->thresh2 = 0;
-    hist->bins = 0;
-    if( type == CV_HIST_ARRAY )
-    {
-        CV_CALL( hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes,
-                                                 CV_HIST_DEFAULT_TYPE ));
-        CV_CALL( cvCreateData( hist->bins ));
-    }
-    else if( type == CV_HIST_SPARSE )
-    {
-        CV_CALL( hist->bins = cvCreateSparseMat( dims, sizes, CV_HIST_DEFAULT_TYPE ));
-    }
-    else
-    {
-        CV_ERROR( CV_StsBadArg, "Invalid histogram type" );
-    }
-
-    if( ranges )
-        CV_CALL( cvSetHistBinRanges( hist, ranges, uniform ));
-
-    __END__;
-
-    if( cvGetErrStatus() < 0 )
-        cvReleaseHist( &hist );
-
-    return hist;
-}
-
-
-/* Creates histogram wrapping header for given array */
-CV_IMPL CvHistogram*
-cvMakeHistHeaderForArray( int dims, int *sizes, CvHistogram *hist,
-                          float *data, float **ranges, int uniform )
-{
-    CvHistogram* result = 0;
-    
-    CV_FUNCNAME( "cvMakeHistHeaderForArray" );
-
-    __BEGIN__;
-
-    if( !hist )
-        CV_ERROR( CV_StsNullPtr, "Null histogram header pointer" );
-
-    if( !data )
-        CV_ERROR( CV_StsNullPtr, "Null data pointer" );
-
-    hist->thresh2 = 0;
-    hist->type = CV_HIST_MAGIC_VAL;
-    CV_CALL( hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes,
-                                             CV_HIST_DEFAULT_TYPE, data ));
-
-    if( ranges )
-    {
-        if( !uniform )
-            CV_ERROR( CV_StsBadArg, "Only uniform bin ranges can be used here "
-                                    "(to avoid memory allocation)" );
-        CV_CALL( cvSetHistBinRanges( hist, ranges, uniform ));
-    }
-
-    result = hist;
-
-    __END__;
-
-    if( cvGetErrStatus() < 0 && hist )
-    {
-        hist->type = 0;
-        hist->bins = 0;
-    }
-
-    return result;
-}
-
-
-CV_IMPL void
-cvReleaseHist( CvHistogram **hist )
-{
-    CV_FUNCNAME( "cvReleaseHist" );
-    
-    __BEGIN__;
-
-    if( !hist )
-        CV_ERROR( CV_StsNullPtr, "" );
-
-    if( *hist )
-    {
-        CvHistogram* temp = *hist;
-
-        if( !CV_IS_HIST(temp))
-            CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-        *hist = 0;
-
-        if( CV_IS_SPARSE_HIST( temp ))
-            cvRelease( &temp->bins );
-        else
-        {
-            cvReleaseData( temp->bins );
-            temp->bins = 0;
-        }
-        
-        if( temp->thresh2 )
-            cvFree( &temp->thresh2 );
-
-        cvFree( &temp );
-    }
-
-    __END__;
-}
-
-CV_IMPL void
-cvClearHist( CvHistogram *hist )
-{
-    CV_FUNCNAME( "cvClearHist" );
-    
-    __BEGIN__;
-
-    if( !CV_IS_HIST(hist) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-    cvZero( hist->bins );
-
-    __END__;
-}
-
-
-// Clears histogram bins that are below than threshold
-CV_IMPL void
-cvThreshHist( CvHistogram* hist, double thresh )
-{
-    CV_FUNCNAME( "cvThreshHist" );
-
-    __BEGIN__;
-
-    if( !CV_IS_HIST(hist) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-    if( !CV_IS_SPARSE_MAT(hist->bins) )
-    {
-        CvMat mat;
-        CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
-        CV_CALL( cvThreshold( &mat, &mat, thresh, 0, CV_THRESH_TOZERO ));
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)hist->bins;
-        CvSparseMatIterator iterator;
-        CvSparseNode *node;
-        
-        for( node = cvInitSparseMatIterator( mat, &iterator );
-             node != 0; node = cvGetNextSparseNode( &iterator ))
-        {
-            float* val = (float*)CV_NODE_VAL( mat, node );
-            if( *val <= thresh )
-                *val = 0;
-        }
-    }
-    
-    __END__;
-}
-
-
-// Normalizes histogram (make sum of the histogram bins == factor)
-CV_IMPL void
-cvNormalizeHist( CvHistogram* hist, double factor )
-{
-    double sum = 0;
-
-    CV_FUNCNAME( "cvNormalizeHist" );
-    __BEGIN__;
-
-    if( !CV_IS_HIST(hist) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-    if( !CV_IS_SPARSE_HIST(hist) )
-    {
-        CvMat mat;
-        CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
-        CV_CALL( sum = cvSum( &mat ).val[0] );
-        if( fabs(sum) < DBL_EPSILON )
-            sum = 1;
-        CV_CALL( cvScale( &mat, &mat, factor/sum, 0 ));
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)hist->bins;
-        CvSparseMatIterator iterator;
-        CvSparseNode *node;
-        float scale;
-        
-        for( node = cvInitSparseMatIterator( mat, &iterator );
-             node != 0; node = cvGetNextSparseNode( &iterator ))
-        {
-            sum += *(float*)CV_NODE_VAL(mat,node);
-        }
-
-        if( fabs(sum) < DBL_EPSILON )
-            sum = 1;
-        scale = (float)(factor/sum);
-
-        for( node = cvInitSparseMatIterator( mat, &iterator );
-             node != 0; node = cvGetNextSparseNode( &iterator ))
-        {
-            *(float*)CV_NODE_VAL(mat,node) *= scale;
-        }
-    }
-
-    __END__;
-}
-
-
-// Retrieves histogram global min, max and their positions
-CV_IMPL void
-cvGetMinMaxHistValue( const CvHistogram* hist,
-                      float *value_min, float* value_max,
-                      int* idx_min, int* idx_max )
-{
-    double minVal, maxVal;
-
-    CV_FUNCNAME( "cvGetMinMaxHistValue" );
-
-    __BEGIN__;
-
-    int i, dims, size[CV_MAX_DIM];
-
-    if( !CV_IS_HIST(hist) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-    dims = cvGetDims( hist->bins, size );
-
-    if( !CV_IS_SPARSE_HIST(hist) )
-    {
-        CvMat mat;
-        CvPoint minPt, maxPt;
-
-        CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
-        CV_CALL( cvMinMaxLoc( &mat, &minVal, &maxVal, &minPt, &maxPt ));
-
-        if( dims == 1 )
-        {
-            if( idx_min )
-                *idx_min = minPt.y + minPt.x;
-            if( idx_max )
-                *idx_max = maxPt.y + maxPt.x;
-        }
-        else if( dims == 2 )
-        {
-            if( idx_min )
-                idx_min[0] = minPt.y, idx_min[1] = minPt.x;
-            if( idx_max )
-                idx_max[0] = maxPt.y, idx_max[1] = maxPt.x;
-        }
-        else if( idx_min || idx_max )
-        {
-            int imin = minPt.y*mat.cols + minPt.x;
-            int imax = maxPt.y*mat.cols + maxPt.x;
-            int i;
-           
-            for( i = dims - 1; i >= 0; i-- )
-            {
-                if( idx_min )
-                {
-                    int t = imin / size[i];
-                    idx_min[i] = imin - t*size[i];
-                    imin = t;
-                }
-
-                if( idx_max )
-                {
-                    int t = imax / size[i];
-                    idx_max[i] = imax - t*size[i];
-                    imax = t;
-                }
-            }
-        }
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)hist->bins;
-        CvSparseMatIterator iterator;
-        CvSparseNode *node;
-        int minv = INT_MAX;
-        int maxv = INT_MIN;
-        CvSparseNode* minNode = 0;
-        CvSparseNode* maxNode = 0;
-        const int *_idx_min = 0, *_idx_max = 0;
-        Cv32suf m;
-
-        for( node = cvInitSparseMatIterator( mat, &iterator );
-             node != 0; node = cvGetNextSparseNode( &iterator ))
-        {
-            int value = *(int*)CV_NODE_VAL(mat,node);
-            value = CV_TOGGLE_FLT(value);
-            if( value < minv )
-            {
-                minv = value;
-                minNode = node;
-            }
-
-            if( value > maxv )
-            {
-                maxv = value;
-                maxNode = node;
-            }
-        }
-
-        if( minNode )
-        {
-            _idx_min = CV_NODE_IDX(mat,minNode);
-            _idx_max = CV_NODE_IDX(mat,maxNode);
-            m.i = CV_TOGGLE_FLT(minv); minVal = m.f;
-            m.i = CV_TOGGLE_FLT(maxv); maxVal = m.f;
-        }
-        else
-        {
-            minVal = maxVal = 0;
-        }
-
-        for( i = 0; i < dims; i++ )
-        {
-            if( idx_min )
-                idx_min[i] = _idx_min ? _idx_min[i] : -1;
-            if( idx_max )
-                idx_max[i] = _idx_max ? _idx_max[i] : -1;
-        }
-    }
-
-    if( value_min )
-        *value_min = (float)minVal;
-
-    if( value_max )
-        *value_max = (float)maxVal;
-
-    __END__;
-}
-
-
-// Compares two histograms using one of a few methods
-CV_IMPL double
-cvCompareHist( const CvHistogram* hist1,
-               const CvHistogram* hist2,
-               int method )
-{
-    double _result = -1;
-    
-    CV_FUNCNAME( "cvCompareHist" );
-
-    __BEGIN__;
-
-    int i, dims1, dims2;
-    int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
-    double result = 0;
-        
-    if( !CV_IS_HIST(hist1) || !CV_IS_HIST(hist2) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header[s]" );
-
-    if( CV_IS_SPARSE_MAT(hist1->bins) != CV_IS_SPARSE_MAT(hist2->bins))
-        CV_ERROR(CV_StsUnmatchedFormats, "One of histograms is sparse and other is not");
-
-    CV_CALL( dims1 = cvGetDims( hist1->bins, size1 ));
-    CV_CALL( dims2 = cvGetDims( hist2->bins, size2 ));
-    
-    if( dims1 != dims2 )
-        CV_ERROR( CV_StsUnmatchedSizes,
-                  "The histograms have different numbers of dimensions" );
-
-    for( i = 0; i < dims1; i++ )
-    {
-        if( size1[i] != size2[i] )
-            CV_ERROR( CV_StsUnmatchedSizes, "The histograms have different sizes" );
-        total *= size1[i];
-    }
-
-
-    if( !CV_IS_SPARSE_MAT(hist1->bins))
-    {
-        union { float* fl; uchar* ptr; } v;
-        float *ptr1, *ptr2;
-        v.fl = 0;
-        CV_CALL( cvGetRawData( hist1->bins, &v.ptr ));
-        ptr1 = v.fl;
-        CV_CALL( cvGetRawData( hist2->bins, &v.ptr ));
-        ptr2 = v.fl;
-
-        switch( method )
-        {
-        case CV_COMP_CHISQR:
-            for( i = 0; i < total; i++ )
-            {
-                double a = ptr1[i] - ptr2[i];
-                double b = ptr1[i] + ptr2[i];
-                if( fabs(b) > DBL_EPSILON )
-                    result += a*a/b;
-            }
-            break;
-        case CV_COMP_CORREL:
-            {
-                double s1 = 0, s11 = 0;
-                double s2 = 0, s22 = 0;
-                double s12 = 0;
-                double num, denom2, scale = 1./total;
-                
-                for( i = 0; i < total; i++ )
-                {
-                    double a = ptr1[i];
-                    double b = ptr2[i];
-
-                    s12 += a*b;
-                    s1 += a;
-                    s11 += a*a;
-                    s2 += b;
-                    s22 += b*b;
-                }
-
-                num = s12 - s1*s2*scale;
-                denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
-                result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1;
-            }
-            break;
-        case CV_COMP_INTERSECT:
-            for( i = 0; i < total; i++ )
-            {
-                float a = ptr1[i];
-                float b = ptr2[i];
-                if( a <= b )
-                    result += a;
-                else
-                    result += b;
-            }
-            break;
-        case CV_COMP_BHATTACHARYYA:
-            {
-                double s1 = 0, s2 = 0;
-                for( i = 0; i < total; i++ )
-                {
-                    double a = ptr1[i];
-                    double b = ptr2[i];
-                    result += sqrt(a*b);
-                    s1 += a;
-                    s2 += b;
-                }
-                s1 *= s2;
-                s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.;
-                result = 1. - result*s1;
-                result = sqrt(MAX(result,0.));
-            }
-            break;
-        default:
-            CV_ERROR( CV_StsBadArg, "Unknown comparison method" );
-        }
-    }
-    else
-    {
-        CvSparseMat* mat1 = (CvSparseMat*)(hist1->bins);
-        CvSparseMat* mat2 = (CvSparseMat*)(hist2->bins);
-        CvSparseMatIterator iterator;
-        CvSparseNode *node1, *node2;
-
-        if( mat1->heap->active_count > mat2->heap->active_count )
-        {
-            CvSparseMat* t;
-            CV_SWAP( mat1, mat2, t );
-        }
-
-        switch( method )
-        {
-        case CV_COMP_CHISQR:
-            for( node1 = cvInitSparseMatIterator( mat1, &iterator );
-                 node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
-            {
-                double v1 = *(float*)CV_NODE_VAL(mat1,node1);
-                uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), 0, 0, &node1->hashval );
-                if( !node2_data )
-                    result += v1;
-                else
-                {
-                    double v2 = *(float*)node2_data;
-                    double a = v1 - v2;
-                    double b = v1 + v2;
-                    if( fabs(b) > DBL_EPSILON )
-                        result += a*a/b;
-                }
-            }
-
-            for( node2 = cvInitSparseMatIterator( mat2, &iterator );
-                 node2 != 0; node2 = cvGetNextSparseNode( &iterator ))
-            {
-                double v2 = *(float*)CV_NODE_VAL(mat2,node2);
-                if( !cvPtrND( mat1, CV_NODE_IDX(mat2,node2), 0, 0, &node2->hashval ))
-                    result += v2;
-            }
-            break;
-        case CV_COMP_CORREL:
-            {
-                double s1 = 0, s11 = 0;
-                double s2 = 0, s22 = 0;
-                double s12 = 0;
-                double num, denom2, scale = 1./total;
-                
-                for( node1 = cvInitSparseMatIterator( mat1, &iterator );
-                     node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
-                {
-                    double v1 = *(float*)CV_NODE_VAL(mat1,node1);
-                    uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
-                                                 0, 0, &node1->hashval );
-                    if( node2_data )
-                    {
-                        double v2 = *(float*)node2_data;
-                        s12 += v1*v2;
-                    }
-                    s1 += v1;
-                    s11 += v1*v1;
-                }
-
-                for( node2 = cvInitSparseMatIterator( mat2, &iterator );
-                     node2 != 0; node2 = cvGetNextSparseNode( &iterator ))
-                {
-                    double v2 = *(float*)CV_NODE_VAL(mat2,node2);
-                    s2 += v2;
-                    s22 += v2*v2;
-                }
-
-                num = s12 - s1*s2*scale;
-                denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
-                result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1;
-            }
-            break;
-        case CV_COMP_INTERSECT:
-            {
-                for( node1 = cvInitSparseMatIterator( mat1, &iterator );
-                     node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
-                {
-                    float v1 = *(float*)CV_NODE_VAL(mat1,node1);
-                    uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
-                                                 0, 0, &node1->hashval );
-                    if( node2_data )
-                    {
-                        float v2 = *(float*)node2_data;
-                        if( v1 <= v2 )
-                            result += v1;
-                        else
-                            result += v2;
-                    }
-                }
-            }
-            break;
-        case CV_COMP_BHATTACHARYYA:
-            {
-                double s1 = 0, s2 = 0;
-                
-                for( node1 = cvInitSparseMatIterator( mat1, &iterator );
-                     node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
-                {
-                    double v1 = *(float*)CV_NODE_VAL(mat1,node1);
-                    uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
-                                                 0, 0, &node1->hashval );
-                    s1 += v1;
-                    if( node2_data )
-                    {
-                        double v2 = *(float*)node2_data;
-                        result += sqrt(v1 * v2);
-                    }
-                }
-
-                for( node1 = cvInitSparseMatIterator( mat2, &iterator );
-                     node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
-                {
-                    double v2 = *(float*)CV_NODE_VAL(mat2,node1);
-                    s2 += v2;
-                }
-
-                s1 *= s2;
-                s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.;
-                result = 1. - result*s1;
-                result = sqrt(MAX(result,0.));
-            }
-            break;
-        default:
-            CV_ERROR( CV_StsBadArg, "Unknown comparison method" );
-        }
-    }
-
-    _result = result;
-    
-    __END__;
-    
-    return _result;
-}
-
-// copies one histogram to another
-CV_IMPL void
-cvCopyHist( const CvHistogram* src, CvHistogram** _dst )
-{
-    CV_FUNCNAME( "cvCopyHist" );
-
-    __BEGIN__;
-
-    int eq = 0;
-    int is_sparse;
-    int i, dims1, dims2;
-    int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
-    float* ranges[CV_MAX_DIM];
-    float** thresh = 0;
-    CvHistogram* dst;
-    
-    if( !_dst )
-        CV_ERROR( CV_StsNullPtr, "Destination double pointer is NULL" );
-
-    dst = *_dst;
-
-    if( !CV_IS_HIST(src) || (dst && !CV_IS_HIST(dst)) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header[s]" );
-
-    is_sparse = CV_IS_SPARSE_MAT(src->bins);
-    CV_CALL( dims1 = cvGetDims( src->bins, size1 ));
-    for( i = 0; i < dims1; i++ )
-        total *= size1[i];
-
-    if( dst && is_sparse == CV_IS_SPARSE_MAT(dst->bins))
-    {
-        CV_CALL( dims2 = cvGetDims( dst->bins, size2 ));
-    
-        if( dims1 == dims2 )
-        {
-            for( i = 0; i < dims1; i++ )
-                if( size1[i] != size2[i] )
-                    break;
-        }
-
-        eq = i == dims1;
-    }
-
-    if( !eq )
-    {
-        cvReleaseHist( _dst );
-        CV_CALL( dst = cvCreateHist( dims1, size1,
-                 !is_sparse ? CV_HIST_ARRAY : CV_HIST_SPARSE, 0, 0 ));
-        *_dst = dst;
-    }
-
-    if( CV_HIST_HAS_RANGES( src ))
-    {
-        if( CV_IS_UNIFORM_HIST( src ))
-        {
-            for( i = 0; i < dims1; i++ )
-                ranges[i] = (float*)src->thresh[i];
-            thresh = ranges;
-        }
-        else
-            thresh = src->thresh2;
-        CV_CALL( cvSetHistBinRanges( dst, thresh, CV_IS_UNIFORM_HIST(src)));
-    }
-
-    CV_CALL( cvCopy( src->bins, dst->bins ));
-    
-    __END__;
-}
-
-
-// Sets a value range for every histogram bin
-CV_IMPL void
-cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform )
-{
-    CV_FUNCNAME( "cvSetHistBinRanges" );
-    
-    __BEGIN__;
-
-    int dims, size[CV_MAX_DIM], total = 0;
-    int i, j;
-    
-    if( !ranges )
-        CV_ERROR( CV_StsNullPtr, "NULL ranges pointer" );
-
-    if( !CV_IS_HIST(hist) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-    CV_CALL( dims = cvGetDims( hist->bins, size ));
-    for( i = 0; i < dims; i++ )
-        total += size[i]+1;
-    
-    if( uniform )
-    {
-        for( i = 0; i < dims; i++ )
-        {
-            if( !ranges[i] )
-                CV_ERROR( CV_StsNullPtr, "One of <ranges> elements is NULL" );
-            hist->thresh[i][0] = ranges[i][0];
-            hist->thresh[i][1] = ranges[i][1];
-        }
-
-        hist->type |= CV_HIST_UNIFORM_FLAG + CV_HIST_RANGES_FLAG;
-    }
-    else
-    {
-        float* dim_ranges;
-
-        if( !hist->thresh2 )
-        {
-            CV_CALL( hist->thresh2 = (float**)cvAlloc(
-                        dims*sizeof(hist->thresh2[0])+
-                        total*sizeof(hist->thresh2[0][0])));
-        }
-        dim_ranges = (float*)(hist->thresh2 + dims);
-
-        for( i = 0; i < dims; i++ )
-        {
-            float val0 = -FLT_MAX;
-
-            if( !ranges[i] )
-                CV_ERROR( CV_StsNullPtr, "One of <ranges> elements is NULL" );
-            
-            for( j = 0; j <= size[i]; j++ )
-            {
-                float val = ranges[i][j];
-                if( val <= val0 )
-                    CV_ERROR(CV_StsOutOfRange, "Bin ranges should go in ascenting order");
-                val0 = dim_ranges[j] = val;
-            }
-
-            hist->thresh2[i] = dim_ranges;
-            dim_ranges += size[i] + 1;
-        }
-
-        hist->type |= CV_HIST_RANGES_FLAG;
-        hist->type &= ~CV_HIST_UNIFORM_FLAG;
-    }
-
-    __END__;
-}
-
-
-#define  ICV_HIST_DUMMY_IDX  (INT_MIN/3)
-
-static CvStatus
-icvCalcHistLookupTables8u( const CvHistogram* hist, int dims, int* size, int* tab )
-{
-    const int lo = 0, hi = 256;
-    int is_sparse = CV_IS_SPARSE_HIST( hist );
-    int have_range = CV_HIST_HAS_RANGES(hist);
-    int i, j;
-    
-    if( !have_range || CV_IS_UNIFORM_HIST(hist))
-    {
-        for( i = 0; i < dims; i++ )
-        {
-            double a = have_range ? hist->thresh[i][0] : 0;
-            double b = have_range ? hist->thresh[i][1] : 256;
-            int sz = size[i];
-            double scale = sz/(b - a);
-            int step = 1;
-
-            if( !is_sparse )
-                step = ((CvMatND*)(hist->bins))->dim[i].step/sizeof(float);
-
-            for( j = lo; j < hi; j++ )
-            {
-                int idx = cvFloor((j - a)*scale);
-                if( (unsigned)idx < (unsigned)sz )
-                    idx *= step;
-                else
-                    idx = ICV_HIST_DUMMY_IDX;
-
-                tab[i*(hi - lo) + j - lo] = idx;
-            }
-        }
-    }
-    else
-    {
-        for( i = 0; i < dims; i++ )
-        {
-            double limit = hist->thresh2[i][0];
-            int idx = -1, write_idx = ICV_HIST_DUMMY_IDX, sz = size[i];
-            int step = 1;
-
-            if( !is_sparse )
-                step = ((CvMatND*)(hist->bins))->dim[i].step/sizeof(float);
-
-            if( limit > hi )
-                limit = hi;
-            
-            j = lo;
-            for(;;)
-            {
-                for( ; j < limit; j++ )
-                    tab[i*(hi - lo) + j - lo] = write_idx;
-
-                if( (unsigned)(++idx) < (unsigned)sz )
-                {
-                    limit = hist->thresh2[i][idx+1];
-                    if( limit > hi )
-                        limit = hi;
-                    write_idx = idx*step;
-                }
-                else
-                {
-                    for( ; j < hi; j++ )
-                        tab[i*(hi - lo) + j - lo] = ICV_HIST_DUMMY_IDX;
-                    break;
-                }
-            }
-        }
-    }
-
-    return CV_OK;
-}
-
-
-/***************************** C A L C   H I S T O G R A M *************************/
-
-// Calculates histogram for one or more 8u arrays
-static CvStatus CV_STDCALL
-    icvCalcHist_8u_C1R( uchar** img, int step, uchar* mask, int maskStep,
-                        CvSize size, CvHistogram* hist )
-{
-    int* tab;
-    int is_sparse = CV_IS_SPARSE_HIST(hist);
-    int dims, histsize[CV_MAX_DIM];
-    int i, x;
-    CvStatus status;
-
-    dims = cvGetDims( hist->bins, histsize );
-
-    tab = (int*)cvStackAlloc( dims*256*sizeof(int));
-    status = icvCalcHistLookupTables8u( hist, dims, histsize, tab );
-
-    if( status < 0 )
-        return status;
-
-    if( !is_sparse )
-    {
-        int total = 1;
-        int* bins = ((CvMatND*)(hist->bins))->data.i;
-
-        for( i = 0; i < dims; i++ )
-            total *= histsize[i];
-
-        if( dims <= 3 && total >= -ICV_HIST_DUMMY_IDX )
-            return CV_BADSIZE_ERR; // too big histogram
-
-        switch( dims )
-        {
-        case 1:
-            {
-            int tab1d[256];
-            memset( tab1d, 0, sizeof(tab1d));
-
-            for( ; size.height--; img[0] += step )
-            {
-                uchar* ptr = img[0];
-                if( !mask )
-                {
-                    for( x = 0; x <= size.width - 4; x += 4 )
-                    {
-                        int v0 = ptr[x];
-                        int v1 = ptr[x+1];
-
-                        tab1d[v0]++;
-                        tab1d[v1]++;
-
-                        v0 = ptr[x+2];
-                        v1 = ptr[x+3];
-
-                        tab1d[v0]++;
-                        tab1d[v1]++;
-                    }
-
-                    for( ; x < size.width; x++ )
-                        tab1d[ptr[x]]++;
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                        if( mask[x] )
-                            tab1d[ptr[x]]++;
-                    mask += maskStep;
-                }
-            }
-
-            for( i = 0; i < 256; i++ )
-            {
-                int idx = tab[i];
-                if( idx >= 0 )
-                    bins[idx] += tab1d[i];
-            }
-            }
-            break;
-        case 2:
-            for( ; size.height--; img[0] += step, img[1] += step )
-            {
-                uchar* ptr0 = img[0];
-                uchar* ptr1 = img[1];
-                if( !mask )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = ptr0[x];
-                        int v1 = ptr1[x];
-                        int idx = tab[v0] + tab[256+v1];
-
-                        if( idx >= 0 )
-                            bins[idx]++;
-                    }
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        if( mask[x] )
-                        {
-                            int v0 = ptr0[x];
-                            int v1 = ptr1[x];
-
-                            int idx = tab[v0] + tab[256+v1];
-
-                            if( idx >= 0 )
-                                bins[idx]++;
-                        }
-                    }
-                    mask += maskStep;
-                }
-            }
-            break;
-        case 3:
-            for( ; size.height--; img[0] += step, img[1] += step, img[2] += step )
-            {
-                uchar* ptr0 = img[0];
-                uchar* ptr1 = img[1];
-                uchar* ptr2 = img[2];
-                if( !mask )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = ptr0[x];
-                        int v1 = ptr1[x];
-                        int v2 = ptr2[x];
-                        int idx = tab[v0] + tab[256+v1] + tab[512+v2];
-
-                        if( idx >= 0 )
-                            bins[idx]++;
-                    }
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        if( mask[x] )
-                        {
-                            int v0 = ptr0[x];
-                            int v1 = ptr1[x];
-                            int v2 = ptr2[x];
-                            int idx = tab[v0] + tab[256+v1] + tab[512+v2];
-
-                            if( idx >= 0 )
-                                bins[idx]++;
-                        }
-                    }
-                    mask += maskStep;
-                }
-            }
-            break;
-        default:
-            for( ; size.height--; )
-            {
-                if( !mask )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int* binptr = bins;
-                        for( i = 0; i < dims; i++ )
-                        {
-                            int idx = tab[i*256 + img[i][x]];
-                            if( idx < 0 )
-                                break;
-                            binptr += idx;
-                        }
-                        if( i == dims )
-                            binptr[0]++;
-                    }
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        if( mask[x] )
-                        {
-                            int* binptr = bins;
-                            for( i = 0; i < dims; i++ )
-                            {
-                                int idx = tab[i*256 + img[i][x]];
-                                if( idx < 0 )
-                                    break;
-                                binptr += idx;
-                            }
-                            if( i == dims )
-                                binptr[0]++;
-                        }
-                    }
-                    mask += maskStep;
-                }
-
-                for( i = 0; i < dims; i++ )
-                    img[i] += step;
-            }
-        }
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)(hist->bins);
-        int node_idx[CV_MAX_DIM];
-
-        for( ; size.height--; )
-        {
-            if( !mask )
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    for( i = 0; i < dims; i++ )
-                    {
-                        int idx = tab[i*256 + img[i][x]];
-                        if( idx < 0 )
-                            break;
-                        node_idx[i] = idx;
-                    }
-                    if( i == dims )
-                    {
-                        int* bin = (int*)cvPtrND( mat, node_idx, 0, 1 );
-                        bin[0]++;
-                    }
-                }
-            }
-            else
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    if( mask[x] )
-                    {
-                        for( i = 0; i < dims; i++ )
-                        {
-                            int idx = tab[i*256 + img[i][x]];
-                            if( idx < 0 )
-                                break;
-                            node_idx[i] = idx;
-                        }
-                        if( i == dims )
-                        {
-                            int* bin = (int*)cvPtrND( mat, node_idx, 0, 1, 0 );
-                            bin[0]++;
-                        }
-                    }
-                }
-                mask += maskStep;
-            }
-
-            for( i = 0; i < dims; i++ )
-                img[i] += step;
-        }
-    }
-
-    return CV_OK;
-}
-
-
-// Calculates histogram for one or more 32f arrays
-static CvStatus CV_STDCALL
-    icvCalcHist_32f_C1R( float** img, int step, uchar* mask, int maskStep,
-                         CvSize size, CvHistogram* hist )
-{
-    int is_sparse = CV_IS_SPARSE_HIST(hist);
-    int uniform = CV_IS_UNIFORM_HIST(hist);
-    int dims, histsize[CV_MAX_DIM];
-    double uni_range[CV_MAX_DIM][2];
-    int i, x;
-
-    dims = cvGetDims( hist->bins, histsize );
-    step /= sizeof(img[0][0]);
-
-    if( uniform )
-    {
-        for( i = 0; i < dims; i++ )
-        {
-            double t = histsize[i]/((double)hist->thresh[i][1] - hist->thresh[i][0]);
-            uni_range[i][0] = t;
-            uni_range[i][1] = -t*hist->thresh[i][0];
-        }
-    }
-
-    if( !is_sparse )
-    {
-        CvMatND* mat = (CvMatND*)(hist->bins);
-        int* bins = mat->data.i;
-
-        if( uniform )
-        {
-            switch( dims )
-            {
-            case 1:
-                {
-                double a = uni_range[0][0], b = uni_range[0][1];
-                int sz = histsize[0];
-
-                for( ; size.height--; img[0] += step )
-                {
-                    float* ptr = img[0];
-
-                    if( !mask )
-                    {
-                        for( x = 0; x <= size.width - 4; x += 4 )
-                        {
-                            int v0 = cvFloor(ptr[x]*a + b);
-                            int v1 = cvFloor(ptr[x+1]*a + b);
-
-                            if( (unsigned)v0 < (unsigned)sz )
-                                bins[v0]++;
-                            if( (unsigned)v1 < (unsigned)sz )
-                                bins[v1]++;
-
-                            v0 = cvFloor(ptr[x+2]*a + b);
-                            v1 = cvFloor(ptr[x+3]*a + b);
-
-                            if( (unsigned)v0 < (unsigned)sz )
-                                bins[v0]++;
-                            if( (unsigned)v1 < (unsigned)sz )
-                                bins[v1]++;
-                        }
-
-                        for( ; x < size.width; x++ )
-                        {
-                            int v0 = cvFloor(ptr[x]*a + b);
-                            if( (unsigned)v0 < (unsigned)sz )
-                                bins[v0]++;
-                        }
-                    }
-                    else
-                    {
-                        for( x = 0; x < size.width; x++ )
-                            if( mask[x] )
-                            {
-                                int v0 = cvFloor(ptr[x]*a + b);
-                                if( (unsigned)v0 < (unsigned)sz )
-                                    bins[v0]++;
-                            }
-                        mask += maskStep;
-                    }
-                }
-                }
-                break;
-            case 2:
-                {
-                double  a0 = uni_range[0][0], b0 = uni_range[0][1];
-                double  a1 = uni_range[1][0], b1 = uni_range[1][1];
-                int sz0 = histsize[0], sz1 = histsize[1];
-                int step0 = ((CvMatND*)(hist->bins))->dim[0].step/sizeof(float);
-
-                for( ; size.height--; img[0] += step, img[1] += step )
-                {
-                    float* ptr0 = img[0];
-                    float* ptr1 = img[1];
-
-                    if( !mask )
-                    {
-                        for( x = 0; x < size.width; x++ )
-                        {
-                            int v0 = cvFloor( ptr0[x]*a0 + b0 );
-                            int v1 = cvFloor( ptr1[x]*a1 + b1 );
-
-                            if( (unsigned)v0 < (unsigned)sz0 &&
-                                (unsigned)v1 < (unsigned)sz1 )
-                                bins[v0*step0 + v1]++;
-                        }
-                    }
-                    else
-                    {
-                        for( x = 0; x < size.width; x++ )
-                        {
-                            if( mask[x] )
-                            {
-                                int v0 = cvFloor( ptr0[x]*a0 + b0 );
-                                int v1 = cvFloor( ptr1[x]*a1 + b1 );
-
-                                if( (unsigned)v0 < (unsigned)sz0 &&
-                                    (unsigned)v1 < (unsigned)sz1 )
-                                    bins[v0*step0 + v1]++;
-                            }
-                        }
-                        mask += maskStep;
-                    }
-                }
-                }
-                break;
-            default:
-                for( ; size.height--; )
-                {
-                    if( !mask )
-                    {
-                        for( x = 0; x < size.width; x++ )
-                        {
-                            int* binptr = bins;
-                            for( i = 0; i < dims; i++ )
-                            {
-                                int idx = cvFloor((double)img[i][x]*uni_range[i][0]
-                                                 + uni_range[i][1]);
-                                if( (unsigned)idx >= (unsigned)histsize[i] )
-                                    break;
-                                binptr += idx*(mat->dim[i].step/sizeof(float));
-                            }
-                            if( i == dims )
-                                binptr[0]++;
-                        }
-                    }
-                    else
-                    {
-                        for( x = 0; x < size.width; x++ )
-                        {
-                            if( mask[x] )
-                            {
-                                int* binptr = bins;
-                                for( i = 0; i < dims; i++ )
-                                {
-                                    int idx = cvFloor((double)img[i][x]*uni_range[i][0]
-                                                     + uni_range[i][1]);
-                                    if( (unsigned)idx >= (unsigned)histsize[i] )
-                                        break;
-                                    binptr += idx*(mat->dim[i].step/sizeof(float));
-                                }
-                                if( i == dims )
-                                    binptr[0]++;
-                            }
-                        }
-                        mask += maskStep;
-                    }
-
-                    for( i = 0; i < dims; i++ )
-                        img[i] += step;
-                }
-            }
-        }
-        else
-        {
-            for( ; size.height--; )
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    if( !mask || mask[x] )
-                    {
-                        int* binptr = bins;
-                        for( i = 0; i < dims; i++ )
-                        {
-                            float v = img[i][x];
-                            float* thresh = hist->thresh2[i];
-                            int idx = -1, sz = histsize[i];
-
-                            while( v >= thresh[idx+1] && ++idx < sz )
-                                /* nop */;
-
-                            if( (unsigned)idx >= (unsigned)sz )
-                                break;
-
-                            binptr += idx*(mat->dim[i].step/sizeof(float));
-                        }
-                        if( i == dims )
-                            binptr[0]++;
-                    }
-                }
-
-                for( i = 0; i < dims; i++ )
-                    img[i] += step;
-                if( mask )
-                    mask += maskStep;
-            }
-        }
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)(hist->bins);
-        int node_idx[CV_MAX_DIM];
-
-        for( ; size.height--; )
-        {
-            if( uniform )
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    if( !mask || mask[x] )
-                    {
-                        for( i = 0; i < dims; i++ )
-                        {
-                            int idx = cvFloor(img[i][x]*uni_range[i][0]
-                                             + uni_range[i][1]);
-                            if( (unsigned)idx >= (unsigned)histsize[i] )
-                                break;
-                            node_idx[i] = idx;
-                        }
-                        if( i == dims )
-                        {
-                            int* bin = (int*)cvPtrND( mat, node_idx, 0, 1, 0 );
-                            bin[0]++;
-                        }
-                    }
-                }
-            }
-            else
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    if( !mask || mask[x] )
-                    {
-                        for( i = 0; i < dims; i++ )
-                        {
-                            float v = img[i][x];
-                            float* thresh = hist->thresh2[i];
-                            int idx = -1, sz = histsize[i];
-
-                            while( v >= thresh[idx+1] && ++idx < sz )
-                                /* nop */;
-
-                            if( (unsigned)idx >= (unsigned)sz )
-                                break;
-
-                            node_idx[i] = idx;
-                        }
-                        if( i == dims )
-                        {
-                            int* bin = (int*)cvPtrND( mat, node_idx, 0, 1, 0 );
-                            bin[0]++;
-                        }
-                    }
-                }
-            }
-
-            for( i = 0; i < dims; i++ )
-                img[i] += step;
-
-            if( mask )
-                mask += maskStep;
-        }
-    }
-
-    return CV_OK;
-}
-
-
-CV_IMPL void
-cvCalcArrHist( CvArr** img, CvHistogram* hist,
-               int do_not_clear, const CvArr* mask )
-{
-    CV_FUNCNAME( "cvCalcHist" );
-
-    __BEGIN__;
-
-    uchar* ptr[CV_MAX_DIM];
-    uchar* maskptr = 0;
-    int maskstep = 0, step = 0;
-    int i, dims;
-    int cont_flag = -1;
-    CvMat stub0, *mat0 = 0;
-    CvMatND dense;
-    CvSize size;
-
-    if( !CV_IS_HIST(hist))
-        CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );
-
-    if( !img )
-        CV_ERROR( CV_StsNullPtr, "Null double array pointer" );
-
-    CV_CALL( dims = cvGetDims( hist->bins ));
-    
-    for( i = 0; i < dims; i++ )
-    {
-        CvMat stub, *mat = (CvMat*)img[i];
-        CV_CALL( mat = cvGetMat( mat, i == 0 ? &stub0 : &stub, 0, 1 ));
-
-        if( CV_MAT_CN( mat->type ) != 1 )
-            CV_ERROR( CV_BadNumChannels, "Only 1-channel arrays are allowed here" );
-
-        if( i == 0 )
-        {
-            mat0 = mat;
-            step = mat0->step;
-        }
-        else
-        {
-            if( !CV_ARE_SIZES_EQ( mat0, mat ))
-                CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal sizes" );
-
-            if( mat0->step != mat->step )
-                CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal steps" );
-
-            if( !CV_ARE_TYPES_EQ( mat0, mat ))
-                CV_ERROR( CV_StsUnmatchedFormats, "Not all the planes have equal types" );
-        }
-
-        cont_flag &= mat->type;
-        ptr[i] = mat->data.ptr;
-    }
-
-    if( mask )
-    {
-        CvMat stub, *mat = (CvMat*)mask;
-        CV_CALL( mat = cvGetMat( mat, &stub, 0, 1 ));
-
-        if( !CV_IS_MASK_ARR(mat))
-            CV_ERROR( CV_StsBadMask, "Bad mask array" );
-
-        if( !CV_ARE_SIZES_EQ( mat0, mat ))
-            CV_ERROR( CV_StsUnmatchedSizes,
-                "Mask size does not match to other arrays\' size" );
-        maskptr = mat->data.ptr;
-        maskstep = mat->step;
-        cont_flag &= mat->type;
-    }
-
-    size = cvGetMatSize(mat0);
-    if( CV_IS_MAT_CONT( cont_flag ))
-    {
-        size.width *= size.height;
-        size.height = 1;
-        maskstep = step = CV_STUB_STEP;
-    }
-
-    if( !CV_IS_SPARSE_HIST(hist))
-    {
-        dense = *(CvMatND*)hist->bins;
-        dense.type = (dense.type & ~CV_MAT_TYPE_MASK) | CV_32SC1;
-    }
-
-    if( !do_not_clear )
-    {
-        CV_CALL( cvZero( hist->bins ));
-    }
-    else if( !CV_IS_SPARSE_HIST(hist))
-    {
-        CV_CALL( cvConvert( (CvMatND*)hist->bins, &dense ));
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)(hist->bins);
-        CvSparseMatIterator iterator;
-        CvSparseNode* node;
-
-        for( node = cvInitSparseMatIterator( mat, &iterator );
-             node != 0; node = cvGetNextSparseNode( &iterator ))
-        {
-            Cv32suf* val = (Cv32suf*)CV_NODE_VAL( mat, node );
-            val->i = cvRound( val->f );
-        }
-    }
-
-    if( CV_MAT_DEPTH(mat0->type) > CV_8S && !CV_HIST_HAS_RANGES(hist))
-        CV_ERROR( CV_StsBadArg, "histogram ranges must be set (via cvSetHistBinRanges) "
-                                "before calling the function" );
-
-    switch( CV_MAT_DEPTH(mat0->type) )
-    {
-    case CV_8U:
-        IPPI_CALL( icvCalcHist_8u_C1R( ptr, step, maskptr, maskstep, size, hist ));
-           break;
-    case CV_32F:
-        {
-        union { uchar** ptr; float** fl; } v;
-        v.ptr = ptr;
-           IPPI_CALL( icvCalcHist_32f_C1R( v.fl, step, maskptr, maskstep, size, hist ));
-        }
-           break;
-    default:
-        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported array type" );
-    }
-
-    if( !CV_IS_SPARSE_HIST(hist))
-    {
-        CV_CALL( cvConvert( &dense, (CvMatND*)hist->bins ));
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)(hist->bins);
-        CvSparseMatIterator iterator;
-        CvSparseNode* node;
-
-        for( node = cvInitSparseMatIterator( mat, &iterator );
-             node != 0; node = cvGetNextSparseNode( &iterator ))
-        {
-            Cv32suf* val = (Cv32suf*)CV_NODE_VAL( mat, node );
-            val->f = (float)val->i;
-        }
-    }
-    
-    __END__;
-}
-
-
-/***************************** B A C K   P R O J E C T *****************************/
-
-// Calculates back project for one or more 8u arrays
-static CvStatus CV_STDCALL
-    icvCalcBackProject_8u_C1R( uchar** img, int step, uchar* dst, int dstStep,
-                               CvSize size, const CvHistogram* hist )
-{
-    const int small_hist_size = 1<<12;
-    int* tab = 0;
-    int is_sparse = CV_IS_SPARSE_HIST(hist);
-    int dims, histsize[CV_MAX_DIM];
-    int i, x;
-    CvStatus status;
-
-    dims = cvGetDims( hist->bins, histsize );
-
-    tab = (int*)cvStackAlloc( dims*256*sizeof(int));
-    status = icvCalcHistLookupTables8u( hist, dims, histsize, tab );
-    if( status < 0 )
-        return status;
-
-    if( !is_sparse )
-    {
-        int total = 1;
-        CvMatND* mat = (CvMatND*)(hist->bins);
-        float* bins = mat->data.fl;
-        uchar* buffer = 0;
-
-        for( i = 0; i < dims; i++ )
-            total *= histsize[i];
-
-        if( dims <= 3 && total >= -ICV_HIST_DUMMY_IDX )
-            return CV_BADSIZE_ERR; // too big histogram
-
-        if( dims > 1 && total <= small_hist_size && CV_IS_MAT_CONT(mat->type))
-        {
-            buffer = (uchar*)cvAlloc(total);
-            if( !buffer )
-                return CV_OUTOFMEM_ERR;
-            for( i = 0; i < total; i++ )
-            {
-                int v = cvRound(bins[i]);
-                buffer[i] = CV_CAST_8U(v);
-            }
-        }
-
-        switch( dims )
-        {
-        case 1:
-            {
-            uchar tab1d[256];
-            for( i = 0; i < 256; i++ )
-            {
-                int idx = tab[i];
-                if( idx >= 0 )
-                {
-                    int v = cvRound(bins[idx]);
-                    tab1d[i] = CV_CAST_8U(v);
-                }
-                else
-                    tab1d[i] = 0;
-            }
-
-            for( ; size.height--; img[0] += step, dst += dstStep )
-            {
-                uchar* ptr = img[0];
-                for( x = 0; x <= size.width - 4; x += 4 )
-                {
-                    uchar v0 = tab1d[ptr[x]];
-                    uchar v1 = tab1d[ptr[x+1]];
-
-                    dst[x] = v0;
-                    dst[x+1] = v1;
-
-                    v0 = tab1d[ptr[x+2]];
-                    v1 = tab1d[ptr[x+3]];
-
-                    dst[x+2] = v0;
-                    dst[x+3] = v1;
-                }
-
-                for( ; x < size.width; x++ )
-                    dst[x] = tab1d[ptr[x]];
-            }
-            }
-            break;
-        case 2:
-            for( ; size.height--; img[0] += step, img[1] += step, dst += dstStep )
-            {
-                uchar* ptr0 = img[0];
-                uchar* ptr1 = img[1];
-
-                if( buffer )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = ptr0[x];
-                        int v1 = ptr1[x];
-                        int idx = tab[v0] + tab[256+v1];
-                        int v = 0;
-
-                        if( idx >= 0 )
-                            v = buffer[idx];
-
-                        dst[x] = (uchar)v;
-                    }
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = ptr0[x];
-                        int v1 = ptr1[x];
-                        int idx = tab[v0] + tab[256+v1];
-                        int v = 0;
-
-                        if( idx >= 0 )
-                        {
-                            v = cvRound(bins[idx]);
-                            v = CV_CAST_8U(v);
-                        }
-
-                        dst[x] = (uchar)v;
-                    }
-                }
-            }
-            break;
-        case 3:
-            for( ; size.height--; img[0] += step, img[1] += step,
-                                  img[2] += step, dst += dstStep )
-            {
-                uchar* ptr0 = img[0];
-                uchar* ptr1 = img[1];
-                uchar* ptr2 = img[2];
-
-                if( buffer )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = ptr0[x];
-                        int v1 = ptr1[x];
-                        int v2 = ptr2[x];
-                        int idx = tab[v0] + tab[256+v1] + tab[512+v2];
-                        int v = 0;
-
-                        if( idx >= 0 )
-                            v = buffer[idx];
-
-                        dst[x] = (uchar)v;
-                    }
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = ptr0[x];
-                        int v1 = ptr1[x];
-                        int v2 = ptr2[x];
-                        int idx = tab[v0] + tab[256+v1] + tab[512+v2];
-                        int v = 0;
-
-                        if( idx >= 0 )
-                        {
-                            v = cvRound(bins[idx]);
-                            v = CV_CAST_8U(v);
-                        }
-                        dst[x] = (uchar)v;
-                    }
-                }
-            }
-            break;
-        default:
-            for( ; size.height--; dst += dstStep )
-            {
-                if( buffer )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        uchar* binptr = buffer;
-                        int v = 0;
-
-                        for( i = 0; i < dims; i++ )
-                        {
-                            int idx = tab[i*256 + img[i][x]];
-                            if( idx < 0 )
-                                break;
-                            binptr += idx;
-                        }
-                        
-                        if( i == dims )
-                            v = binptr[0];
-
-                        dst[x] = (uchar)v;
-                    }
-                }
-                else
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        float* binptr = bins;
-                        int v = 0;
-
-                        for( i = 0; i < dims; i++ )
-                        {
-                            int idx = tab[i*256 + img[i][x]];
-                            if( idx < 0 )
-                                break;
-                            binptr += idx;
-                        }
-
-                        if( i == dims )
-                        {
-                            v = cvRound( binptr[0] );
-                            v = CV_CAST_8U(v);
-                        }
-
-                        dst[x] = (uchar)v;
-                    }
-                }
-
-                for( i = 0; i < dims; i++ )
-                    img[i] += step;
-            }
-        }
-
-        cvFree( &buffer );
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)(hist->bins);
-        int node_idx[CV_MAX_DIM];
-
-        for( ; size.height--; dst += dstStep )
-        {
-            for( x = 0; x < size.width; x++ )
-            {
-                int v = 0;
-
-                for( i = 0; i < dims; i++ )
-                {
-                    int idx = tab[i*256 + img[i][x]];
-                    if( idx < 0 )
-                        break;
-                    node_idx[i] = idx;
-                }
-                if( i == dims )
-                {
-                    float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
-                    v = cvRound(bin[0]);
-                    v = CV_CAST_8U(v);
-                }
-
-                dst[x] = (uchar)v;
-            }
-
-            for( i = 0; i < dims; i++ )
-                img[i] += step;
-        }
-    }
-
-    return CV_OK;
-}
-
-
-// Calculates back project for one or more 32f arrays
-static CvStatus CV_STDCALL
-    icvCalcBackProject_32f_C1R( float** img, int step, float* dst, int dstStep,
-                                CvSize size, const CvHistogram* hist )
-{
-    int is_sparse = CV_IS_SPARSE_HIST(hist);
-    int uniform = CV_IS_UNIFORM_HIST(hist);
-    int dims, histsize[CV_MAX_DIM];
-    double uni_range[CV_MAX_DIM][2];
-    int i, x;
-
-    dims = cvGetDims( hist->bins, histsize );
-    step /= sizeof(img[0][0]);
-    dstStep /= sizeof(dst[0]);
-
-    if( uniform )
-    {
-        for( i = 0; i < dims; i++ )
-        {
-            double t = ((double)histsize[i])/
-                ((double)hist->thresh[i][1] - hist->thresh[i][0]);
-            uni_range[i][0] = t;
-            uni_range[i][1] = -t*hist->thresh[i][0];
-        }
-    }
-
-    if( !is_sparse )
-    {
-        CvMatND* mat = (CvMatND*)(hist->bins);
-        float* bins = mat->data.fl;
-
-        if( uniform )
-        {
-            switch( dims )
-            {
-            case 1:
-                {
-                double a = uni_range[0][0], b = uni_range[0][1];
-                int sz = histsize[0];
-
-                for( ; size.height--; img[0] += step, dst += dstStep )
-                {
-                    float* ptr = img[0];
-
-                    for( x = 0; x <= size.width - 4; x += 4 )
-                    {
-                        int v0 = cvFloor(ptr[x]*a + b);
-                        int v1 = cvFloor(ptr[x+1]*a + b);
-
-                        if( (unsigned)v0 < (unsigned)sz )
-                            dst[x] = bins[v0];
-                        else
-                            dst[x] = 0;
-
-                        if( (unsigned)v1 < (unsigned)sz )
-                            dst[x+1] = bins[v1];
-                        else
-                            dst[x+1] = 0;
-
-                        v0 = cvFloor(ptr[x+2]*a + b);
-                        v1 = cvFloor(ptr[x+3]*a + b);
-
-                        if( (unsigned)v0 < (unsigned)sz )
-                            dst[x+2] = bins[v0];
-                        else
-                            dst[x+2] = 0;
-
-                        if( (unsigned)v1 < (unsigned)sz )
-                            dst[x+3] = bins[v1];
-                        else
-                            dst[x+3] = 0;
-                    }
-
-                    for( ; x < size.width; x++ )
-                    {
-                        int v0 = cvFloor(ptr[x]*a + b);
-
-                        if( (unsigned)v0 < (unsigned)sz )
-                            dst[x] = bins[v0];
-                        else
-                            dst[x] = 0;
-                    }
-                }
-                }
-                break;
-            case 2:
-                {
-                double a0 = uni_range[0][0], b0 = uni_range[0][1];
-                double a1 = uni_range[1][0], b1 = uni_range[1][1];
-                int sz0 = histsize[0], sz1 = histsize[1];
-                int step0 = ((CvMatND*)(hist->bins))->dim[0].step/sizeof(float);
-
-                for( ; size.height--; img[0] += step, img[1] += step, dst += dstStep )
-                {
-                    float* ptr0 = img[0];
-                    float* ptr1 = img[1];
-
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        int v0 = cvFloor( ptr0[x]*a0 + b0 );
-                        int v1 = cvFloor( ptr1[x]*a1 + b1 );
-
-                        if( (unsigned)v0 < (unsigned)sz0 &&
-                            (unsigned)v1 < (unsigned)sz1 )
-                            dst[x] = bins[v0*step0 + v1];
-                        else
-                            dst[x] = 0;
-                    }
-                }
-                }
-                break;
-            default:
-                for( ; size.height--; dst += dstStep )
-                {
-                    for( x = 0; x < size.width; x++ )
-                    {
-                        float* binptr = bins;
-
-                        for( i = 0; i < dims; i++ )
-                        {
-                            int idx = cvFloor(img[i][x]*uni_range[i][0]
-                                             + uni_range[i][1]);
-                            if( (unsigned)idx >= (unsigned)histsize[i] )
-                                break;
-                            binptr += idx*(mat->dim[i].step/sizeof(float));
-                        }
-                        if( i == dims )
-                            dst[x] = binptr[0];
-                        else
-                            dst[x] = 0;
-                    }
-                }
-
-                for( i = 0; i < dims; i++ )
-                    img[i] += step;
-            }
-        }
-        else
-        {
-            for( ; size.height--; dst += dstStep )
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    float* binptr = bins;
-                    for( i = 0; i < dims; i++ )
-                    {
-                        float v = img[i][x];
-                        float* thresh = hist->thresh2[i];
-                        int idx = -1, sz = histsize[i];
-
-                        while( v >= thresh[idx+1] && ++idx < sz )
-                            /* nop */;
-
-                        if( (unsigned)idx >= (unsigned)sz )
-                            break;
-
-                        binptr += idx*(mat->dim[i].step/sizeof(float));
-                    }
-                    if( i == dims )
-                        dst[x] = binptr[0];
-                    else
-                        dst[x] = 0;
-                }
-
-                for( i = 0; i < dims; i++ )
-                    img[i] += step;
-            }
-        }
-    }
-    else
-    {
-        CvSparseMat* mat = (CvSparseMat*)(hist->bins);
-        int node_idx[CV_MAX_DIM];
-
-        for( ; size.height--; dst += dstStep )
-        {
-            if( uniform )
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    for( i = 0; i < dims; i++ )
-                    {
-                        int idx = cvFloor(img[i][x]*uni_range[i][0]
-                                         + uni_range[i][1]);
-                        if( (unsigned)idx >= (unsigned)histsize[i] )
-                            break;
-                        node_idx[i] = idx;
-                    }
-                    if( i == dims )
-                    {
-                        float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
-                        dst[x] = bin[0];
-                    }
-                    else
-                        dst[x] = 0;
-                }
-            }
-            else
-            {
-                for( x = 0; x < size.width; x++ )
-                {
-                    for( i = 0; i < dims; i++ )
-                    {
-                        float v = img[i][x];
-                        float* thresh = hist->thresh2[i];
-                        int idx = -1, sz = histsize[i];
-
-                        while( v >= thresh[idx+1] && ++idx < sz )
-                            /* nop */;
-
-                        if( (unsigned)idx >= (unsigned)sz )
-                            break;
-
-                        node_idx[i] = idx;
-                    }
-                    if( i == dims )
-                    {
-                        float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
-                        dst[x] = bin[0];
-                    }
-                    else
-                        dst[x] = 0;
-                }
-            }
-
-            for( i = 0; i < dims; i++ )
-                img[i] += step;
-        }
-    }
-
-    return CV_OK;
-}
-
-
-CV_IMPL void
-cvCalcArrBackProject( CvArr** img, CvArr* dst, const CvHistogram* hist )
-{
-    CV_FUNCNAME( "cvCalcArrBackProject" );
-
-    __BEGIN__;
-
-    uchar* ptr[CV_MAX_DIM];
-    uchar* dstptr = 0;
-    int dststep = 0, step = 0;
-    int i, dims;
-    int cont_flag = -1;
-    CvMat stub0, *mat0 = 0;
-    CvSize size;
-
-    if( !CV_IS_HIST(hist))
-        CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );
-
-    if( !img )
-        CV_ERROR( CV_StsNullPtr, "Null double array pointer" );
-
-    CV_CALL( dims = cvGetDims( hist->bins ));
-    
-    for( i = 0; i <= dims; i++ )
-    {
-        CvMat stub, *mat = (CvMat*)(i < dims ? img[i] : dst);
-        CV_CALL( mat = cvGetMat( mat, i == 0 ? &stub0 : &stub, 0, 1 ));
-
-        if( CV_MAT_CN( mat->type ) != 1 )
-            CV_ERROR( CV_BadNumChannels, "Only 1-channel arrays are allowed here" );
-
-        if( i == 0 )
-        {
-            mat0 = mat;
-            step = mat0->step;
-        }
-        else
-        {
-            if( !CV_ARE_SIZES_EQ( mat0, mat ))
-                CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal sizes" );
-
-            if( mat0->step != mat->step )
-                CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal steps" );
-
-            if( !CV_ARE_TYPES_EQ( mat0, mat ))
-                CV_ERROR( CV_StsUnmatchedFormats, "Not all the planes have equal types" );
-        }
-
-        cont_flag &= mat->type;
-        if( i < dims )
-            ptr[i] = mat->data.ptr;
-        else
-        {
-            dstptr = mat->data.ptr;
-            dststep = mat->step;
-        }
-    }
-
-    size = cvGetMatSize(mat0);
-    if( CV_IS_MAT_CONT( cont_flag ))
-    {
-        size.width *= size.height;
-        size.height = 1;
-        dststep = step = CV_STUB_STEP;
-    }
-
-    if( CV_MAT_DEPTH(mat0->type) > CV_8S && !CV_HIST_HAS_RANGES(hist))
-        CV_ERROR( CV_StsBadArg, "histogram ranges must be set (via cvSetHistBinRanges) "
-                                "before calling the function" );
-
-    switch( CV_MAT_DEPTH(mat0->type) )
-    {
-    case CV_8U:
-        IPPI_CALL( icvCalcBackProject_8u_C1R( ptr, step, dstptr, dststep, size, hist ));
-           break;
-    case CV_32F:
-        {
-        union { uchar** ptr; float** fl; } v;
-        v.ptr = ptr;
-           IPPI_CALL( icvCalcBackProject_32f_C1R( v.fl, step,
-                                (float*)dstptr, dststep, size, hist ));
-        }
-           break;
-    default:
-        CV_ERROR( CV_StsUnsupportedFormat, "Unsupported array type" );
-    }
-
-    __END__;
-}
-
-
-////////////////////// B A C K   P R O J E C T   P A T C H /////////////////////////
-
-CV_IMPL void
-cvCalcArrBackProjectPatch( CvArr** arr, CvArr* dst, CvSize patch_size, CvHistogram* hist,
-                           int method, double norm_factor )
-{
-    CvHistogram* model = 0;
-    
-    CV_FUNCNAME( "cvCalcArrBackProjectPatch" );
-
-    __BEGIN__;
-
-    IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM];
-    IplROI roi;
-    CvMat dststub, *dstmat;
-    int i, dims;
-    int x, y;
-    CvSize size;
-
-    if( !CV_IS_HIST(hist))
-        CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );
-
-    if( !img )
-        CV_ERROR( CV_StsNullPtr, "Null double array pointer" );
-
-    if( norm_factor <= 0 )
-        CV_ERROR( CV_StsOutOfRange,
-                  "Bad normalization factor (set it to 1.0 if unsure)" );
-
-    if( patch_size.width <= 0 || patch_size.height <= 0 )
-        CV_ERROR( CV_StsBadSize, "The patch width and height must be positive" );
-
-    CV_CALL( dims = cvGetDims( hist->bins ));
-    CV_CALL( cvCopyHist( hist, &model ));
-    CV_CALL( cvNormalizeHist( hist, norm_factor ));
-
-    for( i = 0; i < dims; i++ )
-    {
-        CvMat stub, *mat;
-        CV_CALL( mat = cvGetMat( arr[i], &stub, 0, 0 ));
-        CV_CALL( img[i] = cvGetImage( mat, &imgstub[i] ));
-        img[i]->roi = &roi;
-    }
-
-    CV_CALL( dstmat = cvGetMat( dst, &dststub, 0, 0 ));
-    if( CV_MAT_TYPE( dstmat->type ) != CV_32FC1 )
-        CV_ERROR( CV_StsUnsupportedFormat, "Resultant image must have 32fC1 type" );
-
-    if( dstmat->cols != img[0]->width - patch_size.width + 1 ||
-        dstmat->rows != img[0]->height - patch_size.height + 1 )
-        CV_ERROR( CV_StsUnmatchedSizes,
-            "The output map must be (W-w+1 x H-h+1), "
-            "where the input images are (W x H) each and the patch is (w x h)" );
-
-    size = cvGetMatSize(dstmat);
-    roi.coi = 0;
-    roi.width = patch_size.width;
-    roi.height = patch_size.height;
-
-    for( y = 0; y < size.height; y++ )
-    {
-        for( x = 0; x < size.width; x++ )
-        {
-            double result;
-            
-            roi.xOffset = x;
-            roi.yOffset = y;
-
-            CV_CALL( cvCalcHist( img, model ));
-
-            CV_CALL( cvNormalizeHist( model, norm_factor ));
-            CV_CALL( result = cvCompareHist( model, hist, method ));
-            CV_MAT_ELEM( *dstmat, float, y, x ) = (float)result;
-        }
-    }
-
-    __END__;
-
-    cvReleaseHist( &model );
-}
-
-
-// Calculates Bayes probabilistic histograms
-CV_IMPL void
-cvCalcBayesianProb( CvHistogram** src, int count, CvHistogram** dst )
-{
-    CV_FUNCNAME( "cvCalcBayesianProb" );
-    
-    __BEGIN__;
-
-    int i;
-    
-    if( !src || !dst )
-        CV_ERROR( CV_StsNullPtr, "NULL histogram array pointer" );
-
-    if( count < 2 )
-        CV_ERROR( CV_StsOutOfRange, "Too small number of histograms" );
-    
-    for( i = 0; i < count; i++ )
-    {
-        if( !CV_IS_HIST(src[i]) || !CV_IS_HIST(dst[i]) )
-            CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
-
-        if( !CV_IS_MATND(src[i]->bins) || !CV_IS_MATND(dst[i]->bins) )
-            CV_ERROR( CV_StsBadArg, "The function supports dense histograms only" );
-    }
-    
-    cvZero( dst[0]->bins );
-    // dst[0] = src[0] + ... + src[count-1]
-    for( i = 0; i < count; i++ )
-        CV_CALL( cvAdd( src[i]->bins, dst[0]->bins, dst[0]->bins ));
-
-    CV_CALL( cvDiv( 0, dst[0]->bins, dst[0]->bins ));
-
-    // dst[i] = src[i]*(1/dst[0])
-    for( i = count - 1; i >= 0; i-- )
-        CV_CALL( cvMul( src[i]->bins, dst[0]->bins, dst[i]->bins ));
-    
-    __END__;
-}
-
-
-CV_IMPL void
-cvCalcProbDensity( const CvHistogram* hist, const CvHistogram* hist_mask,
-                   CvHistogram* hist_dens, double scale )
-{
-    CV_FUNCNAME( "cvCalcProbDensity" );
-
-    __BEGIN__;
-
-    if( scale <= 0 )
-        CV_ERROR( CV_StsOutOfRange, "scale must be positive" );
-
-    if( !CV_IS_HIST(hist) || !CV_IS_HIST(hist_mask) || !CV_IS_HIST(hist_dens) )
-        CV_ERROR( CV_StsBadArg, "Invalid histogram pointer[s]" );
-
-    {
-        CvArr* arrs[] = { hist->bins, hist_mask->bins, hist_dens->bins };
-        CvMatND stubs[3];
-        CvNArrayIterator iterator;
-
-        CV_CALL( cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ));
-
-        if( CV_MAT_TYPE(iterator.hdr[0]->type) != CV_32FC1 )
-            CV_ERROR( CV_StsUnsupportedFormat, "All histograms must have 32fC1 type" );
-
-        do
-        {
-            const float* srcdata = (const float*)(iterator.ptr[0]);
-            const float* maskdata = (const float*)(iterator.ptr[1]);
-            float* dstdata = (float*)(iterator.ptr[2]);
-            int i;
-
-            for( i = 0; i < iterator.size.width; i++ )
-            {
-                float s = srcdata[i];
-                float m = maskdata[i];
-                if( s > FLT_EPSILON )
-                    if( m <= s )
-                        dstdata[i] = (float)(m*scale/s);
-                    else
-                        dstdata[i] = (float)scale;
-                else
-                    dstdata[i] = (float)0;
-            }
-        }
-        while( cvNextNArraySlice( &iterator ));
-    }
-
-    __END__;
-}
-
-
-CV_IMPL void cvEqualizeHist( const CvArr* src, CvArr* dst )
-{
-    CvHistogram* hist = 0;
-    CvMat* lut = 0;
-    
-    CV_FUNCNAME( "cvEqualizeHist" );
-
-    __BEGIN__;
-
-    int i, hist_sz = 256;
-    CvSize img_sz;
-    float scale;
-    float* h;
-    int sum = 0;
-    int type;
-    
-    CV_CALL( type = cvGetElemType( src ));
-    if( type != CV_8UC1 )
-        CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" );
-
-    CV_CALL( hist = cvCreateHist( 1, &hist_sz, CV_HIST_ARRAY ));
-    CV_CALL( lut = cvCreateMat( 1, 256, CV_8UC1 ));
-    CV_CALL( cvCalcArrHist( (CvArr**)&src, hist ));
-    CV_CALL( img_sz = cvGetSize( src ));
-    scale = 255.f/(img_sz.width*img_sz.height);
-    h = (float*)cvPtr1D( hist->bins, 0 );
-
-    for( i = 0; i < hist_sz; i++ )
-    {
-        sum += cvRound(h[i]);
-        lut->data.ptr[i] = (uchar)cvRound(sum*scale);
-    }
-
-    lut->data.ptr[0] = 0;
-    CV_CALL( cvLUT( src, dst, lut ));
-
-    __END__;
-
-    cvReleaseHist(&hist);
-    cvReleaseMat(&lut);
-}
-
-/* Implementation of RTTI and Generic Functions for CvHistogram */
-#define CV_TYPE_NAME_HIST "opencv-hist"
-
-static int icvIsHist( const void * ptr ){
-       return CV_IS_HIST( ((CvHistogram*)ptr) );
-}
-
-static CvHistogram * icvCloneHist( const CvHistogram * src ){
-       CvHistogram * dst=NULL;
-       cvCopyHist(src, &dst);
-       return dst;
-}
-
-static void *icvReadHist( CvFileStorage * fs, CvFileNode * node ){
-       CvHistogram * h = 0;
-       int is_uniform = 0;
-       int have_ranges = 0;
-
-       CV_FUNCNAME("icvReadHist");
-       __BEGIN__;
-
-    CV_CALL( h = (CvHistogram *) cvAlloc( sizeof(CvHistogram) ));
-
-       is_uniform = cvReadIntByName( fs, node, "is_uniform", 0 );
-       have_ranges = cvReadIntByName( fs, node, "have_ranges", 0);
-       h->type = CV_HIST_MAGIC_VAL | 
-                     (is_uniform ? CV_HIST_UNIFORM_FLAG : 0) |
-                         (have_ranges ? CV_HIST_RANGES_FLAG : 0);
-
-       if(is_uniform){
-               // read histogram bins
-               CvMatND * mat = (CvMatND *) cvReadByName( fs, node, "mat" );
-               int sizes[CV_MAX_DIM];
-               int i;
-               if(!CV_IS_MATND(mat)){
-                       CV_ERROR( CV_StsError, "Expected CvMatND");
-               }
-               for(i=0; i<mat->dims; i++){
-                       sizes[i] = mat->dim[i].size;
-               }
-
-               cvInitMatNDHeader( &(h->mat), mat->dims, sizes, mat->type, mat->data.ptr );
-               h->bins = &(h->mat);
-               
-               // take ownership of refcount pointer as well
-               h->mat.refcount = mat->refcount;
-
-               // increase refcount so freeing temp header doesn't free data
-               cvIncRefData( mat ); 
-               
-               // free temporary header
-               cvReleaseMatND( &mat );
-       }
-       else{
-               h->bins = cvReadByName( fs, node, "bins" );
-               if(!CV_IS_SPARSE_MAT(h->bins)){
-                       CV_ERROR( CV_StsError, "Unknown Histogram type");
-               }
-       }
-
-       // read thresholds
-       if(have_ranges){
-               int i;
-               int dims;
-               int size[CV_MAX_DIM];
-               int total = 0;
-               CvSeqReader reader;
-               CvFileNode * thresh_node;
-
-               CV_CALL( dims = cvGetDims( h->bins, size ));
-               for( i = 0; i < dims; i++ ){
-                       total += size[i]+1;
-               }
-
-               thresh_node = cvGetFileNodeByName( fs, node, "thresh" );
-               if(!thresh_node){
-                       CV_ERROR( CV_StsError, "'thresh' node is missing");
-               }
-               cvStartReadRawData( fs, thresh_node, &reader );
-
-               if(is_uniform){
-                       for(i=0; i<dims; i++){
-                               cvReadRawDataSlice( fs, &reader, 2, h->thresh[i], "f" );
-                       }
-            h->thresh2 = NULL;
-               }
-               else{
-                       float* dim_ranges;
-                       CV_CALL( h->thresh2 = (float**)cvAlloc(
-                                               dims*sizeof(h->thresh2[0])+
-                                               total*sizeof(h->thresh2[0][0])));
-                       dim_ranges = (float*)(h->thresh2 + dims);
-                       for(i=0; i < dims; i++){
-                               h->thresh2[i] = dim_ranges;
-                               cvReadRawDataSlice( fs, &reader, size[i]+1, dim_ranges, "f" );
-                               dim_ranges += size[i] + 1;
-                       }
-               }
-
-       }
-       
-       __END__;
-
-       return h;
-}
-
-static void icvWriteHist( CvFileStorage* fs, const char* name, const void* struct_ptr, 
-               CvAttrList /*attributes*/ ){
-       const CvHistogram * hist = (const CvHistogram *) struct_ptr;
-       int sizes[CV_MAX_DIM];
-       int dims;
-       int i;
-       int is_uniform, have_ranges;
-
-       CV_FUNCNAME("icvWriteHist");
-       __BEGIN__;
-       cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_HIST );
-
-       is_uniform = (CV_IS_UNIFORM_HIST(hist) ? 1 : 0);
-       have_ranges = (hist->type & CV_HIST_RANGES_FLAG ? 1 : 0);
-       
-       cvWriteInt( fs, "is_uniform", is_uniform );
-       cvWriteInt( fs, "have_ranges", have_ranges );
-       if(CV_IS_UNIFORM_HIST(hist)){
-               cvWrite( fs, "mat", &(hist->mat) );
-       }
-       else if(CV_IS_SPARSE_HIST(hist)){
-               cvWrite( fs, "bins", hist->bins );
-       }
-       else{
-               CV_ERROR( CV_StsError, "Unknown Histogram Type" );
-       }
-
-       // write thresholds
-       if(have_ranges){
-               dims = cvGetDims( hist->bins, sizes );
-               cvStartWriteStruct( fs, "thresh", CV_NODE_SEQ + CV_NODE_FLOW );
-               if(is_uniform){
-                       for(i=0; i<dims; i++){
-                               cvWriteRawData( fs, hist->thresh[i], 2, "f" );
-                       }
-               }
-               else{
-                       for(i=0; i<dims; i++){
-                               cvWriteRawData( fs, hist->thresh2[i], sizes[i]+1, "f" );
-                       }
-               }
-               cvEndWriteStruct( fs );
-       }
-
-       cvEndWriteStruct( fs );
-       __END__;
-}
-
-
-CvType hist_type( CV_TYPE_NAME_HIST, icvIsHist, (CvReleaseFunc)cvReleaseHist,
-                  icvReadHist, icvWriteHist, (CvCloneFunc)icvCloneHist );
-
-/* End of file. */
-