OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2010 The Android Open Source Project | 2 * Copyright 2010 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 #include "SkPDFImage.h" | 8 #include "SkPDFImage.h" |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkColor.h" | 11 #include "SkColor.h" |
12 #include "SkColorPriv.h" | 12 #include "SkColorPriv.h" |
13 #include "SkPDFCatalog.h" | 13 #include "SkPDFCatalog.h" |
14 #include "SkRect.h" | 14 #include "SkRect.h" |
15 #include "SkStream.h" | 15 #include "SkStream.h" |
16 #include "SkString.h" | 16 #include "SkString.h" |
17 #include "SkUnPreMultiply.h" | 17 #include "SkUnPreMultiply.h" |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 /** | |
22 * Unpremultiply an ARGB color, keeping the output in the same format | |
23 * as the input. | |
24 */ | |
25 static uint32_t unpremultiply_argb8888(uint32_t src) { | |
vandebo (ex-Chrome)
2013/08/07 18:02:47
Instead of needing two unpremultiply routines to d
ducky
2013/08/08 03:35:11
I'm not sure that will work - argb4444 is also sto
vandebo (ex-Chrome)
2013/08/09 16:56:49
Sorry I didn't look at it closely enough. You are
| |
26 uint8_t a = SkGetPackedA32(src); | |
vandebo (ex-Chrome)
2013/08/09 16:56:49
Is this currently just the same as PMColorToColor(
ducky
2013/08/09 21:45:14
Not exactly. PMColorToColor turns the output into
vandebo (ex-Chrome)
2013/08/12 15:56:05
SkColor.h says that the order of components in SkC
ducky
2013/08/12 20:51:58
Ok. I think this was back from when I actually nee
| |
27 SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a); | |
28 return SkPackARGB32NoCheck( | |
29 a, | |
30 SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32(src)), | |
31 SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32(src)), | |
32 SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32(src))); | |
33 } | |
34 | |
35 static uint16_t unpremultiply_argb4444(uint16_t src) { | |
vandebo (ex-Chrome)
2013/08/09 16:56:49
The 4444 case is more of a pain. Maybe this shoul
ducky
2013/08/09 21:45:14
Also may be problematic. On the edge case, it only
vandebo (ex-Chrome)
2013/08/12 15:56:05
Yes, for the edge case, you wouldn't pass in the f
ducky
2013/08/12 20:51:58
Done.
| |
36 uint32_t src32 = SkPixel4444ToPixel32(src); | |
vandebo (ex-Chrome)
2013/08/09 16:56:49
Do you need to convert to 8888 space to unpremulti
| |
37 uint8_t a = SkGetPackedA32(src32); | |
38 SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a); | |
39 src32 = SkPackARGB32NoCheck( | |
40 a, | |
41 SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32(src32)), | |
42 SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32(src32)), | |
43 SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32(src32))); | |
44 return SkPixel32ToPixel4444(src32); | |
45 } | |
46 | |
21 void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 47 void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, |
22 SkStream** imageData, SkStream** alphaData) { | 48 SkStream** imageData, SkStream** alphaData) { |
23 SkMemoryStream* image = NULL; | 49 SkMemoryStream* image = NULL; |
24 SkMemoryStream* alpha = NULL; | 50 SkMemoryStream* alpha = NULL; |
25 bool hasAlpha = false; | 51 bool hasAlpha = false; |
26 bool isTransparent = false; | 52 bool isTransparent = false; |
27 | 53 |
28 bitmap.lockPixels(); | 54 bitmap.lockPixels(); |
29 switch (bitmap.getConfig()) { | 55 switch (bitmap.getConfig()) { |
30 case SkBitmap::kIndex8_Config: { | 56 case SkBitmap::kIndex8_Config: { |
(...skipping 11 matching lines...) Expand all Loading... | |
42 const int rowBytes = (srcRect.width() * 3 + 1) / 2; | 68 const int rowBytes = (srcRect.width() * 3 + 1) / 2; |
43 const int alphaRowBytes = (srcRect.width() + 1) / 2; | 69 const int alphaRowBytes = (srcRect.width() + 1) / 2; |
44 image = new SkMemoryStream(rowBytes * srcRect.height()); | 70 image = new SkMemoryStream(rowBytes * srcRect.height()); |
45 alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); | 71 alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); |
46 uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 72 uint8_t* dst = (uint8_t*)image->getMemoryBase(); |
47 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 73 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); |
48 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 74 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { |
49 uint16_t* src = bitmap.getAddr16(0, y); | 75 uint16_t* src = bitmap.getAddr16(0, y); |
50 int x; | 76 int x; |
51 for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { | 77 for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { |
52 dst[0] = (SkGetPackedR4444(src[x]) << 4) | | 78 uint16_t pixel0 = src[x], pixel1 = src[x + 1]; |
53 SkGetPackedG4444(src[x]); | 79 |
54 dst[1] = (SkGetPackedB4444(src[x]) << 4) | | 80 alphaDst[0] = (SkGetPackedA4444(pixel0) << 4) | |
55 SkGetPackedR4444(src[x + 1]); | 81 SkGetPackedA4444(pixel1); |
56 dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) | | 82 if (SkGetPackedA4444(pixel0) != 0xF) { |
57 SkGetPackedB4444(src[x + 1]); | |
58 dst += 3; | |
59 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) | | |
60 SkGetPackedA4444(src[x + 1]); | |
61 if (alphaDst[0] != 0xFF) { | |
62 hasAlpha = true; | 83 hasAlpha = true; |
vandebo (ex-Chrome)
2013/08/07 18:02:47
Your unpremultiply call could drop in right here.
| |
84 pixel0 = unpremultiply_argb4444(pixel0); | |
85 } | |
86 if (SkGetPackedA4444(pixel1) != 0xF) { | |
87 hasAlpha = true; | |
88 pixel1 = unpremultiply_argb4444(pixel1); | |
63 } | 89 } |
64 if (alphaDst[0]) { | 90 if (alphaDst[0]) { |
65 isTransparent = false; | 91 isTransparent = false; |
66 } | 92 } |
93 | |
94 dst[0] = (SkGetPackedR4444(pixel0) << 4) | | |
95 SkGetPackedG4444(pixel0); | |
96 dst[1] = (SkGetPackedB4444(pixel0) << 4) | | |
97 SkGetPackedR4444(pixel1); | |
98 dst[2] = (SkGetPackedG4444(pixel1) << 4) | | |
99 SkGetPackedB4444(pixel1); | |
100 | |
67 alphaDst++; | 101 alphaDst++; |
102 dst += 3; | |
68 } | 103 } |
69 if (srcRect.width() & 1) { | 104 if (srcRect.width() & 1) { |
70 dst[0] = (SkGetPackedR4444(src[x]) << 4) | | 105 uint16_t pixel = src[x]; |
71 SkGetPackedG4444(src[x]); | 106 |
72 dst[1] = (SkGetPackedB4444(src[x]) << 4); | 107 alphaDst[0] = (SkGetPackedA4444(pixel) << 4); |
73 dst += 2; | |
74 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4); | |
75 if (alphaDst[0] != 0xF0) { | 108 if (alphaDst[0] != 0xF0) { |
76 hasAlpha = true; | 109 hasAlpha = true; |
vandebo (ex-Chrome)
2013/08/07 18:02:47
and here
| |
110 pixel = unpremultiply_argb4444(pixel); | |
77 } | 111 } |
78 if (alphaDst[0] & 0xF0) { | 112 if (alphaDst[0] & 0xF0) { |
79 isTransparent = false; | 113 isTransparent = false; |
80 } | 114 } |
115 | |
116 dst[0] = (SkGetPackedR4444(pixel) << 4) | | |
117 SkGetPackedG4444(pixel); | |
118 dst[1] = (SkGetPackedB4444(pixel) << 4); | |
119 | |
81 alphaDst++; | 120 alphaDst++; |
121 dst += 2; | |
82 } | 122 } |
83 } | 123 } |
84 break; | 124 break; |
85 } | 125 } |
86 case SkBitmap::kRGB_565_Config: { | 126 case SkBitmap::kRGB_565_Config: { |
87 const int rowBytes = srcRect.width() * 3; | 127 const int rowBytes = srcRect.width() * 3; |
88 image = new SkMemoryStream(rowBytes * srcRect.height()); | 128 image = new SkMemoryStream(rowBytes * srcRect.height()); |
89 uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 129 uint8_t* dst = (uint8_t*)image->getMemoryBase(); |
90 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 130 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { |
91 uint16_t* src = bitmap.getAddr16(0, y); | 131 uint16_t* src = bitmap.getAddr16(0, y); |
92 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 132 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { |
93 dst[0] = SkGetPackedR16(src[x]); | 133 dst[0] = SkGetPackedR16(src[x]); |
94 dst[1] = SkGetPackedG16(src[x]); | 134 dst[1] = SkGetPackedG16(src[x]); |
95 dst[2] = SkGetPackedB16(src[x]); | 135 dst[2] = SkGetPackedB16(src[x]); |
96 dst += 3; | 136 dst += 3; |
97 } | 137 } |
98 } | 138 } |
99 break; | 139 break; |
100 } | 140 } |
101 case SkBitmap::kARGB_8888_Config: { | 141 case SkBitmap::kARGB_8888_Config: { |
102 isTransparent = true; | 142 isTransparent = true; |
103 const int rowBytes = srcRect.width() * 3; | 143 const int rowBytes = srcRect.width() * 3; |
104 image = new SkMemoryStream(rowBytes * srcRect.height()); | 144 image = new SkMemoryStream(rowBytes * srcRect.height()); |
105 alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); | 145 alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); |
106 uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 146 uint8_t* dst = (uint8_t*)image->getMemoryBase(); |
107 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 147 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); |
108 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 148 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { |
109 uint32_t* src = bitmap.getAddr32(0, y); | 149 uint32_t* src = bitmap.getAddr32(0, y); |
110 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 150 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { |
111 dst[0] = SkGetPackedR32(src[x]); | 151 uint32_t pixel = src[x]; |
112 dst[1] = SkGetPackedG32(src[x]); | 152 alphaDst[0] = SkGetPackedA32(pixel); |
113 dst[2] = SkGetPackedB32(src[x]); | 153 if (alphaDst[0] != SK_AlphaOPAQUE) { |
114 dst += 3; | |
115 alphaDst[0] = SkGetPackedA32(src[x]); | |
116 if (alphaDst[0] != 0xFF) { | |
117 hasAlpha = true; | 154 hasAlpha = true; |
vandebo (ex-Chrome)
2013/08/07 18:02:47
and here
| |
155 pixel = unpremultiply_argb8888(pixel); | |
118 } | 156 } |
119 if (alphaDst[0]) { | 157 if (alphaDst[0] != SK_AlphaTRANSPARENT) { |
120 isTransparent = false; | 158 isTransparent = false; |
121 } | 159 } |
160 | |
161 dst[0] = SkGetPackedR32(pixel); | |
162 dst[1] = SkGetPackedG32(pixel); | |
163 dst[2] = SkGetPackedB32(pixel); | |
164 | |
122 alphaDst++; | 165 alphaDst++; |
166 dst += 3; | |
123 } | 167 } |
124 } | 168 } |
125 break; | 169 break; |
126 } | 170 } |
127 case SkBitmap::kA1_Config: { | 171 case SkBitmap::kA1_Config: { |
128 isTransparent = true; | 172 isTransparent = true; |
129 image = new SkMemoryStream(1); | 173 image = new SkMemoryStream(1); |
130 ((uint8_t*)image->getMemoryBase())[0] = 0; | 174 ((uint8_t*)image->getMemoryBase())[0] = 0; |
131 | 175 |
132 const int alphaRowBytes = (srcRect.width() + 7) / 8; | 176 const int alphaRowBytes = (srcRect.width() + 7) / 8; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 decodeValue->reserve(6); | 374 decodeValue->reserve(6); |
331 decodeValue->append(zeroVal.get()); | 375 decodeValue->append(zeroVal.get()); |
332 decodeValue->append(scale5Val.get()); | 376 decodeValue->append(scale5Val.get()); |
333 decodeValue->append(zeroVal.get()); | 377 decodeValue->append(zeroVal.get()); |
334 decodeValue->append(scale6Val.get()); | 378 decodeValue->append(scale6Val.get()); |
335 decodeValue->append(zeroVal.get()); | 379 decodeValue->append(zeroVal.get()); |
336 decodeValue->append(scale5Val.get()); | 380 decodeValue->append(scale5Val.get()); |
337 insert("Decode", decodeValue.get()); | 381 insert("Decode", decodeValue.get()); |
338 } | 382 } |
339 } | 383 } |
OLD | NEW |