ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

colormasks.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifndef GRAPHICS_COLORMASKS_H
00024 #define GRAPHICS_COLORMASKS_H
00025 
00026 #include "graphics/pixelformat.h"
00027 
00028 namespace Graphics {
00029 
00030 template<int bitFormat>
00031 struct ColorMasks {
00032 };
00033 
00034 /*
00035 The ColorMasks template can be used to map bit format values
00036 (like 555, 565, 1555, 4444) to corresponding bit masks and shift values.
00037 Currently this is only meant for
00038 
00039 The meaning of these is masks is the following:
00040  kBytesPerPixel
00041     -> how many bytes per pixel for that format
00042 
00043  kRedMask, kGreenMask, kBlueMask
00044     -> bitmask, and this with the color to select only the bits of the corresponding color
00045 
00046  The k*Bits and k*Shift values can be used to extract R,G,B. I.e. to get
00047  the red color component of a pixel, as a 8-bit value, you would write
00048 
00049  R = ((color & kRedMask) >> kRedShift) << (8-kRedBits)
00050 
00051  Actually, instead of the simple left shift, one might want to use somewhat
00052  more sophisticated code (which fills up the least significant bits with
00053  appropriate data).
00054 
00055 
00056  The kHighBitsMask / kLowBitsMask / qhighBits / qlowBits are special values that are
00057  used in the super-optimized interpolation functions in scaler/intern.h
00058  and scaler/aspect.cpp. Currently they are only available in 555 and 565 mode.
00059  To be specific: They pack the masks for two 16 bit pixels at once. The pixels
00060  are split into "high" and "low" bits, which are then separately interpolated
00061  and finally re-composed. That way, 2x2 pixels or even 4x2 pixels can
00062  be interpolated in one go. They are also included in 888 and 8888 to make
00063  the same functions compatible when interpolating 2 32-bit pixels.
00064 */
00065 
00066 
00067 template<>
00068 struct ColorMasks<565> {
00069     enum {
00070         kHighBitsMask    = 0xF7DEF7DE,
00071         kLowBitsMask     = 0x08210821,
00072         qhighBits   = 0xE79CE79C,
00073         qlowBits    = 0x18631863,
00074 
00075 
00076         kBytesPerPixel = 2,
00077 
00078         kAlphaBits  = 0,
00079         kRedBits    = 5,
00080         kGreenBits  = 6,
00081         kBlueBits   = 5,
00082 
00083         kAlphaShift = 0,
00084         kRedShift   = kGreenBits+kBlueBits,
00085         kGreenShift = kBlueBits,
00086         kBlueShift  = 0,
00087 
00088         kAlphaMask  = ((1 << kAlphaBits) - 1) << kAlphaShift,
00089         kRedMask    = ((1 << kRedBits) - 1) << kRedShift,
00090         kGreenMask  = ((1 << kGreenBits) - 1) << kGreenShift,
00091         kBlueMask   = ((1 << kBlueBits) - 1) << kBlueShift,
00092 
00093         kRedBlueMask = kRedMask | kBlueMask,
00094 
00095         kLowBits    = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift),
00096         kLow2Bits   = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
00097         kLow3Bits   = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift)
00098     };
00099 
00100     typedef uint16 PixelType;
00101 };
00102 
00103 template<>
00104 struct ColorMasks<555> {
00105     enum {
00106         kHighBitsMask    = 0x7BDE7BDE,
00107         kLowBitsMask     = 0x04210421,
00108         qhighBits   = 0x739C739C,
00109         qlowBits    = 0x0C630C63,
00110 
00111 
00112         kBytesPerPixel = 2,
00113 
00114         kAlphaBits  = 0,
00115         kRedBits    = 5,
00116         kGreenBits  = 5,
00117         kBlueBits   = 5,
00118 
00119 #ifdef __N64__
00120         /* Nintendo 64 uses a BGR555 color format for 16bit display */
00121         kAlphaShift = 0,
00122         kRedShift   = kBlueBits+kGreenBits+1,
00123         kGreenShift = kBlueBits + 1,
00124         kBlueShift  = 1,
00125 #else   /* RGB555 */
00126         kAlphaShift = 0,
00127         kRedShift   = kGreenBits+kBlueBits,
00128         kGreenShift = kBlueBits,
00129         kBlueShift  = 0,
00130 #endif
00131 
00132         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00133         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00134         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00135         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00136 
00137         kRedBlueMask = kRedMask | kBlueMask,
00138 
00139         kLowBits    = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift),
00140         kLow2Bits   = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
00141         kLow3Bits   = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift)
00142     };
00143 
00144     typedef uint16 PixelType;
00145 };
00146 
00147 template<>
00148 struct ColorMasks<1555> {
00149     enum {
00150         kBytesPerPixel = 2,
00151 
00152         kAlphaBits  = 1,
00153         kRedBits    = 5,
00154         kGreenBits  = 5,
00155         kBlueBits   = 5,
00156 
00157         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00158         kRedShift   = 0,
00159         kGreenShift = kBlueBits,
00160         kBlueShift  = kGreenBits+kBlueBits,
00161 
00162         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00163         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00164         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00165         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00166 
00167         kRedBlueMask = kRedMask | kBlueMask
00168     };
00169 
00170     typedef uint16 PixelType;
00171 };
00172 
00173 template<>
00174 struct ColorMasks<5551> {
00175     enum {
00176         kBytesPerPixel = 2,
00177 
00178         kAlphaBits  = 1,
00179         kRedBits    = 5,
00180         kGreenBits  = 5,
00181         kBlueBits   = 5,
00182 
00183         kAlphaShift = 0,
00184         kRedShift   = kGreenBits+kBlueBits+kAlphaBits,
00185         kGreenShift = kBlueBits+kAlphaBits,
00186         kBlueShift  = kAlphaBits,
00187 
00188         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00189         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00190         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00191         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00192 
00193         kRedBlueMask = kRedMask | kBlueMask
00194     };
00195 
00196     typedef uint16 PixelType;
00197 };
00198 
00199 template<>
00200 struct ColorMasks<4444> {
00201     enum {
00202         kBytesPerPixel = 2,
00203 
00204         kAlphaBits  = 4,
00205         kRedBits    = 4,
00206         kGreenBits  = 4,
00207         kBlueBits   = 4,
00208 
00209 #ifdef __PSP__  //PSP uses ABGR
00210         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00211         kRedShift   = 0,
00212         kGreenShift = kRedBits,
00213         kBlueShift  = kRedBits+kGreenBits,
00214 #else       //ARGB
00215         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00216         kRedShift   = kGreenBits+kBlueBits,
00217         kGreenShift = kBlueBits,
00218         kBlueShift  = 0,
00219 #endif
00220 
00221         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00222         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00223         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00224         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00225 
00226         kRedBlueMask = kRedMask | kBlueMask
00227     };
00228 
00229     typedef uint16 PixelType;
00230 };
00231 
00232 template<>
00233 struct ColorMasks<888> {
00234     enum {
00235         kBytesPerPixel = 4,
00236 
00237         kAlphaBits  = 0,
00238         kRedBits    = 8,
00239         kGreenBits  = 8,
00240         kBlueBits   = 8,
00241 
00242         kAlphaShift = 0,
00243         kRedShift   = kGreenBits+kBlueBits,
00244         kGreenShift = kBlueBits,
00245         kBlueShift  = 0,
00246 
00247         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00248         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00249         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00250         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00251 
00252         kRedBlueMask = kRedMask | kBlueMask,
00253 
00254         kLowBits    = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift),
00255         kLow2Bits   = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
00256         kLow3Bits   = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift),
00257         kLow4Bits   = (15 << kRedShift) | (15 << kGreenShift) | (15 << kBlueShift),
00258 
00259         kLowBitsMask = kLowBits,
00260         // Prevent mask from including padding byte
00261         kHighBitsMask = (~kLowBits) & (kRedMask | kBlueMask | kGreenMask),
00262         qlowBits = kLow2Bits,
00263         qhighBits = (~kLowBits) & (kRedMask | kBlueMask | kGreenMask)
00264     };
00265 
00266     typedef uint32 PixelType;
00267 };
00268 
00269 template<>
00270 struct ColorMasks<8888> {
00271     enum {
00272         kBytesPerPixel = 4,
00273 
00274         kAlphaBits  = 8,
00275         kRedBits    = 8,
00276         kGreenBits  = 8,
00277         kBlueBits   = 8,
00278 
00279         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00280         kRedShift   = kGreenBits+kBlueBits,
00281         kGreenShift = kBlueBits,
00282         kBlueShift  = 0,
00283 
00284         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00285         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00286         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00287         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00288 
00289         kRedBlueMask = kRedMask | kBlueMask,
00290 
00291         kLowBits    = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift) | (1 << kAlphaShift),
00292         kLow2Bits   = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift) | (3 << kAlphaShift),
00293         kLow3Bits   = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift) | (7 << kAlphaShift),
00294         kLow4Bits   = (15 << kRedShift) | (15 << kGreenShift) | (15 << kBlueShift) | (15 << kAlphaShift),
00295 
00296         kLowBitsMask = kLowBits,
00297         kHighBitsMask = ~kLowBits,
00298         qlowBits = kLow2Bits,
00299         qhighBits = ~kLow2Bits
00300     };
00301 
00302     typedef uint32 PixelType;
00303 };
00304 
00305 #ifdef __WII__
00306 /* Gamecube/Wii specific ColorMask ARGB3444 */
00307 template<>
00308 struct ColorMasks<3444> {
00309     enum {
00310         kBytesPerPixel = 2,
00311 
00312         kAlphaBits  = 3,
00313         kRedBits    = 4,
00314         kGreenBits  = 4,
00315         kBlueBits   = 4,
00316 
00317         kBlueShift  = 0,
00318         kGreenShift = kBlueBits,
00319         kRedShift   = kGreenBits+kBlueBits,
00320         kAlphaShift = kGreenBits+kBlueBits+kRedBits,
00321 
00322         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00323         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00324         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00325         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00326 
00327         kRedBlueMask = kRedMask | kBlueMask
00328     };
00329 
00330     typedef uint16 PixelType;
00331 };
00332 #endif
00333 
00334 template<class T>
00335 uint32 RGBToColor(uint8 r, uint8 g, uint8 b) {
00336     return T::kAlphaMask |
00337            (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
00338            (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
00339            (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
00340 }
00341 
00342 template<class T>
00343 uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) {
00344     return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) |
00345            (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
00346            (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
00347            (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
00348 }
00349 
00350 template<class T>
00351 void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) {
00352     r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
00353     g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
00354     b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
00355 }
00356 
00357 template<class T>
00358 void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) {
00359     a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits);
00360     r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
00361     g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
00362     b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
00363 }
00364 
00365 
00366 
00371 template<int bitFormat>
00372 PixelFormat createPixelFormat() {
00373     PixelFormat format;
00374 
00375     format.bytesPerPixel = ColorMasks<bitFormat>::kBytesPerPixel;
00376 
00377     format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
00378     format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
00379     format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
00380     format.aLoss = 8 - ColorMasks<bitFormat>::kAlphaBits;
00381 
00382     format.rShift = ColorMasks<bitFormat>::kRedShift;
00383     format.gShift = ColorMasks<bitFormat>::kGreenShift;
00384     format.bShift = ColorMasks<bitFormat>::kBlueShift;
00385     format.aShift = ColorMasks<bitFormat>::kAlphaShift;
00386 
00387     return format;
00388 }
00389 
00390 
00391 } // End of namespace Graphics
00392 
00393 #endif


Generated on Sat Jul 20 2019 05:01:00 for ResidualVM by doxygen 1.7.1
curved edge   curved edge