ImageBase.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   This is a class for holding and handling basic image data             *
00004  *                                                                         *
00005  *   Author:    Graeme van der Vlugt                                       *
00006  *   Copyright: Imetric 3D GmbH                                            *
00007  *   Year:      2004                                                       *
00008  *                                                                         *
00009  *                                                                         *
00010  *   This program is free software; you can redistribute it and/or modify  *
00011  *   it under the terms of the GNU Library General Public License as       *
00012  *   published by the Free Software Foundation; either version 2 of the    *
00013  *   License, or (at your option) any later version.                       *
00014  *   for detail see the LICENCE text file.                                 *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include "PreCompiled.h"
00019 #ifndef _PreComp_
00020 # include <cmath>
00021 # include <cstring>
00022 #endif
00023 
00024 #include "ImageBase.h"
00025 #include <Base/Exception.h>
00026 
00027 using namespace Image;
00028 
00029 // Constructor (constructs an empty image)
00030 ImageBase::ImageBase()
00031 {
00032     _pPixelData = NULL;
00033     _owner = true;
00034     _width = 0;
00035     _height = 0;
00036     _setColorFormat(IB_CF_GREY8, 8);
00037 }
00038 
00039 // Destructor
00040 ImageBase::~ImageBase()
00041 {
00042     try
00043     {
00044         clear();
00045     }
00046     catch(...) {}
00047 }
00048 
00049 // Copy constructor
00050 ImageBase::ImageBase(const ImageBase &rhs)
00051 {
00052         // Do the copy
00053     if (rhs._owner == true)
00054     {
00055         // rhs is the owner - do a deep copy
00056         _pPixelData = NULL;
00057         _owner = false; // avoids a superfluous delete
00058         if (createCopy((void *)(rhs._pPixelData), rhs._width, rhs._height, rhs._format, rhs._numSigBitsPerSample) != 0)
00059             throw Base::Exception("ImageBase::ImageBase. Error creating copy of image");
00060     }
00061     else
00062     {
00063         // rhs is not the owner - do a shallow copy
00064         _pPixelData = rhs._pPixelData;
00065         _owner = rhs._owner;
00066         _width = rhs._width;
00067         _height = rhs._height;
00068         _setColorFormat(rhs._format, rhs._numSigBitsPerSample);
00069     }
00070 }
00071 
00072 // = operator
00073 ImageBase & ImageBase::operator=(const ImageBase &rhs)
00074 {
00075         if (this == &rhs)
00076                 return *this;
00077 
00078         // Implement any deletion necessary
00079         clear();
00080 
00081         // Do the copy
00082     if (rhs._owner == true)
00083     {
00084         // rhs is the owner - do a deep copy
00085         _owner = false; // avoids a superfluous delete
00086         if (createCopy((void *)(rhs._pPixelData), rhs._width, rhs._height, rhs._format, rhs._numSigBitsPerSample) != 0)
00087             throw Base::Exception("ImageBase::operator=. Error creating copy of image");
00088     }
00089     else
00090     {
00091         // rhs is not the owner - do a shallow copy
00092         _pPixelData = rhs._pPixelData;
00093         _owner = rhs._owner;
00094         _width = rhs._width;
00095         _height = rhs._height;
00096         _setColorFormat(rhs._format, rhs._numSigBitsPerSample);
00097     }
00098 
00099         return *this;
00100 }
00101 
00102 
00103 // Clears the image data
00104 // It only deletes the pixel data if this object is the owner of the data
00105 void ImageBase::clear()
00106 {
00107     // If object is the owner of the data then delete the allocated memory
00108     if (_owner == true)
00109     {
00110         delete [] _pPixelData;
00111         _pPixelData = NULL;
00112     }
00113     // Else just reset the pointer (the owner of the pixel data must be responsible for deleting it)
00114     else
00115     {
00116         _pPixelData = NULL;
00117     }
00118 
00119     // Re-initialise the other variables
00120     _owner = true;
00121     _width = 0;
00122     _height = 0;
00123     _setColorFormat(IB_CF_GREY8, 8);
00124 }
00125 
00126 // Sets the color format and the dependant parameters
00127 // Returns 0 for OK, -1 for invalid color format
00128 int ImageBase::_setColorFormat(int format, unsigned short numSigBitsPerSample)
00129 {
00130     switch (format)
00131     {
00132         case IB_CF_GREY8:
00133             _numSamples = 1;
00134             _numBitsPerSample = 8;
00135             _numBytesPerPixel = 1;
00136             break;
00137         case IB_CF_GREY16:
00138             _numSamples = 1;
00139             _numBitsPerSample = 16;
00140             _numBytesPerPixel = 2;
00141             break;
00142         case IB_CF_GREY32:
00143             _numSamples = 1;
00144             _numBitsPerSample = 32;
00145             _numBytesPerPixel = 4;
00146             break;
00147         case IB_CF_RGB24:
00148             _numSamples = 3;
00149             _numBitsPerSample = 8;
00150             _numBytesPerPixel = 3;
00151             break;
00152         case IB_CF_RGB48:
00153             _numSamples = 3;
00154             _numBitsPerSample = 16;
00155             _numBytesPerPixel = 6;
00156             break;
00157         case IB_CF_BGR24:
00158             _numSamples = 3;
00159             _numBitsPerSample = 8;
00160             _numBytesPerPixel = 3;
00161             break;
00162         case IB_CF_BGR48:
00163             _numSamples = 3;
00164             _numBitsPerSample = 16;
00165             _numBytesPerPixel = 6;
00166             break;
00167         case IB_CF_RGBA32:
00168             _numSamples = 4;
00169             _numBitsPerSample = 8;
00170             _numBytesPerPixel = 4;
00171             break;
00172         case IB_CF_RGBA64:
00173             _numSamples = 4;
00174             _numBitsPerSample = 16;
00175             _numBytesPerPixel = 8;
00176             break;
00177         case IB_CF_BGRA32:
00178             _numSamples = 4;
00179             _numBitsPerSample = 8;
00180             _numBytesPerPixel = 4;
00181             break;
00182         case IB_CF_BGRA64:
00183             _numSamples = 4;
00184             _numBitsPerSample = 16;
00185             _numBytesPerPixel = 8;
00186             break;
00187         default:
00188             return -1;
00189     }
00190 
00191     if ((numSigBitsPerSample == 0) || (numSigBitsPerSample > _numBitsPerSample))
00192         _numSigBitsPerSample = _numBitsPerSample;
00193     else
00194         _numSigBitsPerSample = numSigBitsPerSample;
00195 
00196     _format = format;
00197     return 0;
00198 }
00199 
00200 // Allocate own space for an image based on the current color space and image size parameters
00201 // Returns:
00202 //               0 for OK
00203 //              -1 for error
00204 int ImageBase::_allocate()
00205 {
00206     // Check that pixel data pointer is null
00207     if (_pPixelData != NULL)
00208         return -1;
00209 
00210     // Allocate the space needed to store the pixel data
00211     _owner = true;
00212     try
00213     {
00214         _pPixelData = new unsigned char [_width * _height * _numBytesPerPixel];
00215     }
00216     catch(...)
00217     {
00218         // memory allocation error
00219         return -1;
00220     }
00221 
00222     return 0;
00223 }
00224 
00225 // Load an image by copying the pixel data
00226 // This object will take ownership of the copied pixel data
00227 // (the source image is still controlled by the caller)
00228 // If numSigBitsPerSample = 0 then the full range is assumed to be significant
00229 // Returns:
00230 //               0 for OK
00231 //              -1 for invalid color format
00232 //              -2 for memory allocation error
00233 int ImageBase::createCopy(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample)
00234 {
00235     // Clear any existing data
00236     clear();
00237 
00238     // Set the color format and the dependant parameters
00239     if (_setColorFormat(format, numSigBitsPerSample) != 0)
00240         return -1;
00241 
00242     // Set the image size
00243     _width = width;
00244     _height = height;
00245 
00246     // Allocate our own memory for the pixel data
00247     if (_allocate() != 0)
00248     {
00249         clear();
00250         return -2;
00251     }
00252 
00253     // Copy the pixel data
00254     memcpy((void *)_pPixelData, pSrcPixelData, _width * _height * _numBytesPerPixel);
00255 
00256     return 0;
00257 }
00258 
00259 // Make this object point to another image source
00260 // If takeOwnership is false then:
00261 //      This object will not own (control) or copy the pixel data
00262 //      (the source image is still controlled by the caller)
00263 // Else if takeOwnership is true then:
00264 //      This object will take ownership (control) of the pixel data
00265 //      (the source image is not (should not be) controlled by the caller anymore)
00266 //      In this case the memory must have been allocated with the new operator (because this class will use the delete operator)
00267 // If numSigBitsPerSample = 0 then the full range is assumed to be significant
00268 // Returns:
00269 //               0 for OK
00270 //              -1 for invalid color format
00271 int ImageBase::pointTo(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, bool takeOwnership)
00272 {
00273     // Clear any existing data
00274     clear();
00275 
00276     // Set the color format and the dependant parameters
00277     if (_setColorFormat(format, numSigBitsPerSample) != 0)
00278         return -1;
00279 
00280     // Set the image size
00281     _width = width;
00282     _height = height;
00283 
00284     // Point to the source pixel data
00285     _owner = false;
00286     _pPixelData = (unsigned char *)pSrcPixelData;
00287 
00288     // Flag ownership
00289     if (takeOwnership == true)
00290         _owner = true;
00291     else
00292         _owner = false;
00293 
00294     return 0;
00295 }
00296 
00297 // Gets the value of a sample at the given pixel position
00298 // Returns 0 for valid value or -1 if coordinates or sample index are out of range or 
00299 // if there is no image data
00300 int ImageBase::getSample(int x, int y, unsigned short sampleIndex, double &value)
00301 {
00302     if ((_pPixelData == NULL) || 
00303         (sampleIndex >= _numSamples) ||
00304         (x < 0) || (x >= (int)_width) || 
00305         (y < 0) || (y >= (int)_height))
00306         return -1;
00307 
00308     // Get pointer to sample
00309     switch (_format)
00310     {
00311         case IB_CF_GREY8:
00312         case IB_CF_RGB24:
00313         case IB_CF_BGR24:
00314         case IB_CF_RGBA32:
00315         case IB_CF_BGRA32:
00316             {
00317                 unsigned char* pSample = _pPixelData + _numSamples * (y * _width + x) + sampleIndex;
00318                 value = (double)(*pSample);
00319             }
00320             break;
00321         case IB_CF_GREY16:
00322         case IB_CF_RGB48:
00323         case IB_CF_BGR48:
00324         case IB_CF_RGBA64:
00325         case IB_CF_BGRA64:
00326             {
00327                 unsigned short* pPix16 = (unsigned short *)_pPixelData;
00328                 unsigned short* pSample = pPix16 + _numSamples * (y * _width + x) + sampleIndex;
00329                 value = (double)(*pSample);
00330             }
00331             break;
00332         case IB_CF_GREY32:
00333             {
00334                 unsigned long* pPix32 = (unsigned long *)_pPixelData;
00335                 unsigned long* pSample = pPix32 + y * _width + x;
00336                 value = (double)(*pSample);
00337             }
00338             break;
00339         default:
00340             return -1;
00341     }
00342     return 0;
00343 }
00344 
00345 
00346 

Generated on Wed Nov 23 19:00:18 2011 for FreeCAD by  doxygen 1.6.1