Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: src/images/transform_scanline.h

Issue 2325223002: Support RGBA/BGRA Premul/Unpremul from SkPNGImageEncoder (Closed)
Patch Set: Response to comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698