| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 std::vector<unsigned char> v(data, data + size); | 39 std::vector<unsigned char> v(data, data + size); |
| 40 if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) { | 40 if (png_sig_cmp(v.data(), 0, kPngHeaderSize)) { |
| 41 // not a PNG. | 41 // not a PNG. |
| 42 return 0; | 42 return 0; |
| 43 } | 43 } |
| 44 | 44 |
| 45 png_structp png_ptr = png_create_read_struct | 45 png_structp png_ptr = png_create_read_struct |
| 46 (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); | 46 (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); |
| 47 assert(png_ptr); | 47 assert(png_ptr); |
| 48 | 48 |
| 49 png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; | 49 png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); |
| 50 png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_IGNORE; | |
| 51 | |
| 52 png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; | |
| 53 png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; | |
| 54 | 50 |
| 55 png_infop info_ptr = png_create_info_struct(png_ptr); | 51 png_infop info_ptr = png_create_info_struct(png_ptr); |
| 56 assert(info_ptr); | 52 assert(info_ptr); |
| 57 | 53 |
| 58 base::ScopedClosureRunner struct_deleter(base::Bind( | 54 base::ScopedClosureRunner struct_deleter(base::Bind( |
| 59 &png_destroy_read_struct, &png_ptr, &info_ptr, nullptr)); | 55 &png_destroy_read_struct, &png_ptr, &info_ptr, nullptr)); |
| 60 | 56 |
| 61 // Setting up reading from buffer. | 57 // Setting up reading from buffer. |
| 62 std::unique_ptr<BufState> buf_state(new BufState()); | 58 std::unique_ptr<BufState> buf_state(new BufState()); |
| 63 buf_state->data = data + kPngHeaderSize; | 59 buf_state->data = data + kPngHeaderSize; |
| 64 buf_state->bytes_left = size - kPngHeaderSize; | 60 buf_state->bytes_left = size - kPngHeaderSize; |
| 65 png_set_read_fn(png_ptr, buf_state.get(), user_read_data); | 61 png_set_read_fn(png_ptr, buf_state.get(), user_read_data); |
| 66 png_set_sig_bytes(png_ptr, kPngHeaderSize); | 62 png_set_sig_bytes(png_ptr, kPngHeaderSize); |
| 67 | 63 |
| 68 // libpng error handling. | 64 // libpng error handling. |
| 69 if (setjmp(png_ptr->jmpbuf)) { | 65 if (setjmp(png_jmpbuf(png_ptr))) { |
| 70 return 0; | 66 return 0; |
| 71 } | 67 } |
| 72 | 68 |
| 73 // Reading. | 69 // Reading. |
| 74 png_read_info(png_ptr, info_ptr); | 70 png_read_info(png_ptr, info_ptr); |
| 75 png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); | 71 png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); |
| 76 base::ScopedClosureRunner png_deleter(base::Bind( | 72 base::ScopedClosureRunner png_deleter(base::Bind( |
| 77 &png_free, png_ptr, row)); | 73 &png_free, png_ptr, row)); |
| 78 | 74 |
| 79 // reset error handler to put png_deleter into scope. | 75 // reset error handler to put png_deleter into scope. |
| 80 if (setjmp(png_ptr->jmpbuf)) { | 76 if (setjmp(png_jmpbuf(png_ptr))) { |
| 81 return 0; | 77 return 0; |
| 82 } | 78 } |
| 83 | 79 |
| 84 png_uint_32 width, height; | 80 png_uint_32 width, height; |
| 85 int bit_depth, color_type, interlace_type, compression_type; | 81 int bit_depth, color_type, interlace_type, compression_type; |
| 86 int filter_type; | 82 int filter_type; |
| 87 | 83 |
| 88 if (!png_get_IHDR(png_ptr, info_ptr, &width, &height, | 84 if (!png_get_IHDR(png_ptr, info_ptr, &width, &height, |
| 89 &bit_depth, &color_type, &interlace_type, | 85 &bit_depth, &color_type, &interlace_type, |
| 90 &compression_type, &filter_type)) { | 86 &compression_type, &filter_type)) { |
| 91 return 0; | 87 return 0; |
| 92 } | 88 } |
| 93 | 89 |
| 94 // This is going to be too slow. | 90 // This is going to be too slow. |
| 95 if (width && height > 100000000 / width) | 91 if (width && height > 100000000 / width) |
| 96 return 0; | 92 return 0; |
| 97 | 93 |
| 98 int passes = png_set_interlace_handling(png_ptr); | 94 int passes = png_set_interlace_handling(png_ptr); |
| 99 png_start_read_image(png_ptr); | 95 png_start_read_image(png_ptr); |
| 100 | 96 |
| 101 for (int pass = 0; pass < passes; ++pass) { | 97 for (int pass = 0; pass < passes; ++pass) { |
| 102 for (png_uint_32 y = 0; y < height; ++y) { | 98 for (png_uint_32 y = 0; y < height; ++y) { |
| 103 png_read_row(png_ptr, static_cast<png_bytep>(row), NULL); | 99 png_read_row(png_ptr, static_cast<png_bytep>(row), NULL); |
| 104 } | 100 } |
| 105 } | 101 } |
| 106 | 102 |
| 107 return 0; | 103 return 0; |
| 108 } | 104 } |
| OLD | NEW |