|
|
|
Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members
CVImageRGB24.cppGo to the documentation of this file.00001 // CVImageRGB24 - 24-bit 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 //--------------------------------------------------------------------------- 00051 00052 #include <memory.h> 00053 #include "CVUtil.h" 00054 #include "CVFile.h" 00055 #include "CVImageRGB24.h" 00056 #include "CVUtil.h" 00057 00058 //--------------------------------------------------------------------------- 00059 CVImageRGB24::CVImageRGB24() 00060 :CVImage() 00061 { 00062 } 00063 //--------------------------------------------------------------------------- 00064 CVImageRGB24::~CVImageRGB24() 00065 { 00066 // Parent calls destroy 00067 } 00068 00069 //--------------------------------------------------------------------------- 00070 // GetNumChannels 00071 // Retrieves the number channels per pixel 00072 //--------------------------------------------------------------------------- 00073 int CVImageRGB24::GetNumChannels() const 00074 { 00075 return 3; 00076 } 00077 00078 //--------------------------------------------------------------------------- 00079 // GetBytesPerPixel 00080 // Retrieves the number of bytes per pixel. 00081 //--------------------------------------------------------------------------- 00082 int CVImageRGB24::GetBytesPerPixel() const 00083 { 00084 return 3; 00085 } 00086 00087 //-------------------------------------------------------------------------- 00088 // GetImageType 00089 // Retrieves the type of image - see CVIMAGE_TYPE enum in header 00090 //--------------------------------------------------------------------------- 00091 CVImage::CVIMAGE_TYPE CVImageRGB24::GetImageType() const 00092 { 00093 return CVIMAGE_RGB24; 00094 } 00095 00096 //--------------------------------------------------------------------------- 00097 // GetPNMExtension() retrieves the default file extension for PNM 00098 // file saving. (e.g. ".pgm" for greyscale) 00099 // 00100 // \return const char* - ASCIIZ default file extension, 00101 // including preceeding '.' 00102 // \sa Load(), Save() 00103 //--------------------------------------------------------------------------- 00104 const char *CVImageRGB24::GetPNMExtension() const 00105 { 00106 return ".ppm"; 00107 } 00108 00109 //--------------------------------------------------------------------------- 00110 // GetPNMMagicVal() retrieves the magic value for a pnm file 00111 // matching the current image format. 00112 //--------------------------------------------------------------------------- 00113 char CVImageRGB24::GetPNMMagicVal() const 00114 { 00115 return '6'; 00116 } 00117 00118 //--------------------------------------------------------------------------- 00119 // GetMaxPixelValue() retrieves the maximum value of any pixel in 00120 // the image. 00121 // 00122 // In multichannel images (e.g. RGB triplets), it will 00123 // return the maximum value on any of the channels. 00124 // 00125 // All child classes should implement this. 00126 // \param maxValue - reference to max pixel value, set on return. 00127 // \return CVRES result code 00128 // \sa GetPixel(), SetPixel(), CVImage::GetMaxPixel() 00129 //--------------------------------------------------------------------------- 00130 CVRES CVImageRGB24::GetMaxPixelValue(float& maxValue) const 00131 { 00132 unsigned char maxPixel; 00133 CVRES result = GetMaxPixel(maxPixel); 00134 maxValue = (float)maxPixel; 00135 return result; 00136 } 00137 00138 //--------------------------------------------------------------------------- 00139 // GetPixel() retrieves the red, green, and blue values for a specified 00140 // pixel as floating points. 00141 // 00142 // This is for convenience and prototyping - for high-speed image 00143 // processing you'll need to work more directly with the image 00144 // buffer. 00145 // 00146 // Within CVImageRGB24, this returns the red, green, and blue values 00147 // all of which will be between 0-255. 00148 // 00149 // \param x - x position within the image of the pixel 00150 // \param y - y position within the image of the pixel 00151 // \param r - receives the red value of the pixel 00152 // \param g - receives the green value of the pixel 00153 // \param b - receives the blue value of the pixel 00154 // 00155 // \return CVRES result code. CVRES_SUCCESS on success. 00156 // \sa SetPixel() 00157 //--------------------------------------------------------------------------- 00158 CVRES CVImageRGB24::GetPixel( int x, 00159 int y, 00160 float& r, 00161 float& g, 00162 float& b) const 00163 { 00164 CVRES result = CVRES_SUCCESS; 00165 00166 CVAssert(fData != 0, "Image must be created first!"); 00167 if (fData == 0) 00168 { 00169 return CVRES_IMAGE_EMPTY_ERR; 00170 } 00171 00172 // Bounds check coordinates 00173 CVAssert(( (x >= 0) || (x < fWidth)), "X position is out of bounds!"); 00174 CVAssert(( (y >= 0) || (y < fHeight)), "Y position is out of bounds!"); 00175 00176 if ( (x < 0) || (x >= fWidth)) 00177 { 00178 return CVRES_IMAGE_OUT_OF_RANGE; 00179 } 00180 00181 if ( (y < 0) || (y >= fHeight)) 00182 { 00183 return CVRES_IMAGE_OUT_OF_RANGE; 00184 } 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 bytes ( >= fWidth * GetBytesPerPixel()) 00191 int lineLength = this->AbsWidth() * 3; 00192 00193 // current position of start of buffer in source 00194 unsigned char* curPtr = fData + lineOffset + 00195 ((YOffsetAbs() + y) * lineLength); 00196 00197 // pull out pixels 00198 r = (float)curPtr[0]; 00199 g = (float)curPtr[1]; 00200 b = (float)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 // 00212 // Within CVImageRGB24, the values are truncated to be between 00213 // 0 (min) and 255 (max), then set. 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 CVImageRGB24::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 bytes ( >= fWidth * GetBytesPerPixel()) 00259 int lineLength = this->AbsWidth() * 3; 00260 00261 // current position of start of buffer in source 00262 unsigned char* curPtr = fData + lineOffset + 00263 ((YOffsetAbs() + y) * lineLength); 00264 00265 // Bounds check the pixel values 00266 r = CVMax( 0.0f, r ); 00267 r = CVMin( 255.0f, r ); 00268 g = CVMax( 0.0f, g ); 00269 g = CVMin( 255.0f, g ); 00270 b = CVMax( 0.0f, b ); 00271 b = CVMin( 255.0f, b ); 00272 00273 // Store 00274 curPtr[0] = (unsigned char)r; 00275 curPtr[1] = (unsigned char)g; 00276 curPtr[2] = (unsigned char)b; 00277 00278 return result; 00279 } 00280 00281 #ifdef WIN32 00282 //--------------------------------------------------------------------------- 00283 // SetFromWin32Bmp() 00284 // Sets the image from a bitmap buffer 00285 // We do a full copy of the data for this, since we may flip it and 00286 // swap red with blue to get it into RGB order rather than Window's BGR. 00287 // Padding will be removed as well. 00288 // 00289 // Only supports 24-bit RGB bitmaps. 00290 // 00291 //--------------------------------------------------------------------------- 00292 CVRES CVImageRGB24::SetFromWin32Bmp( const BITMAPINFOHEADER* bmih, 00293 const unsigned char* data) 00294 { 00295 CVAssert(fData == 0, 00296 "SetFromWin32Bmp requires a clean, uninitialized,"\ 00297 " but instantiated image"); 00298 00299 // Parent does sanity checks (only called from CreateFromWin32bmp) 00300 CVRES result = CVRES_SUCCESS; 00301 00302 // Negative height means top down. 00303 // Flipped is set if bottom-up image (default for win32) 00304 bool flipped = bmih->biHeight >= 0; 00305 00306 // Create an image of the same size 00307 // Make sure to use a positive height based on flipped var 00308 // Note: this adds our reference 00309 Create( bmih->biWidth, 00310 flipped?(bmih->biHeight):-(bmih->biHeight), 00311 false); 00312 00313 // Set our starting position in the source image and step pos 00314 unsigned char* dstPos = fData; 00315 unsigned char* srcPos = 0; 00316 00317 int srcStep = -((int)bmih->biSizeImage / fHeight); 00318 00319 if (flipped) 00320 { 00321 // Set to point to bottom row in image so we can flip it 00322 srcPos = (unsigned char*)data + (int)bmih->biSizeImage + srcStep; 00323 } 00324 else 00325 { 00326 // Start at top if not flipped 00327 srcPos = (unsigned char*)data; 00328 } 00329 00330 // Copy row by row from source image to destination image 00331 00332 // May want to optimize this one a bit. 00333 // We're just flipping the red and blue channels while flipping from 00334 // bottom to top. For windows-only development where we work with 00335 // bitmaps, this is an unnecessary step. However, I like keeping all 00336 // my images in a neutral RGB 24-bit unpadded format for simplicity, 00337 // so unless it becomes a bottleneck, it makes it simpler. 00338 00339 // profiling - time it. 00340 // CVStartTime(); 00341 00342 int y; 00343 for (y = 0; y < fHeight; y++) 00344 { 00345 unsigned char* srcLine = srcPos; 00346 { 00347 int x; 00348 for (x = 0; x < fWidth; x++) 00349 { 00350 *dstPos = *(srcLine+2); dstPos++; 00351 *dstPos = *(srcLine+1); dstPos++; 00352 *dstPos = *(srcLine); dstPos++; 00353 srcLine +=3; 00354 } 00355 } 00356 srcPos += srcStep; 00357 } 00358 00359 // end profiling - print time 00360 //CVEndTime(); 00361 00362 return result; 00363 } 00364 #endif // WIN32 00365 |
1.3.3