blob: 2a0d3225aaf2329bcb382fefd005a2c88b60ba3c [file] [log] [blame]
[email protected]44013f682012-05-31 13:49:401// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]551707a2010-06-16 16:59:472// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]6d33da172011-11-22 03:56:095#ifndef CHROME_BROWSER_IMAGE_DECODER_H_
6#define CHROME_BROWSER_IMAGE_DECODER_H_
[email protected]551707a2010-06-16 16:59:477
twellingtona71414d2015-03-26 15:09:458#include <map>
[email protected]928c0e712011-03-16 15:01:579#include <string>
[email protected]551707a2010-06-16 16:59:4710#include <vector>
11
avi6846aef2015-12-26 01:09:3812#include "base/macros.h"
[email protected]810dddf52013-01-25 19:37:2613#include "base/memory/ref_counted.h"
thestigc5eeb9f362015-04-22 18:42:3214#include "base/sequence_checker.h"
15#include "base/sequenced_task_runner.h"
twellingtona71414d2015-03-26 15:09:4516#include "base/synchronization/lock.h"
[email protected]373c1062011-06-09 21:11:5117
tschumann30ee1082017-03-02 19:37:5318namespace gfx {
19class Size;
20} // namespace gfx
21
[email protected]373c1062011-06-09 21:11:5122class SkBitmap;
[email protected]551707a2010-06-16 16:59:4723
rockot2a0f4fb32016-11-11 18:44:1924// This is a helper class for decoding images safely in a sandboxed service. To
twellingtona71414d2015-03-26 15:09:4525// use this, call ImageDecoder::Start(...) or
26// ImageDecoder::StartWithOptions(...) on any thread.
27//
rockot2a0f4fb32016-11-11 18:44:1928// ImageRequest::OnImageDecoded or ImageRequest::OnDecodeImageFailed is posted
29// back to the |task_runner_| associated with the ImageRequest.
30//
31// The Cancel() method runs on whichever thread called it.
32//
33// TODO(rockot): Use of this class should be replaced with direct image_decoder
34// client library usage.
35class ImageDecoder {
[email protected]551707a2010-06-16 16:59:4736 public:
thestigc5eeb9f362015-04-22 18:42:3237 // ImageRequest objects needs to be created and destroyed on the same
38 // SequencedTaskRunner.
twellingtona71414d2015-03-26 15:09:4539 class ImageRequest {
[email protected]551707a2010-06-16 16:59:4740 public:
41 // Called when image is decoded.
twellingtona71414d2015-03-26 15:09:4542 virtual void OnImageDecoded(const SkBitmap& decoded_image) = 0;
[email protected]928c0e712011-03-16 15:01:5743
twellingtona71414d2015-03-26 15:09:4544 // Called when decoding image failed. ImageRequest can do some cleanup in
[email protected]928c0e712011-03-16 15:01:5745 // this handler.
twellingtona71414d2015-03-26 15:09:4546 virtual void OnDecodeImageFailed() {}
47
48 base::SequencedTaskRunner* task_runner() const {
49 return task_runner_.get();
50 }
[email protected]551707a2010-06-16 16:59:4751
52 protected:
rockot2a0f4fb32016-11-11 18:44:1953 // Creates an ImageRequest that runs on the thread which created it.
thestigc5eeb9f362015-04-22 18:42:3254 ImageRequest();
rockot2a0f4fb32016-11-11 18:44:1955
thestigc5eeb9f362015-04-22 18:42:3256 // Explicitly pass in |task_runner| if the current thread is part of a
57 // thread pool.
twellingtona71414d2015-03-26 15:09:4558 explicit ImageRequest(
59 const scoped_refptr<base::SequencedTaskRunner>& task_runner);
60 virtual ~ImageRequest();
61
62 private:
thestigc5eeb9f362015-04-22 18:42:3263 // The thread to post OnImageDecoded() or OnDecodeImageFailed() once the
twellingtona71414d2015-03-26 15:09:4564 // the image has been decoded.
65 const scoped_refptr<base::SequencedTaskRunner> task_runner_;
thestigc5eeb9f362015-04-22 18:42:3266
67 base::SequenceChecker sequence_checker_;
[email protected]551707a2010-06-16 16:59:4768 };
69
[email protected]11f16d102012-08-29 23:12:1570 enum ImageCodec {
71 DEFAULT_CODEC = 0, // Uses WebKit image decoding (via WebImage).
edward.baker199f66b2015-05-07 19:13:3072#if defined(OS_CHROMEOS)
[email protected]11f16d102012-08-29 23:12:1573 ROBUST_JPEG_CODEC, // Restrict decoding to robust jpeg codec.
satoruxf7e76f02016-03-09 06:30:4574 ROBUST_PNG_CODEC, // Restrict decoding to robust PNG codec.
edward.baker199f66b2015-05-07 19:13:3075#endif // defined(OS_CHROMEOS)
[email protected]11f16d102012-08-29 23:12:1576 };
77
scottmgd69ee9d2017-02-06 20:55:3678 static ImageDecoder* GetInstance();
rockot2a0f4fb32016-11-11 18:44:1979
thestigc5eeb9f362015-04-22 18:42:3280 // Calls StartWithOptions() with ImageCodec::DEFAULT_CODEC and
twellingtona71414d2015-03-26 15:09:4581 // shrink_to_fit = false.
82 static void Start(ImageRequest* image_request,
nya601d9702016-07-26 18:39:2183 std::vector<uint8_t> image_data);
84 // Deprecated. Use std::vector<uint8_t> version to avoid an extra copy.
85 static void Start(ImageRequest* image_request,
twellingtona71414d2015-03-26 15:09:4586 const std::string& image_data);
pneubeck93871252015-01-20 11:26:3687
[email protected]cdc8a3e2013-06-12 04:18:1788 // Starts asynchronous image decoding. Once finished, the callback will be
twellingtona71414d2015-03-26 15:09:4589 // posted back to image_request's |task_runner_|.
tschumann30ee1082017-03-02 19:37:5390 // For images with multiple frames (e.g. ico files), a frame with a size as
91 // close as possible to |desired_image_frame_size| is chosen (tries to take
92 // one in larger size if there's no precise match). Passing gfx::Size() as
93 // |desired_image_frame_size| is also supported and will result in chosing the
94 // smallest available size.
twellingtona71414d2015-03-26 15:09:4595 static void StartWithOptions(ImageRequest* image_request,
nya601d9702016-07-26 18:39:2196 std::vector<uint8_t> image_data,
97 ImageCodec image_codec,
tschumann30ee1082017-03-02 19:37:5398 bool shrink_to_fit,
99 const gfx::Size& desired_image_frame_size);
nya601d9702016-07-26 18:39:21100 // Deprecated. Use std::vector<uint8_t> version to avoid an extra copy.
101 static void StartWithOptions(ImageRequest* image_request,
twellingtona71414d2015-03-26 15:09:45102 const std::string& image_data,
103 ImageCodec image_codec,
104 bool shrink_to_fit);
[email protected]551707a2010-06-16 16:59:47105
thestigc5eeb9f362015-04-22 18:42:32106 // Removes all instances of |image_request| from |image_request_id_map_|,
twellingtona71414d2015-03-26 15:09:45107 // ensuring callbacks are not made to the image_request after it is destroyed.
108 static void Cancel(ImageRequest* image_request);
[email protected]11b0856d2012-06-13 19:21:56109
[email protected]551707a2010-06-16 16:59:47110 private:
thestigc5eeb9f362015-04-22 18:42:32111 using RequestMap = std::map<int, ImageRequest*>;
112
scottmgd69ee9d2017-02-06 20:55:36113 ImageDecoder();
114 ~ImageDecoder() = delete;
115
thestigc5eeb9f362015-04-22 18:42:32116 void StartWithOptionsImpl(ImageRequest* image_request,
nya601d9702016-07-26 18:39:21117 std::vector<uint8_t> image_data,
thestigc5eeb9f362015-04-22 18:42:32118 ImageCodec image_codec,
tschumann30ee1082017-03-02 19:37:53119 bool shrink_to_fit,
120 const gfx::Size& desired_image_frame_size);
rockot2a0f4fb32016-11-11 18:44:19121
twellingtona71414d2015-03-26 15:09:45122 void CancelImpl(ImageRequest* image_request);
123
[email protected]373c1062011-06-09 21:11:51124 // IPC message handlers.
twellingtona71414d2015-03-26 15:09:45125 void OnDecodeImageSucceeded(const SkBitmap& decoded_image, int request_id);
126 void OnDecodeImageFailed(int request_id);
[email protected]551707a2010-06-16 16:59:47127
thestigc5eeb9f362015-04-22 18:42:32128 // id to use for the next Start() request that comes in.
twellingtona71414d2015-03-26 15:09:45129 int image_request_id_counter_;
[email protected]551707a2010-06-16 16:59:47130
twellingtona71414d2015-03-26 15:09:45131 // Map of request id's to ImageRequests.
132 RequestMap image_request_id_map_;
133
134 // Protects |image_request_id_map_| and |image_request_id_counter_|.
135 base::Lock map_lock_;
136
[email protected]551707a2010-06-16 16:59:47137 DISALLOW_COPY_AND_ASSIGN(ImageDecoder);
138};
139
[email protected]6d33da172011-11-22 03:56:09140#endif // CHROME_BROWSER_IMAGE_DECODER_H_