LCOV - code coverage report
Current view: directory - gfx/thebes - gfxColor.h (source / functions) Found Hit Coverage
Test: app.info Lines: 39 0 0.0 %
Date: 2012-06-02 Functions: 5 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Oracle Corporation code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Oracle Corporation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2005
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Stuart Parmenter <pavlov@pavlov.net>
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #ifndef GFX_COLOR_H
      39                 : #define GFX_COLOR_H
      40                 : 
      41                 : #include "gfxTypes.h"
      42                 : 
      43                 : #include "prbit.h" // for PR_ROTATE_(LEFT,RIGHT)32
      44                 : #include "prio.h"  // for ntohl
      45                 : 
      46                 : #define GFX_UINT32_FROM_BPTR(pbptr,i) (((PRUint32*)(pbptr))[i])
      47                 : 
      48                 : #if defined(IS_BIG_ENDIAN)
      49                 :   #define GFX_NTOHL(x) (x)
      50                 :   #define GFX_HAVE_CHEAP_NTOHL
      51                 : #elif defined(_WIN32)
      52                 :   #if (_MSC_VER >= 1300) // also excludes MinGW
      53                 :     #include <stdlib.h>
      54                 :     #pragma intrinsic(_byteswap_ulong)
      55                 :     #define GFX_NTOHL(x) _byteswap_ulong(x)
      56                 :     #define GFX_HAVE_CHEAP_NTOHL
      57                 :   #else
      58                 :     // A reasonably fast generic little-endian implementation.
      59                 :     #define GFX_NTOHL(x) \
      60                 :          ( (PR_ROTATE_RIGHT32((x),8) & 0xFF00FF00) | \
      61                 :            (PR_ROTATE_LEFT32((x),8)  & 0x00FF00FF) )
      62                 :   #endif
      63                 : #else
      64                 :   #define GFX_NTOHL(x) ntohl(x)
      65                 :   #define GFX_HAVE_CHEAP_NTOHL
      66                 : #endif
      67                 : 
      68                 : /**
      69                 :  * GFX_0XFF_PPIXEL_FROM_BPTR(x)
      70                 :  *
      71                 :  * Avoid tortured construction of 32-bit ARGB pixel from 3 individual bytes
      72                 :  *   of memory plus constant 0xFF.  RGB bytes are already contiguous!
      73                 :  * Equivalent to: GFX_PACKED_PIXEL(0xff,r,g,b)
      74                 :  *
      75                 :  * Attempt to use fast byte-swapping instruction(s), e.g. bswap on x86, in
      76                 :  *   preference to a sequence of shift/or operations.
      77                 :  */
      78                 : #if defined(GFX_HAVE_CHEAP_NTOHL)
      79                 :   #define GFX_0XFF_PPIXEL_FROM_UINT32(x) \
      80                 :        ( (GFX_NTOHL(x) >> 8) | (0xFF << 24) )
      81                 : #else
      82                 :   // A reasonably fast generic little-endian implementation.
      83                 :   #define GFX_0XFF_PPIXEL_FROM_UINT32(x) \
      84                 :        ( (PR_ROTATE_LEFT32((x),16) | 0xFF00FF00) & ((x) | 0xFFFF00FF) )
      85                 : #endif
      86                 : 
      87                 : #define GFX_0XFF_PPIXEL_FROM_BPTR(x) \
      88                 :      ( GFX_0XFF_PPIXEL_FROM_UINT32(GFX_UINT32_FROM_BPTR((x),0)) )
      89                 : 
      90                 : /**
      91                 :  * GFX_BLOCK_RGB_TO_FRGB(from,to)
      92                 :  *   sizeof(*from) == sizeof(char)
      93                 :  *   sizeof(*to)   == sizeof(PRUint32)
      94                 :  *
      95                 :  * Copy 4 pixels at a time, reading blocks of 12 bytes (RGB x4)
      96                 :  *   and writing blocks of 16 bytes (FRGB x4)
      97                 :  */
      98                 : #define GFX_BLOCK_RGB_TO_FRGB(from,to) \
      99                 :   PR_BEGIN_MACRO \
     100                 :     PRUint32 m0 = GFX_UINT32_FROM_BPTR(from,0), \
     101                 :              m1 = GFX_UINT32_FROM_BPTR(from,1), \
     102                 :              m2 = GFX_UINT32_FROM_BPTR(from,2), \
     103                 :              rgbr = GFX_NTOHL(m0), \
     104                 :              gbrg = GFX_NTOHL(m1), \
     105                 :              brgb = GFX_NTOHL(m2), \
     106                 :              p0, p1, p2, p3; \
     107                 :     p0 = 0xFF000000 | ((rgbr) >>  8); \
     108                 :     p1 = 0xFF000000 | ((rgbr) << 16) | ((gbrg) >> 16); \
     109                 :     p2 = 0xFF000000 | ((gbrg) <<  8) | ((brgb) >> 24); \
     110                 :     p3 = 0xFF000000 | (brgb); \
     111                 :     to[0] = p0; to[1] = p1; to[2] = p2; to[3] = p3; \
     112                 :   PR_END_MACRO
     113                 : 
     114                 : /**
     115                 :  * Fast approximate division by 255. It has the property that
     116                 :  * for all 0 <= n <= 255*255, GFX_DIVIDE_BY_255(n) == n/255.
     117                 :  * But it only uses two adds and two shifts instead of an
     118                 :  * integer division (which is expensive on many processors).
     119                 :  *
     120                 :  * equivalent to ((v)/255)
     121                 :  */
     122                 : #define GFX_DIVIDE_BY_255(v)  \
     123                 :      (((((unsigned)(v)) << 8) + ((unsigned)(v)) + 255) >> 16)
     124                 : 
     125                 : /**
     126                 :  * Fast premultiply macro
     127                 :  *
     128                 :  * equivalent to (((c)*(a))/255)
     129                 :  */
     130                 : #define GFX_PREMULTIPLY(c,a) GFX_DIVIDE_BY_255((c)*(a))
     131                 : 
     132                 : /** 
     133                 :  * Macro to pack the 4 8-bit channels (A,R,G,B) 
     134                 :  * into a 32-bit packed premultiplied pixel.
     135                 :  *
     136                 :  * The checks for 0 alpha or max alpha ensure that the
     137                 :  * compiler selects the quicked calculation when alpha is constant.
     138                 :  */
     139                 : #define GFX_PACKED_PIXEL(a,r,g,b)                                       \
     140                 :     ((a) == 0x00) ? 0x00000000 :                                        \
     141                 :     ((a) == 0xFF) ? ((0xFF << 24) | ((r) << 16) | ((g) << 8) | (b))     \
     142                 :                   : ((a) << 24) |                                       \
     143                 :                     (GFX_PREMULTIPLY(r,a) << 16) |                      \
     144                 :                     (GFX_PREMULTIPLY(g,a) << 8) |                       \
     145                 :                     (GFX_PREMULTIPLY(b,a))
     146                 : 
     147                 : /** 
     148                 :  * Macro to pack the 4 8-bit channels (A,R,G,B) 
     149                 :  * into a 32-bit packed NON-premultiplied pixel.
     150                 :  */
     151                 : #define GFX_PACKED_PIXEL_NO_PREMULTIPLY(a,r,g,b)                        \
     152                 :     (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
     153                 : 
     154                 : 
     155                 : /**
     156                 :  * A color value, storing red, green, blue and alpha components.
     157                 :  * This class does not use premultiplied alpha.
     158                 :  *
     159                 :  * XXX should this use doubles (instead of gfxFloat), for consistency with
     160                 :  * cairo?
     161                 :  */
     162               0 : struct THEBES_API gfxRGBA {
     163                 :     gfxFloat r, g, b, a;
     164                 : 
     165                 :     enum PackedColorType {
     166                 :         PACKED_ABGR,
     167                 :         PACKED_ABGR_PREMULTIPLIED,
     168                 : 
     169                 :         PACKED_ARGB,
     170                 :         PACKED_ARGB_PREMULTIPLIED,
     171                 : 
     172                 :         PACKED_XRGB
     173                 :     };
     174                 : 
     175               0 :     gfxRGBA() { }
     176                 :     /**
     177                 :      * Intialize this color using explicit red, green, blue and alpha
     178                 :      * values.
     179                 :      */
     180               0 :     gfxRGBA(gfxFloat _r, gfxFloat _g, gfxFloat _b, gfxFloat _a=1.0) : r(_r), g(_g), b(_b), a(_a) {}
     181                 : 
     182                 :     /**
     183                 :      * Initialize this color from a packed 32-bit color.
     184                 :      * The color value is interpreted based on colorType;
     185                 :      * all values use the native platform endianness.
     186                 :      *
     187                 :      * @see gfxRGBA::Packed
     188                 :      */
     189               0 :     gfxRGBA(PRUint32 c, PackedColorType colorType = PACKED_ABGR) {
     190               0 :         if (colorType == PACKED_ABGR ||
     191                 :             colorType == PACKED_ABGR_PREMULTIPLIED)
     192                 :         {
     193               0 :             r = ((c >> 0) & 0xff) * (1.0 / 255.0);
     194               0 :             g = ((c >> 8) & 0xff) * (1.0 / 255.0);
     195               0 :             b = ((c >> 16) & 0xff) * (1.0 / 255.0);
     196               0 :             a = ((c >> 24) & 0xff) * (1.0 / 255.0);
     197               0 :         } else if (colorType == PACKED_ARGB ||
     198                 :                    colorType == PACKED_XRGB ||
     199                 :                    colorType == PACKED_ARGB_PREMULTIPLIED)
     200                 :         {
     201               0 :             b = ((c >> 0) & 0xff) * (1.0 / 255.0);
     202               0 :             g = ((c >> 8) & 0xff) * (1.0 / 255.0);
     203               0 :             r = ((c >> 16) & 0xff) * (1.0 / 255.0);
     204               0 :             a = ((c >> 24) & 0xff) * (1.0 / 255.0);
     205                 :         }
     206                 : 
     207               0 :         if (colorType == PACKED_ABGR_PREMULTIPLIED ||
     208                 :             colorType == PACKED_ARGB_PREMULTIPLIED)
     209                 :         {
     210               0 :             if (a > 0.0) {
     211               0 :                 r /= a;
     212               0 :                 g /= a;
     213               0 :                 b /= a;
     214                 :             }
     215               0 :         } else if (colorType == PACKED_XRGB) {
     216               0 :             a = 1.0;
     217                 :         }
     218               0 :     }
     219                 : 
     220                 :     bool operator==(const gfxRGBA& other) const
     221                 :     {
     222                 :         return r == other.r && g == other.g && b == other.b && a == other.a;
     223                 :     }
     224                 :     bool operator!=(const gfxRGBA& other) const
     225                 :     {
     226                 :         return !(*this == other);
     227                 :     }
     228                 : 
     229                 :     /**
     230                 :      * Returns this color value as a packed 32-bit integer. This reconstructs
     231                 :      * the int32 based on the given colorType, always in the native byte order.
     232                 :      *
     233                 :      * Note: gcc 4.2.3 on at least Ubuntu (x86) does something strange with
     234                 :      * (PRUint8)(c * 255.0) << x, where the result is different than
     235                 :      * double d = c * 255.0; v = ((PRUint8) d) << x. 
     236                 :      */
     237               0 :     PRUint32 Packed(PackedColorType colorType = PACKED_ABGR) const {
     238               0 :         gfxFloat rb = (r * 255.0);
     239               0 :         gfxFloat gb = (g * 255.0);
     240               0 :         gfxFloat bb = (b * 255.0);
     241               0 :         gfxFloat ab = (a * 255.0);
     242                 : 
     243               0 :         if (colorType == PACKED_ABGR) {
     244                 :             return (PRUint8(ab) << 24) |
     245                 :                    (PRUint8(bb) << 16) |
     246                 :                    (PRUint8(gb) << 8) |
     247               0 :                    (PRUint8(rb) << 0);
     248                 :         }
     249               0 :         if (colorType == PACKED_ARGB || colorType == PACKED_XRGB) {
     250                 :             return (PRUint8(ab) << 24) |
     251                 :                    (PRUint8(rb) << 16) |
     252                 :                    (PRUint8(gb) << 8) |
     253               0 :                    (PRUint8(bb) << 0);
     254                 :         }
     255                 : 
     256               0 :         rb *= a;
     257               0 :         gb *= a;
     258               0 :         bb *= a;
     259                 : 
     260               0 :         if (colorType == PACKED_ABGR_PREMULTIPLIED) {
     261                 :             return (((PRUint8)(ab) << 24) |
     262                 :                     ((PRUint8)(bb) << 16) |
     263                 :                     ((PRUint8)(gb) << 8) |
     264               0 :                     ((PRUint8)(rb) << 0));
     265                 :         }
     266               0 :         if (colorType == PACKED_ARGB_PREMULTIPLIED) {
     267                 :             return (((PRUint8)(ab) << 24) |
     268                 :                     ((PRUint8)(rb) << 16) |
     269                 :                     ((PRUint8)(gb) << 8) |
     270               0 :                     ((PRUint8)(bb) << 0));
     271                 :         }
     272                 : 
     273               0 :         return 0;
     274                 :     }
     275                 : };
     276                 : 
     277                 : #endif /* _GFX_COLOR_H */

Generated by: LCOV version 1.7