image_decoder.h 4.94 KB
Newer Older
1
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
nkostylev@google.com's avatar
nkostylev@google.com committed
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef CHROME_BROWSER_IMAGE_DECODER_H_
#define CHROME_BROWSER_IMAGE_DECODER_H_
nkostylev@google.com's avatar
nkostylev@google.com committed
7

8
#include <map>
9
#include <string>
nkostylev@google.com's avatar
nkostylev@google.com committed
10 11
#include <vector>

12
#include "base/macros.h"
13
#include "base/memory/ref_counted.h"
thestig's avatar
thestig committed
14 15
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
16
#include "base/synchronization/lock.h"
17

18 19 20 21
namespace gfx {
class Size;
}  // namespace gfx

22
class SkBitmap;
nkostylev@google.com's avatar
nkostylev@google.com committed
23

rockot's avatar
rockot committed
24
// This is a helper class for decoding images safely in a sandboxed service. To
25 26 27
// use this, call ImageDecoder::Start(...) or
// ImageDecoder::StartWithOptions(...) on any thread.
//
rockot's avatar
rockot committed
28 29 30 31 32 33 34 35
// ImageRequest::OnImageDecoded or ImageRequest::OnDecodeImageFailed is posted
// back to the |task_runner_| associated with the ImageRequest.
//
// The Cancel() method runs on whichever thread called it.
//
// TODO(rockot): Use of this class should be replaced with direct image_decoder
// client library usage.
class ImageDecoder {
nkostylev@google.com's avatar
nkostylev@google.com committed
36
 public:
thestig's avatar
thestig committed
37 38
  // ImageRequest objects needs to be created and destroyed on the same
  // SequencedTaskRunner.
39
  class ImageRequest {
nkostylev@google.com's avatar
nkostylev@google.com committed
40 41
   public:
    // Called when image is decoded.
42
    virtual void OnImageDecoded(const SkBitmap& decoded_image) = 0;
43

44
    // Called when decoding image failed. ImageRequest can do some cleanup in
45
    // this handler.
46 47 48 49 50
    virtual void OnDecodeImageFailed() {}

    base::SequencedTaskRunner* task_runner() const {
      return task_runner_.get();
    }
nkostylev@google.com's avatar
nkostylev@google.com committed
51 52

   protected:
rockot's avatar
rockot committed
53
    // Creates an ImageRequest that runs on the thread which created it.
thestig's avatar
thestig committed
54
    ImageRequest();
rockot's avatar
rockot committed
55

thestig's avatar
thestig committed
56 57
    // Explicitly pass in |task_runner| if the current thread is part of a
    // thread pool.
58 59 60 61 62
    explicit ImageRequest(
        const scoped_refptr<base::SequencedTaskRunner>& task_runner);
    virtual ~ImageRequest();

   private:
thestig's avatar
thestig committed
63
    // The thread to post OnImageDecoded() or OnDecodeImageFailed() once the
64 65
    // the image has been decoded.
    const scoped_refptr<base::SequencedTaskRunner> task_runner_;
thestig's avatar
thestig committed
66 67

    base::SequenceChecker sequence_checker_;
nkostylev@google.com's avatar
nkostylev@google.com committed
68 69
  };

70 71
  enum ImageCodec {
    DEFAULT_CODEC = 0,  // Uses WebKit image decoding (via WebImage).
72
#if defined(OS_CHROMEOS)
73
    ROBUST_JPEG_CODEC,  // Restrict decoding to robust jpeg codec.
74
    ROBUST_PNG_CODEC,  // Restrict decoding to robust PNG codec.
75
#endif  // defined(OS_CHROMEOS)
76 77
  };

78
  static ImageDecoder* GetInstance();
rockot's avatar
rockot committed
79

thestig's avatar
thestig committed
80
  // Calls StartWithOptions() with ImageCodec::DEFAULT_CODEC and
81
  // shrink_to_fit = false.
82 83 84
  static void Start(ImageRequest* image_request,
                    std::vector<uint8_t> image_data);
  // Deprecated. Use std::vector<uint8_t> version to avoid an extra copy.
85 86
  static void Start(ImageRequest* image_request,
                    const std::string& image_data);
87

88
  // Starts asynchronous image decoding. Once finished, the callback will be
89
  // posted back to image_request's |task_runner_|.
90 91 92 93 94
  // For images with multiple frames (e.g. ico files), a frame with a size as
  // close as possible to |desired_image_frame_size| is chosen (tries to take
  // one in larger size if there's no precise match). Passing gfx::Size() as
  // |desired_image_frame_size| is also supported and will result in chosing the
  // smallest available size.
95 96 97
  static void StartWithOptions(ImageRequest* image_request,
                               std::vector<uint8_t> image_data,
                               ImageCodec image_codec,
98 99
                               bool shrink_to_fit,
                               const gfx::Size& desired_image_frame_size);
100
  // Deprecated. Use std::vector<uint8_t> version to avoid an extra copy.
101 102 103 104
  static void StartWithOptions(ImageRequest* image_request,
                               const std::string& image_data,
                               ImageCodec image_codec,
                               bool shrink_to_fit);
nkostylev@google.com's avatar
nkostylev@google.com committed
105

thestig's avatar
thestig committed
106
  // Removes all instances of |image_request| from |image_request_id_map_|,
107 108
  // ensuring callbacks are not made to the image_request after it is destroyed.
  static void Cancel(ImageRequest* image_request);
109

nkostylev@google.com's avatar
nkostylev@google.com committed
110
 private:
thestig's avatar
thestig committed
111 112
  using RequestMap = std::map<int, ImageRequest*>;

113 114 115
  ImageDecoder();
  ~ImageDecoder() = delete;

thestig's avatar
thestig committed
116
  void StartWithOptionsImpl(ImageRequest* image_request,
117
                            std::vector<uint8_t> image_data,
thestig's avatar
thestig committed
118
                            ImageCodec image_codec,
119 120
                            bool shrink_to_fit,
                            const gfx::Size& desired_image_frame_size);
121

rockot's avatar
rockot committed
122
  void CancelImpl(ImageRequest* image_request);
123 124

  // IPC message handlers.
125 126 127
  void OnDecodeImageSucceeded(const SkBitmap& decoded_image, int request_id);
  void OnDecodeImageFailed(int request_id);

thestig's avatar
thestig committed
128
  // id to use for the next Start() request that comes in.
129 130 131 132 133 134 135 136
  int image_request_id_counter_;

  // Map of request id's to ImageRequests.
  RequestMap image_request_id_map_;

  // Protects |image_request_id_map_| and |image_request_id_counter_|.
  base::Lock map_lock_;

nkostylev@google.com's avatar
nkostylev@google.com committed
137 138 139
  DISALLOW_COPY_AND_ASSIGN(ImageDecoder);
};

140
#endif  // CHROME_BROWSER_IMAGE_DECODER_H_