| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * Functions to transform scanlines between packed-pixel formats. | 9 * Functions to transform scanlines between packed-pixel formats. |
| 10 */ | 10 */ |
| 11 | 11 |
| 12 #include "SkBitmap.h" | 12 #include "SkBitmap.h" |
| 13 #include "SkColor.h" | 13 #include "SkColor.h" |
| 14 #include "SkColorPriv.h" | 14 #include "SkColorPriv.h" |
| 15 #include "SkPreConfig.h" | 15 #include "SkPreConfig.h" |
| 16 #include "SkUnPreMultiply.h" | 16 #include "SkUnPreMultiply.h" |
| 17 | 17 |
| 18 /** | 18 /** |
| 19 * Function template for transforming scanlines. | 19 * Function template for transforming scanlines. |
| 20 * Transform 'width' pixels from 'src' buffer into 'dst' buffer, | 20 * Transform 'width' pixels from 'src' buffer into 'dst' buffer, |
| 21 * repacking color channel data as appropriate for the given transformation. | 21 * repacking color channel data as appropriate for the given transformation. |
| 22 * 'bpp' is bytes per pixel in the 'dst' buffer. |
| 22 */ | 23 */ |
| 23 typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, | 24 typedef void (*transform_scanline_proc)(char* SK_RESTRICT dst, const char* SK_RE
STRICT src, |
| 24 int width, char* SK_RESTRICT dst); | 25 int width, int bpp); |
| 25 | 26 |
| 26 /** | 27 /** |
| 27 * Identity transformation: just copy bytes from src to dst. | 28 * Identity transformation: just copy bytes from src to dst. |
| 28 */ | 29 */ |
| 29 static void transform_scanline_memcpy(const char* SK_RESTRICT src, int width, | 30 static void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_REST
RICT src, |
| 30 char* SK_RESTRICT dst) { | 31 int width, int bpp) { |
| 31 memcpy(dst, src, width); | 32 memcpy(dst, src, width * bpp); |
| 32 } | 33 } |
| 33 | 34 |
| 34 /** | 35 /** |
| 35 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. | 36 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. |
| 36 * Alpha channel data is not present in kRGB_565_Config format, so there is no | 37 * Alpha channel data is not present in kRGB_565_Config format, so there is no |
| 37 * alpha channel data to preserve. | 38 * alpha channel data to preserve. |
| 38 */ | 39 */ |
| 39 static void transform_scanline_565(const char* SK_RESTRICT src, int width, | 40 static void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRIC
T src, |
| 40 char* SK_RESTRICT dst) { | 41 int width, int) { |
| 41 const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; | 42 const uint16_t* srcP = (const uint16_t*)src; |
| 42 for (int i = 0; i < width; i++) { | 43 for (int i = 0; i < width; i++) { |
| 43 unsigned c = *srcP++; | 44 unsigned c = *srcP++; |
| 44 *dst++ = SkPacked16ToR32(c); | 45 *dst++ = SkPacked16ToR32(c); |
| 45 *dst++ = SkPacked16ToG32(c); | 46 *dst++ = SkPacked16ToG32(c); |
| 46 *dst++ = SkPacked16ToB32(c); | 47 *dst++ = SkPacked16ToB32(c); |
| 47 } | 48 } |
| 48 } | 49 } |
| 49 | 50 |
| 50 /** | 51 /** |
| 51 * Transform from kARGB_8888_Config to 3-bytes-per-pixel RGB. | 52 * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB. |
| 52 * Alpha channel data, if any, is abandoned. | 53 * Alpha channel data is abandoned. |
| 53 */ | 54 */ |
| 54 static void transform_scanline_888(const char* SK_RESTRICT src, int width, | 55 static void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 55 char* SK_RESTRICT dst) { | 56 int width, int) { |
| 56 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | 57 const uint32_t* srcP = (const SkPMColor*)src; |
| 57 for (int i = 0; i < width; i++) { | 58 for (int i = 0; i < width; i++) { |
| 58 SkPMColor c = *srcP++; | 59 uint32_t c = *srcP++; |
| 59 *dst++ = SkGetPackedR32(c); | 60 *dst++ = (c >> 0) & 0xFF; |
| 60 *dst++ = SkGetPackedG32(c); | 61 *dst++ = (c >> 8) & 0xFF; |
| 61 *dst++ = SkGetPackedB32(c); | 62 *dst++ = (c >> 16) & 0xFF; |
| 62 } | 63 } |
| 63 } | 64 } |
| 64 | 65 |
| 66 /** |
| 67 * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB. |
| 68 * Alpha channel data is abandoned. |
| 69 */ |
| 70 static void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 71 int width, int) { |
| 72 const uint32_t* srcP = (const SkPMColor*)src; |
| 73 for (int i = 0; i < width; i++) { |
| 74 uint32_t c = *srcP++; |
| 75 *dst++ = (c >> 16) & 0xFF; |
| 76 *dst++ = (c >> 8) & 0xFF; |
| 77 *dst++ = (c >> 0) & 0xFF; |
| 78 } |
| 79 } |
| 80 |
| 65 /** | 81 /** |
| 66 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. | 82 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. |
| 67 * Alpha channel data, if any, is abandoned. | 83 * Alpha channel data, if any, is abandoned. |
| 68 */ | 84 */ |
| 69 static void transform_scanline_444(const char* SK_RESTRICT src, int width, | 85 static void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRIC
T src, |
| 70 char* SK_RESTRICT dst) { | 86 int width, int) { |
| 71 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | 87 const SkPMColor16* srcP = (const SkPMColor16*)src; |
| 72 for (int i = 0; i < width; i++) { | 88 for (int i = 0; i < width; i++) { |
| 73 SkPMColor16 c = *srcP++; | 89 SkPMColor16 c = *srcP++; |
| 74 *dst++ = SkPacked4444ToR32(c); | 90 *dst++ = SkPacked4444ToR32(c); |
| 75 *dst++ = SkPacked4444ToG32(c); | 91 *dst++ = SkPacked4444ToG32(c); |
| 76 *dst++ = SkPacked4444ToB32(c); | 92 *dst++ = SkPacked4444ToB32(c); |
| 77 } | 93 } |
| 78 } | 94 } |
| 79 | 95 |
| 80 /** | 96 template <bool kIsRGBA> |
| 81 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA. | 97 static inline void transform_scanline_unpremultiply(char* SK_RESTRICT dst, |
| 82 * (This would be the identity transformation, except for byte-order and | 98 const char* SK_RESTRICT src,
int width, int) { |
| 83 * scaling of RGB based on alpha channel). | 99 const uint32_t* srcP = (const SkPMColor*)src; |
| 84 */ | 100 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
| 85 static void transform_scanline_8888(const char* SK_RESTRICT src, int width, | |
| 86 char* SK_RESTRICT dst) { | |
| 87 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | |
| 88 const SkUnPreMultiply::Scale* SK_RESTRICT table = | |
| 89 SkUnPreMultiply::GetScaleTable(); | |
| 90 | 101 |
| 91 for (int i = 0; i < width; i++) { | 102 for (int i = 0; i < width; i++) { |
| 92 SkPMColor c = *srcP++; | 103 uint32_t c = *srcP++; |
| 93 unsigned a = SkGetPackedA32(c); | 104 unsigned r, g, b, a; |
| 94 unsigned r = SkGetPackedR32(c); | 105 if (kIsRGBA) { |
| 95 unsigned g = SkGetPackedG32(c); | 106 r = (c >> 0) & 0xFF; |
| 96 unsigned b = SkGetPackedB32(c); | 107 g = (c >> 8) & 0xFF; |
| 108 b = (c >> 16) & 0xFF; |
| 109 a = (c >> 24) & 0xFF; |
| 110 } else { |
| 111 r = (c >> 16) & 0xFF; |
| 112 g = (c >> 8) & 0xFF; |
| 113 b = (c >> 0) & 0xFF; |
| 114 a = (c >> 24) & 0xFF; |
| 115 } |
| 97 | 116 |
| 98 if (0 != a && 255 != a) { | 117 if (0 != a && 255 != a) { |
| 99 SkUnPreMultiply::Scale scale = table[a]; | 118 SkUnPreMultiply::Scale scale = table[a]; |
| 100 r = SkUnPreMultiply::ApplyScale(scale, r); | 119 r = SkUnPreMultiply::ApplyScale(scale, r); |
| 101 g = SkUnPreMultiply::ApplyScale(scale, g); | 120 g = SkUnPreMultiply::ApplyScale(scale, g); |
| 102 b = SkUnPreMultiply::ApplyScale(scale, b); | 121 b = SkUnPreMultiply::ApplyScale(scale, b); |
| 103 } | 122 } |
| 104 *dst++ = r; | 123 *dst++ = r; |
| 105 *dst++ = g; | 124 *dst++ = g; |
| 106 *dst++ = b; | 125 *dst++ = b; |
| 107 *dst++ = a; | 126 *dst++ = a; |
| 108 } | 127 } |
| 109 } | 128 } |
| 110 | 129 |
| 111 /** | 130 /** |
| 131 * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremult
iplied RGBA. |
| 132 */ |
| 133 static void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 134 int width, int bpp) { |
| 135 transform_scanline_unpremultiply<true>(dst, src, width, bpp); |
| 136 } |
| 137 |
| 138 /** |
| 139 * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremult
iplied RGBA. |
| 140 */ |
| 141 static void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 142 int width, int bpp) { |
| 143 transform_scanline_unpremultiply<false>(dst, src, width, bpp); |
| 144 } |
| 145 |
| 146 /** |
| 147 * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremu
ltiplied RGBA. |
| 148 */ |
| 149 static void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 150 int width, int) { |
| 151 const uint32_t* srcP = (const SkPMColor*)src; |
| 152 for (int i = 0; i < width; i++) { |
| 153 uint32_t c = *srcP++; |
| 154 *dst++ = (c >> 16) & 0xFF; |
| 155 *dst++ = (c >> 8) & 0xFF; |
| 156 *dst++ = (c >> 0) & 0xFF; |
| 157 *dst++ = (c >> 24) & 0xFF; |
| 158 } |
| 159 } |
| 160 |
| 161 /** |
| 112 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, | 162 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, |
| 113 * with scaling of RGB based on alpha channel. | 163 * with scaling of RGB based on alpha channel. |
| 114 */ | 164 */ |
| 115 static void transform_scanline_4444(const char* SK_RESTRICT src, int width, | 165 static void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 116 char* SK_RESTRICT dst) { | 166 int width, int) { |
| 117 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | 167 const SkPMColor16* srcP = (const SkPMColor16*)src; |
| 118 const SkUnPreMultiply::Scale* SK_RESTRICT table = | 168 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
| 119 SkUnPreMultiply::GetScaleTable(); | |
| 120 | 169 |
| 121 for (int i = 0; i < width; i++) { | 170 for (int i = 0; i < width; i++) { |
| 122 SkPMColor16 c = *srcP++; | 171 SkPMColor16 c = *srcP++; |
| 123 unsigned a = SkPacked4444ToA32(c); | 172 unsigned a = SkPacked4444ToA32(c); |
| 124 unsigned r = SkPacked4444ToR32(c); | 173 unsigned r = SkPacked4444ToR32(c); |
| 125 unsigned g = SkPacked4444ToG32(c); | 174 unsigned g = SkPacked4444ToG32(c); |
| 126 unsigned b = SkPacked4444ToB32(c); | 175 unsigned b = SkPacked4444ToB32(c); |
| 127 | 176 |
| 128 if (0 != a && 255 != a) { | 177 if (0 != a && 255 != a) { |
| 129 SkUnPreMultiply::Scale scale = table[a]; | 178 SkUnPreMultiply::Scale scale = table[a]; |
| 130 r = SkUnPreMultiply::ApplyScale(scale, r); | 179 r = SkUnPreMultiply::ApplyScale(scale, r); |
| 131 g = SkUnPreMultiply::ApplyScale(scale, g); | 180 g = SkUnPreMultiply::ApplyScale(scale, g); |
| 132 b = SkUnPreMultiply::ApplyScale(scale, b); | 181 b = SkUnPreMultiply::ApplyScale(scale, b); |
| 133 } | 182 } |
| 134 *dst++ = r; | 183 *dst++ = r; |
| 135 *dst++ = g; | 184 *dst++ = g; |
| 136 *dst++ = b; | 185 *dst++ = b; |
| 137 *dst++ = a; | 186 *dst++ = a; |
| 138 } | 187 } |
| 139 } | 188 } |
| OLD | NEW |