Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: chrome/utility/chrome_content_utility_client.cc

Issue 865543002: WIP: Browser image decoding using Mojo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup and add DecodeImageBase64. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/utility/chrome_content_utility_client.h" 5 #include "chrome/utility/chrome_content_utility_client.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/json/json_reader.h" 9 #include "base/json/json_reader.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "content/child/child_process.h"
12 #include "chrome/common/chrome_utility_messages.h" 13 #include "chrome/common/chrome_utility_messages.h"
13 #include "chrome/common/safe_browsing/zip_analyzer.h" 14 #include "chrome/common/safe_browsing/zip_analyzer.h"
14 #include "chrome/utility/chrome_content_utility_ipc_whitelist.h" 15 #include "chrome/utility/chrome_content_utility_ipc_whitelist.h"
16 #include "chrome/utility/image_decoder_impl.h"
15 #include "chrome/utility/utility_message_handler.h" 17 #include "chrome/utility/utility_message_handler.h"
16 #include "content/public/child/image_decoder_utils.h" 18 #include "content/public/child/image_decoder_utils.h"
17 #include "content/public/common/content_switches.h" 19 #include "content/public/common/content_switches.h"
20 #include "content/public/common/service_registry.h"
18 #include "content/public/utility/utility_thread.h" 21 #include "content/public/utility/utility_thread.h"
19 #include "courgette/courgette.h" 22 #include "courgette/courgette.h"
20 #include "courgette/third_party/bsdiff.h" 23 #include "courgette/third_party/bsdiff.h"
21 #include "ipc/ipc_channel.h" 24 #include "ipc/ipc_channel.h"
22 #include "skia/ext/image_operations.h" 25 #include "skia/ext/image_operations.h"
23 #include "third_party/skia/include/core/SkBitmap.h" 26 #include "third_party/skia/include/core/SkBitmap.h"
24 #include "third_party/zlib/google/zip.h" 27 #include "third_party/zlib/google/zip.h"
25 #include "ui/gfx/codec/jpeg_codec.h" 28 #include "ui/gfx/codec/jpeg_codec.h"
26 #include "ui/gfx/geometry/size.h" 29 #include "ui/gfx/geometry/size.h"
27 30
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 125 }
123 } 126 }
124 127
125 bool ChromeContentUtilityClient::OnMessageReceived( 128 bool ChromeContentUtilityClient::OnMessageReceived(
126 const IPC::Message& message) { 129 const IPC::Message& message) {
127 if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) 130 if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type()))
128 return false; 131 return false;
129 132
130 bool handled = true; 133 bool handled = true;
131 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message) 134 IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message)
132 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImage, OnDecodeImage)
133 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustJPEGDecodeImage,
134 OnRobustJPEGDecodeImage)
135 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseJSON, OnParseJSON) 135 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseJSON, OnParseJSON)
136 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff, 136 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff,
137 OnPatchFileBsdiff) 137 OnPatchFileBsdiff)
138 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette, 138 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette,
139 OnPatchFileCourgette) 139 OnPatchFileCourgette)
140 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing) 140 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing)
141 #if defined(FULL_SAFE_BROWSING) 141 #if defined(FULL_SAFE_BROWSING)
142 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection, 142 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection,
143 OnAnalyzeZipFileForDownloadProtection) 143 OnAnalyzeZipFileForDownloadProtection)
144 #endif 144 #endif
145 #if defined(ENABLE_EXTENSIONS) 145 #if defined(ENABLE_EXTENSIONS)
146 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseMediaMetadata, 146 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseMediaMetadata,
147 OnParseMediaMetadata) 147 OnParseMediaMetadata)
148 #endif 148 #endif
149 #if defined(OS_CHROMEOS) 149 #if defined(OS_CHROMEOS)
150 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CreateZipFile, OnCreateZipFile) 150 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CreateZipFile, OnCreateZipFile)
151 #endif 151 #endif
152 IPC_MESSAGE_UNHANDLED(handled = false) 152 IPC_MESSAGE_UNHANDLED(handled = false)
153 IPC_END_MESSAGE_MAP() 153 IPC_END_MESSAGE_MAP()
154 154
155 for (Handlers::iterator it = handlers_.begin(); 155 for (Handlers::iterator it = handlers_.begin();
156 !handled && it != handlers_.end(); ++it) { 156 !handled && it != handlers_.end(); ++it) {
157 handled = (*it)->OnMessageReceived(message); 157 handled = (*it)->OnMessageReceived(message);
158 } 158 }
159 159
160 return handled; 160 return handled;
161 } 161 }
162 162
163 static void CreateImageDecoder(
164 mojo::InterfaceRequest<content::ImageDecoder> request) {
165 // TODO(amistry): Single process mode.
166 content::ChildProcess::current()->AddRefProcess();
167 mojo::BindToRequest(new content::ImageDecoderImpl, &request);
168 }
169
170 void ChromeContentUtilityClient::RegisterMojoServices(
171 content::ServiceRegistry* registry) {
172 registry->AddService<content::ImageDecoder>(base::Bind(
173 CreateImageDecoder));
174 }
175
163 // static 176 // static
164 void ChromeContentUtilityClient::PreSandboxStartup() { 177 void ChromeContentUtilityClient::PreSandboxStartup() {
165 #if defined(ENABLE_EXTENSIONS) 178 #if defined(ENABLE_EXTENSIONS)
166 extensions::ExtensionsHandler::PreSandboxStartup(); 179 extensions::ExtensionsHandler::PreSandboxStartup();
167 #endif 180 #endif
168 181
169 #if defined(ENABLE_PRINT_PREVIEW) || defined(OS_WIN) 182 #if defined(ENABLE_PRINT_PREVIEW) || defined(OS_WIN)
170 PrintingHandler::PreSandboxStartup(); 183 PrintingHandler::PreSandboxStartup();
171 #endif 184 #endif
172 185
173 #if defined(ENABLE_MDNS) 186 #if defined(ENABLE_MDNS)
174 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 187 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
175 switches::kUtilityProcessEnableMDns)) { 188 switches::kUtilityProcessEnableMDns)) {
176 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup(); 189 local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup();
177 } 190 }
178 #endif // ENABLE_MDNS 191 #endif // ENABLE_MDNS
179 } 192 }
180 193
181 // static
182 SkBitmap ChromeContentUtilityClient::DecodeImage(
183 const std::vector<unsigned char>& encoded_data, bool shrink_to_fit) {
184 SkBitmap decoded_image = content::DecodeImage(&encoded_data[0],
185 gfx::Size(),
186 encoded_data.size());
187
188 int64_t struct_size = sizeof(ChromeUtilityHostMsg_DecodeImage_Succeeded);
189 int64_t image_size = decoded_image.computeSize64();
190 int halves = 0;
191 while (struct_size + (image_size >> 2*halves) > max_ipc_message_size_)
192 halves++;
193 if (halves) {
194 if (shrink_to_fit) {
195 // If decoded image is too large for IPC message, shrink it by halves.
196 // This prevents quality loss, and should never overshrink on displays
197 // smaller than 3600x2400.
198 // TODO (Issue 416916): Instead of shrinking, return via shared memory
199 decoded_image = skia::ImageOperations::Resize(
200 decoded_image, skia::ImageOperations::RESIZE_LANCZOS3,
201 decoded_image.width() >> halves, decoded_image.height() >> halves);
202 } else {
203 // Image too big for IPC message, but caller didn't request resize;
204 // pre-delete image so DecodeImageAndSend() will send an error.
205 decoded_image.reset();
206 LOG(ERROR) << "Decoded image too large for IPC message";
207 }
208 }
209
210 return decoded_image;
211 }
212
213 // static
214 void ChromeContentUtilityClient::DecodeImageAndSend(
215 const std::vector<unsigned char>& encoded_data, bool shrink_to_fit){
216 SkBitmap decoded_image = DecodeImage(encoded_data, shrink_to_fit);
217
218 if (decoded_image.empty()) {
219 Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
220 } else {
221 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image));
222 }
223 ReleaseProcessIfNeeded();
224 }
225
226 void ChromeContentUtilityClient::OnDecodeImage(
227 const std::vector<unsigned char>& encoded_data, bool shrink_to_fit) {
228 DecodeImageAndSend(encoded_data, shrink_to_fit);
229 }
230
231 #if defined(OS_CHROMEOS) 194 #if defined(OS_CHROMEOS)
232 void ChromeContentUtilityClient::OnCreateZipFile( 195 void ChromeContentUtilityClient::OnCreateZipFile(
233 const base::FilePath& src_dir, 196 const base::FilePath& src_dir,
234 const std::vector<base::FilePath>& src_relative_paths, 197 const std::vector<base::FilePath>& src_relative_paths,
235 const base::FileDescriptor& dest_fd) { 198 const base::FileDescriptor& dest_fd) {
236 // dest_fd should be closed in the function. See ipc/ipc_message_util.h for 199 // dest_fd should be closed in the function. See ipc/ipc_message_util.h for
237 // details. 200 // details.
238 base::ScopedFD fd_closer(dest_fd.fd); 201 base::ScopedFD fd_closer(dest_fd.fd);
239 bool succeeded = true; 202 bool succeeded = true;
240 203
(...skipping 12 matching lines...) Expand all
253 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd); 216 succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd);
254 217
255 if (succeeded) 218 if (succeeded)
256 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded()); 219 Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded());
257 else 220 else
258 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed()); 221 Send(new ChromeUtilityHostMsg_CreateZipFile_Failed());
259 ReleaseProcessIfNeeded(); 222 ReleaseProcessIfNeeded();
260 } 223 }
261 #endif // defined(OS_CHROMEOS) 224 #endif // defined(OS_CHROMEOS)
262 225
263 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage(
264 const std::vector<unsigned char>& encoded_data) {
265 // Our robust jpeg decoding is using IJG libjpeg.
266 if (gfx::JPEGCodec::JpegLibraryVariant() == gfx::JPEGCodec::IJG_LIBJPEG &&
267 !encoded_data.empty()) {
268 scoped_ptr<SkBitmap> decoded_image(gfx::JPEGCodec::Decode(
269 &encoded_data[0], encoded_data.size()));
270 if (!decoded_image.get() || decoded_image->empty()) {
271 Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
272 } else {
273 Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(*decoded_image));
274 }
275 } else {
276 Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
277 }
278 ReleaseProcessIfNeeded();
279 }
280
281 void ChromeContentUtilityClient::OnParseJSON(const std::string& json) { 226 void ChromeContentUtilityClient::OnParseJSON(const std::string& json) {
282 int error_code; 227 int error_code;
283 std::string error; 228 std::string error;
284 base::Value* value = base::JSONReader::ReadAndReturnError( 229 base::Value* value = base::JSONReader::ReadAndReturnError(
285 json, base::JSON_PARSE_RFC, &error_code, &error); 230 json, base::JSON_PARSE_RFC, &error_code, &error);
286 if (value) { 231 if (value) {
287 base::ListValue wrapper; 232 base::ListValue wrapper;
288 wrapper.Append(value); 233 wrapper.Append(value);
289 Send(new ChromeUtilityHostMsg_ParseJSON_Succeeded(wrapper)); 234 Send(new ChromeUtilityHostMsg_ParseJSON_Succeeded(wrapper));
290 } else { 235 } else {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 const std::string& mime_type, int64 total_size, bool get_attached_images) { 293 const std::string& mime_type, int64 total_size, bool get_attached_images) {
349 // Only one IPCDataSource may be created and added to the list of handlers. 294 // Only one IPCDataSource may be created and added to the list of handlers.
350 metadata::IPCDataSource* source = new metadata::IPCDataSource(total_size); 295 metadata::IPCDataSource* source = new metadata::IPCDataSource(total_size);
351 handlers_.push_back(source); 296 handlers_.push_back(source);
352 297
353 metadata::MediaMetadataParser* parser = new metadata::MediaMetadataParser( 298 metadata::MediaMetadataParser* parser = new metadata::MediaMetadataParser(
354 source, mime_type, get_attached_images); 299 source, mime_type, get_attached_images);
355 parser->Start(base::Bind(&FinishParseMediaMetadata, base::Owned(parser))); 300 parser->Start(base::Bind(&FinishParseMediaMetadata, base::Owned(parser)));
356 } 301 }
357 #endif 302 #endif
OLDNEW
« no previous file with comments | « chrome/utility/chrome_content_utility_client.h ('k') | chrome/utility/extensions/extensions_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698