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.
00063 
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 
00101 template<>
00102 struct ColorMasks<555> {
00103     enum {
00104         kHighBitsMask    = 0x7BDE7BDE,
00105         kLowBitsMask     = 0x04210421,
00106         qhighBits   = 0x739C739C,
00107         qlowBits    = 0x0C630C63,
00108 
00109 
00110         kBytesPerPixel = 2,
00111 
00112         kAlphaBits  = 0,
00113         kRedBits    = 5,
00114         kGreenBits  = 5,
00115         kBlueBits   = 5,
00116 
00117 #ifdef __N64__
00118         /* Nintendo 64 uses a BGR555 color format for 16bit display */
00119         kAlphaShift = 0,
00120         kRedShift   = kBlueBits+kGreenBits+1,
00121         kGreenShift = kBlueBits + 1,
00122         kBlueShift  = 1,
00123 #else   /* RGB555 */
00124         kAlphaShift = 0,
00125         kRedShift   = kGreenBits+kBlueBits,
00126         kGreenShift = kBlueBits,
00127         kBlueShift  = 0,
00128 #endif
00129 
00130         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00131         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00132         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00133         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00134 
00135         kRedBlueMask = kRedMask | kBlueMask,
00136 
00137         kLowBits    = (1 << kRedShift) | (1 << kGreenShift) | (1 << kBlueShift),
00138         kLow2Bits   = (3 << kRedShift) | (3 << kGreenShift) | (3 << kBlueShift),
00139         kLow3Bits   = (7 << kRedShift) | (7 << kGreenShift) | (7 << kBlueShift)
00140     };
00141 };
00142 
00143 template<>
00144 struct ColorMasks<1555> {
00145     enum {
00146         kBytesPerPixel = 2,
00147 
00148         kAlphaBits  = 1,
00149         kRedBits    = 5,
00150         kGreenBits  = 5,
00151         kBlueBits   = 5,
00152 
00153         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00154         kRedShift   = 0,
00155         kGreenShift = kBlueBits,
00156         kBlueShift  = kGreenBits+kBlueBits,
00157 
00158         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00159         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00160         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00161         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00162 
00163         kRedBlueMask = kRedMask | kBlueMask
00164     };
00165 };
00166 
00167 template<>
00168 struct ColorMasks<5551> {
00169     enum {
00170         kBytesPerPixel = 2,
00171 
00172         kAlphaBits  = 1,
00173         kRedBits    = 5,
00174         kGreenBits  = 5,
00175         kBlueBits   = 5,
00176 
00177         kAlphaShift = 0,
00178         kRedShift   = kGreenBits+kBlueBits+kAlphaBits,
00179         kGreenShift = kBlueBits+kAlphaBits,
00180         kBlueShift  = kAlphaBits,
00181 
00182         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00183         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00184         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00185         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00186 
00187         kRedBlueMask = kRedMask | kBlueMask
00188     };
00189 };
00190 
00191 template<>
00192 struct ColorMasks<4444> {
00193     enum {
00194         kBytesPerPixel = 2,
00195 
00196         kAlphaBits  = 4,
00197         kRedBits    = 4,
00198         kGreenBits  = 4,
00199         kBlueBits   = 4,
00200 
00201 #ifdef __PSP__  //PSP uses ABGR
00202         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00203         kRedShift   = 0,
00204         kGreenShift = kRedBits,
00205         kBlueShift  = kRedBits+kGreenBits,
00206 #else       //ARGB
00207         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00208         kRedShift   = kGreenBits+kBlueBits,
00209         kGreenShift = kBlueBits,
00210         kBlueShift  = 0,
00211 #endif
00212 
00213         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00214         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00215         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00216         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00217 
00218         kRedBlueMask = kRedMask | kBlueMask
00219     };
00220 };
00221 
00222 template<>
00223 struct ColorMasks<888> {
00224     enum {
00225         kBytesPerPixel = 4,
00226 
00227         kAlphaBits  = 0,
00228         kRedBits    = 8,
00229         kGreenBits  = 8,
00230         kBlueBits   = 8,
00231 
00232         kAlphaShift = 0,
00233         kRedShift   = kGreenBits+kBlueBits,
00234         kGreenShift = kBlueBits,
00235         kBlueShift  = 0,
00236 
00237         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00238         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00239         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00240         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00241 
00242         kRedBlueMask = kRedMask | kBlueMask
00243     };
00244 };
00245 
00246 template<>
00247 struct ColorMasks<8888> {
00248     enum {
00249         kBytesPerPixel = 4,
00250 
00251         kAlphaBits  = 8,
00252         kRedBits    = 8,
00253         kGreenBits  = 8,
00254         kBlueBits   = 8,
00255 
00256         kAlphaShift = kRedBits+kGreenBits+kBlueBits,
00257         kRedShift   = kGreenBits+kBlueBits,
00258         kGreenShift = kBlueBits,
00259         kBlueShift  = 0,
00260 
00261         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00262         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00263         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00264         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00265 
00266         kRedBlueMask = kRedMask | kBlueMask
00267     };
00268 };
00269 
00270 #ifdef __WII__
00271 /* Gamecube/Wii specific ColorMask ARGB3444 */
00272 template<>
00273 struct ColorMasks<3444> {
00274     enum {
00275         kBytesPerPixel = 2,
00276 
00277         kAlphaBits  = 3,
00278         kRedBits    = 4,
00279         kGreenBits  = 4,
00280         kBlueBits   = 4,
00281 
00282         kBlueShift  = 0,
00283         kGreenShift = kBlueBits,
00284         kRedShift   = kGreenBits+kBlueBits,
00285         kAlphaShift = kGreenBits+kBlueBits+kRedBits,
00286 
00287         kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
00288         kRedMask   = ((1 << kRedBits) - 1) << kRedShift,
00289         kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
00290         kBlueMask  = ((1 << kBlueBits) - 1) << kBlueShift,
00291 
00292         kRedBlueMask = kRedMask | kBlueMask
00293     };
00294 };
00295 #endif
00296 
00297 template<class T>
00298 uint32 RGBToColor(uint8 r, uint8 g, uint8 b) {
00299     return T::kAlphaMask |
00300            (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
00301            (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
00302            (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
00303 }
00304 
00305 template<class T>
00306 uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) {
00307     return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) |
00308            (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
00309            (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
00310            (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
00311 }
00312 
00313 template<class T>
00314 void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) {
00315     r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
00316     g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
00317     b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
00318 }
00319 
00320 template<class T>
00321 void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) {
00322     a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits);
00323     r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
00324     g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
00325     b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
00326 }
00327 
00328 
00329 
00334 template<int bitFormat>
00335 PixelFormat createPixelFormat() {
00336     PixelFormat format;
00337 
00338     format.bytesPerPixel = ColorMasks<bitFormat>::kBytesPerPixel;
00339 
00340     format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
00341     format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
00342     format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
00343     format.aLoss = 8 - ColorMasks<bitFormat>::kAlphaBits;
00344 
00345     format.rShift = ColorMasks<bitFormat>::kRedShift;
00346     format.gShift = ColorMasks<bitFormat>::kGreenShift;
00347     format.bShift = ColorMasks<bitFormat>::kBlueShift;
00348     format.aShift = ColorMasks<bitFormat>::kAlphaShift;
00349 
00350     return format;
00351 }
00352 
00353 
00354 } // End of namespace Graphics
00355 
00356 #endif


Generated on Sat Mar 16 2019 05:01:22 for ResidualVM by doxygen 1.7.1
curved edge   curved edge