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 "services/data_decoder/public/cpp/decode_image.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback_helpers.h"
12 #include "mojo/public/cpp/bindings/remote.h"
13 #include "services/data_decoder/public/cpp/data_decoder.h"
14 #include "third_party/skia/include/core/SkBitmap.h"
15
16 namespace data_decoder {
17
18 namespace {
19
20 // Helper callback which owns a mojo::Remote<ImageDecoder> until invoked. This
21 // keeps the ImageDecoder pipe open just long enough to dispatch a reply, at
22 // which point the reply is forwarded to the wrapped |callback|.
OnDecodeImage(mojo::Remote<mojom::ImageDecoder> decoder,mojom::ImageDecoder::DecodeImageCallback callback,const SkBitmap & bitmap)23 void OnDecodeImage(mojo::Remote<mojom::ImageDecoder> decoder,
24 mojom::ImageDecoder::DecodeImageCallback callback,
25 const SkBitmap& bitmap) {
26 std::move(callback).Run(bitmap);
27 }
28
OnDecodeImages(mojo::Remote<mojom::ImageDecoder> decoder,mojom::ImageDecoder::DecodeAnimationCallback callback,std::vector<mojom::AnimationFramePtr> bitmaps)29 void OnDecodeImages(mojo::Remote<mojom::ImageDecoder> decoder,
30 mojom::ImageDecoder::DecodeAnimationCallback callback,
31 std::vector<mojom::AnimationFramePtr> bitmaps) {
32 std::move(callback).Run(std::move(bitmaps));
33 }
34
35 } // namespace
36
DecodeImageIsolated(const std::vector<uint8_t> & encoded_bytes,mojom::ImageCodec codec,bool shrink_to_fit,uint64_t max_size_in_bytes,const gfx::Size & desired_image_frame_size,mojom::ImageDecoder::DecodeImageCallback callback)37 void DecodeImageIsolated(const std::vector<uint8_t>& encoded_bytes,
38 mojom::ImageCodec codec,
39 bool shrink_to_fit,
40 uint64_t max_size_in_bytes,
41 const gfx::Size& desired_image_frame_size,
42 mojom::ImageDecoder::DecodeImageCallback callback) {
43 // Create a new DataDecoder that we keep alive until |callback| is invoked.
44 auto data_decoder = std::make_unique<DataDecoder>();
45 auto* raw_decoder = data_decoder.get();
46 auto wrapped_callback = base::BindOnce(
47 [](std::unique_ptr<DataDecoder>,
48 mojom::ImageDecoder::DecodeImageCallback callback,
49 const SkBitmap& bitmap) { std::move(callback).Run(bitmap); },
50 std::move(data_decoder), std::move(callback));
51 DecodeImage(raw_decoder, encoded_bytes, codec, shrink_to_fit,
52 max_size_in_bytes, desired_image_frame_size,
53 std::move(wrapped_callback));
54 }
55
DecodeImage(DataDecoder * data_decoder,const std::vector<uint8_t> & encoded_bytes,mojom::ImageCodec codec,bool shrink_to_fit,uint64_t max_size_in_bytes,const gfx::Size & desired_image_frame_size,mojom::ImageDecoder::DecodeImageCallback callback)56 void DecodeImage(DataDecoder* data_decoder,
57 const std::vector<uint8_t>& encoded_bytes,
58 mojom::ImageCodec codec,
59 bool shrink_to_fit,
60 uint64_t max_size_in_bytes,
61 const gfx::Size& desired_image_frame_size,
62 mojom::ImageDecoder::DecodeImageCallback callback) {
63 mojo::Remote<mojom::ImageDecoder> decoder;
64 data_decoder->GetService()->BindImageDecoder(
65 decoder.BindNewPipeAndPassReceiver());
66
67 // |call_once| runs |callback| on its first invocation.
68 auto call_once = base::AdaptCallbackForRepeating(std::move(callback));
69 decoder.set_disconnect_handler(base::BindOnce(call_once, SkBitmap()));
70
71 mojom::ImageDecoder* raw_decoder = decoder.get();
72 raw_decoder->DecodeImage(
73 encoded_bytes, codec, shrink_to_fit, max_size_in_bytes,
74 desired_image_frame_size,
75 base::BindOnce(&OnDecodeImage, std::move(decoder), std::move(call_once)));
76 }
77
DecodeAnimationIsolated(const std::vector<uint8_t> & encoded_bytes,bool shrink_to_fit,uint64_t max_size_in_bytes,mojom::ImageDecoder::DecodeAnimationCallback callback)78 void DecodeAnimationIsolated(
79 const std::vector<uint8_t>& encoded_bytes,
80 bool shrink_to_fit,
81 uint64_t max_size_in_bytes,
82 mojom::ImageDecoder::DecodeAnimationCallback callback) {
83 // Create a new DataDecoder that we keep alive until |callback| is invoked.
84 auto decoder = std::make_unique<DataDecoder>();
85 auto* raw_decoder = decoder.get();
86 auto wrapped_callback = base::BindOnce(
87 [](std::unique_ptr<DataDecoder>,
88 mojom::ImageDecoder::DecodeAnimationCallback callback,
89 std::vector<mojom::AnimationFramePtr> frames) {
90 std::move(callback).Run(std::move(frames));
91 },
92 std::move(decoder), std::move(callback));
93 DecodeAnimation(raw_decoder, encoded_bytes, shrink_to_fit, max_size_in_bytes,
94 std::move(wrapped_callback));
95 }
96
DecodeAnimation(DataDecoder * data_decoder,const std::vector<uint8_t> & encoded_bytes,bool shrink_to_fit,uint64_t max_size_in_bytes,mojom::ImageDecoder::DecodeAnimationCallback callback)97 void DecodeAnimation(DataDecoder* data_decoder,
98 const std::vector<uint8_t>& encoded_bytes,
99 bool shrink_to_fit,
100 uint64_t max_size_in_bytes,
101 mojom::ImageDecoder::DecodeAnimationCallback callback) {
102 mojo::Remote<mojom::ImageDecoder> decoder;
103 data_decoder->GetService()->BindImageDecoder(
104 decoder.BindNewPipeAndPassReceiver());
105
106 // |call_once| runs |callback| on its first invocation.
107 auto call_once = base::AdaptCallbackForRepeating(std::move(callback));
108 decoder.set_disconnect_handler(
109 base::BindOnce(call_once, std::vector<mojom::AnimationFramePtr>()));
110
111 mojom::ImageDecoder* raw_decoder = decoder.get();
112 raw_decoder->DecodeAnimation(
113 encoded_bytes, shrink_to_fit, max_size_in_bytes,
114 base::BindOnce(&OnDecodeImages, std::move(decoder),
115 std::move(call_once)));
116 }
117
118 } // namespace data_decoder
119