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

Side by Side Diff: src/pdf/SkPDFImage.cpp

Issue 22329003: Unpremultiply SkBitmaps for PDF output (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Style fixes; add stripe slide to GM Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698