16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//*F///////////////////////////////////////////////////////////////////////////////////////
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvImgToObs_DCT_8u32f_C1R
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function takes as input an image and returns the sequnce of observations
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             to be used with an embedded HMM; Each observation is top-left block of DCT
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             coefficient matrix.
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: img     - pointer to the original image ROI
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                imgStep - full row width of the image in bytes
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                roi     - width and height of ROI in pixels
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                obs     - pointer to resultant observation vectors
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                dctSize - size of the block for which DCT is calculated
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                obsSize - size of top-left block of DCT coeffs matrix, which is treated
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          as observation. Each observation vector consists of
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          obsSize.width * obsSize.height floats.
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          The following conditions should be satisfied:
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          0 < objSize.width <= dctSize.width,
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          0 < objSize.height <= dctSize.height.
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                delta   - dctBlocks are overlapped and this parameter specifies horizontal
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          and vertical shift.
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns:
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      CV_NO_ERR or error code
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//      The algorithm is following:
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          1. First, number of observation vectors per row and per column are calculated:
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             Nx = floor((roi.width - dctSize.width + delta.width)/delta.width);
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             Ny = floor((roi.height - dctSize.height + delta.height)/delta.height);
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             So, total number of observation vectors is Nx*Ny, and total size of
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             array obs must be >= Nx*Ny*obsSize.width*obsSize.height*sizeof(float).
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//          2. Observation vectors are calculated in the following loop
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               ( actual implementation may be different ), where
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               I[x1:x2,y1:y2] means block of pixels from source image with
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               x1 <= x < x2, y1 <= y < y2,
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               D[x1:x2,y1:y2] means sub matrix of DCT matrix D.
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               O[x,y] means observation vector that corresponds to position
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               (x*delta.width,y*delta.height) in the source image
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               ( all indices are counted from 0 ).
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               for( y = 0; y < Ny; y++ )
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               {
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                   for( x = 0; x < Nx; x++ )
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                   {
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                       D = DCT(I[x*delta.width : x*delta.width + dctSize.width,
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                                  y*delta.height : y*delta.height + dctSize.height]);
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                       O[x,y] = D[0:obsSize.width, 0:obsSize.height];
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                   }
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//               }
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*comment out the following line to make DCT be calculated in floating-point arithmetics*/
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//#define _CV_INT_DCT
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* for integer DCT only */
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DCT_SCALE  15
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _CV_INT_DCT
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef int work_t;
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  DESCALE      CV_DESCALE
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  SCALE(x)     CV_FLT_TO_FIX((x),DCT_SCALE)
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef float work_t;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  DESCALE(x,n) (float)(x)
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  SCALE(x)     (float)(x)
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* calculate dct transform matrix */
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void icvCalcDCTMatrix( work_t * cfs, int n );
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define  MAX_DCT_SIZE  32
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvImgToObs_DCT_8u32f_C1R( uchar * img, int imgStep, CvSize roi,
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           float *obs, CvSize dctSize,
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           CvSize obsSize, CvSize delta )
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* dct transform matrices: horizontal and vertical */
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t tab_x[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t tab_y[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* temporary buffers for dct */
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t temp0[MAX_DCT_SIZE * 4];
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t temp1[MAX_DCT_SIZE * 4];
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t *buffer = 0;
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t *buf_limit;
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double s;
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y;
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Nx, Ny;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n1 = dctSize.height, m1 = n1 / 2;
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n2 = dctSize.width, m2 = n2 / 2;
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !img || !obs )
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.width <= 0 || roi.height <= 0 )
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( delta.width <= 0 || delta.height <= 0 )
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obsSize.width <= 0 || dctSize.width < obsSize.width ||
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        obsSize.height <= 0 || dctSize.height < obsSize.height )
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dctSize.width > MAX_DCT_SIZE || dctSize.height > MAX_DCT_SIZE )
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Nx = (roi.width - dctSize.width + delta.width) / delta.width;
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Ny = (roi.height - dctSize.height + delta.height) / delta.height;
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( Nx <= 0 || Ny <= 0 )
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buffer = (work_t *)cvAlloc( roi.width * obsSize.height * sizeof( buffer[0] ));
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !buffer )
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvCalcDCTMatrix( tab_x, dctSize.width );
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvCalcDCTMatrix( tab_y, dctSize.height );
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_limit = buffer + obsSize.height * roi.width;
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < Ny; y++, img += delta.height * imgStep )
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x, i, j, k;
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        work_t k0 = 0;
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* do transfroms for each column. Calc only first obsSize.height DCT coefficients */
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < roi.width; x++ )
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float is = 0;
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            work_t *buf = buffer + x;
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            work_t *tab = tab_y + 2;
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( n1 & 1 )
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                is = img[x + m1 * imgStep];
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                k0 = ((work_t) is) * tab[-1];
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* first coefficient */
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < m1; j++ )
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t0 = img[x + j * imgStep];
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t1 = img[x + (n1 - 1 - j) * imgStep];
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t2 = t0 + t1;
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 -= t1;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp0[j] = (work_t) t2;
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                is += t2;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp1[j] = (work_t) t0;
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf[0] = DESCALE( is * tab[-2], PASS1_SHIFT );
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (buf += roi.width) >= buf_limit )
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* other coefficients */
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ;; )
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s = 0;
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < m1; k++ )
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += temp1[k] * tab[k];
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[0] = DESCALE( s, PASS1_SHIFT );
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (buf += roi.width) >= buf_limit )
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tab += m1;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s = 0;
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n1 & 1 )
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    k0 = -k0;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = k0;
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < m1; k++ )
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += temp0[k] * tab[k];
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[0] = DESCALE( s, PASS1_SHIFT );
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tab += m1;
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (buf += roi.width) >= buf_limit )
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        k0 = 0;
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* do transforms for rows. */
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x + dctSize.width <= roi.width; x += delta.width )
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < obsSize.height; i++ )
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                work_t *buf = buffer + x + roi.width * i;
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                work_t *tab = tab_x + 2;
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *obs_limit = obs + obsSize.width;
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s = 0;
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n2 & 1 )
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = buf[m2];
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    k0 = (work_t) (s * tab[-1]);
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* first coefficient */
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < m2; j++ )
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    work_t t0 = buf[j];
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    work_t t1 = buf[n2 - 1 - j];
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    work_t t2 = t0 + t1;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    t0 -= t1;
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp0[j] = (work_t) t2;
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += t2;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp1[j] = (work_t) t0;
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *obs++ = (float) DESCALE( s * tab[-2], PASS2_SHIFT );
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( obs == obs_limit )
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    continue;
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* other coefficients */
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ;; )
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = 0;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < m2; k++ )
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s += temp1[k] * tab[k];
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    obs[0] = (float) DESCALE( s, PASS2_SHIFT );
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( ++obs == obs_limit )
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    tab += m2;
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = 0;
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( n2 & 1 )
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        k0 = -k0;
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s = k0;
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < m2; k++ )
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s += temp0[k] * tab[k];
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    obs[0] = (float) DESCALE( s, PASS2_SHIFT );
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    tab += m2;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( ++obs == obs_limit )
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &buffer );
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvImgToObs_DCT_32f_C1R( float * img, int imgStep, CvSize roi,
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         float *obs, CvSize dctSize,
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         CvSize obsSize, CvSize delta )
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* dct transform matrices: horizontal and vertical */
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t tab_x[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t tab_y[MAX_DCT_SIZE * MAX_DCT_SIZE / 2 + 2];
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* temporary buffers for dct */
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t temp0[MAX_DCT_SIZE * 4];
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t temp1[MAX_DCT_SIZE * 4];
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t *buffer = 0;
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    work_t *buf_limit;
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double s;
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int y;
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int Nx, Ny;
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n1 = dctSize.height, m1 = n1 / 2;
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n2 = dctSize.width, m2 = n2 / 2;
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !img || !obs )
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( roi.width <= 0 || roi.height <= 0 )
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( delta.width <= 0 || delta.height <= 0 )
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obsSize.width <= 0 || dctSize.width < obsSize.width ||
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        obsSize.height <= 0 || dctSize.height < obsSize.height )
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dctSize.width > MAX_DCT_SIZE || dctSize.height > MAX_DCT_SIZE )
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Nx = (roi.width - dctSize.width + delta.width) / delta.width;
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Ny = (roi.height - dctSize.height + delta.height) / delta.height;
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( Nx <= 0 || Ny <= 0 )
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADRANGE_ERR;
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buffer = (work_t *)cvAlloc( roi.width * obsSize.height * sizeof( buffer[0] ));
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !buffer )
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvCalcDCTMatrix( tab_x, dctSize.width );
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvCalcDCTMatrix( tab_y, dctSize.height );
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf_limit = buffer + obsSize.height * roi.width;
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    imgStep /= sizeof(img[0]);
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( y = 0; y < Ny; y++, img += delta.height * imgStep )
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int x, i, j, k;
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        work_t k0 = 0;
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* do transfroms for each column. Calc only first obsSize.height DCT coefficients */
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x < roi.width; x++ )
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float is = 0;
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            work_t *buf = buffer + x;
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            work_t *tab = tab_y + 2;
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( n1 & 1 )
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                is = img[x + m1 * imgStep];
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                k0 = ((work_t) is) * tab[-1];
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* first coefficient */
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < m1; j++ )
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t0 = img[x + j * imgStep];
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t1 = img[x + (n1 - 1 - j) * imgStep];
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float t2 = t0 + t1;
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t0 -= t1;
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp0[j] = (work_t) t2;
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                is += t2;
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                temp1[j] = (work_t) t0;
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf[0] = DESCALE( is * tab[-2], PASS1_SHIFT );
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (buf += roi.width) >= buf_limit )
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                continue;
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* other coefficients */
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ;; )
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s = 0;
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < m1; k++ )
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += temp1[k] * tab[k];
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[0] = DESCALE( s, PASS1_SHIFT );
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (buf += roi.width) >= buf_limit )
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tab += m1;
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s = 0;
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n1 & 1 )
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    k0 = -k0;
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = k0;
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < m1; k++ )
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += temp0[k] * tab[k];
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf[0] = DESCALE( s, PASS1_SHIFT );
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tab += m1;
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (buf += roi.width) >= buf_limit )
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        k0 = 0;
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* do transforms for rows. */
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( x = 0; x + dctSize.width <= roi.width; x += delta.width )
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < obsSize.height; i++ )
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                work_t *buf = buffer + x + roi.width * i;
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                work_t *tab = tab_x + 2;
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *obs_limit = obs + obsSize.width;
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                s = 0;
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( n2 & 1 )
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = buf[m2];
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    k0 = (work_t) (s * tab[-1]);
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* first coefficient */
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0; j < m2; j++ )
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    work_t t0 = buf[j];
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    work_t t1 = buf[n2 - 1 - j];
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    work_t t2 = t0 + t1;
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    t0 -= t1;
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp0[j] = (work_t) t2;
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s += t2;
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    temp1[j] = (work_t) t0;
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *obs++ = (float) DESCALE( s * tab[-2], PASS2_SHIFT );
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( obs == obs_limit )
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    continue;
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* other coefficients */
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ;; )
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = 0;
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < m2; k++ )
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s += temp1[k] * tab[k];
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    obs[0] = (float) DESCALE( s, PASS2_SHIFT );
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( ++obs == obs_limit )
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    tab += m2;
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = 0;
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( n2 & 1 )
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        k0 = -k0;
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s = k0;
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < m2; k++ )
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        s += temp0[k] * tab[k];
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    obs[0] = (float) DESCALE( s, PASS2_SHIFT );
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    tab += m2;
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( ++obs == obs_limit )
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &buffer );
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCalcDCTMatrix( work_t * cfs, int n )
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const double sqrt2 = 1.4142135623730950488016887242097;
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const double pi = 3.1415926535897932384626433832795;
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const double sincos[16 * 2] = {
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        1.00000000000000000, 0.00000000000000006,
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.70710678118654746, 0.70710678118654757,
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.49999999999999994, 0.86602540378443871,
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.38268343236508978, 0.92387953251128674,
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.30901699437494740, 0.95105651629515353,
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.25881904510252074, 0.96592582628906831,
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.22252093395631439, 0.97492791218182362,
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.19509032201612825, 0.98078528040323043,
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.17364817766693033, 0.98480775301220802,
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.15643446504023087, 0.98768834059513777,
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.14231483827328514, 0.98982144188093268,
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.13052619222005157, 0.99144486137381038,
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.12053668025532305, 0.99270887409805397,
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.11196447610330786, 0.99371220989324260,
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.10452846326765346, 0.99452189536827329,
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        0.09801714032956060, 0.99518472667219693,
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    };
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ROTATE( c, s, dc, ds ) \
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                              \
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = c*dc - s*ds;           \
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        s = c*ds + s*dc;           \
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        c = t;                     \
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define WRITE2( j, a, b ) \
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                         \
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cfs[j]   = SCALE(a);  \
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cfs2[j]  = SCALE(b);  \
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double t, scale = 1. / sqrt( (double)n );
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, m = n / 2;
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cfs[0] = SCALE( scale );
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    scale *= sqrt2;
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cfs[1] = SCALE( scale );
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cfs += 2 - m;
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n > 1 )
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double a0, b0;
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double da0, db0;
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        work_t *cfs2 = cfs + m * n;
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( n <= 16 )
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            da0 = a0 = sincos[2 * n - 1];
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            db0 = b0 = sincos[2 * n - 2];
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = pi / (2 * n);
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            da0 = a0 = cos( t );
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            db0 = b0 = sin( t );
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* other rows */
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i <= m; i++ )
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double a = a0 * scale;
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double b = b0 * scale;
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double da = a0 * a0 - b0 * b0;
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double db = a0 * b0 + a0 * b0;
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cfs += m;
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cfs2 -= m;
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < m; j += 2 )
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                WRITE2( j, a, b );
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ROTATE( a, b, da, db );
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( j + 1 < m )
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    WRITE2( j + 1, a, -b );
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ROTATE( a, b, da, db );
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ROTATE( a0, b0, da0, db0 );
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef ROTATE
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef WRITE2
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvImgToObs_DCT( const void* arr, float *obs, CvSize dctSize,
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvSize obsSize, CvSize delta )
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvImgToObs_DCT" );
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stub, *mat = (CvMat*)arr;
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( mat = cvGetMat( arr, &stub ));
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch( CV_MAT_TYPE( mat->type ))
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_8UC1:
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( icvImgToObs_DCT_8u32f_C1R( mat->data.ptr, mat->step,
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           cvGetMatSize(mat), obs,
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           dctSize, obsSize, delta ));
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_32FC1:
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IPPI_CALL( icvImgToObs_DCT_32f_C1R( mat->data.fl, mat->step,
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           cvGetMatSize(mat), obs,
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           dctSize, obsSize, delta ));
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "" );
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
635