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(RShift),
177  gShift(GShift),
178  bShift(BShift),
179  aShift(AShift) {}
180 
182  static inline PixelFormat createFormatCLUT8() {
183  return PixelFormat(1, 0, 0, 0, 0, 0, 0, 0, 0);
184  }
185 
187  inline bool operator==(const PixelFormat &fmt) const {
188  // TODO: If aLoss==8, then the value of aShift is irrelevant, and should be ignored.
189  return bytesPerPixel == fmt.bytesPerPixel &&
190  rLoss == fmt.rLoss &&
191  gLoss == fmt.gLoss &&
192  bLoss == fmt.bLoss &&
193  aLoss == fmt.aLoss &&
194  rShift == fmt.rShift &&
195  gShift == fmt.gShift &&
196  bShift == fmt.bShift &&
197  aShift == fmt.aShift;
198  }
199 
201  inline bool operator!=(const PixelFormat &fmt) const {
202  return !(*this == fmt);
203  }
204 
206  inline uint32 RGBToColor(uint8 r, uint8 g, uint8 b) const {
207  return
208  ((0xFF >> aLoss) << aShift) |
209  (( r >> rLoss) << rShift) |
210  (( g >> gLoss) << gShift) |
211  (( b >> bLoss) << bShift);
212  }
213 
214  template<class T>
215  inline uint32 RGBToColorT(uint8 r, uint8 g, uint8 b) const {
216  return T::kAlphaMask |
217  (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
218  (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
219  (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
220  }
221 
223  inline uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const {
224  return
225  ((a >> aLoss) << aShift) |
226  ((r >> rLoss) << rShift) |
227  ((g >> gLoss) << gShift) |
228  ((b >> bLoss) << bShift);
229  }
230 
231  template<class T>
232  inline uint32 ARGBToColorT(uint8 a, uint8 r, uint8 g, uint8 b) const {
233  return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) |
234  (((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
235  (((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
236  (((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
237  }
238 
240  inline void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
241  r = expand(rBits(), color >> rShift);
242  g = expand(gBits(), color >> gShift);
243  b = expand(bBits(), color >> bShift);
244  }
245 
246  template<class T>
247  inline void colorToRGBT(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
248  r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
249  g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
250  b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
251  }
252 
254  inline void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
255  a = (aBits() == 0) ? 0xFF : expand(aBits(), color >> aShift);
256  r = expand(rBits(), color >> rShift);
257  g = expand(gBits(), color >> gShift);
258  b = expand(bBits(), color >> bShift);
259  }
260 
261  template<class T>
262  inline void colorToARGBT(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
263  a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits);
264  r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
265  g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
266  b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
267  }
268 
277  inline byte rBits() const {
278  return (8 - rLoss);
279  }
280 
284  inline byte gBits() const {
285  return (8 - gLoss);
286  }
287 
291  inline byte bBits() const {
292  return (8 - bLoss);
293  }
294 
298  inline byte aBits() const {
299  return (8 - aLoss);
300  }
301 
305  inline byte bpp() const {
306  return rBits() + gBits() + bBits() + aBits();
307  }
318  inline uint rMax() const {
319  return (1 << rBits()) - 1;
320  }
321 
325  inline uint gMax() const {
326  return (1 << gBits()) - 1;
327  }
328 
332  inline uint bMax() const {
333  return (1 << bBits()) - 1;
334  }
335 
339  inline uint aMax() const {
340  return (1 << aBits()) - 1;
341  }
344  static inline uint expand(uint bits, uint color) {
345  switch (bits) {
346  case 0:
347  return ColorComponent<0>::expand(color);
348  case 1:
349  return ColorComponent<1>::expand(color);
350  case 2:
351  return ColorComponent<2>::expand(color);
352  case 3:
353  return ColorComponent<3>::expand(color);
354  case 4:
355  return ColorComponent<4>::expand(color);
356  case 5:
357  return ColorComponent<5>::expand(color);
358  case 6:
359  return ColorComponent<6>::expand(color);
360  case 7:
361  return ColorComponent<7>::expand(color);
362  case 8:
363  return ColorComponent<8>::expand(color);
364  default:
365  break;
366  }
367 
368  // Unsupported
369  return 0;
370  }
372  Common::String toString() const;
373 
375  bool isCLUT8() const {
376  // We do not really need to check masks when all shifts equal zeroes
377  return bytesPerPixel == 1 && rShift == 0 && gShift == 0 && bShift == 0 && aShift == 0;
378  }
379 };
380 
381 template<>
382 inline uint32 PixelFormat::RGBToColorT<ColorMasks<0> >(uint8 r, uint8 g, uint8 b) const {
383  return RGBToColor(r, g, b);
384 }
385 
386 template<>
387 inline uint32 PixelFormat::ARGBToColorT<ColorMasks<0> >(uint8 a, uint8 r, uint8 g, uint8 b) const {
388  return ARGBToColor(a, r, g, b);
389 }
390 
391 template<>
392 inline void PixelFormat::colorToRGBT<ColorMasks<0> >(uint32 color, uint8 &r, uint8 &g, uint8 &b) const {
393  colorToRGB(color, r, g, b);
394 }
395 
396 template<>
397 inline void PixelFormat::colorToARGBT<ColorMasks<0> >(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const {
398  colorToARGB(color, a, r, g, b);
399 }
400 
405 template<int bitFormat>
407  PixelFormat format;
408 
410 
411  format.rLoss = 8 - ColorMasks<bitFormat>::kRedBits;
412  format.gLoss = 8 - ColorMasks<bitFormat>::kGreenBits;
413  format.bLoss = 8 - ColorMasks<bitFormat>::kBlueBits;
415 
416  format.rShift = ColorMasks<bitFormat>::kRedShift;
417  format.gShift = ColorMasks<bitFormat>::kGreenShift;
418  format.bShift = ColorMasks<bitFormat>::kBlueShift;
420 
421  return format;
422 }
423 
424 
426 } // End of namespace Graphics
427 
428 #endif
uint rMax() const
Definition: pixelformat.h:318
bool operator==(const PixelFormat &fmt) const
Definition: pixelformat.h:187
byte aBits() const
Definition: pixelformat.h:298
Definition: str.h:59
static uint expand(uint bits, uint color)
Definition: pixelformat.h:344
uint gMax() const
Definition: pixelformat.h:325
Definition: pixelformat.h:43
Definition: pixelformat.h:138
uint aMax() const
Definition: pixelformat.h:339
PixelFormat createPixelFormat()
Definition: pixelformat.h:406
uint bMax() const
Definition: pixelformat.h:332
bool isCLUT8() const
Definition: pixelformat.h:375
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:291
void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) const
Definition: pixelformat.h:240
Definition: formatinfo.h:28
byte aShift
Definition: pixelformat.h:142
Definition: colormasks.h:30
byte rBits() const
Definition: pixelformat.h:277
byte aLoss
Definition: pixelformat.h:141
bool operator!=(const PixelFormat &fmt) const
Definition: pixelformat.h:201
byte gBits() const
Definition: pixelformat.h:284
uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:223
constexpr PixelFormat()
Definition: pixelformat.h:145
static PixelFormat createFormatCLUT8()
Definition: pixelformat.h:182
byte bpp() const
Definition: pixelformat.h:305
byte bytesPerPixel
Definition: pixelformat.h:139
uint32 RGBToColor(uint8 r, uint8 g, uint8 b) const
Definition: pixelformat.h:206
void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) const
Definition: pixelformat.h:254