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 static void unpremultiply_and_pack_argb8888(uint32_t src, uint8_t dst[3]) { | |
22 uint8_t alpha = SkGetPackedA32(src); | |
23 if (alpha != SK_AlphaOPAQUE) { | |
24 SkColor unpremul = SkUnPreMultiply::PMColorToColor(src); | |
25 dst[0] = SkColorGetR(unpremul); | |
26 dst[1] = SkColorGetG(unpremul); | |
27 dst[2] = SkColorGetB(unpremul); | |
28 } else { | |
29 dst[0] = SkGetPackedR32(src); | |
30 dst[1] = SkGetPackedG32(src); | |
31 dst[2] = SkGetPackedB32(src); | |
32 } | |
33 } | |
34 | |
35 static void unpremultiply_and_pack_argb4444(uint16_t src0, uint16_t src1, | |
36 uint8_t dst[3]) { | |
37 // Unpack and transform the alpha values from 4 bits to 8 bits. | |
38 // This is necessary since the unpremultiply functions expect to work in | |
39 // 8-bit space, but we are passing in 4-bit values. Since we scale up | |
40 // the alpha, we scale down the amount the value is increased by, so that | |
41 // the results are correct for 4-bit color components. | |
42 uint8_t alpha0 = SkGetPackedA4444(src0); | |
43 alpha0 = alpha0 | (alpha0 << 4); | |
44 if (alpha0 != SK_AlphaOPAQUE) { | |
45 SkUnPreMultiply::Scale scale0 = SkUnPreMultiply::GetScale(alpha0); | |
46 dst[0] = SkUnPreMultiply::ApplyScale(scale0, | |
47 SkGetPackedR4444(src0)) << 4; | |
48 dst[0] |= SkUnPreMultiply::ApplyScale(scale0, SkGetPackedG4444(src0)); | |
49 dst[1] = SkUnPreMultiply::ApplyScale(scale0, | |
50 SkGetPackedB4444(src0)) << 4; | |
51 } else { | |
52 dst[0] = SkGetPackedR4444(src0) << 4; | |
53 dst[0] |= SkGetPackedG4444(src0); | |
54 dst[1] = SkGetPackedB4444(src0) << 4; | |
55 } | |
56 | |
57 uint8_t alpha1 = SkGetPackedA4444(src1); | |
58 alpha1 = alpha1 | (alpha1 << 4); | |
59 if (alpha1 != SK_AlphaOPAQUE) { | |
60 SkUnPreMultiply::Scale scale1 = SkUnPreMultiply::GetScale(alpha1); | |
61 dst[1] |= SkUnPreMultiply::ApplyScale(scale1, SkGetPackedR4444(src1)); | |
62 dst[2] = SkUnPreMultiply::ApplyScale(scale1, | |
63 SkGetPackedG4444(src1)) << 4; | |
64 dst[2] |= SkUnPreMultiply::ApplyScale(scale1, SkGetPackedB4444(src1)); | |
65 } else { | |
66 dst[1] |= SkGetPackedR4444(src1); | |
67 dst[2] = SkGetPackedG4444(src1) << 4; | |
68 dst[2] |= SkGetPackedB4444(src1); | |
69 } | |
70 } | |
71 | |
21 void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, | 72 void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, |
22 SkStream** imageData, SkStream** alphaData) { | 73 SkStream** imageData, SkStream** alphaData) { |
23 SkMemoryStream* image = NULL; | 74 SkMemoryStream* image = NULL; |
24 SkMemoryStream* alpha = NULL; | 75 SkMemoryStream* alpha = NULL; |
25 bool hasAlpha = false; | 76 bool hasAlpha = false; |
26 bool isTransparent = false; | 77 bool isTransparent = false; |
27 | 78 |
28 bitmap.lockPixels(); | 79 bitmap.lockPixels(); |
29 switch (bitmap.getConfig()) { | 80 switch (bitmap.getConfig()) { |
30 case SkBitmap::kIndex8_Config: { | 81 case SkBitmap::kIndex8_Config: { |
(...skipping 11 matching lines...) Expand all Loading... | |
42 const int rowBytes = (srcRect.width() * 3 + 1) / 2; | 93 const int rowBytes = (srcRect.width() * 3 + 1) / 2; |
43 const int alphaRowBytes = (srcRect.width() + 1) / 2; | 94 const int alphaRowBytes = (srcRect.width() + 1) / 2; |
44 image = new SkMemoryStream(rowBytes * srcRect.height()); | 95 image = new SkMemoryStream(rowBytes * srcRect.height()); |
45 alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); | 96 alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); |
46 uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 97 uint8_t* dst = (uint8_t*)image->getMemoryBase(); |
47 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 98 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); |
48 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 99 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { |
49 uint16_t* src = bitmap.getAddr16(0, y); | 100 uint16_t* src = bitmap.getAddr16(0, y); |
50 int x; | 101 int x; |
51 for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { | 102 for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { |
52 dst[0] = (SkGetPackedR4444(src[x]) << 4) | | |
53 SkGetPackedG4444(src[x]); | |
54 dst[1] = (SkGetPackedB4444(src[x]) << 4) | | |
55 SkGetPackedR4444(src[x + 1]); | |
56 dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) | | |
57 SkGetPackedB4444(src[x + 1]); | |
58 dst += 3; | |
59 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) | | 103 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) | |
60 SkGetPackedA4444(src[x + 1]); | 104 SkGetPackedA4444(src[x + 1]); |
61 if (alphaDst[0] != 0xFF) { | 105 if (alphaDst[0] != SK_AlphaOPAQUE) { |
62 hasAlpha = true; | 106 hasAlpha = true; |
63 } | 107 } |
64 if (alphaDst[0]) { | 108 if (alphaDst[0]) { |
65 isTransparent = false; | 109 isTransparent = false; |
66 } | 110 } |
111 unpremultiply_and_pack_argb4444(src[x], src[x + 1], dst); | |
67 alphaDst++; | 112 alphaDst++; |
113 dst += 3; | |
68 } | 114 } |
69 if (srcRect.width() & 1) { | 115 if (srcRect.width() & 1) { |
70 dst[0] = (SkGetPackedR4444(src[x]) << 4) | | 116 alphaDst[0] = SkGetPackedA4444(src[x]) << 4; |
71 SkGetPackedG4444(src[x]); | 117 // Use a buffer to translate from the usual 2 4444 values |
72 dst[1] = (SkGetPackedB4444(src[x]) << 4); | 118 // in 12 bytes to the single 4444 value in 2 bytes. |
vandebo (ex-Chrome)
2013/08/13 20:52:33
nit: 12 bytes -> 3 bytes.
| |
73 dst += 2; | 119 uint8_t buffer[3]; |
74 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4); | |
75 if (alphaDst[0] != 0xF0) { | 120 if (alphaDst[0] != 0xF0) { |
76 hasAlpha = true; | 121 hasAlpha = true; |
77 } | 122 } |
78 if (alphaDst[0] & 0xF0) { | 123 if (alphaDst[0] & 0xF0) { |
79 isTransparent = false; | 124 isTransparent = false; |
80 } | 125 } |
126 unpremultiply_and_pack_argb4444(src[x], 0x00, buffer); | |
127 dst[0] = buffer[0]; | |
128 dst[1] = buffer[1]; | |
129 | |
81 alphaDst++; | 130 alphaDst++; |
131 dst += 2; | |
82 } | 132 } |
83 } | 133 } |
84 break; | 134 break; |
85 } | 135 } |
86 case SkBitmap::kRGB_565_Config: { | 136 case SkBitmap::kRGB_565_Config: { |
87 const int rowBytes = srcRect.width() * 3; | 137 const int rowBytes = srcRect.width() * 3; |
88 image = new SkMemoryStream(rowBytes * srcRect.height()); | 138 image = new SkMemoryStream(rowBytes * srcRect.height()); |
89 uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 139 uint8_t* dst = (uint8_t*)image->getMemoryBase(); |
90 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 140 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { |
91 uint16_t* src = bitmap.getAddr16(0, y); | 141 uint16_t* src = bitmap.getAddr16(0, y); |
92 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 142 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { |
93 dst[0] = SkGetPackedR16(src[x]); | 143 dst[0] = SkGetPackedR16(src[x]); |
94 dst[1] = SkGetPackedG16(src[x]); | 144 dst[1] = SkGetPackedG16(src[x]); |
95 dst[2] = SkGetPackedB16(src[x]); | 145 dst[2] = SkGetPackedB16(src[x]); |
96 dst += 3; | 146 dst += 3; |
97 } | 147 } |
98 } | 148 } |
99 break; | 149 break; |
100 } | 150 } |
101 case SkBitmap::kARGB_8888_Config: { | 151 case SkBitmap::kARGB_8888_Config: { |
102 isTransparent = true; | 152 isTransparent = true; |
103 const int rowBytes = srcRect.width() * 3; | 153 const int rowBytes = srcRect.width() * 3; |
104 image = new SkMemoryStream(rowBytes * srcRect.height()); | 154 image = new SkMemoryStream(rowBytes * srcRect.height()); |
105 alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); | 155 alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); |
106 uint8_t* dst = (uint8_t*)image->getMemoryBase(); | 156 uint8_t* dst = (uint8_t*)image->getMemoryBase(); |
107 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); | 157 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); |
108 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { | 158 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { |
109 uint32_t* src = bitmap.getAddr32(0, y); | 159 uint32_t* src = bitmap.getAddr32(0, y); |
110 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { | 160 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { |
111 dst[0] = SkGetPackedR32(src[x]); | |
112 dst[1] = SkGetPackedG32(src[x]); | |
113 dst[2] = SkGetPackedB32(src[x]); | |
114 dst += 3; | |
115 alphaDst[0] = SkGetPackedA32(src[x]); | 161 alphaDst[0] = SkGetPackedA32(src[x]); |
116 if (alphaDst[0] != 0xFF) { | 162 if (alphaDst[0] != SK_AlphaOPAQUE) { |
117 hasAlpha = true; | 163 hasAlpha = true; |
118 } | 164 } |
119 if (alphaDst[0]) { | 165 if (alphaDst[0] != SK_AlphaTRANSPARENT) { |
120 isTransparent = false; | 166 isTransparent = false; |
121 } | 167 } |
168 unpremultiply_and_pack_argb8888(src[x], dst); | |
122 alphaDst++; | 169 alphaDst++; |
170 dst += 3; | |
123 } | 171 } |
124 } | 172 } |
125 break; | 173 break; |
126 } | 174 } |
127 case SkBitmap::kA1_Config: { | 175 case SkBitmap::kA1_Config: { |
128 isTransparent = true; | 176 isTransparent = true; |
129 image = new SkMemoryStream(1); | 177 image = new SkMemoryStream(1); |
130 ((uint8_t*)image->getMemoryBase())[0] = 0; | 178 ((uint8_t*)image->getMemoryBase())[0] = 0; |
131 | 179 |
132 const int alphaRowBytes = (srcRect.width() + 7) / 8; | 180 const int alphaRowBytes = (srcRect.width() + 7) / 8; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 decodeValue->reserve(6); | 378 decodeValue->reserve(6); |
331 decodeValue->append(zeroVal.get()); | 379 decodeValue->append(zeroVal.get()); |
332 decodeValue->append(scale5Val.get()); | 380 decodeValue->append(scale5Val.get()); |
333 decodeValue->append(zeroVal.get()); | 381 decodeValue->append(zeroVal.get()); |
334 decodeValue->append(scale6Val.get()); | 382 decodeValue->append(scale6Val.get()); |
335 decodeValue->append(zeroVal.get()); | 383 decodeValue->append(zeroVal.get()); |
336 decodeValue->append(scale5Val.get()); | 384 decodeValue->append(scale5Val.get()); |
337 insert("Decode", decodeValue.get()); | 385 insert("Decode", decodeValue.get()); |
338 } | 386 } |
339 } | 387 } |
OLD | NEW |