|
|
|
Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members
CVImageRGBFloat.cppGo to the documentation of this file.00001 // CVImageRGBFloat - floating point RGB image class 00002 // Written by Michael Ellison 00003 //------------------------------------------------------------------------- 00004 // CodeVis's Free License 00005 // www.codevis.com 00006 // 00007 // Copyright (c) 2003 by Michael Ellison (mike@codevis.com) 00008 // All rights reserved. 00009 // 00010 // You may use this software in source and/or binary form, with or without 00011 // modification, for commercial or non-commercial purposes, provided that 00012 // you comply with the following conditions: 00013 // 00014 // * Redistributions of source code must retain the above copyright notice, 00015 // this list of conditions and the following disclaimer. 00016 // 00017 // * Redistributions of modified source must be clearly marked as modified, 00018 // and due notice must be placed in the modified source indicating the 00019 // type of modification(s) and the name(s) of the person(s) performing 00020 // said modification(s). 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00025 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00026 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00027 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00028 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00029 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00030 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00031 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00032 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 // 00034 //--------------------------------------------------------------------------- 00035 // Modifications: 00036 // 00037 //--------------------------------------------------------------------------- 00038 // 00052 00053 #include <memory.h> 00054 #include "CVUtil.h" 00055 #include "CVFile.h" 00056 #include "CVUtil.h" 00057 #include "CVImageRGBFloat.h" 00058 00059 //--------------------------------------------------------------------------- 00060 // constructor - Note that if we're on a big endian machine, we use the 00061 // '8' type of custom P?M file. If we're on a little-endian machine, 00062 // we use '7'. 00063 //--------------------------------------------------------------------------- 00064 CVImageRGBFloat::CVImageRGBFloat() 00065 :CVImage() 00066 { 00067 } 00068 //--------------------------------------------------------------------------- 00069 CVImageRGBFloat::~CVImageRGBFloat() 00070 { 00071 // Parent calls destroy 00072 } 00073 00074 //--------------------------------------------------------------------------- 00075 // GetNumChannels 00076 // Retrieves the number channels per pixel 00077 //--------------------------------------------------------------------------- 00078 int CVImageRGBFloat::GetNumChannels() const 00079 { 00080 return 3; 00081 } 00082 00083 //--------------------------------------------------------------------------- 00084 // GetBytesPerPixel 00085 // Retrieves the number of bytes per pixel. 00086 //--------------------------------------------------------------------------- 00087 int CVImageRGBFloat::GetBytesPerPixel() const 00088 { 00089 return 12; 00090 } 00091 00092 //-------------------------------------------------------------------------- 00093 // GetImageType 00094 // Retrieves the type of image - see CVIMAGE_TYPE enum in header 00095 //--------------------------------------------------------------------------- 00096 CVImage::CVIMAGE_TYPE CVImageRGBFloat::GetImageType() const 00097 { 00098 return CVIMAGE_RGBFLOAT; 00099 } 00100 00101 //--------------------------------------------------------------------------- 00102 // GetPNMExtension() retrieves the default file extension for PNM 00103 // file saving. (e.g. ".pgm" for greyscale) 00104 // 00105 // \return const char* - ASCIIZ default file extension, 00106 // including preceeding '.' 00107 // \sa Load(), Save() 00108 //--------------------------------------------------------------------------- 00109 const char *CVImageRGBFloat::GetPNMExtension() const 00110 { 00111 return ".pxm"; 00112 } 00113 00114 //--------------------------------------------------------------------------- 00115 // GetPNMMagicVal() retrieves the magic value for a pnm file 00116 // matching the current image format. 00117 //--------------------------------------------------------------------------- 00118 char CVImageRGBFloat::GetPNMMagicVal() const 00119 { 00120 // 8 is big-endian floating point, 7 is little-endian. 00121 return CVImage::IsBigEndianMachine()?'8':'7'; 00122 } 00123 00124 //--------------------------------------------------------------------------- 00125 // GetMaxPixelValue() retrieves the maximum value of any pixel in 00126 // the image. 00127 // 00128 // In multichannel images (e.g. RGB triplets), it will 00129 // return the maximum value on any of the channels. 00130 // 00131 // All child classes should implement this. 00132 // \param maxValue - reference to max pixel value, set on return. 00133 // \return CVRES result code 00134 // \sa GetPixel(), SetPixel(), CVImage::GetMaxPixel() 00135 //--------------------------------------------------------------------------- 00136 CVRES CVImageRGBFloat::GetMaxPixelValue(float& maxValue) const 00137 { 00138 return GetMaxPixel(maxValue); 00139 } 00140 00141 //--------------------------------------------------------------------------- 00142 // GetPixel() retrieves the red, green, and blue values for a specified 00143 // pixel as floating points. 00144 // 00145 // This is for convenience and prototyping - for high-speed image 00146 // processing you'll need to work more directly with the image 00147 // buffer. 00148 // 00149 // 00150 // \param x - x position within the image of the pixel 00151 // \param y - y position within the image of the pixel 00152 // \param r - receives the red value of the pixel 00153 // \param g - receives the green value of the pixel 00154 // \param b - receives the blue value of the pixel 00155 // 00156 // \return CVRES result code. CVRES_SUCCESS on success. 00157 // \sa SetPixel() 00158 //--------------------------------------------------------------------------- 00159 CVRES CVImageRGBFloat::GetPixel( int x, 00160 int y, 00161 float& r, 00162 float& g, 00163 float& b) const 00164 { 00165 CVRES result = CVRES_SUCCESS; 00166 00167 CVAssert(fData != 0, "Image must be created first!"); 00168 if (fData == 0) 00169 { 00170 return CVRES_IMAGE_EMPTY_ERR; 00171 } 00172 00173 // Bounds check coordinates 00174 CVAssert(( (x >= 0) || (x < fWidth)), "X position is out of bounds!"); 00175 CVAssert(( (y >= 0) || (y < fHeight)), "Y position is out of bounds!"); 00176 00177 if ( (x < 0) || (x >= fWidth)) 00178 { 00179 return CVRES_IMAGE_OUT_OF_RANGE; 00180 } 00181 00182 if ( (y < 0) || (y >= fHeight)) 00183 { 00184 return CVRES_IMAGE_OUT_OF_RANGE; 00185 } 00186 00187 // Offset of pixel on x axis in image data 00188 int lineOffset = (this->XOffsetAbs() + x) * 3; 00189 00190 // Absolute length of line in fData in floats ( >= fWidth * GetBytesPerPixel()) 00191 int lineLength = this->AbsWidth() * 3; 00192 00193 // current position of start of buffer in source 00194 float* curPtr = (float*)fData + lineOffset + 00195 ((YOffsetAbs() + y) * lineLength); 00196 00197 // pull out pixels 00198 r = curPtr[0]; 00199 g = curPtr[1]; 00200 b = curPtr[2]; 00201 00202 return result; 00203 } 00204 //--------------------------------------------------------------------------- 00205 // SetPixel() sets the red, green, and blue pixel values 00206 // for a pixel 00207 // 00208 // This is for convenience and prototyping - for high-speed image 00209 // processing you'll need to work more directly with the image 00210 // buffer. 00211 // 00214 // 00215 // Intensity values above 255 will be truncated to 255. Values 00216 // below 0 will be set to 0. 00217 // 00218 // \param x - x position within the image of the pixel 00219 // \param y - y position within the image of the pixel 00220 // \param r - receives the red value of the pixel 00221 // \param g - receives the green value of the pixel 00222 // \param b - receives the blue value of the pixel 00223 // 00224 // \return CVRES result code. CVRES_SUCCESS on success. 00225 // \sa GetPixel() 00226 //--------------------------------------------------------------------------- 00227 CVRES CVImageRGBFloat::SetPixel( int x, 00228 int y, 00229 float r, 00230 float g, 00231 float b) 00232 { 00233 CVRES result = CVRES_SUCCESS; 00234 00235 CVAssert(fData != 0, "Image must be created first!"); 00236 if (fData == 0) 00237 { 00238 return CVRES_IMAGE_EMPTY_ERR; 00239 } 00240 00241 // Bounds check coordinates 00242 CVAssert(( (x >= 0) || (x < fWidth)), "X position is out of bounds!"); 00243 CVAssert(( (y >= 0) || (y < fHeight)), "Y position is out of bounds!"); 00244 00245 if ( (x < 0) || (x >= fWidth)) 00246 { 00247 return CVRES_IMAGE_OUT_OF_RANGE; 00248 } 00249 00250 if ( (y < 0) || (y >= fHeight)) 00251 { 00252 return CVRES_IMAGE_OUT_OF_RANGE; 00253 } 00254 00255 // Offset of pixel on x axis in image data 00256 int lineOffset = (this->XOffsetAbs() + x) * 3; 00257 00258 // Absolute length of line in fData in floats ( >= fWidth * GetBytesPerPixel()) 00259 int lineLength = this->AbsWidth() * 3; 00260 00261 // current position of start of buffer in source 00262 float* curPtr = (float*)fData + lineOffset + 00263 ((YOffsetAbs() + y) * lineLength); 00264 00265 // Store 00266 curPtr[0] = r; 00267 curPtr[1] = g; 00268 curPtr[2] = b; 00269 00270 return result; 00271 } 00272 00273 00274 #ifdef WIN32 00275 //--------------------------------------------------------------------------- 00276 // SetFromWin32Bmp() 00277 // Sets the image from a bitmap buffer 00278 // We do a full copy of the data for this, since we may flip it and 00279 // swap red with blue to get it into RGB order rather than Window's BGR. 00280 // Padding will be removed as well. 00281 // 00282 // Only supports 24-bit RGB bitmaps. 00283 // 00284 //--------------------------------------------------------------------------- 00285 CVRES CVImageRGBFloat::SetFromWin32Bmp( const BITMAPINFOHEADER* bmih, 00286 const unsigned char* data) 00287 { 00288 // Parent does sanity checks (only called from CreateFromWin32Bmp) 00289 CVRES result = CVRES_SUCCESS; 00290 00291 // Negative height means top down. 00292 // Flipped is set if bottom-up image (default for win32) 00293 bool flipped = bmih->biHeight >= 0; 00294 00295 // Create an image of the same size 00296 // Make sure to use a positive height based on flipped var 00297 // Note: this adds our reference count 00298 this->Create( bmih->biWidth, 00299 flipped?(bmih->biHeight):-(bmih->biHeight), 00300 false); 00301 00302 // Set our starting position in the source image and step pos 00303 float* dstPos = (float*)fData; 00304 unsigned char* srcPos = 0; 00305 00306 int srcStep = -((int)bmih->biSizeImage / fHeight); 00307 00308 if (flipped) 00309 { 00310 // Set to point to bottom row in image so we can flip it 00311 srcPos = (unsigned char*)data + (int)bmih->biSizeImage + srcStep; 00312 } 00313 else 00314 { 00315 // Start at top if not flipped 00316 srcPos = (unsigned char*)data; 00317 } 00318 00319 // Copy row by row from source image to destination image 00320 00321 // May want to optimize this one a bit. 00322 // We're just flipping the red and blue channels while flipping from 00323 // bottom to top. For windows-only development where we work with 00324 // bitmaps, this is an unnecessary step. However, I like keeping all 00325 // my images in a neutral RGB 24-bit unpadded format for simplicity, 00326 // so unless it becomes a bottleneck, it makes it simpler. 00327 00328 00329 // profiling - time it. 00330 // CVStartTime(); 00331 00332 int y; 00333 for (y = 0; y < fHeight; y++) 00334 { 00335 unsigned char* srcLine = srcPos; 00336 { 00337 int x; 00338 for (x = 0; x < fWidth; x++) 00339 { 00340 *dstPos = (float)(*(srcLine+2)); dstPos++; 00341 *dstPos = (float)(*(srcLine+1)); dstPos++; 00342 *dstPos = (float)(*(srcLine) ); dstPos++; 00343 srcLine +=3; 00344 } 00345 } 00346 srcPos += srcStep; 00347 } 00348 00349 // end profiling - print time 00350 //CVEndTime(); 00351 00352 return result; 00353 } 00354 #endif // WIN32 00355 |
1.3.3