Index: chrome/browser/search/suggestions/image_decoder_impl.cc |
diff --git a/chrome/browser/search/suggestions/image_decoder_impl.cc b/chrome/browser/search/suggestions/image_decoder_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2b7543dc0d1eb137d637b307d707ac2e2c85a33b |
--- /dev/null |
+++ b/chrome/browser/search/suggestions/image_decoder_impl.cc |
@@ -0,0 +1,88 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <algorithm> |
+#include <vector> |
+ |
+#include "chrome/browser/search/suggestions/image_decoder_impl.h" |
+#include "ui/gfx/image/image.h" |
+ |
+namespace suggestions { |
+ |
+// A request for decoding an image. |
+class ImageDecoderImpl::DecodeImageRequest |
+ : public ::ImageDecoder::ImageRequest { |
+ public: |
+ DecodeImageRequest(ImageDecoderImpl* decoder, |
+ const image_fetcher::ImageDecodedCallback& callback) |
+ : decoder_(decoder), callback_(callback) {} |
+ ~DecodeImageRequest() override {} |
+ |
+ private: |
+ // Runs the callback and remove the request from the internal request queue. |
+ void RunCallbackAndRemoveRequest(const gfx::Image& image); |
+ |
+ // Methods inherited from ImageDecoder::ImageRequest |
+ |
+ void OnImageDecoded(const SkBitmap& decoded_image) override; |
+ |
+ void OnDecodeImageFailed() override; |
+ |
+ ImageDecoderImpl* decoder_; |
+ |
+ // The callback to call after the request completed. |
+ image_fetcher::ImageDecodedCallback callback_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DecodeImageRequest); |
+}; |
+ |
+void ImageDecoderImpl::DecodeImageRequest::OnImageDecoded( |
+ const SkBitmap& decoded_bitmap) { |
+ // TODO(markusheintz): Check whether high res displays that require 2x and 3x |
+ // image versions need to be supported here. |
+ gfx::Image image(gfx::Image::CreateFrom1xBitmap(decoded_bitmap)); |
+ RunCallbackAndRemoveRequest(image); |
+} |
+ |
+// Called when decoding image failed. |
+void ImageDecoderImpl::DecodeImageRequest::OnDecodeImageFailed() { |
+ RunCallbackAndRemoveRequest(gfx::Image()); |
+} |
+ |
+void ImageDecoderImpl::DecodeImageRequest::RunCallbackAndRemoveRequest( |
+ const gfx::Image& image) { |
+ callback_.Run(image); |
+ |
+ // This must be the last line in the method body. |
+ decoder_->RemoveDecodeImageRequest(this); |
+} |
+ |
+ImageDecoderImpl::ImageDecoderImpl() {} |
+ |
+ImageDecoderImpl::~ImageDecoderImpl() {} |
+ |
+void ImageDecoderImpl::DecodeImage( |
+ const std::string& image_data, |
+ const image_fetcher::ImageDecodedCallback& callback) { |
+ std::unique_ptr<DecodeImageRequest> decode_image_request( |
+ new DecodeImageRequest(this, callback)); |
+ |
+ ::ImageDecoder::Start(decode_image_request.get(), image_data); |
+ |
+ decode_image_requests_.push_back(std::move(decode_image_request)); |
+} |
+ |
+void ImageDecoderImpl::RemoveDecodeImageRequest(DecodeImageRequest* request) { |
+ // Remove the finished request from the request queue. |
+ auto request_it = |
+ std::find_if(decode_image_requests_.begin(), |
+ decode_image_requests_.end(), |
+ [request](const std::unique_ptr<DecodeImageRequest>& r) { |
+ return r.get() == request; |
+ }); |
+ DCHECK(request_it != decode_image_requests_.end()); |
+ decode_image_requests_.erase(request_it); |
+} |
+ |
+} // namespace suggestions |