markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 1 | // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include <algorithm> |
| 6 | #include <vector> |
| 7 | |
rockot | 2a0f4fb3 | 2016-11-11 18:44:19 | [diff] [blame] | 8 | #include "base/callback.h" |
Brandon Wylie | 7debc71 | 2019-04-10 00:27:58 | [diff] [blame] | 9 | #include "chrome/browser/image_fetcher/image_decoder_impl.h" |
tschumann | 30ee108 | 2017-03-02 19:37:53 | [diff] [blame] | 10 | #include "ui/gfx/geometry/size.h" |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 11 | #include "ui/gfx/image/image.h" |
| 12 | |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 13 | // A request for decoding an image. |
| 14 | class ImageDecoderImpl::DecodeImageRequest |
| 15 | : public ::ImageDecoder::ImageRequest { |
| 16 | public: |
| 17 | DecodeImageRequest(ImageDecoderImpl* decoder, |
Brandon Wylie | b8bf92d | 2019-04-10 19:18:26 | [diff] [blame] | 18 | image_fetcher::ImageDecodedCallback callback) |
| 19 | : decoder_(decoder), callback_(std::move(callback)) {} |
Peter Boström | 53c6c595 | 2021-09-17 09:41:26 | [diff] [blame^] | 20 | |
| 21 | DecodeImageRequest(const DecodeImageRequest&) = delete; |
| 22 | DecodeImageRequest& operator=(const DecodeImageRequest&) = delete; |
| 23 | |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 24 | ~DecodeImageRequest() override {} |
| 25 | |
| 26 | private: |
| 27 | // Runs the callback and remove the request from the internal request queue. |
| 28 | void RunCallbackAndRemoveRequest(const gfx::Image& image); |
| 29 | |
| 30 | // Methods inherited from ImageDecoder::ImageRequest |
| 31 | |
| 32 | void OnImageDecoded(const SkBitmap& decoded_image) override; |
| 33 | |
| 34 | void OnDecodeImageFailed() override; |
| 35 | |
| 36 | ImageDecoderImpl* decoder_; |
| 37 | |
| 38 | // The callback to call after the request completed. |
| 39 | image_fetcher::ImageDecodedCallback callback_; |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 40 | }; |
| 41 | |
| 42 | void ImageDecoderImpl::DecodeImageRequest::OnImageDecoded( |
| 43 | const SkBitmap& decoded_bitmap) { |
| 44 | // TODO(markusheintz): Check whether high res displays that require 2x and 3x |
| 45 | // image versions need to be supported here. |
| 46 | gfx::Image image(gfx::Image::CreateFrom1xBitmap(decoded_bitmap)); |
| 47 | RunCallbackAndRemoveRequest(image); |
| 48 | } |
| 49 | |
| 50 | // Called when decoding image failed. |
| 51 | void ImageDecoderImpl::DecodeImageRequest::OnDecodeImageFailed() { |
| 52 | RunCallbackAndRemoveRequest(gfx::Image()); |
| 53 | } |
| 54 | |
| 55 | void ImageDecoderImpl::DecodeImageRequest::RunCallbackAndRemoveRequest( |
| 56 | const gfx::Image& image) { |
Brandon Wylie | b8bf92d | 2019-04-10 19:18:26 | [diff] [blame] | 57 | std::move(callback_).Run(image); |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 58 | |
| 59 | // This must be the last line in the method body. |
| 60 | decoder_->RemoveDecodeImageRequest(this); |
| 61 | } |
| 62 | |
Brandon Wylie | 7debc71 | 2019-04-10 00:27:58 | [diff] [blame] | 63 | ImageDecoderImpl::ImageDecoderImpl() {} |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 64 | |
| 65 | ImageDecoderImpl::~ImageDecoderImpl() {} |
| 66 | |
| 67 | void ImageDecoderImpl::DecodeImage( |
| 68 | const std::string& image_data, |
tschumann | 30ee108 | 2017-03-02 19:37:53 | [diff] [blame] | 69 | const gfx::Size& desired_image_frame_size, |
Brandon Wylie | b8bf92d | 2019-04-10 19:18:26 | [diff] [blame] | 70 | image_fetcher::ImageDecodedCallback callback) { |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 71 | std::unique_ptr<DecodeImageRequest> decode_image_request( |
Brandon Wylie | b8bf92d | 2019-04-10 19:18:26 | [diff] [blame] | 72 | new DecodeImageRequest(this, std::move(callback))); |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 73 | |
tschumann | 30ee108 | 2017-03-02 19:37:53 | [diff] [blame] | 74 | ::ImageDecoder::StartWithOptions( |
| 75 | decode_image_request.get(), |
| 76 | std::vector<uint8_t>(image_data.begin(), image_data.end()), |
| 77 | ::ImageDecoder::DEFAULT_CODEC, |
| 78 | /*shrink_to_fit=*/false, desired_image_frame_size); |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 79 | |
| 80 | decode_image_requests_.push_back(std::move(decode_image_request)); |
| 81 | } |
| 82 | |
| 83 | void ImageDecoderImpl::RemoveDecodeImageRequest(DecodeImageRequest* request) { |
| 84 | // Remove the finished request from the request queue. |
| 85 | auto request_it = |
Brandon Wylie | 7debc71 | 2019-04-10 00:27:58 | [diff] [blame] | 86 | std::find_if(decode_image_requests_.begin(), decode_image_requests_.end(), |
markusheintz | c757076 | 2016-06-15 10:17:25 | [diff] [blame] | 87 | [request](const std::unique_ptr<DecodeImageRequest>& r) { |
| 88 | return r.get() == request; |
| 89 | }); |
| 90 | DCHECK(request_it != decode_image_requests_.end()); |
| 91 | decode_image_requests_.erase(request_it); |
| 92 | } |