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

Unified Diff: chrome/utility/image_decoder_impl.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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/utility/image_decoder_impl.h ('k') | content/browser/utility_process_host_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/utility/image_decoder_impl.cc
diff --git a/chrome/utility/image_decoder_impl.cc b/chrome/utility/image_decoder_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1c809334e89c8d62ad9d374fa4bb7d6d6e8cc7d9
--- /dev/null
+++ b/chrome/utility/image_decoder_impl.cc
@@ -0,0 +1,137 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "chrome/utility/image_decoder_impl.h"
+
+#include <string.h>
+
+#include "base/base64.h"
+#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
+#include "chrome/common/chrome_utility_messages.h"
+#include "content/child/child_process.h"
+#include "content/public/child/image_decoder_utils.h"
+#include "content/public/common/content_switches.h"
+#include "skia/ext/image_operations.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/jpeg_codec.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace mojo {
+
+// TODO(amistry): Move somewhere else.
+template <>
+struct TypeConverter<content::ImageDataPtr, SkBitmap> {
+ static content::ImageDataPtr Convert(const SkBitmap& bitmap) {
+ content::ImageDataPtr result = content::ImageData::New();
+ const SkImageInfo& info = bitmap.info();
+ result->color_type = info.fColorType;
+ result->alpha_type = info.fAlphaType;
+ result->width = info.fWidth;
+ result->height = info.fHeight;
+ SkAutoLockPixels lock(bitmap);
+ size_t size = bitmap.getSize();
+ result->pixels = mojo::Array<uint8_t>::New(size);
+ memcpy(&result->pixels[0], bitmap.getPixels(), size);
+ return result.Pass();
+ }
+};
+
+} // namespace mojo
+
+namespace content {
+
+ImageDecoderImpl::ImageDecoderImpl() {
+}
+
+ImageDecoderImpl::~ImageDecoderImpl() {
+ // TODO(amistry): Single process mode.
+ // TODO(amistry): This is the wrong place to do this.
+ LOG(INFO) << "Possibly destroying utility process";
+ content::ChildProcess::current()->ReleaseProcess();
+}
+
+void ImageDecoderImpl::DecodeImage(
+ mojo::Array<uint8_t> encoded_data,
+ bool use_robust_jpeg,
+ bool shrink_to_fit,
+ const mojo::Callback<void(bool, ImageDataPtr)>& callback) {
+ LOG(INFO) << "ImageDecoderImpl::DecodeImage: " << encoded_data.size()
+ << ", " << use_robust_jpeg << ", " << shrink_to_fit;
+ if (use_robust_jpeg) {
+ // Our robust jpeg decoding is using IJG libjpeg.
+ if (gfx::JPEGCodec::JpegLibraryVariant() == gfx::JPEGCodec::IJG_LIBJPEG &&
+ encoded_data.size()) {
+ scoped_ptr<SkBitmap> decoded_image(gfx::JPEGCodec::Decode(
+ &encoded_data[0], encoded_data.size()));
+ if (decoded_image.get() && !decoded_image->empty()) {
+ ImageDataPtr image = ImageData::From(*decoded_image);
+ LOG(INFO) << "............Done decoding image";
+ callback.Run(true, image.Pass());
+ return;
+ }
+ }
+ LOG(ERROR) << "Unable to do robust JPEG decode";
+ callback.Run(false, ImageDataPtr());
+ } else {
+ SkBitmap decoded_image = content::DecodeImage(&encoded_data[0],
+ gfx::Size(),
+ encoded_data.size());
+
+ ImageDataPtr image = ImageData::From(decoded_image);
+ // TODO(amistry): Do this!
+ // TODO(amistry): Resizing is (should be) orthogonal to decoding.
+ if (GetSerializedSize_(image) > 32*1024*1024) {
+ if (shrink_to_fit) {
+ LOG(ERROR) << "Resize currently unsupported";
+ } else {
+ // Image too big for IPC message, but caller didn't request resize;
+ LOG(ERROR) << "Decoded image too large for IPC message";
+ }
+ callback.Run(false, ImageDataPtr());
+ return;
+ }
+
+ callback.Run(true, image.Pass());
+ }
+ LOG(INFO) << "............Done decoding image";
+/*
+ int64_t struct_size = sizeof(ChromeUtilityHostMsg_DecodeImage_Succeeded);
+ int64_t image_size = decoded_image.computeSize64();
+ int halves = 0;
+ while (struct_size + (image_size >> 2*halves) > max_ipc_message_size_)
+ halves++;
+ if (halves) {
+ if (shrink_to_fit) {
+ // If decoded image is too large for IPC message, shrink it by halves.
+ // This prevents quality loss, and should never overshrink on displays
+ // smaller than 3600x2400.
+ // TODO (Issue 416916): Instead of shrinking, return via shared memory
+ decoded_image = skia::ImageOperations::Resize(
+ decoded_image, skia::ImageOperations::RESIZE_LANCZOS3,
+ decoded_image.width() >> halves, decoded_image.height() >> halves);
+ } else {
+ decoded_image.reset();
+ }
+ }
+ return decoded_image;
+*/
+}
+
+void ImageDecoderImpl::DecodeImageBase64(
+ const mojo::String& encoded_data,
+ const mojo::Callback<void(bool, ImageDataPtr)>& callback) {
+ std::string decoded_data;
+ if (!base::Base64Decode(encoded_data.get(), &decoded_data)) {
+ LOG(ERROR) << "Unable to base64 decode image";
+ callback.Run(false, ImageDataPtr());
+ return;
+ }
+
+ mojo::Array<uint8_t> decoded_array(decoded_data.size());
+ // TODO(amistry): This seems wrong.
+ memcpy(&decoded_array[0], decoded_data.data(), decoded_data.size());
+ DecodeImage(decoded_array.Pass(), false, false, callback);
+}
+
+} // namespace content
« no previous file with comments | « chrome/utility/image_decoder_impl.h ('k') | content/browser/utility_process_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698