| Index: ui/gfx/codec/png_codec.cc
|
| diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc
|
| index ac386ad91d0b656e146776c8077694c881719e99..7f0a569d7892e09eac7219d2449a5e85ac7ec52d 100644
|
| --- a/ui/gfx/codec/png_codec.cc
|
| +++ b/ui/gfx/codec/png_codec.cc
|
| @@ -313,60 +313,56 @@ void DecodeEndCallback(png_struct* png_ptr, png_info* info) {
|
| state->done = true;
|
| }
|
|
|
| -// Automatically destroys the given read structs on destruction to make
|
| -// cleanup and error handling code cleaner.
|
| -class PngReadStructDestroyer {
|
| +// Holds png struct and info ensuring the proper destruction.
|
| +class PngReadStructInfo {
|
| public:
|
| - PngReadStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) {
|
| + PngReadStructInfo(): png_ptr_(nullptr), info_ptr_(nullptr) {
|
| }
|
| - ~PngReadStructDestroyer() {
|
| - png_destroy_read_struct(ps_, pi_, NULL);
|
| + ~PngReadStructInfo() {
|
| + png_destroy_read_struct(&png_ptr_, &info_ptr_, NULL);
|
| }
|
| - private:
|
| - png_struct** ps_;
|
| - png_info** pi_;
|
| - DISALLOW_COPY_AND_ASSIGN(PngReadStructDestroyer);
|
| -};
|
|
|
| -// Automatically destroys the given write structs on destruction to make
|
| -// cleanup and error handling code cleaner.
|
| -class PngWriteStructDestroyer {
|
| - public:
|
| - explicit PngWriteStructDestroyer(png_struct** ps) : ps_(ps), pi_(0) {
|
| - }
|
| - ~PngWriteStructDestroyer() {
|
| - png_destroy_write_struct(ps_, pi_);
|
| - }
|
| - void SetInfoStruct(png_info** pi) {
|
| - pi_ = pi;
|
| + bool Build(const unsigned char* input, size_t input_size) {
|
| + if (input_size < 8)
|
| + return false; // Input data too small to be a png
|
| +
|
| + // Have libpng check the signature, it likes the first 8 bytes.
|
| + if (png_sig_cmp(const_cast<unsigned char*>(input), 0, 8) != 0)
|
| + return false;
|
| +
|
| + png_ptr_ = png_create_read_struct(
|
| + PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
| + if (!png_ptr_)
|
| + return false;
|
| +
|
| + info_ptr_ = png_create_info_struct(png_ptr_);
|
| + if (!info_ptr_) {
|
| + return false;
|
| + }
|
| + return true;
|
| }
|
| +
|
| + png_struct* png_ptr_;
|
| + png_info* info_ptr_;
|
| private:
|
| - png_struct** ps_;
|
| - png_info** pi_;
|
| - DISALLOW_COPY_AND_ASSIGN(PngWriteStructDestroyer);
|
| + DISALLOW_COPY_AND_ASSIGN(PngReadStructInfo);
|
| };
|
|
|
| -bool BuildPNGStruct(const unsigned char* input, size_t input_size,
|
| - png_struct** png_ptr, png_info** info_ptr) {
|
| - if (input_size < 8)
|
| - return false; // Input data too small to be a png
|
| -
|
| - // Have libpng check the signature, it likes the first 8 bytes.
|
| - if (png_sig_cmp(const_cast<unsigned char*>(input), 0, 8) != 0)
|
| - return false;
|
| -
|
| - *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
| - if (!*png_ptr)
|
| - return false;
|
| +// Holds png struct and info ensuring the proper destruction.
|
| +class PngWriteStructInfo {
|
| + public:
|
| + PngWriteStructInfo() : png_ptr_(nullptr), info_ptr_(nullptr) {
|
| + }
|
|
|
| - *info_ptr = png_create_info_struct(*png_ptr);
|
| - if (!*info_ptr) {
|
| - png_destroy_read_struct(png_ptr, NULL, NULL);
|
| - return false;
|
| + ~PngWriteStructInfo() {
|
| + png_destroy_write_struct(&png_ptr_, &info_ptr_);
|
| }
|
|
|
| - return true;
|
| -}
|
| + png_struct* png_ptr_;
|
| + png_info* info_ptr_;
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(PngWriteStructInfo);
|
| +};
|
|
|
| // Libpng user error and warning functions which allows us to print libpng
|
| // errors and warnings using Chrome's logging facilities instead of stderr.
|
| @@ -395,13 +391,11 @@ void LogLibPNGEncodeWarning(png_structp png_ptr, png_const_charp warning_msg) {
|
| bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
|
| ColorFormat format, std::vector<unsigned char>* output,
|
| int* w, int* h) {
|
| - png_struct* png_ptr = NULL;
|
| - png_info* info_ptr = NULL;
|
| - if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr))
|
| + PngReadStructInfo si;
|
| + if (!si.Build(input, input_size))
|
| return false;
|
|
|
| - PngReadStructDestroyer destroyer(&png_ptr, &info_ptr);
|
| - if (setjmp(png_jmpbuf(png_ptr))) {
|
| + if (setjmp(png_jmpbuf(si.png_ptr_))) {
|
| // The destroyer will ensure that the structures are cleaned up in this
|
| // case, even though we may get here as a jump from random parts of the
|
| // PNG library called below.
|
| @@ -410,11 +404,12 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
|
|
|
| PngDecoderState state(format, output);
|
|
|
| - png_set_error_fn(png_ptr, NULL, LogLibPNGDecodeError, LogLibPNGDecodeWarning);
|
| - png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback,
|
| + png_set_error_fn(si.png_ptr_, NULL,
|
| + LogLibPNGDecodeError, LogLibPNGDecodeWarning);
|
| + png_set_progressive_read_fn(si.png_ptr_, &state, &DecodeInfoCallback,
|
| &DecodeRowCallback, &DecodeEndCallback);
|
| - png_process_data(png_ptr,
|
| - info_ptr,
|
| + png_process_data(si.png_ptr_,
|
| + si.info_ptr_,
|
| const_cast<unsigned char*>(input),
|
| input_size);
|
|
|
| @@ -434,13 +429,11 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
|
| bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
|
| SkBitmap* bitmap) {
|
| DCHECK(bitmap);
|
| - png_struct* png_ptr = NULL;
|
| - png_info* info_ptr = NULL;
|
| - if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr))
|
| + PngReadStructInfo si;
|
| + if (!si.Build(input, input_size))
|
| return false;
|
|
|
| - PngReadStructDestroyer destroyer(&png_ptr, &info_ptr);
|
| - if (setjmp(png_jmpbuf(png_ptr))) {
|
| + if (setjmp(png_jmpbuf(si.png_ptr_))) {
|
| // The destroyer will ensure that the structures are cleaned up in this
|
| // case, even though we may get here as a jump from random parts of the
|
| // PNG library called below.
|
| @@ -449,10 +442,10 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
|
|
|
| PngDecoderState state(bitmap);
|
|
|
| - png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback,
|
| + png_set_progressive_read_fn(si.png_ptr_, &state, &DecodeInfoCallback,
|
| &DecodeRowCallback, &DecodeEndCallback);
|
| - png_process_data(png_ptr,
|
| - info_ptr,
|
| + png_process_data(si.png_ptr_,
|
| + si.info_ptr_,
|
| const_cast<unsigned char*>(input),
|
| input_size);
|
|
|
| @@ -708,20 +701,20 @@ bool EncodeWithCompressionLevel(const unsigned char* input,
|
| // Row stride should be at least as long as the length of the data.
|
| DCHECK(input_color_components * size.width() <= row_byte_width);
|
|
|
| - png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
| - NULL, NULL, NULL);
|
| - if (!png_ptr)
|
| + PngWriteStructInfo si;
|
| + si.png_ptr_ = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
| + NULL, NULL, NULL);
|
| + if (!si.png_ptr_)
|
| return false;
|
| - PngWriteStructDestroyer destroyer(&png_ptr);
|
| - png_info* info_ptr = png_create_info_struct(png_ptr);
|
| - if (!info_ptr)
|
| +
|
| + si.info_ptr_ = png_create_info_struct(si.png_ptr_);
|
| + if (!si.info_ptr_)
|
| return false;
|
| - destroyer.SetInfoStruct(&info_ptr);
|
|
|
| output->clear();
|
|
|
| PngEncoderState state(output);
|
| - bool success = DoLibpngWrite(png_ptr, info_ptr, &state,
|
| + bool success = DoLibpngWrite(si.png_ptr_, si.info_ptr_, &state,
|
| size.width(), size.height(), row_byte_width,
|
| input, compression_level, png_output_color_type,
|
| output_color_components, converter, comments);
|
|
|