File: image_decoder.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (149 lines) | stat: -rw-r--r-- 5,243 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_IMAGE_DECODER_IMAGE_DECODER_H_
#define CHROME_BROWSER_IMAGE_DECODER_IMAGE_DECODER_H_

#include <map>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/no_destructor.h"
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "ui/gfx/geometry/size.h"

namespace data_decoder {
class DataDecoder;
}  // namespace data_decoder

namespace gfx {
class Size;
}  // namespace gfx

class SkBitmap;

// This is a helper class for decoding images safely in a sandboxed service. To
// use this, call ImageDecoder::Start(...) or
// ImageDecoder::StartWithOptions(...) on any thread.
//
// 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 {
 public:
  // ImageRequest objects needs to be created and destroyed on the same
  // SequencedTaskRunner.
  class ImageRequest {
   public:
    // Called when image is decoded.
    virtual void OnImageDecoded(const SkBitmap& decoded_image) = 0;

    // Called when decoding image failed. ImageRequest can do some cleanup in
    // this handler.
    virtual void OnDecodeImageFailed() {}

    base::SequencedTaskRunner* task_runner() const {
      return task_runner_.get();
    }

    data_decoder::DataDecoder* data_decoder() { return data_decoder_; }

   protected:
    // Creates an ImageRequest that runs on the thread which created it.
    ImageRequest();
    // Explicitly pass in |task_runner| if the current thread is part of a
    // thread pool.
    explicit ImageRequest(
        const scoped_refptr<base::SequencedTaskRunner>& task_runner);
    // Explicitly pass in |data_decoder| if there's a specific decoder that
    // should be used; otherwise, an isolated decoder will created and used.
    explicit ImageRequest(data_decoder::DataDecoder* data_decoder);
    virtual ~ImageRequest();

   private:
    // The thread to post OnImageDecoded() or OnDecodeImageFailed() once the
    // the image has been decoded.
    const scoped_refptr<base::SequencedTaskRunner> task_runner_;

    // If null, will use a new decoder via DecodeImageIsolated() instead.
    const raw_ptr<data_decoder::DataDecoder> data_decoder_ = nullptr;

    SEQUENCE_CHECKER(sequence_checker_);
  };

  enum ImageCodec {
    DEFAULT_CODEC = 0,  // Uses WebKit image decoding (via WebImage).
#if BUILDFLAG(IS_CHROMEOS)
    PNG_CODEC,  // Restrict decoding to libpng.
#endif
  };

  static ImageDecoder* GetInstance();

  ImageDecoder(const ImageDecoder&) = delete;
  ImageDecoder& operator=(const ImageDecoder&) = delete;

  // Calls StartWithOptions() with default options.
  // ImageDataType can be std::vector<uint8_t> or std::string.
  template <typename ImageDataType>
  static void Start(ImageRequest* image_request, ImageDataType image_data);

  // Starts asynchronous image decoding. Once finished, the callback will be
  // posted back to image_request's |task_runner_|.
  // 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.
  template <typename ImageDataType>
  static void StartWithOptions(
      ImageRequest* image_request,
      ImageDataType image_data,
      ImageCodec image_codec = DEFAULT_CODEC,
      bool shrink_to_fit = false,
      const gfx::Size& desired_image_frame_size = gfx::Size());

  // Removes all instances of |image_request| from |image_request_id_map_|,
  // ensuring callbacks are not made to the image_request after it is destroyed.
  static void Cancel(ImageRequest* image_request);

 private:
  friend base::NoDestructor<ImageDecoder>;
  using RequestMap = std::map<int, raw_ptr<ImageRequest, CtnExperimental>>;

  ImageDecoder();
  ~ImageDecoder() = delete;

  template <typename ImageDataType>
  void StartWithOptionsImpl(ImageRequest* image_request,
                            ImageDataType image_data,
                            ImageCodec image_codec,
                            bool shrink_to_fit,
                            const gfx::Size& desired_image_frame_size);

  void CancelImpl(ImageRequest* image_request);

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

  // id to use for the next Start() request that comes in.
  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_;
};

#endif  // CHROME_BROWSER_IMAGE_DECODER_IMAGE_DECODER_H_