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

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

Issue 305133006: use colortype instead of config (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/opts/SkBlitMask_opts_arm.cpp ('k') | src/utils/SkBitmapHasher.h » ('j') | 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 "SkData.h" 13 #include "SkData.h"
14 #include "SkFlate.h" 14 #include "SkFlate.h"
15 #include "SkPDFCatalog.h" 15 #include "SkPDFCatalog.h"
16 #include "SkRect.h" 16 #include "SkRect.h"
17 #include "SkStream.h" 17 #include "SkStream.h"
18 #include "SkString.h" 18 #include "SkString.h"
19 #include "SkUnPreMultiply.h" 19 #include "SkUnPreMultiply.h"
20 20
21 static const int kNoColorTransform = 0; 21 static const int kNoColorTransform = 0;
22 22
23 static bool skip_compression(SkPDFCatalog* catalog) { 23 static bool skip_compression(SkPDFCatalog* catalog) {
24 return SkToBool(catalog->getDocumentFlags() & 24 return SkToBool(catalog->getDocumentFlags() &
25 SkPDFDocument::kFavorSpeedOverSize_Flags); 25 SkPDFDocument::kFavorSpeedOverSize_Flags);
26 } 26 }
27 27
28 static size_t get_uncompressed_size(const SkBitmap& bitmap, 28 static size_t get_uncompressed_size(const SkBitmap& bitmap,
29 const SkIRect& srcRect) { 29 const SkIRect& srcRect) {
30 switch (bitmap.config()) { 30 switch (bitmap.colorType()) {
31 case SkBitmap::kIndex8_Config: 31 case kIndex_8_SkColorType:
32 return srcRect.width() * srcRect.height(); 32 return srcRect.width() * srcRect.height();
33 case SkBitmap::kARGB_4444_Config: 33 case kARGB_4444_SkColorType:
34 return ((srcRect.width() * 3 + 1) / 2) * srcRect.height(); 34 return ((srcRect.width() * 3 + 1) / 2) * srcRect.height();
35 case SkBitmap::kRGB_565_Config: 35 case kRGB_565_SkColorType:
36 return srcRect.width() * 3 * srcRect.height(); 36 return srcRect.width() * 3 * srcRect.height();
37 case SkBitmap::kARGB_8888_Config: 37 case kRGBA_8888_SkColorType:
38 case kBGRA_8888_SkColorType:
38 return srcRect.width() * 3 * srcRect.height(); 39 return srcRect.width() * 3 * srcRect.height();
39 case SkBitmap::kA8_Config: 40 case kAlpha_8_SkColorType:
40 return 1; 41 return 1;
41 default: 42 default:
42 SkASSERT(false); 43 SkASSERT(false);
43 return 0; 44 return 0;
44 } 45 }
45 } 46 }
46 47
47 static SkStream* extract_index8_image(const SkBitmap& bitmap, 48 static SkStream* extract_index8_image(const SkBitmap& bitmap,
48 const SkIRect& srcRect) { 49 const SkIRect& srcRect) {
49 const int rowBytes = srcRect.width(); 50 const int rowBytes = srcRect.width();
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 * @param isTransparent Pointer to a bool to output whether the alpha is 202 * @param isTransparent Pointer to a bool to output whether the alpha is
202 * completely transparent. May be NULL. Only valid when 203 * completely transparent. May be NULL. Only valid when
203 * extractAlpha == true. 204 * extractAlpha == true.
204 * @return Unencoded image data, or NULL if either data was not 205 * @return Unencoded image data, or NULL if either data was not
205 * available or alpha data was requested but the image was 206 * available or alpha data was requested but the image was
206 * entirely transparent or opaque. 207 * entirely transparent or opaque.
207 */ 208 */
208 static SkStream* extract_image_data(const SkBitmap& bitmap, 209 static SkStream* extract_image_data(const SkBitmap& bitmap,
209 const SkIRect& srcRect, 210 const SkIRect& srcRect,
210 bool extractAlpha, bool* isTransparent) { 211 bool extractAlpha, bool* isTransparent) {
211 SkBitmap::Config config = bitmap.config(); 212 SkColorType colorType = bitmap.colorType();
212 if (extractAlpha && (config == SkBitmap::kIndex8_Config || 213 if (extractAlpha && (kIndex_8_SkColorType == colorType ||
213 config == SkBitmap::kRGB_565_Config)) { 214 kRGB_565_SkColorType == colorType)) {
214 if (isTransparent != NULL) { 215 if (isTransparent != NULL) {
215 *isTransparent = false; 216 *isTransparent = false;
216 } 217 }
217 return NULL; 218 return NULL;
218 } 219 }
219 bool isOpaque = true; 220 bool isOpaque = true;
220 bool transparent = extractAlpha; 221 bool transparent = extractAlpha;
221 SkStream* stream = NULL; 222 SkStream* stream = NULL;
222 223
223 bitmap.lockPixels(); 224 bitmap.lockPixels();
224 switch (config) { 225 switch (colorType) {
225 case SkBitmap::kIndex8_Config: 226 case kIndex_8_SkColorType:
226 if (!extractAlpha) { 227 if (!extractAlpha) {
227 stream = extract_index8_image(bitmap, srcRect); 228 stream = extract_index8_image(bitmap, srcRect);
228 } 229 }
229 break; 230 break;
230 case SkBitmap::kARGB_4444_Config: 231 case kARGB_4444_SkColorType:
231 stream = extract_argb4444_data(bitmap, srcRect, extractAlpha, 232 stream = extract_argb4444_data(bitmap, srcRect, extractAlpha,
232 &isOpaque, &transparent); 233 &isOpaque, &transparent);
233 break; 234 break;
234 case SkBitmap::kRGB_565_Config: 235 case kRGB_565_SkColorType:
235 if (!extractAlpha) { 236 if (!extractAlpha) {
236 stream = extract_rgb565_image(bitmap, srcRect); 237 stream = extract_rgb565_image(bitmap, srcRect);
237 } 238 }
238 break; 239 break;
239 case SkBitmap::kARGB_8888_Config: 240 case kN32_SkColorType:
240 stream = extract_argb8888_data(bitmap, srcRect, extractAlpha, 241 stream = extract_argb8888_data(bitmap, srcRect, extractAlpha,
241 &isOpaque, &transparent); 242 &isOpaque, &transparent);
242 break; 243 break;
243 case SkBitmap::kA8_Config: 244 case kAlpha_8_SkColorType:
244 if (!extractAlpha) { 245 if (!extractAlpha) {
245 stream = create_black_image(); 246 stream = create_black_image();
246 } else { 247 } else {
247 stream = extract_a8_alpha(bitmap, srcRect, 248 stream = extract_a8_alpha(bitmap, srcRect,
248 &isOpaque, &transparent); 249 &isOpaque, &transparent);
249 } 250 }
250 break; 251 break;
251 default: 252 default:
252 SkASSERT(false); 253 SkASSERT(false);
253 } 254 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, 0, 0, 0); 367 return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, 0, 0, 0);
367 } else { 368 } else {
368 return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F, 369 return SkPackARGB4444(SK_AlphaOPAQUE & 0x0F,
369 r / count, g / count, b / count); 370 r / count, g / count, b / count);
370 } 371 }
371 } 372 }
372 373
373 static SkBitmap unpremultiply_bitmap(const SkBitmap& bitmap, 374 static SkBitmap unpremultiply_bitmap(const SkBitmap& bitmap,
374 const SkIRect& srcRect) { 375 const SkIRect& srcRect) {
375 SkBitmap outBitmap; 376 SkBitmap outBitmap;
376 outBitmap.setConfig(bitmap.config(), srcRect.width(), srcRect.height()); 377 outBitmap.allocPixels(bitmap.info().makeWH(srcRect.width(), srcRect.height() ));
377 outBitmap.allocPixels();
378 int dstRow = 0; 378 int dstRow = 0;
379 379
380 outBitmap.lockPixels(); 380 outBitmap.lockPixels();
381 bitmap.lockPixels(); 381 bitmap.lockPixels();
382 switch (bitmap.config()) { 382 switch (bitmap.colorType()) {
383 case SkBitmap::kARGB_4444_Config: { 383 case kARGB_4444_SkColorType: {
384 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { 384 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
385 uint16_t* dst = outBitmap.getAddr16(0, dstRow); 385 uint16_t* dst = outBitmap.getAddr16(0, dstRow);
386 uint16_t* src = bitmap.getAddr16(0, y); 386 uint16_t* src = bitmap.getAddr16(0, y);
387 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { 387 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
388 uint8_t a = SkGetPackedA4444(src[x]); 388 uint8_t a = SkGetPackedA4444(src[x]);
389 // It is necessary to average the color component of 389 // It is necessary to average the color component of
390 // transparent pixels with their surrounding neighbors 390 // transparent pixels with their surrounding neighbors
391 // since the PDF renderer may separately re-sample the 391 // since the PDF renderer may separately re-sample the
392 // alpha and color channels when the image is not 392 // alpha and color channels when the image is not
393 // displayed at its native resolution. Since an alpha of 393 // displayed at its native resolution. Since an alpha of
394 // zero gives no information about the color component, 394 // zero gives no information about the color component,
395 // the pathological case is a white image with sharp 395 // the pathological case is a white image with sharp
396 // transparency bounds - the color channel goes to black, 396 // transparency bounds - the color channel goes to black,
397 // and the should-be-transparent pixels are rendered 397 // and the should-be-transparent pixels are rendered
398 // as grey because of the separate soft mask and color 398 // as grey because of the separate soft mask and color
399 // resizing. 399 // resizing.
400 if (a == (SK_AlphaTRANSPARENT & 0x0F)) { 400 if (a == (SK_AlphaTRANSPARENT & 0x0F)) {
401 *dst = get_argb4444_neighbor_avg_color(bitmap, x, y); 401 *dst = get_argb4444_neighbor_avg_color(bitmap, x, y);
402 } else { 402 } else {
403 *dst = remove_alpha_argb4444(src[x]); 403 *dst = remove_alpha_argb4444(src[x]);
404 } 404 }
405 dst++; 405 dst++;
406 } 406 }
407 dstRow++; 407 dstRow++;
408 } 408 }
409 break; 409 break;
410 } 410 }
411 case SkBitmap::kARGB_8888_Config: { 411 case kN32_SkColorType: {
412 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) { 412 for (int y = srcRect.fTop; y < srcRect.fBottom; y++) {
413 uint32_t* dst = outBitmap.getAddr32(0, dstRow); 413 uint32_t* dst = outBitmap.getAddr32(0, dstRow);
414 uint32_t* src = bitmap.getAddr32(0, y); 414 uint32_t* src = bitmap.getAddr32(0, y);
415 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) { 415 for (int x = srcRect.fLeft; x < srcRect.fRight; x++) {
416 uint8_t a = SkGetPackedA32(src[x]); 416 uint8_t a = SkGetPackedA32(src[x]);
417 if (a == SK_AlphaTRANSPARENT) { 417 if (a == SK_AlphaTRANSPARENT) {
418 *dst = get_argb8888_neighbor_avg_color(bitmap, x, y); 418 *dst = get_argb8888_neighbor_avg_color(bitmap, x, y);
419 } else { 419 } else {
420 *dst = remove_alpha_argb8888(src[x]); 420 *dst = remove_alpha_argb8888(src[x]);
421 } 421 }
(...skipping 11 matching lines...) Expand all
433 433
434 outBitmap.setImmutable(); 434 outBitmap.setImmutable();
435 435
436 return outBitmap; 436 return outBitmap;
437 } 437 }
438 438
439 // static 439 // static
440 SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap, 440 SkPDFImage* SkPDFImage::CreateImage(const SkBitmap& bitmap,
441 const SkIRect& srcRect, 441 const SkIRect& srcRect,
442 SkPicture::EncodeBitmap encoder) { 442 SkPicture::EncodeBitmap encoder) {
443 if (bitmap.config() == SkBitmap::kNo_Config) { 443 if (bitmap.colorType() == kUnknown_SkColorType) {
444 return NULL; 444 return NULL;
445 } 445 }
446 446
447 bool isTransparent = false; 447 bool isTransparent = false;
448 SkAutoTUnref<SkStream> alphaData; 448 SkAutoTUnref<SkStream> alphaData;
449 if (!bitmap.isOpaque()) { 449 if (!bitmap.isOpaque()) {
450 // Note that isOpaque is not guaranteed to return false for bitmaps 450 // Note that isOpaque is not guaranteed to return false for bitmaps
451 // with alpha support but a completely opaque alpha channel, 451 // with alpha support but a completely opaque alpha channel,
452 // so alphaData may still be NULL if we have a completely opaque 452 // so alphaData may still be NULL if we have a completely opaque
453 // (or transparent) bitmap. 453 // (or transparent) bitmap.
454 alphaData.reset( 454 alphaData.reset(
455 extract_image_data(bitmap, srcRect, true, &isTransparent)); 455 extract_image_data(bitmap, srcRect, true, &isTransparent));
456 } 456 }
457 if (isTransparent) { 457 if (isTransparent) {
458 return NULL; 458 return NULL;
459 } 459 }
460 460
461 SkPDFImage* image; 461 SkPDFImage* image;
462 SkBitmap::Config config = bitmap.config(); 462 SkColorType colorType = bitmap.colorType();
463 if (alphaData.get() != NULL && (config == SkBitmap::kARGB_8888_Config || 463 if (alphaData.get() != NULL && (kN32_SkColorType == colorType ||
464 config == SkBitmap::kARGB_4444_Config)) { 464 kARGB_4444_SkColorType == colorType)) {
465 SkBitmap unpremulBitmap = unpremultiply_bitmap(bitmap, srcRect); 465 SkBitmap unpremulBitmap = unpremultiply_bitmap(bitmap, srcRect);
466 image = SkNEW_ARGS(SkPDFImage, (NULL, unpremulBitmap, false, 466 image = SkNEW_ARGS(SkPDFImage, (NULL, unpremulBitmap, false,
467 SkIRect::MakeWH(srcRect.width(), srcRect.height()), 467 SkIRect::MakeWH(srcRect.width(), srcRect.height()),
468 encoder)); 468 encoder));
469 } else { 469 } else {
470 image = SkNEW_ARGS(SkPDFImage, (NULL, bitmap, false, srcRect, encoder)); 470 image = SkNEW_ARGS(SkPDFImage, (NULL, bitmap, false, srcRect, encoder));
471 } 471 }
472 if (alphaData.get() != NULL) { 472 if (alphaData.get() != NULL) {
473 SkAutoTUnref<SkPDFImage> mask( 473 SkAutoTUnref<SkPDFImage> mask(
474 SkNEW_ARGS(SkPDFImage, (alphaData.get(), bitmap, 474 SkNEW_ARGS(SkPDFImage, (alphaData.get(), bitmap,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 fBitmap.setImmutable(); 511 fBitmap.setImmutable();
512 } 512 }
513 513
514 if (stream != NULL) { 514 if (stream != NULL) {
515 setData(stream); 515 setData(stream);
516 fStreamValid = true; 516 fStreamValid = true;
517 } else { 517 } else {
518 fStreamValid = false; 518 fStreamValid = false;
519 } 519 }
520 520
521 SkBitmap::Config config = fBitmap.config(); 521 SkColorType colorType = fBitmap.colorType();
522 522
523 insertName("Type", "XObject"); 523 insertName("Type", "XObject");
524 insertName("Subtype", "Image"); 524 insertName("Subtype", "Image");
525 525
526 bool alphaOnly = (config == SkBitmap::kA8_Config); 526 bool alphaOnly = (kAlpha_8_SkColorType == colorType);
527 527
528 if (!isAlpha && alphaOnly) { 528 if (!isAlpha && alphaOnly) {
529 // For alpha only images, we stretch a single pixel of black for 529 // For alpha only images, we stretch a single pixel of black for
530 // the color/shape part. 530 // the color/shape part.
531 SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1)); 531 SkAutoTUnref<SkPDFInt> one(new SkPDFInt(1));
532 insert("Width", one.get()); 532 insert("Width", one.get());
533 insert("Height", one.get()); 533 insert("Height", one.get());
534 } else { 534 } else {
535 insertInt("Width", fSrcRect.width()); 535 insertInt("Width", fSrcRect.width());
536 insertInt("Height", fSrcRect.height()); 536 insertInt("Height", fSrcRect.height());
537 } 537 }
538 538
539 if (isAlpha || alphaOnly) { 539 if (isAlpha || alphaOnly) {
540 insertName("ColorSpace", "DeviceGray"); 540 insertName("ColorSpace", "DeviceGray");
541 } else if (config == SkBitmap::kIndex8_Config) { 541 } else if (kIndex_8_SkColorType == colorType) {
542 SkAutoLockPixels alp(fBitmap); 542 SkAutoLockPixels alp(fBitmap);
543 insert("ColorSpace", 543 insert("ColorSpace",
544 make_indexed_color_space(fBitmap.getColorTable()))->unref(); 544 make_indexed_color_space(fBitmap.getColorTable()))->unref();
545 } else { 545 } else {
546 insertName("ColorSpace", "DeviceRGB"); 546 insertName("ColorSpace", "DeviceRGB");
547 } 547 }
548 548
549 int bitsPerComp = 8; 549 int bitsPerComp = 8;
550 if (config == SkBitmap::kARGB_4444_Config) { 550 if (kARGB_4444_SkColorType == colorType) {
551 bitsPerComp = 4; 551 bitsPerComp = 4;
552 } 552 }
553 insertInt("BitsPerComponent", bitsPerComp); 553 insertInt("BitsPerComponent", bitsPerComp);
554 554
555 if (config == SkBitmap::kRGB_565_Config) { 555 if (kRGB_565_SkColorType == colorType) {
556 SkASSERT(!isAlpha); 556 SkASSERT(!isAlpha);
557 SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0)); 557 SkAutoTUnref<SkPDFInt> zeroVal(new SkPDFInt(0));
558 SkAutoTUnref<SkPDFScalar> scale5Val( 558 SkAutoTUnref<SkPDFScalar> scale5Val(
559 new SkPDFScalar(8.2258f)); // 255/2^5-1 559 new SkPDFScalar(8.2258f)); // 255/2^5-1
560 SkAutoTUnref<SkPDFScalar> scale6Val( 560 SkAutoTUnref<SkPDFScalar> scale6Val(
561 new SkPDFScalar(4.0476f)); // 255/2^6-1 561 new SkPDFScalar(4.0476f)); // 255/2^6-1
562 SkAutoTUnref<SkPDFArray> decodeValue(new SkPDFArray()); 562 SkAutoTUnref<SkPDFArray> decodeValue(new SkPDFArray());
563 decodeValue->reserve(6); 563 decodeValue->reserve(6);
564 decodeValue->append(zeroVal.get()); 564 decodeValue->append(zeroVal.get());
565 decodeValue->append(scale5Val.get()); 565 decodeValue->append(scale5Val.get());
(...skipping 19 matching lines...) Expand all
585 585
586 bool SkPDFImage::populate(SkPDFCatalog* catalog) { 586 bool SkPDFImage::populate(SkPDFCatalog* catalog) {
587 if (getState() == kUnused_State) { 587 if (getState() == kUnused_State) {
588 // Initializing image data for the first time. 588 // Initializing image data for the first time.
589 SkDynamicMemoryWStream dctCompressedWStream; 589 SkDynamicMemoryWStream dctCompressedWStream;
590 if (!skip_compression(catalog) && fEncoder && 590 if (!skip_compression(catalog) && fEncoder &&
591 get_uncompressed_size(fBitmap, fSrcRect) > 1) { 591 get_uncompressed_size(fBitmap, fSrcRect) > 1) {
592 SkBitmap subset; 592 SkBitmap subset;
593 // Extract subset 593 // Extract subset
594 if (!fBitmap.extractSubset(&subset, fSrcRect)) { 594 if (!fBitmap.extractSubset(&subset, fSrcRect)) {
595 // TODO(edisonn) It fails only for kA1_Config, if that is a
596 // major concern we will fix it later, so far it is NYI.
597 return false; 595 return false;
598 } 596 }
599 size_t pixelRefOffset = 0; 597 size_t pixelRefOffset = 0;
600 SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset)); 598 SkAutoTUnref<SkData> data(fEncoder(&pixelRefOffset, subset));
601 if (data.get() && data->size() < get_uncompressed_size(fBitmap, 599 if (data.get() && data->size() < get_uncompressed_size(fBitmap,
602 fSrcRect)) { 600 fSrcRect)) {
603 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, 601 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream,
604 (data))); 602 (data)));
605 setData(stream.get()); 603 setData(stream.get());
606 604
(...skipping 19 matching lines...) Expand all
626 // but the new catalog wants it compressed. 624 // but the new catalog wants it compressed.
627 if (!getSubstitute()) { 625 if (!getSubstitute()) {
628 SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this)); 626 SkPDFStream* substitute = SkNEW_ARGS(SkPDFImage, (*this));
629 setSubstitute(substitute); 627 setSubstitute(substitute);
630 catalog->setSubstitute(this, substitute); 628 catalog->setSubstitute(this, substitute);
631 } 629 }
632 return false; 630 return false;
633 } 631 }
634 return true; 632 return true;
635 } 633 }
OLDNEW
« no previous file with comments | « src/opts/SkBlitMask_opts_arm.cpp ('k') | src/utils/SkBitmapHasher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698