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

Side by Side Diff: ui/gfx/codec/png_codec.cc

Issue 2944633002: Use SkPngEncoder in gfx jpeg_codec (Closed)
Patch Set: Nit Created 3 years, 5 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 | « ui/gfx/codec/png_codec.h ('k') | ui/gfx/codec/vector_wstream.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 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/codec/png_codec.h" 5 #include "ui/gfx/codec/png_codec.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "third_party/libpng/png.h" 12 #include "third_party/libpng/png.h"
13 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "third_party/skia/include/core/SkColorPriv.h" 14 #include "third_party/skia/include/core/SkColorPriv.h"
15 #include "third_party/skia/include/core/SkUnPreMultiply.h" 15 #include "third_party/skia/include/core/SkUnPreMultiply.h"
16 #include "third_party/skia/include/encode/SkPngEncoder.h"
16 #include "third_party/zlib/zlib.h" 17 #include "third_party/zlib/zlib.h"
18 #include "ui/gfx/codec/vector_wstream.h"
17 #include "ui/gfx/geometry/size.h" 19 #include "ui/gfx/geometry/size.h"
18 #include "ui/gfx/skia_util.h" 20 #include "ui/gfx/skia_util.h"
19 21
20 namespace gfx { 22 namespace gfx {
21 23
22 namespace {
23
24 // Converts BGRA->RGBA and RGBA->BGRA.
25 void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width,
26 unsigned char* output, bool* is_opaque) {
27 for (int x = 0; x < pixel_width; x++) {
28 const unsigned char* pixel_in = &input[x * 4];
29 unsigned char* pixel_out = &output[x * 4];
30 pixel_out[0] = pixel_in[2];
31 pixel_out[1] = pixel_in[1];
32 pixel_out[2] = pixel_in[0];
33 pixel_out[3] = pixel_in[3];
34 }
35 }
36
37 void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width,
38 unsigned char* rgb, bool* is_opaque) {
39 for (int x = 0; x < pixel_width; x++)
40 memcpy(&rgb[x * 3], &rgba[x * 4], 3);
41 }
42
43 void ConvertSkiaToRGB(const unsigned char* skia, int pixel_width,
44 unsigned char* rgb, bool* is_opaque) {
45 for (int x = 0; x < pixel_width; x++) {
46 const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]);
47 unsigned char* pixel_out = &rgb[x * 3];
48
49 int alpha = SkGetPackedA32(pixel_in);
50 if (alpha != 0 && alpha != 255) {
51 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in);
52 pixel_out[0] = SkColorGetR(unmultiplied);
53 pixel_out[1] = SkColorGetG(unmultiplied);
54 pixel_out[2] = SkColorGetB(unmultiplied);
55 } else {
56 pixel_out[0] = SkGetPackedR32(pixel_in);
57 pixel_out[1] = SkGetPackedG32(pixel_in);
58 pixel_out[2] = SkGetPackedB32(pixel_in);
59 }
60 }
61 }
62
63 void ConvertSkiaToRGBA(const unsigned char* skia, int pixel_width,
64 unsigned char* rgba, bool* is_opaque) {
65 gfx::ConvertSkiaToRGBA(skia, pixel_width, rgba);
66 }
67
68 } // namespace
69
70 // Decoder -------------------------------------------------------------------- 24 // Decoder --------------------------------------------------------------------
71 // 25 //
72 // This code is based on WebKit libpng interface (PNGImageDecoder), which is 26 // This code is based on WebKit libpng interface (PNGImageDecoder), which is
73 // in turn based on the Mozilla png decoder. 27 // in turn based on the Mozilla png decoder.
74 28
75 namespace { 29 namespace {
76 30
77 // Gamma constants: We assume we're on Windows which uses a gamma of 2.2. 31 // Gamma constants: We assume we're on Windows which uses a gamma of 2.2.
78 const double kMaxGamma = 21474.83; // Maximum gamma accepted by png library. 32 const double kMaxGamma = 21474.83; // Maximum gamma accepted by png library.
79 const double kDefaultGamma = 2.2; 33 const double kDefaultGamma = 2.2;
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 316
363 void LogLibPNGDecodeError(png_structp png_ptr, png_const_charp error_msg) { 317 void LogLibPNGDecodeError(png_structp png_ptr, png_const_charp error_msg) {
364 DLOG(ERROR) << "libpng decode error: " << error_msg; 318 DLOG(ERROR) << "libpng decode error: " << error_msg;
365 longjmp(png_jmpbuf(png_ptr), 1); 319 longjmp(png_jmpbuf(png_ptr), 1);
366 } 320 }
367 321
368 void LogLibPNGDecodeWarning(png_structp png_ptr, png_const_charp warning_msg) { 322 void LogLibPNGDecodeWarning(png_structp png_ptr, png_const_charp warning_msg) {
369 DLOG(ERROR) << "libpng decode warning: " << warning_msg; 323 DLOG(ERROR) << "libpng decode warning: " << warning_msg;
370 } 324 }
371 325
372 void LogLibPNGEncodeError(png_structp png_ptr, png_const_charp error_msg) {
373 DLOG(ERROR) << "libpng encode error: " << error_msg;
374 longjmp(png_jmpbuf(png_ptr), 1);
375 }
376
377 void LogLibPNGEncodeWarning(png_structp png_ptr, png_const_charp warning_msg) {
378 DLOG(ERROR) << "libpng encode warning: " << warning_msg;
379 }
380
381 } // namespace 326 } // namespace
382 327
383 // static 328 // static
384 bool PNGCodec::Decode(const unsigned char* input, size_t input_size, 329 bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
385 ColorFormat format, std::vector<unsigned char>* output, 330 ColorFormat format, std::vector<unsigned char>* output,
386 int* w, int* h) { 331 int* w, int* h) {
387 PngReadStructInfo si; 332 PngReadStructInfo si;
388 if (!si.Build(input, input_size)) 333 if (!si.Build(input, input_size))
389 return false; 334 return false;
390 335
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 } 392 }
448 393
449 // Set the bitmap's opaqueness based on what we saw. 394 // Set the bitmap's opaqueness based on what we saw.
450 bitmap->setAlphaType(state.is_opaque ? 395 bitmap->setAlphaType(state.is_opaque ?
451 kOpaque_SkAlphaType : kPremul_SkAlphaType); 396 kOpaque_SkAlphaType : kPremul_SkAlphaType);
452 397
453 return true; 398 return true;
454 } 399 }
455 400
456 // Encoder -------------------------------------------------------------------- 401 // Encoder --------------------------------------------------------------------
457 //
458 // This section of the code is based on nsPNGEncoder.cpp in Mozilla
459 // (Copyright 2005 Google Inc.)
460 402
461 namespace { 403 namespace {
462 404
463 // Passed around as the io_ptr in the png structs so our callbacks know where 405 static void AddComments(SkPngEncoder::Options& options,
464 // to write data. 406 const std::vector<PNGCodec::Comment>& comments) {
465 struct PngEncoderState { 407 std::vector<const char*> comment_pointers;
466 explicit PngEncoderState(std::vector<unsigned char>* o) : out(o) {} 408 std::vector<size_t> comment_sizes;
467 std::vector<unsigned char>* out; 409 for (const auto& comment : comments) {
468 }; 410 comment_pointers.push_back(comment.key.c_str());
469 411 comment_pointers.push_back(comment.text.c_str());
470 // Called by libpng to flush its internal buffer to ours. 412 comment_sizes.push_back(comment.key.length() + 1);
471 void EncoderWriteCallback(png_structp png, png_bytep data, png_size_t size) { 413 comment_sizes.push_back(comment.text.length() + 1);
472 PngEncoderState* state = static_cast<PngEncoderState*>(png_get_io_ptr(png)); 414 }
473 DCHECK(state->out); 415 options.fComments = SkDataTable::MakeCopyArrays(
474 416 (void const* const*)comment_pointers.data(), comment_sizes.data(),
475 size_t old_size = state->out->size(); 417 comment_pointers.size());
476 state->out->resize(old_size + size);
477 memcpy(&(*state->out)[old_size], data, size);
478 } 418 }
479 419
480 void FakeFlushCallback(png_structp png) { 420 } // namespace
481 // We don't need to perform any flushing since we aren't doing real IO, but 421
482 // we're required to provide this function by libpng. 422 static bool EncodeSkPixmap(const SkPixmap& src,
423 const std::vector<PNGCodec::Comment>& comments,
424 std::vector<unsigned char>* output,
425 int zlib_level) {
426 output->clear();
427 VectorWStream dst(output);
428
429 SkPngEncoder::Options options;
430 AddComments(options, comments);
431 options.fZLibLevel = zlib_level;
432 return SkPngEncoder::Encode(&dst, src, options);
483 } 433 }
484 434
485 void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width, 435 static bool EncodeSkPixmap(const SkPixmap& src,
486 unsigned char* rgb, bool* is_opaque) { 436 bool discard_transparency,
487 for (int x = 0; x < pixel_width; x++) { 437 const std::vector<PNGCodec::Comment>& comments,
488 const unsigned char* pixel_in = &bgra[x * 4]; 438 std::vector<unsigned char>* output,
489 unsigned char* pixel_out = &rgb[x * 3]; 439 int zlib_level) {
490 pixel_out[0] = pixel_in[2]; 440 if (discard_transparency) {
491 pixel_out[1] = pixel_in[1]; 441 SkImageInfo opaque_info = src.info().makeAlphaType(kOpaque_SkAlphaType);
492 pixel_out[2] = pixel_in[0]; 442 SkBitmap copy;
443 if (!copy.tryAllocPixels(opaque_info)) {
444 return false;
445 }
446 SkPixmap opaque_pixmap;
447 SkASSERT(copy.peekPixels(&opaque_pixmap));
scroggo_chromium 2017/07/11 16:01:06 This only happens in debug. Maybe you want: bool
liyuqian 2017/07/11 19:24:55 Done.
448 // The following step does the unpremul as we set the dst alpha type to be
449 // kUnpremul_SkAlphaType. Later, because opaque_pixmap has
450 // kOpaque_SkAlphaType, we'll discard the transparency as required.
451 SkASSERT(src.readPixels(opaque_info.makeAlphaType(kUnpremul_SkAlphaType),
scroggo_chromium 2017/07/11 16:01:06 Again, this only happens in debug, and we should b
liyuqian 2017/07/11 19:24:55 Done.
452 opaque_pixmap.writable_addr(),
453 opaque_pixmap.rowBytes()));
454 return EncodeSkPixmap(opaque_pixmap, comments, output, zlib_level);
493 } 455 }
456 return EncodeSkPixmap(src, comments, output, zlib_level);
494 } 457 }
495 458
496 #ifdef PNG_TEXT_SUPPORTED
497 class CommentWriter {
498 public:
499 explicit CommentWriter(const std::vector<PNGCodec::Comment>& comments)
500 : comments_(comments),
501 png_text_(new png_text[comments.size()]) {
502 for (size_t i = 0; i < comments.size(); ++i)
503 AddComment(i, comments[i]);
504 }
505
506 ~CommentWriter() {
507 for (size_t i = 0; i < comments_.size(); ++i) {
508 free(png_text_[i].key);
509 free(png_text_[i].text);
510 }
511 delete [] png_text_;
512 }
513
514 bool HasComments() {
515 return !comments_.empty();
516 }
517
518 png_text* get_png_text() {
519 return png_text_;
520 }
521
522 int size() {
523 return static_cast<int>(comments_.size());
524 }
525
526 private:
527 void AddComment(size_t pos, const PNGCodec::Comment& comment) {
528 png_text_[pos].compression = PNG_TEXT_COMPRESSION_NONE;
529 // A PNG comment's key can only be 79 characters long.
530 DCHECK(comment.key.length() < 79);
531 png_text_[pos].key = base::strdup(comment.key.substr(0, 78).c_str());
532 png_text_[pos].text = base::strdup(comment.text.c_str());
533 png_text_[pos].text_length = comment.text.length();
534 #ifdef PNG_iTXt_SUPPORTED
535 png_text_[pos].itxt_length = 0;
536 png_text_[pos].lang = 0;
537 png_text_[pos].lang_key = 0;
538 #endif
539 }
540
541 DISALLOW_COPY_AND_ASSIGN(CommentWriter);
542
543 const std::vector<PNGCodec::Comment> comments_;
544 png_text* png_text_;
545 };
546 #endif // PNG_TEXT_SUPPORTED
547
548 // The type of functions usable for converting between pixel formats.
549 typedef void (*FormatConverter)(const unsigned char* in, int w,
550 unsigned char* out, bool* is_opaque);
551
552 // libpng uses a wacky setjmp-based API, which makes the compiler nervous.
553 // We constrain all of the calls we make to libpng where the setjmp() is in
554 // place to this function.
555 // Returns true on success.
556 bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr,
557 PngEncoderState* state,
558 int width, int height, int row_byte_width,
559 const unsigned char* input, int compression_level,
560 int png_output_color_type, int output_color_components,
561 FormatConverter converter,
562 const std::vector<PNGCodec::Comment>& comments) {
563 #ifdef PNG_TEXT_SUPPORTED
564 CommentWriter comment_writer(comments);
565 #endif
566 unsigned char* row_buffer = NULL;
567
568 // Make sure to not declare any locals here -- locals in the presence
569 // of setjmp() in C++ code makes gcc complain.
570
571 if (setjmp(png_jmpbuf(png_ptr))) {
572 delete[] row_buffer;
573 return false;
574 }
575
576 png_set_compression_level(png_ptr, compression_level);
577
578 // Set our callback for libpng to give us the data.
579 png_set_write_fn(png_ptr, state, EncoderWriteCallback, FakeFlushCallback);
580 png_set_error_fn(png_ptr, NULL, LogLibPNGEncodeError, LogLibPNGEncodeWarning);
581
582 png_set_IHDR(png_ptr, info_ptr, width, height, 8, png_output_color_type,
583 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
584 PNG_FILTER_TYPE_DEFAULT);
585
586 #ifdef PNG_TEXT_SUPPORTED
587 if (comment_writer.HasComments()) {
588 png_set_text(png_ptr, info_ptr, comment_writer.get_png_text(),
589 comment_writer.size());
590 }
591 #endif
592
593 png_write_info(png_ptr, info_ptr);
594
595 if (!converter) {
596 // No conversion needed, give the data directly to libpng.
597 for (int y = 0; y < height; y ++) {
598 png_write_row(png_ptr,
599 const_cast<unsigned char*>(&input[y * row_byte_width]));
600 }
601 } else {
602 // Needs conversion using a separate buffer.
603 row_buffer = new unsigned char[width * output_color_components];
604 for (int y = 0; y < height; y ++) {
605 converter(&input[y * row_byte_width], width, row_buffer, NULL);
606 png_write_row(png_ptr, row_buffer);
607 }
608 delete[] row_buffer;
609 }
610
611 png_write_end(png_ptr, info_ptr);
612 return true;
613 }
614
615 bool EncodeWithCompressionLevel(const unsigned char* input,
616 PNGCodec::ColorFormat format,
617 const Size& size,
618 int row_byte_width,
619 bool discard_transparency,
620 const std::vector<PNGCodec::Comment>& comments,
621 int compression_level,
622 std::vector<unsigned char>* output) {
623 // Run to convert an input row into the output row format, NULL means no
624 // conversion is necessary.
625 FormatConverter converter = NULL;
626
627 int input_color_components, output_color_components;
628 int png_output_color_type;
629 switch (format) {
630 case PNGCodec::FORMAT_RGBA:
631 input_color_components = 4;
632 if (discard_transparency) {
633 output_color_components = 3;
634 png_output_color_type = PNG_COLOR_TYPE_RGB;
635 converter = ConvertRGBAtoRGB;
636 } else {
637 output_color_components = 4;
638 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
639 converter = NULL;
640 }
641 break;
642
643 case PNGCodec::FORMAT_BGRA:
644 input_color_components = 4;
645 if (discard_transparency) {
646 output_color_components = 3;
647 png_output_color_type = PNG_COLOR_TYPE_RGB;
648 converter = ConvertBGRAtoRGB;
649 } else {
650 output_color_components = 4;
651 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
652 converter = ConvertBetweenBGRAandRGBA;
653 }
654 break;
655
656 case PNGCodec::FORMAT_SkBitmap:
657 // Compare row_byte_width and size.width() to detect the format of
658 // SkBitmap. kA8_Config (1bpp) and kARGB_8888_Config (4bpp) are the two
659 // supported formats.
660 if (row_byte_width < 4 * size.width()) {
661 // Not 4bpp, so must be 1bpp.
662 // Ignore discard_transparency - it doesn't make sense in this context,
663 // since alpha is the only thing we have and it needs to be used for
664 // color intensity.
665 input_color_components = 1;
666 output_color_components = 1;
667 png_output_color_type = PNG_COLOR_TYPE_GRAY;
668 // |converter| is left as null
669 } else {
670 input_color_components = 4;
671 if (discard_transparency) {
672 output_color_components = 3;
673 png_output_color_type = PNG_COLOR_TYPE_RGB;
674 converter = ConvertSkiaToRGB;
675 } else {
676 output_color_components = 4;
677 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
678 converter = ConvertSkiaToRGBA;
679 }
680 }
681 break;
682
683 default:
684 NOTREACHED() << "Unknown pixel format";
685 return false;
686 }
687
688 // Row stride should be at least as long as the length of the data.
689 DCHECK(input_color_components * size.width() <= row_byte_width);
690
691 PngWriteStructInfo si;
692 si.png_ptr_ = png_create_write_struct(PNG_LIBPNG_VER_STRING,
693 NULL, NULL, NULL);
694 if (!si.png_ptr_)
695 return false;
696
697 si.info_ptr_ = png_create_info_struct(si.png_ptr_);
698 if (!si.info_ptr_)
699 return false;
700
701 output->clear();
702
703 PngEncoderState state(output);
704 bool success = DoLibpngWrite(si.png_ptr_, si.info_ptr_, &state,
705 size.width(), size.height(), row_byte_width,
706 input, compression_level, png_output_color_type,
707 output_color_components, converter, comments);
708
709 return success;
710 }
711
712 bool InternalEncodeSkBitmap(const SkBitmap& input,
713 bool discard_transparency,
714 int compression_level,
715 std::vector<unsigned char>* output) {
716 if (input.empty() || input.isNull())
717 return false;
718 int bpp = input.bytesPerPixel();
719 DCHECK(bpp == 1 || bpp == 4); // We support kA8_Config and kARGB_8888_Config.
720
721 unsigned char* inputAddr = bpp == 1 ?
722 reinterpret_cast<unsigned char*>(input.getAddr8(0, 0)) :
723 reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)); // bpp = 4
724 return EncodeWithCompressionLevel(
725 inputAddr,
726 PNGCodec::FORMAT_SkBitmap,
727 Size(input.width(), input.height()),
728 static_cast<int>(input.rowBytes()),
729 discard_transparency,
730 std::vector<PNGCodec::Comment>(),
731 compression_level,
732 output);
733 }
734
735
736 } // namespace
737
738 // static 459 // static
739 bool PNGCodec::Encode(const unsigned char* input, 460 bool PNGCodec::Encode(const unsigned char* input,
740 ColorFormat format, 461 ColorFormat format,
741 const Size& size, 462 const Size& size,
742 int row_byte_width, 463 int row_byte_width,
743 bool discard_transparency, 464 bool discard_transparency,
744 const std::vector<Comment>& comments, 465 const std::vector<Comment>& comments,
745 std::vector<unsigned char>* output) { 466 std::vector<unsigned char>* output) {
746 return EncodeWithCompressionLevel(input, 467 auto colorType =
747 format, 468 format == FORMAT_RGBA ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType;
scroggo_chromium 2017/07/11 16:01:06 Just to make sure I understand - if format is FORM
liyuqian 2017/07/11 19:24:55 I'm also very confused because: 1. The method is
scroggo_chromium 2017/07/11 19:33:09 Yeah, Configs were replaced with SkColorTypes befo
liyuqian 2017/07/11 19:59:25 Acknowledged.
748 size, 469 auto alphaType =
749 row_byte_width, 470 format == FORMAT_SkBitmap ? kPremul_SkAlphaType : kUnpremul_SkAlphaType;
750 discard_transparency, 471 SkImageInfo info =
751 comments, 472 SkImageInfo::Make(size.width(), size.height(), colorType, alphaType);
752 Z_DEFAULT_COMPRESSION, 473 SkPixmap src(info, input, row_byte_width);
753 output); 474 return EncodeSkPixmap(src, discard_transparency, comments, output,
475 DEFAULT_ZLIB_COMPRESSION);
476 }
477
478 static bool EncodeSkBitmap(const SkBitmap& input,
479 bool discard_transparency,
480 std::vector<unsigned char>* output,
481 int zlib_level) {
482 SkPixmap src;
483 if (!input.peekPixels(&src)) {
484 return false;
485 }
486 std::vector<PNGCodec::Comment> empty_comments;
scroggo_chromium 2017/07/11 16:01:06 Too bad we need to create this empty vector just t
liyuqian 2017/07/11 19:24:55 Agree. I can use {} in Mac but Linux can only comp
scroggo_chromium 2017/07/11 19:33:09 Maybe it should take a pointer, which can be null?
liyuqian 2017/07/11 19:59:25 That sounds good. However, it will require the pub
scroggo_chromium 2017/07/11 20:09:30 Sgtm
487 return EncodeSkPixmap(src, discard_transparency, empty_comments, output,
488 zlib_level);
754 } 489 }
755 490
756 // static 491 // static
757 bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input, 492 bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input,
758 bool discard_transparency, 493 bool discard_transparency,
759 std::vector<unsigned char>* output) { 494 std::vector<unsigned char>* output) {
760 return InternalEncodeSkBitmap(input, 495 return EncodeSkBitmap(input, discard_transparency, output,
761 discard_transparency, 496 DEFAULT_ZLIB_COMPRESSION);
762 Z_DEFAULT_COMPRESSION,
763 output);
764 } 497 }
765 498
766 // static 499 // static
767 bool PNGCodec::EncodeA8SkBitmap(const SkBitmap& input, 500 bool PNGCodec::EncodeA8SkBitmap(const SkBitmap& input,
768 std::vector<unsigned char>* output) { 501 std::vector<unsigned char>* output) {
769 return InternalEncodeSkBitmap(input, 502 SkASSERT(input.colorType() == kAlpha_8_SkColorType);
scroggo_chromium 2017/07/11 16:01:06 DCHECK. There might be a DCHECK_EQ, so this could
liyuqian 2017/07/11 19:24:55 Done.
770 false, 503 auto info = input.info()
771 Z_DEFAULT_COMPRESSION, 504 .makeColorType(kGray_8_SkColorType)
772 output); 505 .makeAlphaType(kOpaque_SkAlphaType);
506 SkPixmap src(info, input.getAddr(0, 0), input.rowBytes());
scroggo_chromium 2017/07/11 16:01:06 You could instead use readPixels here, as you do e
liyuqian 2017/07/11 19:24:55 In the other place, we need to do unpremul and cop
scroggo_chromium 2017/07/11 19:33:09 Oh, oops, you are correct.
507 std::vector<Comment> empty_comments;
508 return EncodeSkPixmap(src, empty_comments, output, DEFAULT_ZLIB_COMPRESSION);
773 } 509 }
774 510
775 // static 511 // static
776 bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input, 512 bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input,
777 bool discard_transparency, 513 bool discard_transparency,
778 std::vector<unsigned char>* output) { 514 std::vector<unsigned char>* output) {
779 return InternalEncodeSkBitmap(input, 515 return EncodeSkBitmap(input, discard_transparency, output, Z_BEST_SPEED);
780 discard_transparency,
781 Z_BEST_SPEED,
782 output);
783 } 516 }
784 517
785 PNGCodec::Comment::Comment(const std::string& k, const std::string& t) 518 PNGCodec::Comment::Comment(const std::string& k, const std::string& t)
786 : key(k), text(t) { 519 : key(k), text(t) {
787 } 520 }
788 521
789 PNGCodec::Comment::~Comment() { 522 PNGCodec::Comment::~Comment() {
790 } 523 }
791 524
792 } // namespace gfx 525 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/codec/png_codec.h ('k') | ui/gfx/codec/vector_wstream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698