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

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

Issue 2037083002: SkPDF: handle unpremul right (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2016-06-03 (Friday) 11:32:03 EDT Created 4 years, 6 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
« no previous file with comments | « no previous file | 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 2015 Google Inc. 2 * Copyright 2015 Google Inc.
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 "SkColorPriv.h" 8 #include "SkColorPriv.h"
9 #include "SkData.h" 9 #include "SkData.h"
10 #include "SkDeflate.h" 10 #include "SkDeflate.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 static U8CPU SkGetR32Component(uint32_t value, SkColorType ct) { 85 static U8CPU SkGetR32Component(uint32_t value, SkColorType ct) {
86 return (value >> (SkIsBGRA(ct) ? SK_BGRA_R32_SHIFT : SK_RGBA_R32_SHIFT)) & 0 xFF; 86 return (value >> (SkIsBGRA(ct) ? SK_BGRA_R32_SHIFT : SK_RGBA_R32_SHIFT)) & 0 xFF;
87 } 87 }
88 static U8CPU SkGetG32Component(uint32_t value, SkColorType ct) { 88 static U8CPU SkGetG32Component(uint32_t value, SkColorType ct) {
89 return (value >> (SkIsBGRA(ct) ? SK_BGRA_G32_SHIFT : SK_RGBA_G32_SHIFT)) & 0 xFF; 89 return (value >> (SkIsBGRA(ct) ? SK_BGRA_G32_SHIFT : SK_RGBA_G32_SHIFT)) & 0 xFF;
90 } 90 }
91 static U8CPU SkGetB32Component(uint32_t value, SkColorType ct) { 91 static U8CPU SkGetB32Component(uint32_t value, SkColorType ct) {
92 return (value >> (SkIsBGRA(ct) ? SK_BGRA_B32_SHIFT : SK_RGBA_B32_SHIFT)) & 0 xFF; 92 return (value >> (SkIsBGRA(ct) ? SK_BGRA_B32_SHIFT : SK_RGBA_B32_SHIFT)) & 0 xFF;
93 } 93 }
94 94
95
96 // unpremultiply and extract R, G, B components. 95 // unpremultiply and extract R, G, B components.
97 static void pmcolor_to_rgb24(uint32_t color, uint8_t* rgb, SkColorType ct) { 96 static void pmcolor_to_rgb24(uint32_t color, uint8_t* rgb, SkColorType ct) {
98 uint32_t s = SkUnPreMultiply::GetScale(SkGetA32Component(color, ct)); 97 uint32_t s = SkUnPreMultiply::GetScale(SkGetA32Component(color, ct));
99 rgb[0] = SkUnPreMultiply::ApplyScale(s, SkGetR32Component(color, ct)); 98 rgb[0] = SkUnPreMultiply::ApplyScale(s, SkGetR32Component(color, ct));
100 rgb[1] = SkUnPreMultiply::ApplyScale(s, SkGetG32Component(color, ct)); 99 rgb[1] = SkUnPreMultiply::ApplyScale(s, SkGetG32Component(color, ct));
101 rgb[2] = SkUnPreMultiply::ApplyScale(s, SkGetB32Component(color, ct)); 100 rgb[2] = SkUnPreMultiply::ApplyScale(s, SkGetB32Component(color, ct));
102 } 101 }
103 102
104 /* It is necessary to average the color component of transparent 103 /* It is necessary to average the color component of transparent
105 pixels with their surrounding neighbors since the PDF renderer may 104 pixels with their surrounding neighbors since the PDF renderer may
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 if (!bitmap.getPixels()) { 175 if (!bitmap.getPixels()) {
177 size_t size = pixel_count(bitmap) * 176 size_t size = pixel_count(bitmap) *
178 pdf_color_component_count(bitmap.colorType()); 177 pdf_color_component_count(bitmap.colorType());
179 fill_stream(out, '\x00', size); 178 fill_stream(out, '\x00', size);
180 return; 179 return;
181 } 180 }
182 SkBitmap copy; 181 SkBitmap copy;
183 const SkBitmap& bm = not4444(bitmap, &copy); 182 const SkBitmap& bm = not4444(bitmap, &copy);
184 SkAutoLockPixels autoLockPixels(bm); 183 SkAutoLockPixels autoLockPixels(bm);
185 SkColorType colorType = bm.colorType(); 184 SkColorType colorType = bm.colorType();
185 SkAlphaType alphaType = bm.alphaType();
186 switch (colorType) { 186 switch (colorType) {
187 case kRGBA_8888_SkColorType: 187 case kRGBA_8888_SkColorType:
188 case kBGRA_8888_SkColorType: { 188 case kBGRA_8888_SkColorType: {
189 SkASSERT(3 == pdf_color_component_count(colorType)); 189 SkASSERT(3 == pdf_color_component_count(colorType));
190 SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); 190 SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
191 for (int y = 0; y < bm.height(); ++y) { 191 for (int y = 0; y < bm.height(); ++y) {
192 const uint32_t* src = bm.getAddr32(0, y); 192 const uint32_t* src = bm.getAddr32(0, y);
193 uint8_t* dst = scanline.get(); 193 uint8_t* dst = scanline.get();
194 for (int x = 0; x < bm.width(); ++x) { 194 for (int x = 0; x < bm.width(); ++x) {
195 uint32_t color = *src++; 195 if (alphaType == kPremul_SkAlphaType) {
196 U8CPU alpha = SkGetA32Component(color, colorType); 196 uint32_t color = *src++;
197 if (alpha != SK_AlphaTRANSPARENT) { 197 U8CPU alpha = SkGetA32Component(color, colorType);
198 pmcolor_to_rgb24(color, dst, colorType); 198 if (alpha != SK_AlphaTRANSPARENT) {
199 pmcolor_to_rgb24(color, dst, colorType);
200 } else {
201 get_neighbor_avg_color(bm, x, y, dst, colorType);
202 }
203 dst += 3;
199 } else { 204 } else {
200 get_neighbor_avg_color(bm, x, y, dst, colorType); 205 uint32_t color = *src++;
206 *dst++ = SkGetR32Component(color, colorType);
207 *dst++ = SkGetG32Component(color, colorType);
208 *dst++ = SkGetB32Component(color, colorType);
201 } 209 }
202 dst += 3;
203 } 210 }
204 out->write(scanline.get(), 3 * bm.width()); 211 out->write(scanline.get(), 3 * bm.width());
205 } 212 }
206 return; 213 return;
207 } 214 }
208 case kRGB_565_SkColorType: { 215 case kRGB_565_SkColorType: {
209 SkASSERT(3 == pdf_color_component_count(colorType)); 216 SkASSERT(3 == pdf_color_component_count(colorType));
210 SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); 217 SkAutoTMalloc<uint8_t> scanline(3 * bm.width());
211 for (int y = 0; y < bm.height(); ++y) { 218 for (int y = 0; y < bm.height(); ++y) {
212 const uint16_t* src = bm.getAddr16(0, y); 219 const uint16_t* src = bm.getAddr16(0, y);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 return; 297 return;
291 case kARGB_4444_SkColorType: 298 case kARGB_4444_SkColorType:
292 SkDEBUGFAIL("4444 color type should have been converted to N32"); 299 SkDEBUGFAIL("4444 color type should have been converted to N32");
293 return; 300 return;
294 case kUnknown_SkColorType: 301 case kUnknown_SkColorType:
295 default: 302 default:
296 SkDEBUGFAIL("unexpected color type"); 303 SkDEBUGFAIL("unexpected color type");
297 } 304 }
298 } 305 }
299 306
300 static sk_sp<SkPDFArray> make_indexed_color_space(const SkColorTable* table) { 307 static sk_sp<SkPDFArray> make_indexed_color_space(
308 const SkColorTable* table,
309 SkAlphaType alphaType) {
301 auto result = sk_make_sp<SkPDFArray>(); 310 auto result = sk_make_sp<SkPDFArray>();
302 result->reserve(4); 311 result->reserve(4);
303 result->appendName("Indexed"); 312 result->appendName("Indexed");
304 result->appendName("DeviceRGB"); 313 result->appendName("DeviceRGB");
305 SkASSERT(table); 314 SkASSERT(table);
306 if (table->count() < 1) { 315 if (table->count() < 1) {
307 result->appendInt(0); 316 result->appendInt(0);
308 char shortTableArray[3] = {0, 0, 0}; 317 char shortTableArray[3] = {0, 0, 0};
309 SkString tableString(shortTableArray, SK_ARRAY_COUNT(shortTableArray)); 318 SkString tableString(shortTableArray, SK_ARRAY_COUNT(shortTableArray));
310 result->appendString(tableString); 319 result->appendString(tableString);
311 return result; 320 return result;
312 } 321 }
313 result->appendInt(table->count() - 1); // maximum color index. 322 result->appendInt(table->count() - 1); // maximum color index.
314 323
315 // Potentially, this could be represented in fewer bytes with a stream. 324 // Potentially, this could be represented in fewer bytes with a stream.
316 // Max size as a string is 1.5k. 325 // Max size as a string is 1.5k.
317 char tableArray[256 * 3]; 326 char tableArray[256 * 3];
318 SkASSERT(3u * table->count() <= SK_ARRAY_COUNT(tableArray)); 327 SkASSERT(3u * table->count() <= SK_ARRAY_COUNT(tableArray));
319 uint8_t* tablePtr = reinterpret_cast<uint8_t*>(tableArray); 328 uint8_t* tablePtr = reinterpret_cast<uint8_t*>(tableArray);
320 const SkPMColor* colors = table->readColors(); 329 const SkPMColor* colors = table->readColors();
321 for (int i = 0; i < table->count(); i++) { 330 for (int i = 0; i < table->count(); i++) {
322 pmcolor_to_rgb24(colors[i], tablePtr, kN32_SkColorType); 331 if (alphaType == kPremul_SkAlphaType) {
323 tablePtr += 3; 332 pmcolor_to_rgb24(colors[i], tablePtr, kN32_SkColorType);
333 tablePtr += 3;
334 } else {
335 *tablePtr++ = SkGetR32Component(colors[i], kN32_SkColorType);
336 *tablePtr++ = SkGetG32Component(colors[i], kN32_SkColorType);
337 *tablePtr++ = SkGetB32Component(colors[i], kN32_SkColorType);
338 }
324 } 339 }
325 SkString tableString(tableArray, 3 * table->count()); 340 SkString tableString(tableArray, 3 * table->count());
326 result->appendString(tableString); 341 result->appendString(tableString);
327 return result; 342 return result;
328 } 343 }
329 344
330 static void emit_image_xobject(SkWStream* stream, 345 static void emit_image_xobject(SkWStream* stream,
331 const SkImage* image, 346 const SkImage* image,
332 bool alpha, 347 bool alpha,
333 const sk_sp<SkPDFObject>& smask, 348 const sk_sp<SkPDFObject>& smask,
(...skipping 16 matching lines...) Expand all
350 365
351 SkPDFDict pdfDict("XObject"); 366 SkPDFDict pdfDict("XObject");
352 pdfDict.insertName("Subtype", "Image"); 367 pdfDict.insertName("Subtype", "Image");
353 pdfDict.insertInt("Width", bitmap.width()); 368 pdfDict.insertInt("Width", bitmap.width());
354 pdfDict.insertInt("Height", bitmap.height()); 369 pdfDict.insertInt("Height", bitmap.height());
355 if (alpha) { 370 if (alpha) {
356 pdfDict.insertName("ColorSpace", "DeviceGray"); 371 pdfDict.insertName("ColorSpace", "DeviceGray");
357 } else if (bitmap.colorType() == kIndex_8_SkColorType) { 372 } else if (bitmap.colorType() == kIndex_8_SkColorType) {
358 SkASSERT(1 == pdf_color_component_count(bitmap.colorType())); 373 SkASSERT(1 == pdf_color_component_count(bitmap.colorType()));
359 pdfDict.insertObject("ColorSpace", 374 pdfDict.insertObject("ColorSpace",
360 make_indexed_color_space(bitmap.getColorTable())); 375 make_indexed_color_space(bitmap.getColorTable(),
376 bitmap.alphaType()));
361 } else if (1 == pdf_color_component_count(bitmap.colorType())) { 377 } else if (1 == pdf_color_component_count(bitmap.colorType())) {
362 pdfDict.insertName("ColorSpace", "DeviceGray"); 378 pdfDict.insertName("ColorSpace", "DeviceGray");
363 } else { 379 } else {
364 pdfDict.insertName("ColorSpace", "DeviceRGB"); 380 pdfDict.insertName("ColorSpace", "DeviceRGB");
365 } 381 }
366 if (smask) { 382 if (smask) {
367 pdfDict.insertObjRef("SMask", smask); 383 pdfDict.insertObjRef("SMask", smask);
368 } 384 }
369 pdfDict.insertInt("BitsPerComponent", 8); 385 pdfDict.insertInt("BitsPerComponent", 8);
370 pdfDict.insertName("Filter", "FlateDecode"); 386 pdfDict.insertName("Filter", "FlateDecode");
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 527
512 sk_sp<SkPDFObject> smask; 528 sk_sp<SkPDFObject> smask;
513 if (!image_compute_is_opaque(image.get())) { 529 if (!image_compute_is_opaque(image.get())) {
514 smask = sk_make_sp<PDFAlphaBitmap>(image); 530 smask = sk_make_sp<PDFAlphaBitmap>(image);
515 } 531 }
516 #ifdef SK_PDF_IMAGE_STATS 532 #ifdef SK_PDF_IMAGE_STATS
517 gRegularImageObjects.fetch_add(1); 533 gRegularImageObjects.fetch_add(1);
518 #endif 534 #endif
519 return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask)); 535 return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask));
520 } 536 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698