Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef GFX_COLOR_H
7 : #define GFX_COLOR_H
8 :
9 : #include "mozilla/Attributes.h" // for MOZ_ALWAYS_INLINE
10 : #include "mozilla/EndianUtils.h" // for mozilla::NativeEndian::swapToBigEndian
11 :
12 : /**
13 : * GFX_BLOCK_RGB_TO_FRGB(from,to)
14 : * sizeof(*from) == sizeof(char)
15 : * sizeof(*to) == sizeof(uint32_t)
16 : *
17 : * Copy 4 pixels at a time, reading blocks of 12 bytes (RGB x4)
18 : * and writing blocks of 16 bytes (FRGB x4)
19 : */
20 : #define GFX_BLOCK_RGB_TO_FRGB(from,to) \
21 : PR_BEGIN_MACRO \
22 : uint32_t m0 = ((uint32_t*)from)[0], \
23 : m1 = ((uint32_t*)from)[1], \
24 : m2 = ((uint32_t*)from)[2], \
25 : rgbr = mozilla::NativeEndian::swapToBigEndian(m0), \
26 : gbrg = mozilla::NativeEndian::swapToBigEndian(m1), \
27 : brgb = mozilla::NativeEndian::swapToBigEndian(m2), \
28 : p0, p1, p2, p3; \
29 : p0 = 0xFF000000 | ((rgbr) >> 8); \
30 : p1 = 0xFF000000 | ((rgbr) << 16) | ((gbrg) >> 16); \
31 : p2 = 0xFF000000 | ((gbrg) << 8) | ((brgb) >> 24); \
32 : p3 = 0xFF000000 | (brgb); \
33 : to[0] = p0; to[1] = p1; to[2] = p2; to[3] = p3; \
34 : PR_END_MACRO
35 :
36 : /**
37 : * Fast approximate division by 255. It has the property that
38 : * for all 0 <= n <= 255*255, GFX_DIVIDE_BY_255(n) == n/255.
39 : * But it only uses two adds and two shifts instead of an
40 : * integer division (which is expensive on many processors).
41 : *
42 : * equivalent to ((v)/255)
43 : */
44 : #define GFX_DIVIDE_BY_255(v) \
45 : (((((unsigned)(v)) << 8) + ((unsigned)(v)) + 255) >> 16)
46 :
47 : /**
48 : * Fast premultiply
49 : *
50 : * equivalent to (((c)*(a))/255)
51 : */
52 70894 : uint8_t MOZ_ALWAYS_INLINE gfxPreMultiply(uint8_t c, uint8_t a) {
53 70894 : return GFX_DIVIDE_BY_255((c)*(a));
54 : }
55 :
56 : /**
57 : * Pack the 4 8-bit channels (A,R,G,B)
58 : * into a 32-bit packed NON-premultiplied pixel.
59 : */
60 : uint32_t MOZ_ALWAYS_INLINE
61 1812 : gfxPackedPixelNoPreMultiply(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
62 1812 : return (((a) << 24) | ((r) << 16) | ((g) << 8) | (b));
63 : }
64 :
65 : /**
66 : * Pack the 4 8-bit channels (A,R,G,B)
67 : * into a 32-bit packed premultiplied pixel.
68 : */
69 : uint32_t MOZ_ALWAYS_INLINE
70 57467 : gfxPackedPixel(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
71 57467 : if (a == 0x00)
72 32021 : return 0x00000000;
73 25446 : else if (a == 0xFF) {
74 1813 : return gfxPackedPixelNoPreMultiply(a, r, g, b);
75 : } else {
76 47267 : return ((a) << 24) |
77 47266 : (gfxPreMultiply(r,a) << 16) |
78 47268 : (gfxPreMultiply(g,a) << 8) |
79 47267 : (gfxPreMultiply(b,a));
80 : }
81 : }
82 :
83 : #endif /* _GFX_COLOR_H */
|