www.pudn.com > 99273898StereoMatch_1_0.zip > Image.cpp


/////////////////////////////////////////////////////////////////////////// 
// 
// NAME 
//  Image.cpp -- a simple reference-counted image structure 
// 
// SEE ALSO 
//  Image.h             definition and explanation of these classes 
// 
// Copyright © Richard Szeliski, 2001. 
// See Copyright.h for more details 
// 
/////////////////////////////////////////////////////////////////////////// 
 
#include "Image.h" 
#include "Error.h" 
 
// 
// struct CShape: shape of image (width x height x nbands) 
// 
 
bool CShape::operator==(const CShape& ref) 
{ 
    // Are two shapes the same? 
    return (width  == ref.width && 
            height == ref.height && 
            nBands == ref.nBands); 
} 
 
bool CShape::SameIgnoringNBands(const CShape& ref) 
{ 
    // Are two shapes the same ignoring the number of bands? 
    return (width  == ref.width && 
            height == ref.height); 
} 
 
bool CShape::operator!=(const CShape& ref) 
{ 
    // Are two shapes not the same? 
    return ! ((*this) == ref); 
} 
 
 
// 
// class CImage : generic (weakly typed) image 
// 
 
void CImage::SetDefaults() 
{ 
    // Set internal state to default values 
    m_pTI = 0;              // pointer to type_info class 
    m_bandSize = 0;         // size of each band in bytes 
    m_pixSize = 0;          // stride between pixels in bytes 
    m_rowSize = 0;          // stride between rows in bytes 
    m_memStart = 0;         // start of addressable memory 
    alphaChannel = 3;       // which channel contains alpha (for compositing) 
 
    // Set default attribute values 
    alphaChannel = 3;       // which channel contains alpha (for compositing) 
    origin[0] = 0;          // x and y coordinate origin (for some operations) 
    origin[1] = 0;          // x and y coordinate origin (for some operations) 
    borderMode = eBorderReplicate;   // border behavior for neighborhood operations... 
} 
 
CImage::CImage() 
{ 
    // Default constructor 
    SetDefaults(); 
} 
 
CImage::CImage(CShape s, const type_info& ti, int cS) 
{ 
    SetDefaults(); 
    ReAllocate(s, ti, cS, 0, true, 0); 
} 
 
void CImage::ReAllocate(CShape s, const type_info& ti, int bandSize, 
                        bool evenIfShapeDiffers) 
{ 
    if (! evenIfShapeDiffers && s == m_shape && ti == *m_pTI && bandSize == m_bandSize) 
        return; 
    ReAllocate(s, ti, bandSize, 0, true, 0); 
} 
 
void CImage::ReAllocate(CShape s, const type_info& ti, int bandSize, 
                        void *memory, bool deleteWhenDone, int rowSize) 
{ 
    // Set up the type_id, shape, and size info 
    m_shape     = s;                        // image shape (dimensions) 
    m_pTI       = &ti;                      // pointer to type_info class 
    m_bandSize  = bandSize;                 // size of each band in bytes 
    m_pixSize   = m_bandSize * s.nBands;    // stride between pixels in bytes 
 
    // Do the real allocation work 
    m_rowSize   = (rowSize) ? rowSize :     // stride between rows in bytes 
        (m_pixSize * s.width + 7) & -8;     // round up to 8 (quadwords) 
    int nBytes  = m_rowSize * s.height; 
    if (memory == 0 && nBytes > 0)          // allocate if necessary 
    { 
        memory = new double[(nBytes + 7)/ 8]; 
        if (memory == 0) 
            throw CError("CImage::Reallocate: could not allocate %d bytes", nBytes); 
    } 
    m_memStart = (char *) memory;           // start of addressable memory 
    m_memory.ReAllocate(nBytes, memory, deleteWhenDone); 
} 
 
void CImage::DeAllocate() 
{ 
    // Release the memory & set to default values 
    ReAllocate(CShape(), *(const type_info *) 0, 0, 0, false, 0); 
    SetDefaults(); 
} 
 
 
void CImage::SetSubImage(int x, int y, int width, int height) 
{ 
    // Adjust the start of memory pointer 
    m_memStart = (char *) PixelAddress(x, y, 0); 
 
    // Compute area of intersection and adjust the shape and origin 
    int x1 = __min(m_shape.width,  x+width);    // end column 
    int y1 = __min(m_shape.height, y+height);   // end row 
    x = __max(0, __min(x, m_shape.width));      // clip to original shape 
    y = __max(0, __min(y, m_shape.height));     // clip to original shape 
    m_shape.width  = x1 - x;                    // actual width 
    m_shape.height = y1 - y;                    // actual height 
} 
 
void CImage::SetPixels(void *val_ptr) 
{ 
    // Fill the image with a value 
    uchar *vc = (uchar *) val_ptr; 
 
    // Test if all the bytes are the same 
    bool all_same = true; 
    for (int b = 0; b < m_bandSize; b++) 
        all_same = all_same && (vc[b] == vc[0]); 
 
    // Iterate over the rows 
    int nC = m_shape.width * m_shape.nBands; 
    for (int y = 0; y < m_shape.height; y++) 
    { 
        uchar *rp = (uchar *) PixelAddress(0, y, 0); 
        if (all_same) 
            memset(rp, vc[0], nC * m_bandSize); 
        else if (m_bandSize == sizeof(int)) 
        { 
            int vi = *(int *) val_ptr; 
            int *ip = (int *) rp; 
            for (int c = 0; c < nC; c++) 
                ip[c] = vi; 
        } 
        else 
        { 
            for (int c = 0; c < nC; c++, rp += m_bandSize) 
                memcpy(rp, vc, m_bandSize); 
        } 
    } 
} 
 
// 
// class CImageOf: strongly typed image 
// 
 
uchar CImageOf::MinVal(void)     { return 0; } 
uchar CImageOf::MaxVal(void)     { return 255; } 
int   CImageOf::MinVal(void)     { return -1 ^ (1 << 31); } 
int   CImageOf::MaxVal(void)     { return  0 ^ (1 << 31); } 
float CImageOf::MinVal(void)     { return -FLT_MAX; } 
float CImageOf::MaxVal(void)     { return FLT_MAX; }