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