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

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: 80 cols 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(uint8_t alpha, uint32_t src,
22 uint8_t* dst) {
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(uint8_t alpha0, uint8_t alpha1,
vandebo (ex-Chrome) 2013/08/12 22:20:48 Don't pass in alpha, just extract it from source a
ducky 2013/08/12 23:25:23 Done.
36 uint16_t src0, uint16_t src1,
37 uint8_t* dst) {
vandebo (ex-Chrome) 2013/08/12 22:20:48 uint8_t dst[3]
ducky 2013/08/12 23:25:23 Done.
38 if (alpha0 != 0x0F) {
vandebo (ex-Chrome) 2013/08/12 22:20:48 SK_AlphaOPAQUE
ducky 2013/08/12 23:25:23 Done.
39 alpha0 = alpha0 | (alpha0 << 4);
40 SkUnPreMultiply::Scale scale0 = SkUnPreMultiply::GetScale(alpha0);
41 dst[0] = SkUnPreMultiply::ApplyScale(scale0, SkGetPackedR4444(src0));
42 dst[0] = dst[0] << 4;
vandebo (ex-Chrome) 2013/08/12 22:20:48 Breaking out the shift into a different assignment
ducky 2013/08/12 23:25:23 Fixed.
43 dst[0] |= SkUnPreMultiply::ApplyScale(scale0, SkGetPackedG4444(src0));
44 dst[1] = SkUnPreMultiply::ApplyScale(scale0, SkGetPackedB4444(src0));
45 dst[1] = dst[1] << 4;
46 } else {
47 dst[0] = SkGetPackedR4444(src0) << 4;
48 dst[0] |= SkGetPackedG4444(src0);
49 dst[1] = SkGetPackedB4444(src0) << 4;
50 }
51
52 if (alpha1 != 0x0F) {
53 alpha1 = alpha1 | (alpha1 << 4);
54 SkUnPreMultiply::Scale scale1 = SkUnPreMultiply::GetScale(alpha1);
55 dst[1] |= SkUnPreMultiply::ApplyScale(scale1, SkGetPackedR4444(src1));
56 dst[2] = SkUnPreMultiply::ApplyScale(scale1, SkGetPackedG4444(src1));
57 dst[2] = dst[2] << 4;
58 dst[2] |= SkUnPreMultiply::ApplyScale(scale1, SkGetPackedB4444(src1));
59 } else {
60 dst[1] |= SkGetPackedR4444(src1);
61 dst[2] = SkGetPackedG4444(src1) << 4;
62 dst[2] |= SkGetPackedB4444(src1);
63 }
64 }
65
21 void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect, 66 void extractImageData(const SkBitmap& bitmap, const SkIRect& srcRect,
22 SkStream** imageData, SkStream** alphaData) { 67 SkStream** imageData, SkStream** alphaData) {
23 SkMemoryStream* image = NULL; 68 SkMemoryStream* image = NULL;
24 SkMemoryStream* alpha = NULL; 69 SkMemoryStream* alpha = NULL;
25 bool hasAlpha = false; 70 bool hasAlpha = false;
26 bool isTransparent = false; 71 bool isTransparent = false;
27 72
28 bitmap.lockPixels(); 73 bitmap.lockPixels();
29 switch (bitmap.getConfig()) { 74 switch (bitmap.getConfig()) {
30 case SkBitmap::kIndex8_Config: { 75 case SkBitmap::kIndex8_Config: {
(...skipping 11 matching lines...) Expand all
42 const int rowBytes = (srcRect.width() * 3 + 1) / 2; 87 const int rowBytes = (srcRect.width() * 3 + 1) / 2;
43 const int alphaRowBytes = (srcRect.width() + 1) / 2; 88 const int alphaRowBytes = (srcRect.width() + 1) / 2;
44 image = new SkMemoryStream(rowBytes * srcRect.height()); 89 image = new SkMemoryStream(rowBytes * srcRect.height());
45 alpha = new SkMemoryStream(alphaRowBytes * srcRect.height()); 90 alpha = new SkMemoryStream(alphaRowBytes * srcRect.height());
46 uint8_t* dst = (uint8_t*)image->getMemoryBase(); 91 uint8_t* dst = (uint8_t*)image->getMemoryBase();
47 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); 92 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase();
48 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { 93 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
49 uint16_t* src = bitmap.getAddr16(0, y); 94 uint16_t* src = bitmap.getAddr16(0, y);
50 int x; 95 int x;
51 for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) { 96 for (x = srcRect.fLeft; x + 1 < srcRect.fRight; x += 2) {
52 dst[0] = (SkGetPackedR4444(src[x]) << 4) | 97 uint16_t pixel0 = src[x];
vandebo (ex-Chrome) 2013/08/12 22:20:48 Inline these four variables.
53 SkGetPackedG4444(src[x]); 98 uint16_t pixel1 = src[x + 1];
54 dst[1] = (SkGetPackedB4444(src[x]) << 4) | 99 uint8_t alpha0 = SkGetPackedA4444(pixel0);
55 SkGetPackedR4444(src[x + 1]); 100 uint8_t alpha1 = SkGetPackedA4444(pixel1);
56 dst[2] = (SkGetPackedG4444(src[x + 1]) << 4) | 101 alphaDst[0] = (alpha0 << 4) | alpha1;
57 SkGetPackedB4444(src[x + 1]); 102 if (alphaDst[0] != SK_AlphaOPAQUE) {
58 dst += 3;
59 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4) |
60 SkGetPackedA4444(src[x + 1]);
61 if (alphaDst[0] != 0xFF) {
62 hasAlpha = true; 103 hasAlpha = true;
63 } 104 }
64 if (alphaDst[0]) { 105 if (alphaDst[0]) {
65 isTransparent = false; 106 isTransparent = false;
66 } 107 }
108 unpremultiply_and_pack_argb4444(alpha0, alpha1,
109 pixel0, pixel1,
110 dst);
67 alphaDst++; 111 alphaDst++;
112 dst += 3;
68 } 113 }
69 if (srcRect.width() & 1) { 114 if (srcRect.width() & 1) {
70 dst[0] = (SkGetPackedR4444(src[x]) << 4) | 115 uint16_t pixel = src[x];
71 SkGetPackedG4444(src[x]); 116 uint8_t alpha = SkGetPackedA4444(pixel);
72 dst[1] = (SkGetPackedB4444(src[x]) << 4); 117 alphaDst[0] = (alpha << 4);
73 dst += 2; 118 // Use a buffer to translate from the usual 2 4444 values
74 alphaDst[0] = (SkGetPackedA4444(src[x]) << 4); 119 // in 12 bytes to the single 4444 value in 2 bytes.
120 uint8_t buffer[3];
75 if (alphaDst[0] != 0xF0) { 121 if (alphaDst[0] != 0xF0) {
76 hasAlpha = true; 122 hasAlpha = true;
77 } 123 }
78 if (alphaDst[0] & 0xF0) { 124 if (alphaDst[0] & 0xF0) {
79 isTransparent = false; 125 isTransparent = false;
80 } 126 }
127 unpremultiply_and_pack_argb4444(alpha, 0x0F, pixel, 0x00,
128 buffer);
129 dst[0] = buffer[0];
130 dst[1] = buffer[1];
131
81 alphaDst++; 132 alphaDst++;
133 dst += 2;
82 } 134 }
83 } 135 }
84 break; 136 break;
85 } 137 }
86 case SkBitmap::kRGB_565_Config: { 138 case SkBitmap::kRGB_565_Config: {
87 const int rowBytes = srcRect.width() * 3; 139 const int rowBytes = srcRect.width() * 3;
88 image = new SkMemoryStream(rowBytes * srcRect.height()); 140 image = new SkMemoryStream(rowBytes * srcRect.height());
89 uint8_t* dst = (uint8_t*)image->getMemoryBase(); 141 uint8_t* dst = (uint8_t*)image->getMemoryBase();
90 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { 142 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
91 uint16_t* src = bitmap.getAddr16(0, y); 143 uint16_t* src = bitmap.getAddr16(0, y);
92 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { 144 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
93 dst[0] = SkGetPackedR16(src[x]); 145 dst[0] = SkGetPackedR16(src[x]);
94 dst[1] = SkGetPackedG16(src[x]); 146 dst[1] = SkGetPackedG16(src[x]);
95 dst[2] = SkGetPackedB16(src[x]); 147 dst[2] = SkGetPackedB16(src[x]);
96 dst += 3; 148 dst += 3;
97 } 149 }
98 } 150 }
99 break; 151 break;
100 } 152 }
101 case SkBitmap::kARGB_8888_Config: { 153 case SkBitmap::kARGB_8888_Config: {
102 isTransparent = true; 154 isTransparent = true;
103 const int rowBytes = srcRect.width() * 3; 155 const int rowBytes = srcRect.width() * 3;
104 image = new SkMemoryStream(rowBytes * srcRect.height()); 156 image = new SkMemoryStream(rowBytes * srcRect.height());
105 alpha = new SkMemoryStream(srcRect.width() * srcRect.height()); 157 alpha = new SkMemoryStream(srcRect.width() * srcRect.height());
106 uint8_t* dst = (uint8_t*)image->getMemoryBase(); 158 uint8_t* dst = (uint8_t*)image->getMemoryBase();
107 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase(); 159 uint8_t* alphaDst = (uint8_t*)alpha->getMemoryBase();
108 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { 160 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
109 uint32_t* src = bitmap.getAddr32(0, y); 161 uint32_t* src = bitmap.getAddr32(0, y);
110 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { 162 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
111 dst[0] = SkGetPackedR32(src[x]); 163 uint32_t pixel = src[x];
112 dst[1] = SkGetPackedG32(src[x]); 164 alphaDst[0] = SkGetPackedA32(pixel);
113 dst[2] = SkGetPackedB32(src[x]); 165 if (alphaDst[0] != SK_AlphaOPAQUE) {
114 dst += 3;
115 alphaDst[0] = SkGetPackedA32(src[x]);
116 if (alphaDst[0] != 0xFF) {
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(alphaDst[0], pixel, 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