last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998-2004 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 00042 /** 00043 * \file cvrRGBAPixel.h 00044 * Contains the basic template class to represent RGB pixels with 00045 * an alpha channel 00046 * \author Pablo Alvarado 00047 * \date 01.11.2002 00048 * 00049 * $Id: cvrRGBAPixel.h,v 1.11 2007/04/16 16:39:32 alvarado Exp $ 00050 */ 00051 00052 #ifndef _CVR_RGBA_PIXEL_H_ 00053 #define _CVR_RGBA_PIXEL_H_ 00054 00055 #include "cvrConfig.h" 00056 #include "cvrAssert.h" 00057 #include "cvrTypes.h" 00058 #include "cvrIoHandler.h" 00059 00060 #include <iostream> 00061 00062 namespace cvr { 00063 00064 /** 00065 * Color pixel representation in RGB color space with an alpha channel. 00066 * 00067 * Since most modern cameras provide the images as matrices of RGB triplets 00068 * with values between 0 and 255 for each color channel, and the modern 00069 * processor architectures allow a more efficient access to the memory if 00070 * each pixel is 32-bit aligned, the CVR-Libuses a pixel data structure 00071 * which also corresponds with a cvr::uint32 type. 00072 * 00073 * This type contains therefore four unsigned bytes (cvr::ubyte) which can 00074 * be accessed through their color names (red, green, blue) and an additional 00075 * alpha channel, which is ignored in most operations but can also be used 00076 * to operate with partial "transparent" pixels. 00077 * 00078 * The alpha value of 0 is the default and means also zero transparency. 00079 * An alpha value of 255 means fully transparent. 00080 * 00081 * The related template type cvr::rgbPixel<T> can be used to represent 00082 * the RGB triplets with other types. 00083 * 00084 * The use of rgbaPixel as a vector structure considers it as a three 00085 * dimensional point in the RGB color space, i.e. the alpha value is ignored 00086 * for the distance and magniture operators, the access operator[] or at() 00087 * methods can only access the three color components, and the arithmetical 00088 * operations always ignore the alpha component. 00089 * 00090 * @ingroup gColor 00091 */ 00092 class rgbaPixel { 00093 public: 00094 /** 00095 * Anonymous union to provide efficient access through three different 00096 * mechanism to the pixel components. 00097 * 00098 * The order of the data in this union assumes little endianness. 00099 */ 00100 union { 00101 /** 00102 * Anonymous structure with the three channels 00103 */ 00104 __extension__ struct { 00105 // the sequence blue, green, red _is_ important! 00106 00107 /** 00108 * Blue channel 00109 */ 00110 ubyte blue; 00111 00112 /** 00113 * Green channel 00114 */ 00115 ubyte green; 00116 00117 /** 00118 * Red channel 00119 */ 00120 ubyte red; 00121 00122 /** 00123 * Alpha channel. 00124 * 00125 * This value can be considered proportional to transparency. 00126 * 255 means fully transparent, and 0 means a solid color. 00127 */ 00128 ubyte alpha; 00129 }; 00130 00131 /** 00132 * All three channels (and the alpha channel) together 00133 */ 00134 uint32 value; 00135 00136 /** 00137 * The four values as array 00138 */ 00139 ubyte data[4]; 00140 }; 00141 00142 /** 00143 * Used for the template-based interface for pixels as vectors. 00144 */ 00145 typedef ubyte value_type; 00146 00147 /** 00148 * Return type of the size() member 00149 */ 00150 typedef int size_type; 00151 00152 /** 00153 * Default constructor 00154 * 00155 * The default constructor of the CVR-LibrgbaPixel does \b not initialize 00156 * anything, in order to allow the creation of uninitialized images in a 00157 * more efficient way. 00158 */ 00159 rgbaPixel(); 00160 00161 /** 00162 * Copy constructor 00163 */ 00164 rgbaPixel(const rgbaPixel& other); 00165 00166 /** 00167 * Constructor with initialization of attributes. 00168 * 00169 * The new rgbaPixel will be initialized with the given value. 00170 * @param val a 4 ubyte value to be assigned to the three channels and 00171 * the alpha channel. 00172 * Note that the order depends on the system endianness: 00173 * - If you use little endian (for example: Intel Processor) 00174 * a value of 0x00010203 means red=01,green=02 and blue=03 00175 * - If you use big endian (for example: PowerPC Processor) 00176 * a value of 0x00010203 means red=02,green=01 and blue=00 00177 * Avoid the use of this constructor if you want to maintain 00178 * platform compatibility. 00179 */ 00180 rgbaPixel(const uint32 val); 00181 00182 /** 00183 * RGB constructor 00184 * @param r 8 bit value for the red component 00185 * @param g 8 bit value for the green component 00186 * @param b 8 bit value for the blue component 00187 * @param d 8 bit value for the alpha byte (default value 0) 00188 */ 00189 rgbaPixel(const ubyte r,const ubyte g,const ubyte b,const ubyte d=0); 00190 00191 /** 00192 * Set the red, green, blue and alpha values for the pixel 00193 */ 00194 inline void set(const ubyte r, 00195 const ubyte g, 00196 const ubyte b, 00197 const ubyte a); 00198 00199 /** 00200 * Set the red, green, blue values for the pixel 00201 */ 00202 inline void set(const ubyte r, const ubyte g, const ubyte blue); 00203 00204 /** 00205 * Sets the red component to given value 00206 */ 00207 inline void setRed(const ubyte r); 00208 00209 /** 00210 * Sets the green component to given value 00211 */ 00212 inline void setGreen(const ubyte g); 00213 00214 /** 00215 * Sets the blue component to given value 00216 */ 00217 inline void setBlue(const ubyte b); 00218 00219 /** 00220 * Sets the alpha component to given value 00221 */ 00222 inline void setAlpha(const ubyte d); 00223 00224 /** 00225 * Sets the value component (all components together) to given value 00226 */ 00227 inline void setValue(const uint32& v); 00228 00229 /** 00230 * Get the three color components and write them in the given arguments 00231 */ 00232 inline void get(ubyte& r,ubyte& g,ubyte& b) const; 00233 00234 /** 00235 * Get the three color components and write them in the given arguments 00236 */ 00237 inline void get(int& r,int& g,int& b) const; 00238 00239 /** 00240 * Get the four components and write them in the given arguments 00241 */ 00242 inline void get(ubyte& r,ubyte& g,ubyte& b,ubyte& a) const; 00243 00244 /** 00245 * Get the four components and write them in the given arguments 00246 */ 00247 inline void get(int& r,int& g,int& b,int& a) const; 00248 00249 /** 00250 * Returns red component 00251 */ 00252 inline const ubyte& getRed() const; 00253 00254 /** 00255 * Returns green component 00256 */ 00257 inline const ubyte& getGreen() const; 00258 00259 /** 00260 * Returns blue component 00261 */ 00262 inline const ubyte& getBlue() const; 00263 00264 /** 00265 * Returns alpha component 00266 */ 00267 inline const ubyte& getAlpha() const; 00268 00269 /** 00270 * Returns red component 00271 */ 00272 inline ubyte& getRed(); 00273 00274 /** 00275 * Returns green component 00276 */ 00277 inline ubyte& getGreen(); 00278 00279 /** 00280 * Returns blue component 00281 */ 00282 inline ubyte& getBlue(); 00283 00284 /** 00285 * Returns alpha component 00286 */ 00287 inline ubyte& getAlpha(); 00288 00289 /** 00290 * Returns 4 byte component with RGB and alpha value 00291 */ 00292 inline const uint32& getValue() const; 00293 00294 /** 00295 * Returns 4 byte component with RGB value 00296 */ 00297 inline uint32& getValue(); 00298 00299 /** 00300 * Used to simulate vector access. 00301 * 00302 * The correspondence between the elements of the vector and 00303 * the color components is at(0) for red, at(1) for green and 00304 * at(2) for blue. 00305 */ 00306 inline ubyte& at(const int x); 00307 00308 /** 00309 * Used to simulate read-only vector access. 00310 * 00311 * The correspondence between the elements of the vector and 00312 * the color components still depents on the endianness of the 00313 * system, but is usually at(0) for red, at(1) for green and 00314 * at(2) for blue. 00315 */ 00316 inline const ubyte& at(const int x) const; 00317 00318 /** 00319 * Used to simulate vector access. 00320 * 00321 * The correspondence between the elements of the vector and 00322 * the color components is [0] for red, [1] for green and 00323 * [2] for blue. 00324 */ 00325 inline ubyte& operator[](const int x); 00326 00327 /** 00328 * Used to simulate read-only vector access. 00329 * 00330 * The correspondence between the elements of the vector and 00331 * the color components still depents on the endianness of the 00332 * system, but is usually [0] for red, [1] for green and 00333 * [2] for blue. 00334 */ 00335 inline const ubyte& operator[](const int x) const; 00336 00337 /** 00338 * Used to simulate the vector size. 00339 * 00340 * It returns always 3. 00341 */ 00342 inline size_type size() const; 00343 00344 /** 00345 * Copy the "other" pixel 00346 */ 00347 inline rgbaPixel& copy(const rgbaPixel& other); 00348 00349 /** 00350 * Alias for copy 00351 */ 00352 inline rgbaPixel& operator=(const rgbaPixel& other); 00353 00354 /** 00355 * Compare two pixels (true if equal!) 00356 * 00357 * Two pixels are \e equal if all \b four components (red, green, 00358 * blue, and \b alpha) are equal. It is an usual error to leave the 00359 * alpha channel uninizalized and then compare for equalilty. 00360 */ 00361 inline bool isEqual(const rgbaPixel& other) const; 00362 00363 /** 00364 * Alias for compare() 00365 * 00366 * Two pixels are \e equal if all \b four components (red, green, 00367 * blue, and \b alpha) are equal. It is an usual error to leave the 00368 * alpha channel uninizalized and then compare for equalilty. 00369 */ 00370 inline bool operator==(const rgbaPixel& other) const; 00371 00372 /** 00373 * Alias for !compare() 00374 * 00375 * Two pixels are \e equal if all \b four components (red, green, 00376 * blue, and \b alpha) are equal. It is an usual error to leave the 00377 * alpha channel uninizalized and then compare for equalilty. 00378 */ 00379 inline bool operator!=(const rgbaPixel& other) const; 00380 00381 /** 00382 * Less than operator. 00383 * 00384 * An rgbaPixel is said to be "smaller" than another one, if 00385 * getValue() < other.getValue() 00386 */ 00387 inline bool operator<(const rgbaPixel& other) const; 00388 00389 /** 00390 * Less than operator. 00391 * 00392 * An rgbaPixel is said to be "bigger" than another one, if 00393 * getValue() > other.getValue() 00394 */ 00395 inline bool operator>(const rgbaPixel& other) const; 00396 00397 /** 00398 * Add this pixel with another one. 00399 * 00400 * The alpha channel is kept unchanged. 00401 */ 00402 inline rgbaPixel& add(const rgbaPixel& other); 00403 00404 /** 00405 * Add this pixel with another one. 00406 * 00407 * The alpha channel is kept unchanged. 00408 */ 00409 inline rgbaPixel& operator+=(const rgbaPixel& other); 00410 00411 /** 00412 * Add this pixel with the other one without altering anything. 00413 * 00414 * The alpha channel of the resulting pixel is equal to 00415 * the one of this pixel (the first operand in the binary expression) 00416 */ 00417 inline rgbaPixel operator+(const rgbaPixel& other) const; 00418 00419 /** 00420 * Subtract 'other' from this pixel. 00421 * 00422 * The alpha channel is kept unchanged. 00423 */ 00424 inline rgbaPixel& subtract(const rgbaPixel& other); 00425 00426 /** 00427 * Subtract 'other' from this pixel. 00428 * 00429 * The alpha channel is kept unchanged. 00430 */ 00431 inline rgbaPixel& operator-=(const rgbaPixel& other); 00432 00433 /** 00434 * Subtract 'other' from this pixel without altering anything. 00435 * 00436 * The alpha channel of the resulting pixel is equal to 00437 * the one of this pixel (the first operand in the binary expression) 00438 */ 00439 inline rgbaPixel operator-(const rgbaPixel& other) const; 00440 00441 /** 00442 * Multiply this pixel with another one. 00443 * 00444 * The pixel multiplication multiplies elementwise the elements of 00445 * the pixel, except the alpha channel, which is kept unchanged. 00446 */ 00447 inline rgbaPixel& multiply(const rgbaPixel& other); 00448 00449 /** 00450 * Multiply this pixel with another one. 00451 * 00452 * The pixel multiplication multiplies elementwise the elements of 00453 * the pixel, except the alpha channel, which is kept unchanged. 00454 */ 00455 inline rgbaPixel& operator*=(const rgbaPixel& other); 00456 00457 /** 00458 * Multiply this pixel with another one without altering anything. 00459 * 00460 * The alpha channel of the resulting pixel is equal to 00461 * the one of this pixel (the first operand in the binary expression) 00462 */ 00463 inline rgbaPixel operator*(const rgbaPixel& other) const; 00464 00465 /** 00466 * Multiply all components of this pixel with an integer, except the alpha 00467 * channel, which is kept unchanged. 00468 */ 00469 inline rgbaPixel& multiply(const int other); 00470 00471 /** 00472 * Multiply all components of this pixel with a float, except the alpha 00473 * channel, which is kept unchanged. 00474 */ 00475 inline rgbaPixel& multiply(const float& other); 00476 00477 /** 00478 * Multiply all components of this pixel with a float, except the alpha 00479 * channel, which is kept unchanged. 00480 */ 00481 inline rgbaPixel& multiply(const double& other); 00482 00483 /** 00484 * Multiply all components of this pixel with a an integer, except the 00485 * alpha channel, which is kept unchanged. 00486 */ 00487 inline rgbaPixel& operator*=(const int other); 00488 00489 /** 00490 * Multiply all components of this pixel with a a float, except the 00491 * alpha channel, which is kept unchanged. 00492 */ 00493 inline rgbaPixel& operator*=(const float& other); 00494 00495 /** 00496 * Multiply all components of this pixel with a a double, except the 00497 * alpha channel, which is kept unchanged. 00498 */ 00499 inline rgbaPixel& operator*=(const double& other); 00500 00501 /** 00502 * Multiply all components of this pixel with a an integer, except the 00503 * alpha channel. 00504 * 00505 * The alpha channel of the resulting pixel is equal to 00506 * the one of this pixel (the first operand in the binary expression) 00507 */ 00508 inline rgbaPixel operator*(const int other) const; 00509 00510 /** 00511 * Multiply all components of this pixel with a a float, except the 00512 * alpha channel. 00513 * 00514 * The alpha channel of the resulting pixel is equal to 00515 * the one of this pixel (the first operand in the binary expression) 00516 */ 00517 inline rgbaPixel operator*(const float& other) const; 00518 00519 /** 00520 * Multiply all components of this pixel with a a double, except the 00521 * alpha channel. 00522 * 00523 * The alpha channel of the resulting pixel is equal to 00524 * the one of this pixel (the first operand in the binary expression) 00525 */ 00526 inline rgbaPixel operator*(const double& other) const; 00527 00528 /** 00529 * Divide this pixel with another one. 00530 * 00531 * The pixel division divides elementwise the elements of the pixel 00532 * except the alpha channel, which is kept unchanged. 00533 */ 00534 inline rgbaPixel& divide(const rgbaPixel& other); 00535 00536 /** 00537 * Divide this pixel with another one. 00538 * 00539 * The pixel division divides elementwise the elements of the pixel 00540 * except the alpha channel, which is kept unchanged. 00541 */ 00542 inline rgbaPixel& operator/=(const rgbaPixel& other); 00543 00544 /** 00545 * Divide this pixel with another one. 00546 * 00547 * The pixel division divides elementwise the elements of the pixel 00548 * except the alpha channel. 00549 * 00550 * The alpha channel of the resulting pixel is equal to 00551 * the one of this pixel (the first operand in the binary expression) 00552 */ 00553 inline rgbaPixel operator/(const rgbaPixel& other) const; 00554 00555 /** 00556 * Divide all components of this pixel with an integer. 00557 */ 00558 inline rgbaPixel& divide(const int other); 00559 00560 /** 00561 * Divide all components of this pixel with an integer. 00562 */ 00563 inline rgbaPixel& divide(const float& other); 00564 00565 /** 00566 * Divide all components of this pixel with an integer. 00567 */ 00568 inline rgbaPixel& divide(const double& other); 00569 00570 /** 00571 * Divide all components of this pixel with an integer. 00572 */ 00573 inline rgbaPixel& operator/=(const int other); 00574 00575 /** 00576 * Divide all components of this pixel with an integer. 00577 */ 00578 inline rgbaPixel& operator/=(const float& other); 00579 00580 /** 00581 * Divide all components of this pixel with an integer. 00582 */ 00583 inline rgbaPixel& operator/=(const double& other); 00584 00585 /** 00586 * Divide all components of this pixel with an integer without altering 00587 * anything. 00588 * 00589 * The alpha channel of the resulting pixel is equal to 00590 * the one of this pixel (the first operand in the binary expression) 00591 */ 00592 inline rgbaPixel operator/(const int other) const; 00593 00594 /** 00595 * Divide all components of this pixel with an integer without altering 00596 * anything. 00597 * 00598 * The alpha channel of the resulting pixel is equal to 00599 * the one of this pixel (the first operand in the binary expression) 00600 */ 00601 inline rgbaPixel operator/(const float& other) const; 00602 00603 /** 00604 * Divide all components of this pixel with an integer without altering 00605 * anything. 00606 * 00607 * The alpha channel of the resulting pixel is equal to 00608 * the one of this pixel (the first operand in the binary expression) 00609 */ 00610 inline rgbaPixel operator/(const double& other) const; 00611 00612 /** 00613 * Overlay the current pixel on the given one. 00614 * 00615 * The current pixel will be altered considering the "transparency" given 00616 * in the alpha channel. 00617 * 00618 * The new pixel will be equal to the current one multiplied by 00619 * (1.0-alpha/255) plus the other pixel multiplied by (alpha/255). 00620 * The new alpha value is equal to the product of both alpha values 00621 * divided by 255. 00622 */ 00623 inline rgbaPixel& overlay(const rgbaPixel& below); 00624 00625 /** 00626 * Overlay the first pixel on the second pixel 00627 * 00628 * The current pixel will be computed considering the "transparency" given 00629 * in the alpha channel of the first pixel. 00630 * 00631 * This pixel will be equal to the first one multiplied by 00632 * (1.0-alpha/255) plus the other pixel multiplied by (alpha/255). The 00633 * new alpha value is equal to the product of the alpha values of the 00634 * other pixels divided by 255. 00635 */ 00636 inline rgbaPixel& overlay(const rgbaPixel& above, 00637 const rgbaPixel& below); 00638 00639 00640 /** 00641 * Compute the square of the magnitud of this pixel 00642 * \f$red^2+green^2+blue^2\f$. 00643 */ 00644 inline int absSqr() const; 00645 00646 /** 00647 * Scalar product in the 3D RGB color space. 00648 * 00649 * Get the scalar product of this pixel with another one, considering 00650 * them as a 3D point in the RGB color space. 00651 * 00652 * The dot product will be the sum of the 00653 * red*other.red + green*other.green + blue*other.blue 00654 */ 00655 inline int dot(const rgbaPixel& other) const; 00656 00657 /** 00658 * Square of the distance between this pixel and the other one. 00659 * 00660 * \f$(red-other.red)^2+(green-other.green)^2+(blue-other.blue)^2\f$. 00661 */ 00662 inline int distanceSqr(const rgbaPixel& other) const; 00663 00664 /** 00665 * @name Storable interface 00666 */ 00667 //@{ 00668 /** 00669 * Read the pixel from the given ioHandler. 00670 * 00671 * The complete flag indicates if the enclosing begin and end should be 00672 * also be readed 00673 * 00674 * @ingroup gStorable 00675 */ 00676 bool read(ioHandler& handler,const bool complete=true); 00677 00678 /** 00679 * Write the vector in the given ioHandler. 00680 * 00681 * The complete flag indicates if the enclosing begin and end should be 00682 * also be written or not. 00683 * 00684 * @ingroup gStorable 00685 */ 00686 bool write(ioHandler& handler,const bool complete=true) const; 00687 //@} 00688 }; 00689 00690 /** 00691 * Multiply all components of the given pixel with an integer 00692 * except the alpha channel. 00693 */ 00694 inline rgbaPixel operator*(const int p,const rgbaPixel& other); 00695 00696 /** 00697 * Multiply all components of the given pixel with an integer 00698 * except the alpha channel. 00699 */ 00700 inline rgbaPixel operator*(const float p,const rgbaPixel& other); 00701 00702 /** 00703 * Multiply all components of the given pixel with an integer 00704 * except the alpha channel. 00705 */ 00706 inline rgbaPixel operator*(const double& p,const rgbaPixel& other); 00707 00708 /** 00709 * Read the rgbaPixel from the given ioHandler. 00710 * 00711 * The complete flag indicates if the enclosing begin and end should be also 00712 * be readed 00713 * 00714 * @ingroup gStorable 00715 */ 00716 bool read(ioHandler& handler,rgbaPixel& p,const bool complete=true); 00717 00718 /** 00719 * Write the rgbaPixel in the given ioHandler. 00720 * 00721 * The complete flag indicates if the enclosing begin and end should be also 00722 * be written or not 00723 * 00724 * @ingroup gStorable 00725 */ 00726 bool write(ioHandler& handler,const rgbaPixel& p,const bool complete=true); 00727 } 00728 00729 00730 00731 namespace std { 00732 ostream& operator<<(ostream& s,const cvr::rgbaPixel& p); 00733 istream& operator>>(istream& s,cvr::rgbaPixel& p); 00734 } 00735 00736 00737 #include "cvrTypeInfo.h" 00738 namespace cvr { 00739 template<> 00740 class typeInfo<rgbaPixel> { 00741 public: 00742 typedef int32 accumulation_type; 00743 typedef int32 square_accumulation_type; 00744 static ubyte suggestedNorm() throw() {return 255;} 00745 static bool isFloatingPointType() throw() {return false;} 00746 static const char* name() throw() {return "cvr::rgbaPixel";}; 00747 static ubyte min() throw() {return std::numeric_limits<ubyte>::min();} 00748 private: 00749 typeInfo() {}; 00750 }; 00751 } 00752 00753 #include "cvrRGBAPixel_inline.h" 00754 00755 #endif 00756 00757