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 constexpr inline PixelFormat createFormatCLUT8() {
185  return PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0);
186  }
187 
189  static constexpr inline PixelFormat createFormatRGB24() {
190 #ifdef SCUMM_BIG_ENDIAN
191  return Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0);
192 #else
193  return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
194 #endif
195  }
196 
198  static constexpr inline PixelFormat createFormatBGR24() {
199 #ifdef SCUMM_BIG_ENDIAN
200  return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
201 #else
202  return Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0);
203 #endif
204  }
205 
207  static constexpr inline PixelFormat createFormatRGBA32(bool alpha = true) {
208 #ifdef SCUMM_BIG_ENDIAN
209  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 24, 16, 8, 0);
210 #else
211  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 0, 8, 16, 24);
212 #endif
213  }
214 
216  static constexpr inline PixelFormat createFormatBGRA32(bool alpha = true) {
217 #ifdef SCUMM_BIG_ENDIAN
218  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 8, 16, 24, 0);
219 #else
220  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 16, 8, 0, 24);
221 #endif
222  }
223 
225  static constexpr inline PixelFormat createFormatABGR32(bool alpha = true) {
226 #ifdef SCUMM_BIG_ENDIAN
227  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 0, 8, 16, 24);
228 #else
229  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 24, 16, 8, 0);
230 #endif
231  }
232 
234  static constexpr inline PixelFormat createFormatARGB32(bool alpha = true) {
235 #ifdef SCUMM_BIG_ENDIAN
236  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 16, 8, 0, 24);
237 #else
238  return Graphics::PixelFormat(4, 8, 8, 8, alpha ? 8 : 0, 8, 16, 24, 0);
239 #endif
240  }
241 
243  inline bool operator==(const PixelFormat &fmt) const {
244  return bytesPerPixel == fmt.bytesPerPixel &&
245  rLoss == fmt.rLoss &&
246  gLoss == fmt.gLoss &&
247  bLoss == fmt.bLoss &&
248  aLoss == fmt.aLoss &&
249  rShift == fmt.rShift &&
250  gShift == fmt.gShift &&
251  bShift == fmt.bShift &&
252  aShift == fmt.aShift;
253  }
254 
256  inline bool operator!=(const PixelFormat &fmt) const {
257  return !(*this == fmt);
258  }
259 
261  inline uint32 RGBToColor(uint8 r, uint8 g, uint8 b) const {
262  return
263  ((0xFF >> aLoss) << aShift) |
264  (( r >> rLoss) << rShift) |
265  (( g >> gLoss) << gShift) |
266  (( b >> bLoss) << bShift);
267  }
268 
269  template<class T>
270  inline uint32 RGBToColorT(uint8 r, uint8 g, uint8 b) const {
271  return T::kAlphaMask |
272  (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
273  (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
274  (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
275  }
276 
278  inline uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const {
279  return
280  ((a >> aLoss) << aShift) |
281  ((r >> rLoss) << rShift) |
282  ((g >> gLoss) << gShift) |
283  ((b >> bLoss) << bShift);
284  }
285 
286  template<class T>
287  inline uint32 ARGBToColorT(uint8 a, uint8 r, uint8 g, uint8 b) const {
288  return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) |
289  (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
290  (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
291  (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
292  }
293 
295  inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
296  r = expand(rBits(), color >> rShift);
297  g = expand(gBits(), color >> gShift);
298  b = expand(bBits(), color >> bShift);
299  }
300 
301  template<class T>
302  inline void colorToRGBT(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
303  r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
304  g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
305  b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
306  }
307 
309  inline void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
310  a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift);
311  r = expand(rBits(), color >> rShift);
312  g = expand(gBits(), color >> gShift);
313  b = expand(bBits(), color >> bShift);
314  }
315 
316  template<class T>
317  inline void colorToARGBT(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
318  a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits);
319  r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
320  g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
321  b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
322  }
323 
332  inline byte rBits() const {
333  return (8 - rLoss);
334  }
335 
339  inline byte gBits() const {
340  return (8 - gLoss);
341  }
342 
346  inline byte bBits() const {
347  return (8 - bLoss);
348  }
349 
353  inline byte aBits() const {
354  return (8 - aLoss);
355  }
356 
360  inline byte bpp() const {
361  return rBits() + gBits() + bBits() + aBits();
362  }
373  inline uint rMax() const {
374  return (1 << rBits()) - 1;
375  }
376 
380  inline uint gMax() const {
381  return (1 << gBits()) - 1;
382  }
383 
387  inline uint bMax() const {
388  return (1 << bBits()) - 1;
389  }
390 
394  inline uint aMax() const {
395  return (1 << aBits()) - 1;
396  }
399  static inline uint expand(uint bits, uint color) {
400  switch (bits) {
401  case 0:
402  return ColorComponent<0>::expand(color);
403  case 1:
404  return ColorComponent<1>::expand(color);
405  case 2:
406  return ColorComponent<2>::expand(color);
407  case 3:
408  return ColorComponent<3>::expand(color);
409  case 4:
410  return ColorComponent<4>::expand(color);
411  case 5:
412  return ColorComponent<5>::expand(color);
413  case 6:
414  return ColorComponent<6>::expand(color);
415  case 7:
416  return ColorComponent<7>::expand(color);
417  case 8:
418  return ColorComponent<8>::expand(color);
419  default:
420  break;
421  }
422 
423  // Unsupported
424  return 0;
425  }
427  Common::String toString() const;
428 
430  bool isCLUT8() const {
431  // We do not really need to check masks when all shifts equal zeroes
432  return bytesPerPixel == 1 && rShift == 0 && gShift == 0 && bShift == 0 && aShift == 0;
433  }
434 };
435 
436 template<>
437 inline uint32 PixelFormat::RGBToColorT<ColorMasks<0> >(uint8 r, uint8 g, uint8 b) const {
438  return RGBToColor(r, g, b);
439 }
440 
441 template<>
442 inline uint32 PixelFormat::ARGBToColorT<ColorMasks<0> >(uint8 a, uint8 r, uint8 g, uint8 b) const {
443  return ARGBToColor(a, r, g, b);
444 }
445 
446 template<>
447 inline void PixelFormat::colorToRGBT<ColorMasks<0> >(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
448  colorToRGB(color, r, g, b);
449 }
450 
451 template<>
452 inline void PixelFormat::colorToARGBT<ColorMasks<0> >(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
453  colorToARGB(color, a, r, g, b);
454 }
455 
460 template<int bitFormat>
462  PixelFormat format;
463 
465 
466  format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
467  format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
468  format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
470 
471  format.rShift = ColorMasks<bitFormat>::kRedShift;
472  format.gShift = ColorMasks<bitFormat>::kGreenShift;
473  format.bShift = ColorMasks<bitFormat>::kBlueShift;
475 
476  return format;
477 }
478 
479 
481 } // End of namespace Graphics
482 
483 #endif
uint rMax() const
Definition: pixelformat.h:373
bool operator==(const PixelFormat &fmt) const
Definition: pixelformat.h:243
byte aBits() const
Definition: pixelformat.h:353
Definition: str.h:59
static uint expand(uint bits, uint color)
Definition: pixelformat.h:399
static constexpr PixelFormat createFormatARGB32(bool alpha=true)
Definition: pixelformat.h:234
uint gMax() const
Definition: pixelformat.h:380
Definition: pixelformat.h:43
Definition: pixelformat.h:138
static constexpr PixelFormat createFormatCLUT8()
Definition: pixelformat.h:184
uint aMax() const
Definition: pixelformat.h:394
PixelFormat createPixelFormat()
Definition: pixelformat.h:461
static constexpr PixelFormat createFormatABGR32(bool alpha=true)
Definition: pixelformat.h:225
static constexpr PixelFormat createFormatRGBA32(bool alpha=true)
Definition: pixelformat.h:207
uint bMax() const
Definition: pixelformat.h:387
bool isCLUT8() const
Definition: pixelformat.h:430
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:346
void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const
Definition: pixelformat.h:295
static constexpr PixelFormat createFormatBGR24()
Definition: pixelformat.h:198
Definition: formatinfo.h:28
byte aShift
Definition: pixelformat.h:142
static constexpr PixelFormat createFormatBGRA32(bool alpha=true)
Definition: pixelformat.h:216
Definition: colormasks.h:30
byte rBits() const
Definition: pixelformat.h:332
byte aLoss
Definition: pixelformat.h:141
bool operator!=(const PixelFormat &fmt) const
Definition: pixelformat.h:256
static constexpr PixelFormat createFormatRGB24()
Definition: pixelformat.h:189
byte gBits() const
Definition: pixelformat.h:339
uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:278
constexpr PixelFormat()
Definition: pixelformat.h:145
byte bpp() const
Definition: pixelformat.h:360
byte bytesPerPixel
Definition: pixelformat.h:139
uint32 RGBToColor(uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:261
void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const
Definition: pixelformat.h:309