OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/renderer/extensions/chrome_private_custom_bindings.h" | |
6 | |
7 #include <algorithm> | |
8 #include <string> | |
9 #include <vector> | |
10 | |
11 #include "chrome/common/extensions/extension_action.h" | |
12 #include "chrome/renderer/extensions/extension_dispatcher.h" | |
13 #include "grit/renderer_resources.h" | |
14 #include "third_party/skia/include/core/SkBitmap.h" | |
15 #include "v8/include/v8.h" | |
16 #include "webkit/glue/webkit_glue.h" | |
17 | |
18 namespace extensions { | |
19 | |
20 ChromePrivateCustomBindings::ChromePrivateCustomBindings( | |
21 ExtensionDispatcher* extension_dispatcher) | |
22 : ChromeV8Extension(extension_dispatcher) { | |
23 RouteStaticFunction("DecodeJPEG", &DecodeJPEG); | |
24 } | |
25 | |
26 // static | |
27 v8::Handle<v8::Value> ChromePrivateCustomBindings::DecodeJPEG( | |
28 const v8::Arguments& args) { | |
29 ChromePrivateCustomBindings* v8_extension = | |
30 GetFromArguments<ChromePrivateCustomBindings>(args); | |
31 const ::Extension* extension = | |
32 v8_extension->GetExtensionForCurrentRenderView(); | |
33 if (!extension) | |
34 return v8::Undefined(); | |
35 | |
36 DCHECK(args.Length() == 1); | |
37 DCHECK(args[0]->IsArray()); | |
38 v8::Local<v8::Object> jpeg_array = args[0]->ToObject(); | |
39 size_t jpeg_length = | |
40 jpeg_array->Get(v8::String::New("length"))->Int32Value(); | |
41 | |
42 // Put input JPEG array into string for DecodeImage(). | |
43 std::string jpeg_array_string; | |
44 jpeg_array_string.reserve(jpeg_length); | |
45 | |
46 // Unfortunately we cannot request continuous backing store of the | |
47 // |jpeg_array| object as it might not have one. So we make | |
48 // element copy here. | |
49 // Note(mnaganov): If it is not fast enough | |
50 // (and main constraints might be in repetition of v8 API calls), | |
51 // change the argument type from Array to String and use | |
52 // String::Write(). | |
53 // Note(vitalyr): Another option is to use Int8Array for inputs and | |
54 // Int32Array for output. | |
55 for (size_t i = 0; i != jpeg_length; ++i) { | |
56 jpeg_array_string.push_back( | |
57 jpeg_array->Get(v8::Integer::New(i))->Int32Value()); | |
58 } | |
59 | |
60 // Decode and verify resulting image metrics. | |
61 SkBitmap bitmap; | |
62 if (!webkit_glue::DecodeImage(jpeg_array_string, &bitmap)) | |
63 return v8::Undefined(); | |
64 if (bitmap.config() != SkBitmap::kARGB_8888_Config) | |
65 return v8::Undefined(); | |
66 const int width = bitmap.width(); | |
67 const int height = bitmap.height(); | |
68 SkAutoLockPixels lockpixels(bitmap); | |
69 const uint32_t* pixels = static_cast<uint32_t*>(bitmap.getPixels()); | |
70 if (!pixels) | |
71 return v8::Undefined(); | |
72 | |
73 // Compose output array. This API call only accepts kARGB_8888_Config images | |
74 // so we rely on each pixel occupying 4 bytes. | |
75 // Note(mnaganov): to speed this up, you may use backing store | |
76 // technique from CreateExternalArray() of v8/src/d8.cc. | |
77 v8::Local<v8::Array> bitmap_array(v8::Array::New(width * height)); | |
78 for (int i = 0; i != width * height; ++i) { | |
79 bitmap_array->Set(v8::Integer::New(i), | |
80 v8::Integer::New(pixels[i] & 0xFFFFFF)); | |
81 } | |
82 return bitmap_array; | |
83 } | |
84 | |
85 } // namespace extensions | |
OLD | NEW |