| Index: services/image_decoder/image_decoder_impl.cc
|
| diff --git a/chrome/utility/image_decoder_impl.cc b/services/image_decoder/image_decoder_impl.cc
|
| similarity index 59%
|
| rename from chrome/utility/image_decoder_impl.cc
|
| rename to services/image_decoder/image_decoder_impl.cc
|
| index 472f9873ae9422796fea48003de1711ad14631b7..e82c497825fcdf9723679dab43f96538bb0256bf 100644
|
| --- a/chrome/utility/image_decoder_impl.cc
|
| +++ b/services/image_decoder/image_decoder_impl.cc
|
| @@ -2,7 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "chrome/utility/image_decoder_impl.h"
|
| +#include "services/image_decoder/image_decoder_impl.h"
|
|
|
| #include <string.h>
|
|
|
| @@ -10,7 +10,6 @@
|
|
|
| #include "base/logging.h"
|
| #include "content/public/child/image_decoder_utils.h"
|
| -#include "ipc/ipc_channel.h"
|
| #include "mojo/public/cpp/bindings/strong_binding.h"
|
| #include "skia/ext/image_operations.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| @@ -21,24 +20,26 @@
|
| #include "ui/gfx/codec/png_codec.h"
|
| #endif
|
|
|
| +namespace image_decoder {
|
| +
|
| namespace {
|
| -int64_t kMaxMessageSize = IPC::Channel::kMaximumMessageSize;
|
| +
|
| int64_t kPadding = 64;
|
| -}
|
|
|
| -ImageDecoderImpl::ImageDecoderImpl() : ImageDecoderImpl(kMaxMessageSize) {}
|
| +} // namespace
|
|
|
| -ImageDecoderImpl::ImageDecoderImpl(int64_t max_message_size)
|
| - : max_message_size_(max_message_size) {}
|
| +ImageDecoderImpl::ImageDecoderImpl(
|
| + std::unique_ptr<service_manager::ServiceContextRef> service_ref)
|
| + : service_ref_(std::move(service_ref)) {}
|
|
|
| -ImageDecoderImpl::~ImageDecoderImpl() {
|
| -}
|
| +ImageDecoderImpl::~ImageDecoderImpl() = default;
|
|
|
| void ImageDecoderImpl::DecodeImage(const std::vector<uint8_t>& encoded_data,
|
| mojom::ImageCodec codec,
|
| bool shrink_to_fit,
|
| + int64_t max_size_in_bytes,
|
| const DecodeImageCallback& callback) {
|
| - if (encoded_data.empty()) {
|
| + if (encoded_data.size() == 0) {
|
| callback.Run(SkBitmap());
|
| return;
|
| }
|
| @@ -47,22 +48,26 @@ void ImageDecoderImpl::DecodeImage(const std::vector<uint8_t>& encoded_data,
|
| #if defined(OS_CHROMEOS)
|
| if (codec == mojom::ImageCodec::ROBUST_JPEG) {
|
| // Our robust jpeg decoding is using IJG libjpeg.
|
| - std::unique_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodecRobustSlow::Decode(
|
| - encoded_data.data(), encoded_data.size()));
|
| - if (decoded_jpeg.get() && !decoded_jpeg->empty())
|
| - decoded_image = *decoded_jpeg;
|
| + if (encoded_data.size()) {
|
| + std::unique_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodecRobustSlow::Decode(
|
| + encoded_data.data(), encoded_data.size()));
|
| + if (decoded_jpeg.get() && !decoded_jpeg->empty())
|
| + decoded_image = *decoded_jpeg;
|
| + }
|
| } else if (codec == mojom::ImageCodec::ROBUST_PNG) {
|
| // Our robust PNG decoding is using libpng.
|
| - SkBitmap decoded_png;
|
| - if (gfx::PNGCodec::Decode(encoded_data.data(), encoded_data.size(),
|
| - &decoded_png)) {
|
| - decoded_image = decoded_png;
|
| + if (encoded_data.size()) {
|
| + SkBitmap decoded_png;
|
| + if (gfx::PNGCodec::Decode(
|
| + encoded_data.data(), encoded_data.size(), &decoded_png)) {
|
| + decoded_image = decoded_png;
|
| + }
|
| }
|
| }
|
| #endif // defined(OS_CHROMEOS)
|
| if (codec == mojom::ImageCodec::DEFAULT) {
|
| - decoded_image = content::DecodeImage(encoded_data.data(), gfx::Size(),
|
| - encoded_data.size());
|
| + decoded_image = content::DecodeImage(
|
| + encoded_data.data(), gfx::Size(), encoded_data.size());
|
| }
|
|
|
| if (!decoded_image.isNull()) {
|
| @@ -73,14 +78,16 @@ void ImageDecoderImpl::DecodeImage(const std::vector<uint8_t>& encoded_data,
|
| int64_t struct_size = sizeof(skia::mojom::Bitmap::Data_) + kPadding;
|
| int64_t image_size = decoded_image.computeSize64();
|
| int halves = 0;
|
| - while (struct_size + (image_size >> 2 * halves) > max_message_size_)
|
| + while (struct_size + (image_size >> 2 * halves) > max_size_in_bytes)
|
| halves++;
|
| if (halves) {
|
| + // If the decoded image is too large, either discard it or shrink it.
|
| + //
|
| + // TODO(rockot): Also support exposing the bytes via shared memory for
|
| + // larger images. https://crbug.com/416916.
|
| if (shrink_to_fit) {
|
| - // If decoded image is too large for IPC message, shrink it by halves.
|
| - // This prevents quality loss, and should never overshrink on displays
|
| - // smaller than 3600x2400.
|
| - // TODO (Issue 416916): Instead of shrinking, return via shared memory
|
| + // Shrinking by halves prevents quality loss and should never overshrink
|
| + // on displays smaller than 3600x2400.
|
| decoded_image = skia::ImageOperations::Resize(
|
| decoded_image, skia::ImageOperations::RESIZE_LANCZOS3,
|
| decoded_image.width() >> halves, decoded_image.height() >> halves);
|
| @@ -92,3 +99,5 @@ void ImageDecoderImpl::DecodeImage(const std::vector<uint8_t>& encoded_data,
|
|
|
| callback.Run(decoded_image);
|
| }
|
| +
|
| +} // namespace image_decoder
|
|
|