bool ExrDecoder::readData()

in modules/imgcodecs/src/grfmt_exr.cpp [185:385]


bool  ExrDecoder::readData( Mat& img )
{
    m_native_depth = CV_MAT_DEPTH(type()) == img.depth();
    bool color = img.channels() > 1;

    uchar* data = img.ptr();
    int step = img.step;
    bool justcopy = m_native_depth;
    bool chromatorgb = false;
    bool rgbtogray = false;
    bool result = true;
    FrameBuffer frame;
    int xsample[3] = {1, 1, 1};
    char *buffer;
    int xstep;
    int ystep;

    xstep = m_native_depth ? 4 : 1;

    if( !m_native_depth || (!color && m_iscolor ))
    {
        buffer = (char *)new float[ m_width * 3 ];
        ystep = 0;
    }
    else
    {
        buffer = (char *)data;
        ystep = step;
    }

    if( m_ischroma )
    {
        if( color )
        {
            if( m_iscolor )
            {
                if( m_blue )
                {
                    frame.insert( "BY", Slice( m_type,
                                    buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,
                                    12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));
                    xsample[0] = m_blue->ySampling;
                }
                if( m_green )
                {
                    frame.insert( "Y", Slice( m_type,
                                    buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,
                                    12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
                    xsample[1] = m_green->ySampling;
                }
                if( m_red )
                {
                    frame.insert( "RY", Slice( m_type,
                                    buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,
                                    12, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));
                    xsample[2] = m_red->ySampling;
                }
                chromatorgb = true;
            }
            else
            {
                frame.insert( "Y", Slice( m_type,
                              buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,
                              12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
                frame.insert( "Y", Slice( m_type,
                              buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,
                              12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
                frame.insert( "Y", Slice( m_type,
                              buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,
                              12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
                xsample[0] = m_green->ySampling;
                xsample[1] = m_green->ySampling;
                xsample[2] = m_green->ySampling;
            }
        }
        else
        {
            frame.insert( "Y", Slice( m_type,
                            buffer - m_datawindow.min.x * 4 - m_datawindow.min.y * ystep,
                            4, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
            xsample[0] = m_green->ySampling;
        }
    }
    else
    {
        if( m_blue )
        {
            frame.insert( "B", Slice( m_type,
                            buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep,
                            12, ystep, m_blue->xSampling, m_blue->ySampling, 0.0 ));
            xsample[0] = m_blue->ySampling;
        }
        if( m_green )
        {
            frame.insert( "G", Slice( m_type,
                            buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 4,
                            12, ystep, m_green->xSampling, m_green->ySampling, 0.0 ));
            xsample[1] = m_green->ySampling;
        }
        if( m_red )
        {
            frame.insert( "R", Slice( m_type,
                            buffer - m_datawindow.min.x * 12 - m_datawindow.min.y * ystep + 8,
                            12, ystep, m_red->xSampling, m_red->ySampling, 0.0 ));
            xsample[2] = m_red->ySampling;
        }
        if(color == 0)
        {
            rgbtogray = true;
            justcopy = false;
        }
    }

    m_file->setFrameBuffer( frame );
    if( justcopy )
    {
        m_file->readPixels( m_datawindow.min.y, m_datawindow.max.y );

        if( color )
        {
            if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )
                UpSample( data, 3, step / xstep, xsample[0], m_blue->ySampling );
            if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
                UpSample( data + xstep, 3, step / xstep, xsample[1], m_green->ySampling );
            if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )
                UpSample( data + 2 * xstep, 3, step / xstep, xsample[2], m_red->ySampling );
        }
        else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
            UpSample( data, 1, step / xstep, xsample[0], m_green->ySampling );
    }
    else
    {
        uchar *out = data;
        int x, y;
        for( y = m_datawindow.min.y; y <= m_datawindow.max.y; y++ )
        {
            m_file->readPixels( y, y );

            if( rgbtogray )
            {
                if( xsample[0] != 1 )
                    UpSampleX( (float *)buffer, 3, xsample[0] );
                if( xsample[1] != 1 )
                    UpSampleX( (float *)buffer + 4, 3, xsample[1] );
                if( xsample[2] != 1 )
                    UpSampleX( (float *)buffer + 8, 3, xsample[2] );

                RGBToGray( (float *)buffer, (float *)out );
            }
            else
            {
                if( xsample[0] != 1 )
                    UpSampleX( (float *)buffer, 3, xsample[0] );
                if( xsample[1] != 1 )
                    UpSampleX( (float *)(buffer + 4), 3, xsample[1] );
                if( xsample[2] != 1 )
                    UpSampleX( (float *)(buffer + 8), 3, xsample[2] );

                if( chromatorgb )
                    ChromaToBGR( (float *)buffer, 1, step );

                if( m_type == FLOAT )
                {
                    float *fi = (float *)buffer;
                    for( x = 0; x < m_width * 3; x++)
                    {
                        out[x] = cv::saturate_cast<uchar>(fi[x]*5);
                    }
                }
                else
                {
                    unsigned *ui = (unsigned *)buffer;
                    for( x = 0; x < m_width * 3; x++)
                    {
                        out[x] = cv::saturate_cast<uchar>(ui[x]);
                    }
                }
            }

            out += step;
        }
        if( color )
        {
            if( m_blue && (m_blue->xSampling != 1 || m_blue->ySampling != 1) )
                UpSampleY( data, 3, step / xstep, m_blue->ySampling );
            if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
                UpSampleY( data + xstep, 3, step / xstep, m_green->ySampling );
            if( m_red && (m_red->xSampling != 1 || m_red->ySampling != 1) )
                UpSampleY( data + 2 * xstep, 3, step / xstep, m_red->ySampling );
        }
        else if( m_green && (m_green->xSampling != 1 || m_green->ySampling != 1) )
            UpSampleY( data, 1, step / xstep, m_green->ySampling );
    }

    if( chromatorgb )
        ChromaToBGR( (float *)data, m_height, step / xstep );

    close();

    return result;
}