ScummVM API documentation
pixelformat.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef GRAPHICS_PIXELFORMAT_H
23 #define GRAPHICS_PIXELFORMAT_H
24 
25 #include "common/scummsys.h"
26 #include "common/str.h"
27 
28 #include "graphics/colormasks.h"
29 
30 namespace Graphics {
31 
42 template<int depth>
44 };
46 template<>
47 struct ColorComponent<0> {
48  static inline uint expand(uint value) {
49  return 0;
50  }
51 };
53 template<>
54 struct ColorComponent<1> {
55  static inline uint expand(uint value) {
56  return value ? 0xff : 0;
57  }
58 };
60 template<>
61 struct ColorComponent<2> {
62  static inline uint expand(uint value) {
63  value &= 3;
64  return value |
65  (value << 2) |
66  (value << 4) |
67  (value << 6);
68  }
69 };
71 template<>
72 struct ColorComponent<3> {
73  static inline uint expand(uint value) {
74  value &= 7;
75  return (value << 5) |
76  (value << 2) |
77  (value >> 1);
78  }
79 };
81 template<>
82 struct ColorComponent<4> {
83  static inline uint expand(uint value) {
84  value &= 15;
85  return value |
86  (value << 4);
87  }
88 };
90 template<>
91 struct ColorComponent<5> {
92  static inline uint expand(uint value) {
93  value &= 31;
94  return (value << 3) |
95  (value >> 2);
96  }
97 };
99 template<>
100 struct ColorComponent<6> {
101  static inline uint expand(uint value) {
102  value &= 63;
103  return (value << 2) |
104  (value >> 4);
105  }
106 };
108 template<>
109 struct ColorComponent<7> {
110  static inline uint expand(uint value) {
111  value &= 127;
112  return (value << 1) |
113  (value >> 6);
114  }
115 };
117 template<>
118 struct ColorComponent<8> {
119  static inline uint expand(uint value) {
120  return value & 255;
121  }
122 };
123 
138 struct PixelFormat {
141  byte rLoss, gLoss, bLoss, aLoss;
142  byte rShift, gShift, bShift, aShift;
145  constexpr PixelFormat() :
146  bytesPerPixel(0),
147  rLoss(0), gLoss(0), bLoss(0), aLoss(0),
148  rShift(0), gShift(0), bShift(0), aShift(0) {}
149 
168  constexpr PixelFormat(byte BytesPerPixel,
169  byte RBits, byte GBits, byte BBits, byte ABits,
170  byte RShift, byte GShift, byte BShift, byte AShift) :
171  bytesPerPixel(BytesPerPixel),
172  rLoss(8 - RBits),
173  gLoss(8 - GBits),
174  bLoss(8 - BBits),
175  aLoss(8 - ABits),
176  rShift((RBits == 0) ? 0 : RShift),
177  gShift((GBits == 0) ? 0 : GShift),
178  bShift((BBits == 0) ? 0 : BShift),
179  aShift((ABits == 0) ? 0 : AShift)
180  {
181  }
182 
184  static inline PixelFormat createFormatCLUT8() {
185  return PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0);
186  }
187 
189  inline bool operator==(const PixelFormat &fmt) const {
190  return bytesPerPixel == fmt.bytesPerPixel &&
191  rLoss == fmt.rLoss &&
192  gLoss == fmt.gLoss &&
193  bLoss == fmt.bLoss &&
194  aLoss == fmt.aLoss &&
195  rShift == fmt.rShift &&
196  gShift == fmt.gShift &&
197  bShift == fmt.bShift &&
198  aShift == fmt.aShift;
199  }
200 
202  inline bool operator!=(const PixelFormat &fmt) const {
203  return !(*this == fmt);
204  }
205 
207  inline uint32 RGBToColor(uint8 r, uint8 g, uint8 b) const {
208  return
209  ((0xFF >> aLoss) << aShift) |
210  (( r >> rLoss) << rShift) |
211  (( g >> gLoss) << gShift) |
212  (( b >> bLoss) << bShift);
213  }
214 
215  template<class T>
216  inline uint32 RGBToColorT(uint8 r, uint8 g, uint8 b) const {
217  return T::kAlphaMask |
218  (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
219  (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
220  (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
221  }
222 
224  inline uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const {
225  return
226  ((a >> aLoss) << aShift) |
227  ((r >> rLoss) << rShift) |
228  ((g >> gLoss) << gShift) |
229  ((b >> bLoss) << bShift);
230  }
231 
232  template<class T>
233  inline uint32 ARGBToColorT(uint8 a, uint8 r, uint8 g, uint8 b) const {
234  return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) |
235  (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
236  (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
237  (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
238  }
239 
241  inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
242  r = expand(rBits(), color >> rShift);
243  g = expand(gBits(), color >> gShift);
244  b = expand(bBits(), color >> bShift);
245  }
246 
247  template<class T>
248  inline void colorToRGBT(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
249  r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
250  g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
251  b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
252  }
253 
255  inline void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
256  a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift);
257  r = expand(rBits(), color >> rShift);
258  g = expand(gBits(), color >> gShift);
259  b = expand(bBits(), color >> bShift);
260  }
261 
262  template<class T>
263  inline void colorToARGBT(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
264  a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits);
265  r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
266  g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
267  b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
268  }
269 
278  inline byte rBits() const {
279  return (8 - rLoss);
280  }
281 
285  inline byte gBits() const {
286  return (8 - gLoss);
287  }
288 
292  inline byte bBits() const {
293  return (8 - bLoss);
294  }
295 
299  inline byte aBits() const {
300  return (8 - aLoss);
301  }
302 
306  inline byte bpp() const {
307  return rBits() + gBits() + bBits() + aBits();
308  }
319  inline uint rMax() const {
320  return (1 << rBits()) - 1;
321  }
322 
326  inline uint gMax() const {
327  return (1 << gBits()) - 1;
328  }
329 
333  inline uint bMax() const {
334  return (1 << bBits()) - 1;
335  }
336 
340  inline uint aMax() const {
341  return (1 << aBits()) - 1;
342  }
345  static inline uint expand(uint bits, uint color) {
346  switch (bits) {
347  case 0:
348  return ColorComponent<0>::expand(color);
349  case 1:
350  return ColorComponent<1>::expand(color);
351  case 2:
352  return ColorComponent<2>::expand(color);
353  case 3:
354  return ColorComponent<3>::expand(color);
355  case 4:
356  return ColorComponent<4>::expand(color);
357  case 5:
358  return ColorComponent<5>::expand(color);
359  case 6:
360  return ColorComponent<6>::expand(color);
361  case 7:
362  return ColorComponent<7>::expand(color);
363  case 8:
364  return ColorComponent<8>::expand(color);
365  default:
366  break;
367  }
368 
369  // Unsupported
370  return 0;
371  }
373  Common::String toString() const;
374 
376  bool isCLUT8() const {
377  // We do not really need to check masks when all shifts equal zeroes
378  return bytesPerPixel == 1 && rShift == 0 && gShift == 0 && bShift == 0 && aShift == 0;
379  }
380 };
381 
382 template<>
383 inline uint32 PixelFormat::RGBToColorT<ColorMasks<0> >(uint8 r, uint8 g, uint8 b) const {
384  return RGBToColor(r, g, b);
385 }
386 
387 template<>
388 inline uint32 PixelFormat::ARGBToColorT<ColorMasks<0> >(uint8 a, uint8 r, uint8 g, uint8 b) const {
389  return ARGBToColor(a, r, g, b);
390 }
391 
392 template<>
393 inline void PixelFormat::colorToRGBT<ColorMasks<0> >(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
394  colorToRGB(color, r, g, b);
395 }
396 
397 template<>
398 inline void PixelFormat::colorToARGBT<ColorMasks<0> >(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
399  colorToARGB(color, a, r, g, b);
400 }
401 
406 template<int bitFormat>
408  PixelFormat format;
409 
411 
412  format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
413  format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
414  format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
416 
417  format.rShift = ColorMasks<bitFormat>::kRedShift;
418  format.gShift = ColorMasks<bitFormat>::kGreenShift;
419  format.bShift = ColorMasks<bitFormat>::kBlueShift;
421 
422  return format;
423 }
424 
425 
427 } // End of namespace Graphics
428 
429 #endif
uint rMax() const
Definition: pixelformat.h:319
bool operator==(const PixelFormat &fmt) const
Definition: pixelformat.h:189
byte aBits() const
Definition: pixelformat.h:299
Definition: str.h:59
static uint expand(uint bits, uint color)
Definition: pixelformat.h:345
uint gMax() const
Definition: pixelformat.h:326
Definition: pixelformat.h:43
Definition: pixelformat.h:138
uint aMax() const
Definition: pixelformat.h:340
PixelFormat createPixelFormat()
Definition: pixelformat.h:407
uint bMax() const
Definition: pixelformat.h:333
bool isCLUT8() const
Definition: pixelformat.h:376
constexpr PixelFormat(byte BytesPerPixel, byte RBits, byte GBits, byte BBits, byte ABits, byte RShift, byte GShift, byte BShift, byte AShift)
Definition: pixelformat.h:168
byte bBits() const
Definition: pixelformat.h:292
void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const
Definition: pixelformat.h:241
Definition: formatinfo.h:28
byte aShift
Definition: pixelformat.h:142
Definition: colormasks.h:30
byte rBits() const
Definition: pixelformat.h:278
byte aLoss
Definition: pixelformat.h:141
bool operator!=(const PixelFormat &fmt) const
Definition: pixelformat.h:202
byte gBits() const
Definition: pixelformat.h:285
uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:224
constexpr PixelFormat()
Definition: pixelformat.h:145
static PixelFormat createFormatCLUT8()
Definition: pixelformat.h:184
byte bpp() const
Definition: pixelformat.h:306
byte bytesPerPixel
Definition: pixelformat.h:139
uint32 RGBToColor(uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:207
void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const
Definition: pixelformat.h:255