Chromium Code Reviews| 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. |
|
scroggo
2016/09/12 17:16:50
This should probably state what "bpp" means. I'm g
msarett
2016/09/12 19:39:20
Done. It is dst bytesPerPixel, though src would b
scroggo
2016/09/12 19:54:31
It looks like you pass the src's bytes per pixel.
msarett
2016/09/12 20:27:57
Done, thanks
| |
| 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 */ | 22 */ |
| 23 typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, | 23 typedef void (*transform_scanline_proc)(uint8_t* dst, const void* src, int width , int bpp); |
|
scroggo
2016/09/12 17:16:50
Just out of curiosity, why did you switch to uint8
msarett
2016/09/12 19:39:20
You're right, back to char and SK_RESTRICT.
| |
| 24 int width, char* SK_RESTRICT dst); | |
| 25 | 24 |
| 26 /** | 25 /** |
| 27 * Identity transformation: just copy bytes from src to dst. | 26 * Identity transformation: just copy bytes from src to dst. |
| 28 */ | 27 */ |
| 29 static void transform_scanline_memcpy(const char* SK_RESTRICT src, int width, | 28 static void transform_scanline_memcpy(uint8_t* dst, const void* src, int width, int bpp) { |
| 30 char* SK_RESTRICT dst) { | 29 memcpy(dst, src, width * bpp); |
| 31 memcpy(dst, src, width); | |
| 32 } | 30 } |
| 33 | 31 |
| 34 /** | 32 /** |
| 35 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. | 33 * 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 | 34 * Alpha channel data is not present in kRGB_565_Config format, so there is no |
| 37 * alpha channel data to preserve. | 35 * alpha channel data to preserve. |
| 38 */ | 36 */ |
| 39 static void transform_scanline_565(const char* SK_RESTRICT src, int width, | 37 static void transform_scanline_565(uint8_t* dst, const void* src, int width, int ) { |
| 40 char* SK_RESTRICT dst) { | 38 const uint16_t* srcP = (const uint16_t*)src; |
| 41 const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; | |
| 42 for (int i = 0; i < width; i++) { | 39 for (int i = 0; i < width; i++) { |
| 43 unsigned c = *srcP++; | 40 unsigned c = *srcP++; |
| 44 *dst++ = SkPacked16ToR32(c); | 41 *dst++ = SkPacked16ToR32(c); |
| 45 *dst++ = SkPacked16ToG32(c); | 42 *dst++ = SkPacked16ToG32(c); |
| 46 *dst++ = SkPacked16ToB32(c); | 43 *dst++ = SkPacked16ToB32(c); |
| 47 } | 44 } |
| 48 } | 45 } |
| 49 | 46 |
| 50 /** | 47 /** |
| 51 * Transform from kARGB_8888_Config to 3-bytes-per-pixel RGB. | 48 * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB. |
| 52 * Alpha channel data, if any, is abandoned. | 49 * Alpha channel data is abandoned. |
| 53 */ | 50 */ |
| 54 static void transform_scanline_888(const char* SK_RESTRICT src, int width, | 51 static void transform_scanline_RGB1(uint8_t* dst, const void* src, int width, in t) { |
|
scroggo
2016/09/12 17:16:50
How'd you choose the "1" in the name? (I might be
msarett
2016/09/12 19:39:20
I think RGBX is a better name, switching.
| |
| 55 char* SK_RESTRICT dst) { | 52 const SkPMColor* srcP = (const SkPMColor*)src; |
| 56 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | |
| 57 for (int i = 0; i < width; i++) { | 53 for (int i = 0; i < width; i++) { |
| 58 SkPMColor c = *srcP++; | 54 SkPMColor c = *srcP++; |
| 59 *dst++ = SkGetPackedR32(c); | 55 *dst++ = (c >> 0) & 0xFF; |
| 60 *dst++ = SkGetPackedG32(c); | 56 *dst++ = (c >> 8) & 0xFF; |
| 61 *dst++ = SkGetPackedB32(c); | 57 *dst++ = (c >> 16) & 0xFF; |
| 62 } | 58 } |
| 63 } | 59 } |
| 64 | 60 |
| 61 /** | |
| 62 * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB. | |
| 63 * Alpha channel data is abandoned. | |
| 64 */ | |
| 65 static void transform_scanline_BGR1(uint8_t* dst, const void* src, int width, in t) { | |
| 66 const SkPMColor* srcP = (const SkPMColor*)src; | |
| 67 for (int i = 0; i < width; i++) { | |
| 68 SkPMColor c = *srcP++; | |
|
scroggo
2016/09/12 17:16:50
One of these uses of SkPMColor is a lie, but I sup
msarett
2016/09/12 19:39:20
Let's use uint32_t...
| |
| 69 *dst++ = (c >> 16) & 0xFF; | |
| 70 *dst++ = (c >> 8) & 0xFF; | |
| 71 *dst++ = (c >> 0) & 0xFF; | |
| 72 } | |
| 73 } | |
| 74 | |
| 65 /** | 75 /** |
| 66 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. | 76 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. |
| 67 * Alpha channel data, if any, is abandoned. | 77 * Alpha channel data, if any, is abandoned. |
| 68 */ | 78 */ |
| 69 static void transform_scanline_444(const char* SK_RESTRICT src, int width, | 79 static void transform_scanline_444(uint8_t* dst, const void* src, int width, int ) { |
| 70 char* SK_RESTRICT dst) { | 80 const SkPMColor16* srcP = (const SkPMColor16*)src; |
| 71 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | |
| 72 for (int i = 0; i < width; i++) { | 81 for (int i = 0; i < width; i++) { |
| 73 SkPMColor16 c = *srcP++; | 82 SkPMColor16 c = *srcP++; |
| 74 *dst++ = SkPacked4444ToR32(c); | 83 *dst++ = SkPacked4444ToR32(c); |
| 75 *dst++ = SkPacked4444ToG32(c); | 84 *dst++ = SkPacked4444ToG32(c); |
| 76 *dst++ = SkPacked4444ToB32(c); | 85 *dst++ = SkPacked4444ToB32(c); |
| 77 } | 86 } |
| 78 } | 87 } |
| 79 | 88 |
| 80 /** | 89 /** |
| 81 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA. | 90 * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremult iplied RGBA. |
| 82 * (This would be the identity transformation, except for byte-order and | |
| 83 * scaling of RGB based on alpha channel). | |
| 84 */ | 91 */ |
| 85 static void transform_scanline_8888(const char* SK_RESTRICT src, int width, | 92 static void transform_scanline_rgbA(uint8_t* dst, const void* src, int width, in t) { |
| 86 char* SK_RESTRICT dst) { | 93 const SkPMColor* srcP = (const SkPMColor*)src; |
| 87 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | 94 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
| 88 const SkUnPreMultiply::Scale* SK_RESTRICT table = | |
| 89 SkUnPreMultiply::GetScaleTable(); | |
| 90 | 95 |
| 91 for (int i = 0; i < width; i++) { | 96 for (int i = 0; i < width; i++) { |
| 92 SkPMColor c = *srcP++; | 97 SkPMColor c = *srcP++; |
| 93 unsigned a = SkGetPackedA32(c); | 98 unsigned r = (c >> 0) & 0xFF; |
| 94 unsigned r = SkGetPackedR32(c); | 99 unsigned g = (c >> 8) & 0xFF; |
| 95 unsigned g = SkGetPackedG32(c); | 100 unsigned b = (c >> 16) & 0xFF; |
| 96 unsigned b = SkGetPackedB32(c); | 101 unsigned a = (c >> 24) & 0xFF; |
| 97 | 102 |
| 98 if (0 != a && 255 != a) { | 103 if (0 != a && 255 != a) { |
| 99 SkUnPreMultiply::Scale scale = table[a]; | 104 SkUnPreMultiply::Scale scale = table[a]; |
| 105 r = SkUnPreMultiply::ApplyScale(scale, r); | |
| 106 g = SkUnPreMultiply::ApplyScale(scale, g); | |
| 107 b = SkUnPreMultiply::ApplyScale(scale, b); | |
| 108 } | |
| 109 *dst++ = r; | |
| 110 *dst++ = g; | |
| 111 *dst++ = b; | |
| 112 *dst++ = a; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 /** | |
| 117 * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremult iplied RGBA. | |
| 118 */ | |
| 119 static void transform_scanline_bgrA(uint8_t* dst, const void* src, int width, in t) { | |
| 120 const SkPMColor* srcP = (const SkPMColor*)src; | |
| 121 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); | |
| 122 | |
| 123 for (int i = 0; i < width; i++) { | |
| 124 SkPMColor c = *srcP++; | |
| 125 unsigned r = (c >> 16) & 0xFF; | |
|
scroggo
2016/09/12 17:16:50
Can we share code between these two methods (maybe
msarett
2016/09/12 19:39:20
SGTM
| |
| 126 unsigned g = (c >> 8) & 0xFF; | |
| 127 unsigned b = (c >> 0) & 0xFF; | |
| 128 unsigned a = (c >> 24) & 0xFF; | |
| 129 | |
| 130 if (0 != a && 255 != a) { | |
| 131 SkUnPreMultiply::Scale scale = table[a]; | |
| 100 r = SkUnPreMultiply::ApplyScale(scale, r); | 132 r = SkUnPreMultiply::ApplyScale(scale, r); |
| 101 g = SkUnPreMultiply::ApplyScale(scale, g); | 133 g = SkUnPreMultiply::ApplyScale(scale, g); |
| 102 b = SkUnPreMultiply::ApplyScale(scale, b); | 134 b = SkUnPreMultiply::ApplyScale(scale, b); |
| 103 } | 135 } |
| 104 *dst++ = r; | 136 *dst++ = r; |
| 105 *dst++ = g; | 137 *dst++ = g; |
| 106 *dst++ = b; | 138 *dst++ = b; |
| 107 *dst++ = a; | 139 *dst++ = a; |
| 108 } | 140 } |
| 109 } | 141 } |
| 110 | 142 |
| 111 /** | 143 /** |
| 144 * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremu ltiplied RGBA. | |
| 145 */ | |
| 146 static void transform_scanline_BGRA(uint8_t* dst, const void* src, int width, in t) { | |
| 147 const SkPMColor* srcP = (const SkPMColor*)src; | |
| 148 for (int i = 0; i < width; i++) { | |
| 149 SkPMColor c = *srcP++; | |
| 150 *dst++ = (c >> 16) & 0xFF; | |
| 151 *dst++ = (c >> 8) & 0xFF; | |
| 152 *dst++ = (c >> 0) & 0xFF; | |
| 153 *dst++ = (c >> 24) & 0xFF; | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 /** | |
| 112 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, | 158 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, |
| 113 * with scaling of RGB based on alpha channel. | 159 * with scaling of RGB based on alpha channel. |
| 114 */ | 160 */ |
| 115 static void transform_scanline_4444(const char* SK_RESTRICT src, int width, | 161 static void transform_scanline_4444(uint8_t* dst, const void* src, int width, in t) { |
| 116 char* SK_RESTRICT dst) { | 162 const SkPMColor16* srcP = (const SkPMColor16*)src; |
| 117 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | 163 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
| 118 const SkUnPreMultiply::Scale* SK_RESTRICT table = | |
| 119 SkUnPreMultiply::GetScaleTable(); | |
| 120 | 164 |
| 121 for (int i = 0; i < width; i++) { | 165 for (int i = 0; i < width; i++) { |
| 122 SkPMColor16 c = *srcP++; | 166 SkPMColor16 c = *srcP++; |
| 123 unsigned a = SkPacked4444ToA32(c); | 167 unsigned a = SkPacked4444ToA32(c); |
| 124 unsigned r = SkPacked4444ToR32(c); | 168 unsigned r = SkPacked4444ToR32(c); |
| 125 unsigned g = SkPacked4444ToG32(c); | 169 unsigned g = SkPacked4444ToG32(c); |
| 126 unsigned b = SkPacked4444ToB32(c); | 170 unsigned b = SkPacked4444ToB32(c); |
| 127 | 171 |
| 128 if (0 != a && 255 != a) { | 172 if (0 != a && 255 != a) { |
| 129 SkUnPreMultiply::Scale scale = table[a]; | 173 SkUnPreMultiply::Scale scale = table[a]; |
| 130 r = SkUnPreMultiply::ApplyScale(scale, r); | 174 r = SkUnPreMultiply::ApplyScale(scale, r); |
| 131 g = SkUnPreMultiply::ApplyScale(scale, g); | 175 g = SkUnPreMultiply::ApplyScale(scale, g); |
| 132 b = SkUnPreMultiply::ApplyScale(scale, b); | 176 b = SkUnPreMultiply::ApplyScale(scale, b); |
| 133 } | 177 } |
| 134 *dst++ = r; | 178 *dst++ = r; |
| 135 *dst++ = g; | 179 *dst++ = g; |
| 136 *dst++ = b; | 180 *dst++ = b; |
| 137 *dst++ = a; | 181 *dst++ = a; |
| 138 } | 182 } |
| 139 } | 183 } |
| OLD | NEW |