osg::ImageScaler Class Reference

#include <OSGImageScaler.h>

List of all members.

Static Public Member Functions

static bool scale (ImagePtr &srcImg, ImagePtr &dstImg, osg::Int32 width, osg::Int32 height, osg::Int32 depth, const ImageGenericFilter &filter)

Private Member Functions

 ImageScaler (void)
 ~ImageScaler (void)

Static Private Member Functions

static void calcContributions (UInt32 axis, Int32 uResSize, Int32 uSrcSize, const ImageGenericFilter &filter, std::vector< Contribution > contrib[3])

Classes

struct  Contribution


Detailed Description

Image scaler

Definition at line 113 of file OSGImageScaler.h.


Constructor & Destructor Documentation

ImageScaler::ImageScaler ( void   )  [private]

constructor

Definition at line 257 of file OSGImageScaler.cpp.

00258 {
00259 }

ImageScaler::~ImageScaler ( void   )  [private]

destructor

Definition at line 264 of file OSGImageScaler.cpp.

00265 {
00266 }


Member Function Documentation

bool ImageScaler::scale ( ImagePtr srcImg,
ImagePtr dstImg,
osg::Int32  width,
osg::Int32  height,
osg::Int32  depth,
const ImageGenericFilter filter 
) [static]

rescale image

Definition at line 370 of file OSGImageScaler.cpp.

References osg::beginEditCP(), calcContributions(), osg::endEditCP(), ValueHandler::getValue(), osg::Image::OSG_FLOAT16_IMAGEDATA, osg::Image::OSG_FLOAT32_IMAGEDATA, osg::Image::OSG_UINT16_IMAGEDATA, osg::Image::OSG_UINT32_IMAGEDATA, osg::Image::OSG_UINT8_IMAGEDATA, ValueHandler::setValue(), and SWARNING.

00376 {
00377     ValueHandler             *valueHandler = NULL;
00378     Int32                     channels = srcImg->getComponents();
00379     std::vector<Contribution> contrib[3]; 
00380 
00381     beginEditCP(dstImg);
00382 
00383     switch(srcImg->getDataType())
00384     {
00385         case Image::OSG_UINT8_IMAGEDATA:
00386             valueHandler = new ValueHandlerTempl<UInt8>();
00387             break;
00388         case Image::OSG_UINT16_IMAGEDATA:
00389             valueHandler = new ValueHandlerTempl<UInt16>();
00390             break;
00391         case Image::OSG_UINT32_IMAGEDATA:
00392             valueHandler = new ValueHandlerTempl<UInt32>();
00393             break;
00394         case Image::OSG_FLOAT16_IMAGEDATA:
00395             valueHandler = new ValueHandlerTempl<Real16>();
00396             break;
00397         case Image::OSG_FLOAT32_IMAGEDATA:
00398             valueHandler = new ValueHandlerTempl<Real32>();
00399             break;
00400         default:
00401             SWARNING << "PixelType not scalable" << std::endl;
00402             return false;
00403     };
00404 
00405     // create kernel
00406     calcContributions(0,width, srcImg->getWidth() ,filter,contrib);
00407     calcContributions(1,height,srcImg->getHeight(),filter,contrib);
00408     calcContributions(2,depth, srcImg->getDepth() ,filter,contrib);
00409 
00410     if(!dstImg->set((Image::PixelFormat)srcImg->getPixelFormat(),
00411                     width,
00412                     height,
00413                     depth,
00414                     // create mipmaps from rescaled image
00415                     1,
00416                     srcImg->getFrameCount(),
00417                     srcImg->getFrameDelay(),
00418                     NULL,
00419                     srcImg->getDataType(),
00420                     true,
00421                     srcImg->getSideCount()))
00422     {
00423         SWARNING << "Unable to set image format" << std::endl;
00424         return false;
00425     }
00426 
00427     UInt32 srcImgWidth  = srcImg->getWidth();
00428     UInt32 srcImgHeight = srcImg->getHeight();
00429     Real64 *weightX;
00430     Real64 *weightY;
00431     Real64 *weightZ;
00432     UInt32 frames = srcImg->getFrameCount();
00433     UInt32 sides = srcImg->getSideCount();
00434 
00435     // it makes no sense to rescale the mipmap levels, so
00436     // we simply scale the main image and then rebuild the
00437     // mipmaps
00438     Real64 value;
00439     UInt32 x,y,z,c,f,s;
00440     UInt32 x1,x2,y1,y2,z1,z2;
00441     for(s = 0 ; s < sides ; ++s)
00442     {
00443         for(f = 0 ; f < frames ; ++f)
00444         {
00445             UInt8 *dstImgData   = dstImg->getData(0,f,s);
00446             UInt8 *srcImgData   = srcImg->getData(0,f,s);
00447             for(z = 0 ; z < depth ; ++z)
00448             {
00449                 z1 = contrib[2][z].left;
00450                 z2 = contrib[2][z].right;
00451                 weightZ = &contrib[2][z].weights[0];
00452                 for(y = 0 ; y < height ; ++y)
00453                 {
00454                     y1 = contrib[1][y].left;
00455                     y2 = contrib[1][y].right;
00456                     weightY = &contrib[1][y].weights[0];
00457                     for(x = 0 ; x < width ; ++x)
00458                     {
00459                         x1 = contrib[0][x].left;
00460                         x2 = contrib[0][x].right;
00461 
00462                         weightX = &contrib[0][x].weights[0];
00463                         for(c = 0 ; c < channels ; ++c)
00464                         {
00465                             value = valueHandler->getValue(srcImgData,
00466                                                            channels,
00467                                                            srcImgWidth,
00468                                                            srcImgHeight,
00469                                                            c,
00470                                                            x1,y1,z1,
00471                                                            x2,y2,z2,
00472                                                            weightX,weightY,weightZ);
00473 
00474                             valueHandler->setValue(value,
00475                                                    dstImgData,
00476                                                    channels,width,height,
00477                                                    c,x,y,z);
00478                         }
00479                     }
00480                 }
00481             }
00482         }
00483     }
00484 
00485     if(valueHandler != NULL)
00486         delete valueHandler;
00487 
00488     // rebuild mipmaps
00489     if(srcImg->getMipMapCount() > 1)
00490         dstImg->createMipmap(-1);
00491 
00492     endEditCP(dstImg);
00493 
00494     return true;
00495 }

void ImageScaler::calcContributions ( UInt32  axis,
Int32  uResSize,
Int32  uSrcSize,
const ImageGenericFilter filter,
std::vector< Contribution contrib[3] 
) [static, private]

calculation contribution values from filter object

Definition at line 271 of file OSGImageScaler.cpp.

References osg::ImageGenericFilter::filter(), osg::ImageGenericFilter::getWidth(), osg::osgMax(), and osg::osgMin().

Referenced by scale().

00276 {
00277     Real64 dWidth;
00278     Real64 dFScale = 1.0;
00279     Real64 dFilterWidth = filter.getWidth();
00280 
00281     Real64 dScale = (Real64)uResSize / (Real64)uSrcSize;
00282 
00283     // resize arrays
00284     contrib[axis].resize(uResSize);
00285 
00286     if (dScale < 1.0)
00287     {    // Minification
00288         dWidth = dFilterWidth / dScale;
00289         dFScale = dScale;
00290     }
00291     else
00292     {    // Magnification
00293         dWidth= dFilterWidth;
00294     }
00295 
00296     // Window size is the number of sampled pixels
00297     Int32 iWindowSize = 2 * (Int32)ceil(dWidth) + 1;
00298 
00299     for (Int32 u = 0; u < uResSize; u++)
00300     {   
00301         // Scan through line of contributions
00302         Real64 dCenter = (Real64)u / dScale;   // Reverse mapping
00303         // Find the significant edge points that affect the pixel
00304         Int32 iLeft = osgMax (0, (Int32)floor (dCenter - dWidth));
00305         //res->ContribRow[u].Left = iLeft;
00306         Int32 iRight = osgMin ((Int32)ceil (dCenter + dWidth), Int32(uSrcSize) - 1);
00307         //res->ContribRow[u].Right = iRight;
00308 
00309         // Cut edge points to fit in filter window in case of spill-off
00310         if (iRight - iLeft + 1 > iWindowSize)
00311         {
00312             if (iLeft < (Int32(uSrcSize) - 1 / 2))
00313             {
00314                 iLeft++;
00315             }
00316             else
00317             {
00318                 iRight--;
00319             }
00320         }
00321         // amz store the modified values!
00322         contrib[axis][u].left = iLeft;
00323         contrib[axis][u].right = iRight;
00324 
00325         Real64 dTotalWeight = 0.0;  // Zero sum of weights
00326         contrib[axis][u].weights.resize(iRight - iLeft + 1);
00327         for (Int32 iSrc = iLeft; iSrc <= iRight; iSrc++)
00328         { 
00329             // calculate weight
00330             Real64 weight = dFScale * 
00331                 filter.filter(dFScale * (dCenter - (Real64)iSrc));
00332             contrib[axis][u].weights[iSrc-iLeft] = weight;
00333             // sum weights
00334             dTotalWeight += weight;
00335         }
00336         if (dTotalWeight > 0.0)
00337         {
00338             // Normalize weight of neighbouring points
00339             for (Int32 iSrc = iLeft; iSrc <= iRight; iSrc++)
00340             {
00341                 // Normalize point
00342                 contrib[axis][u].weights[iSrc-iLeft] /= dTotalWeight;
00343             }
00344             // optimize kernel size
00345             while(contrib[axis][u].weights.front() == 0)
00346             {
00347                 contrib[axis][u].left++;
00348                 contrib[axis][u].weights.erase(contrib[axis][u].weights.begin());
00349             }
00350             while(contrib[axis][u].weights.back() == 0)
00351             {
00352                 contrib[axis][u].right--;
00353                 contrib[axis][u].weights.erase(contrib[axis][u].weights.end() - 1);
00354             }
00355 #if 0
00356             printf("%d %d  %d,%d\n",axis,u,contrib[axis][u].left,contrib[axis][u].right);
00357             for (Int32 iSrc = 0; iSrc < contrib[axis][u].weights.size(); iSrc++)
00358             {
00359                 printf("%lf ",contrib[axis][u].weights[iSrc]);
00360             }
00361             printf("\n");
00362 #endif
00363         }
00364     }
00365 }


The documentation for this class was generated from the following files:

Generated on Mon Mar 17 11:12:44 2008 for OpenSG by  doxygen 1.5.5