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

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: Add 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
« gm/bitmappremul.cpp ('K') | « 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 /**
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
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
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 }
OLDNEW
« gm/bitmappremul.cpp ('K') | « gyp/gmslides.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698