17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ImageProc/processor_invert.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 |
3 | class InvertProcessor : public Processor {
4 | public:
5 | cv::Mat operator()(cv::Mat);
6 | };
7 |
8 | cv::Mat InvertProcessor::operator()(cv::Mat im) {
9 | cv::Mat dest;
10 | // Subtract the image from a constant 255 4-channel array
11 | cv::subtract( cv::Scalar(255, 255, 255, 255), im, dest );
12 | // Set the alpha channel back to fully opaque
13 | cv::add( cv::Scalar(0,0,0,255), dest, im );
14 |
15 | return im;
16 | }
17 |
18 | namespace {
19 | auto invertProcReg = ProcessorRegister("Invert");
20 | }
21 |
--------------------------------------------------------------------------------
/ImageProc/processor_facedetect.hpp:
--------------------------------------------------------------------------------
1 | #ifndef PROCESSOR_FACEDETECT_HPP
2 | #define PROCESSOR_FACEDETECT_HPP
3 | #include "face_detector.hpp"
4 |
5 | class FaceDetectorProcessor : public FaceDetector {
6 | public:
7 | cv::Mat operator()(cv::Mat);
8 | FaceDetectorProcessor();
9 | virtual ~FaceDetectorProcessor(){};
10 | // Helper method to detect faces
11 | virtual void detectFaces(const cv::Mat, std::vector&);
12 | private:
13 | cv::CascadeClassifier face_cascade;
14 | bool xmlLoaded;
15 | static void createOutput(cv::Mat&, cv::Mat&);
16 | static std::string getClassifier();
17 | };
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/Counter/instance_factory.hpp:
--------------------------------------------------------------------------------
1 | #ifndef INSTANCE_FACTORY_HPP
2 | #define INSTANCE_FACTORY_HPP
3 |
4 | #include "ppapi/cpp/instance.h"
5 | #include "ppapi/cpp/module.h"
6 | #include "ppapi/cpp/var.h"
7 |
8 | // Factory method called by the browser when first loaded
9 | namespace pp {
10 | Module* CreateModule();
11 | };
12 |
13 | // Module used to create instance of NaCl module on webpage
14 | template
15 | class InstanceFactory : public pp::Module {
16 | public:
17 | InstanceFactory( ){};
18 | virtual ~InstanceFactory(){};
19 | virtual pp::Instance* CreateInstance( PP_Instance instance ) {
20 | return new T(instance);
21 | };
22 | };
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/ImageProc/instance_factory.hpp:
--------------------------------------------------------------------------------
1 | #ifndef INSTANCE_FACTORY_HPP
2 | #define INSTANCE_FACTORY_HPP
3 |
4 | #include "ppapi/cpp/instance.h"
5 | #include "ppapi/cpp/module.h"
6 | #include "ppapi/cpp/var.h"
7 |
8 | // Factory method called by the browser when first loaded
9 | namespace pp {
10 | Module* CreateModule();
11 | };
12 |
13 | // Module used to create instance of NaCl module on webpage
14 | template
15 | class InstanceFactory : public pp::Module {
16 | public:
17 | InstanceFactory( ){};
18 | virtual ~InstanceFactory(){};
19 | virtual pp::Instance* CreateInstance( PP_Instance instance ) {
20 | return new T(instance);
21 | };
22 | };
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/MonteCarlo/instance_factory.hpp:
--------------------------------------------------------------------------------
1 | #ifndef INSTANCE_FACTORY_HPP
2 | #define INSTANCE_FACTORY_HPP
3 |
4 | #include "ppapi/cpp/instance.h"
5 | #include "ppapi/cpp/module.h"
6 | #include "ppapi/cpp/var.h"
7 |
8 | // Factory method called by the browser when first loaded
9 | namespace pp {
10 | Module* CreateModule();
11 | };
12 |
13 | // Module used to create instance of NaCl module on webpage
14 | template
15 | class InstanceFactory : public pp::Module {
16 | public:
17 | InstanceFactory( ){};
18 | virtual ~InstanceFactory(){};
19 | virtual pp::Instance* CreateInstance( PP_Instance instance ) {
20 | return new T(instance);
21 | };
22 | };
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/ImageProc/processor_diff.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 | #include
3 |
4 | class DiffProcessor : public Processor {
5 | public:
6 | cv::Mat operator()(cv::Mat);
7 | private:
8 | cv::Mat prevFrame;
9 | };
10 |
11 | cv::Mat DiffProcessor::operator()(cv::Mat im) {
12 | if ( prevFrame.empty() ) {
13 | prevFrame = im.clone();
14 | } else {
15 | cv::Mat dest;
16 | cv::absdiff( im, prevFrame, dest);
17 | prevFrame = im.clone(); // NB: need to clone image not just copy ref
18 | // Set alpha channel
19 | cv::add( cv::Scalar(0,0,0,255), dest, im );
20 | }
21 | return im;
22 | }
23 |
24 | namespace {
25 | auto diffProcReg = ProcessorRegister("Diff");
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/ImageProc/test_processor.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 | #include
3 | #include
4 |
5 | int main(int argc, char* argv[])
6 | {
7 | cv::Mat input = cv::Mat( 2, 2, CV_8UC4, cv::Scalar(128,192,216,255));
8 | std::cout << "Input = " << std::endl << input << std::endl << std::endl;
9 |
10 | auto processorName = "Invert";
11 | if (argc > 1) {
12 | processorName = argv[1];
13 | }
14 | auto processorFactory = SingletonFactory()>>::getInstance();
15 | auto processor = processorFactory.getObject( processorName )();
16 | auto output = (*processor)( input );
17 |
18 | std::cout << "Output = " << std::endl << output << std::endl << std::endl;
19 |
20 | return 0;
21 | }
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NaCl
2 | ====
3 |
4 | A collection of Google Native Client examples designed primarily to help me learn the platform.
5 | Development history so far:
6 |
7 | - Counter - simple example to get the build chain working.
8 | - Monte Carlo - a more complicated example to use user input and background threads.
9 | - ImageProc - use OpenCV naclport for image processing in the browser.
10 | - Simple - found out there are some example files in the distribution
11 | that simplify things. This is why it can be a good idea to read the doc
12 | occasionally.
13 |
14 | Setup
15 | -----
16 | Please see setup.txt for steps needed to install NaCl SDK and naclports on Ubuntu 14.04.
17 | This works on Amazon AWS t2.micro instance so should be easy to get up and running.
18 |
--------------------------------------------------------------------------------
/ImageProc/processor_redchannel.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 | #include
3 |
4 | class SingleChannelProcessor : public Processor {
5 | public:
6 | cv::Mat operator()(cv::Mat);
7 | };
8 |
9 | cv::Mat SingleChannelProcessor::operator()(cv::Mat im) {
10 | cv::Mat dest;
11 | // Split the matrix into its channels
12 | std::vector rgba;
13 | cv::split(im, rgba);
14 | // Blank matrix for Green and Blue channels
15 | cv::Mat blank = cv::Mat( im.size(), CV_8UC1, cv::Scalar(0));
16 | std::vector rgba_out;
17 | rgba_out.push_back( rgba[0] );
18 | rgba_out.push_back( rgba[0] );
19 | rgba_out.push_back( rgba[0] );
20 | rgba_out.push_back( rgba[3] );
21 |
22 | cv::merge( rgba_out, dest);
23 | return dest;
24 | }
25 |
26 | namespace {
27 | auto scProcReg = ProcessorRegister("Red");
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/Counter/counterView.js:
--------------------------------------------------------------------------------
1 | // Global handle to module
2 | CounterModule = null;
3 |
4 | // Global status message
5 | statusText = 'NO-STATUS';
6 |
7 | function pageDidLoad() {
8 | var listener = document.getElementById("listener");
9 | listener.addEventListener('load', moduleDidLoad, true );
10 | listener.addEventListener('message', handleMessage, true );
11 | if ( CounterModule == null ) {
12 | updateStatus( 'LOADING...' );
13 | } else {
14 | updateStatus();
15 | }
16 | }
17 |
18 | function moduleDidLoad() {
19 | CounterModule = document.getElementById( 'counter' );
20 | updateStatus( 'OK' );
21 | var inc = document.getElementById( 'inc' );
22 | inc.onclick = function() { CounterModule.postMessage(1); };
23 | inc.disabled = false;
24 | }
25 |
26 | function handleMessage(message_event) {
27 | updateStatus(message_event.data);
28 | }
29 |
30 | function updateStatus( optMessage ) {
31 | if (optMessage)
32 | statusText = optMessage;
33 | var statusField = document.getElementById('statusField');
34 | if (statusField) {
35 | statusField.innerHTML = statusText;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/ImageProc/test/simpledom.cpp:
--------------------------------------------------------------------------------
1 | // rapidjson/example/simpledom/simpledom.cpp`
2 | #define CATCH_CONFIG_MAIN
3 | #include "catch/catch.hpp"
4 | #include "rapidjson/document.h"
5 | #include "rapidjson/writer.h"
6 | #include "rapidjson/stringbuffer.h"
7 | #include
8 |
9 | using namespace rapidjson;
10 |
11 | TEST_CASE("JSON Parsed", "[rapidjson]"){
12 | // 1. Parse a JSON string into DOM.
13 | const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
14 | Document d;
15 | d.Parse(json);
16 |
17 | // 2. Modify it by DOM.
18 | Value& s = d["stars"];
19 | s.SetInt(s.GetInt() + 1);
20 | REQUIRE(s.GetInt() == 11);
21 |
22 | // 3. Stringify the DOM
23 | StringBuffer buffer;
24 | Writer writer(buffer);
25 | d.Accept(writer);
26 |
27 | // Output {"project":"rapidjson","stars":11}
28 | const std::string expectedString = "{\"project\":\"rapidjson\",\"stars\":11}";
29 | const std::string testString = buffer.GetString();
30 | REQUIRE( testString == expectedString );
31 | // std::cout << buffer.GetString() << std::endl;
32 | // return 0;
33 | }
34 |
--------------------------------------------------------------------------------
/Simple/Makefile:
--------------------------------------------------------------------------------
1 | # Project Build flags
2 | WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror
3 | CXXFLAGS := -pthread -std=gnu++11 $(WARNINGS)
4 |
5 | #
6 | # Compute tool paths
7 | #
8 | GETOS := python $(NACL_SDK_ROOT)/tools/getos.py
9 | OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py
10 | OSNAME := $(shell $(GETOS))
11 | RM := $(OSHELPERS) rm
12 |
13 | PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl)
14 | PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++
15 | PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize
16 | PNACL_CXXFLAGS := -I$(NACL_SDK_ROOT)/include $(CXXFLAGS)
17 | PNACL_LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_simple -lnacl_io -lppapi_cpp -lppapi -lpthread
18 |
19 | IMPROC_HEADERS := simple_template.cpp
20 |
21 | # Declare the ALL target first, to make the 'all' target the default build
22 | all: simple_template.pexe
23 |
24 |
25 | clean:
26 | $(RM) simple_template.pexe simple_template.bc
27 |
28 | #$(PROC_OBJECTS): $(PROCESSORS) singleton_factory.hpp
29 | # $(PNACL_CXX) -o $@ $< -O2 $(CXXFLAGS) $(LDFLAGS)
30 |
31 | simple_template.bc: $(IMPROC_HEADERS) $(PROCESSORS)
32 | $(PNACL_CXX) -o $@ $< -O2 $(PNACL_CXXFLAGS) $(PNACL_LDFLAGS)
33 |
34 | simple_template.pexe: simple_template.bc
35 | $(PNACL_FINALIZE) -o $@ $<
36 |
37 | serve:
38 | python -m SimpleHTTPServer 8000
39 |
--------------------------------------------------------------------------------
/Simple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 | PPAPI Simple Template
12 |
13 |
14 |
15 |
16 |
PPAPI Simple Template
17 |
Simple template for communication between front end and NaCl backend
18 | using PPAPI Simple library. This example is a cut down combination of
19 | demos/voronoi and tutorials/using_simple_ppapi in the NaCl SDK examples.
20 |
Status: NO-STATUS
21 |
22 |
23 |
24 |
26 |
Output:
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Simple/example.js:
--------------------------------------------------------------------------------
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 | // Once we load, hide the plugin
6 | function moduleDidLoad() {
7 | common.hideModule();
8 | }
9 |
10 | // Add event listeners
11 | function attachListeners() {
12 | document.getElementById('go').addEventListener( 'click',
13 | function() {
14 | common.naclModule.postMessage({'message':'hello'});
15 | });
16 | document.getElementById('quit').addEventListener( 'click',
17 | function() {
18 | common.naclModule.postMessage({'message':'quit'});
19 | });
20 | }
21 |
22 | // Called by the common.js module.
23 | // nacl_io/ppapi_simple generates two different types of messages:
24 | // - messages from /dev/tty (prefixed with PS_TTY_PREFIX)
25 | // - exit message (prefixed with PS_EXIT_MESSAGE)
26 | function handleMessage(message) {
27 | if (message.data.indexOf("exit:") == 0) {
28 | // When we receive the exit message we post an empty reply back to
29 | // confirm, at which point the module will exit.
30 | message.srcElement.postMessage({"exit" : ""});
31 | } else if (message.data.indexOf("tty:") == 0) {
32 | common.logMessage(message.data.slice("tty:".length));
33 | } else {
34 | console.log("Unhandled message: " + message.data);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Counter/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2013 The Native Client 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 | #
6 | # GNU Make based build file. For details on GNU Make see:
7 | # http://www.gnu.org/software/make/manual/make.html
8 | #
9 |
10 | # Project Build flags
11 | WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror
12 | CXXFLAGS := -pthread -std=c++11 $(WARNINGS)
13 |
14 | #
15 | # Compute tool paths
16 | #
17 | GETOS := python $(NACL_SDK_ROOT)/tools/getos.py
18 | OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py
19 | OSNAME := $(shell $(GETOS))
20 | RM := $(OSHELPERS) rm
21 |
22 | PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl)
23 | PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++
24 | PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize
25 | CXXFLAGS := -I$(NACL_SDK_ROOT)/include $(CXXFLAGS)
26 | LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi
27 |
28 | # Declare the ALL target first, to make the 'all' target the default build
29 | all: counter.pexe
30 |
31 | clean:
32 | $(RM) counter.pexe counter.bc
33 |
34 | counter.bc: counter.cpp counter.hpp instance_factory.hpp
35 | $(PNACL_CXX) -o $@ $< -O2 $(CXXFLAGS) $(LDFLAGS)
36 |
37 | counter.pexe: counter.bc
38 | $(PNACL_FINALIZE) -o $@ $<
39 |
40 | serve:
41 | python -m SimpleHTTPServer 8000
42 |
--------------------------------------------------------------------------------
/ImageProc/include/catch/LICENSE_1_0.txt:
--------------------------------------------------------------------------------
1 | Boost Software License - Version 1.0 - August 17th, 2003
2 |
3 | Permission is hereby granted, free of charge, to any person or organization
4 | obtaining a copy of the software and accompanying documentation covered by
5 | this license (the "Software") to use, reproduce, display, distribute,
6 | execute, and transmit the Software, and to prepare derivative works of the
7 | Software, and to permit third-parties to whom the Software is furnished to
8 | do so, all subject to the following:
9 |
10 | The copyright notices in the Software and this entire statement, including
11 | the above license grant, this restriction and the following disclaimer,
12 | must be included in all copies of the Software, in whole or in part, and
13 | all derivative works of the Software, unless such copies or derivative
14 | works are solely in the form of machine-executable object code generated by
15 | a source language processor.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/MonteCarlo/monte_carlo.hpp:
--------------------------------------------------------------------------------
1 | #ifndef MONTE_CARLO_HPP
2 | #define MONTE_CARLO_HPP
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | typedef long unsigned int len_t;
9 |
10 | struct result {
11 | double Mean;
12 | double StDev;
13 | len_t Total; // Total number of points
14 | len_t PointCount; // Number that passed
15 | };
16 |
17 | class MonteCarlo {
18 | public:
19 | explicit MonteCarlo() : unifdist(0.0,1.0) {
20 | };
21 | virtual ~MonteCarlo() {};
22 | result sim( std::function const& f, len_t N) {
23 | // Bind the generator to the first argument of distribution so that
24 | // we can call with rng() instead of dist(gen).
25 | // auto rng = std::bind( unifdist, generator );
26 |
27 | len_t sum = 0;
28 | for( len_t i=0; i unifdist;
47 |
48 | };
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/MonteCarlo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Monte Carlo simulation
5 |
6 |
7 |
8 |
9 |
Monte Carlo simulation using NaCl
10 |
11 |
This page uses
13 | Google Native Client to perform a
15 | Monte Carlo simulation that estimates the fraction of points in the
16 | unit square falling below the selected curve by random sampling using the
17 | selected number of points. The simulation runs in
18 | portable native code, taking around 1 second per million points.
19 |
20 |
Requires Chrome web browser version 31 or above (not Android app)
21 |
22 |
23 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
Status NO-STATUS
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/ImageProc/include/rapidjson/internal/swap.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_
16 | #define RAPIDJSON_INTERNAL_SWAP_H_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | //! Custom swap() to avoid dependency on C++ header
24 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
25 | \note This has the same semantics as std::swap().
26 | */
27 | template
28 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
29 | T tmp = a;
30 | a = b;
31 | b = tmp;
32 | }
33 |
34 | } // namespace internal
35 | RAPIDJSON_NAMESPACE_END
36 |
37 | #endif // RAPIDJSON_INTERNAL_SWAP_H_
38 |
--------------------------------------------------------------------------------
/MonteCarlo/d3/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Michael Bostock
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * The name Michael Bostock may not be used to endorse or promote products
15 | derived from this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/ImageProc/include/rapidjson/internal/strfunc.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | //! Custom strlen() which works on different character types.
24 | /*! \tparam Ch Character type (e.g. char, wchar_t, short)
25 | \param s Null-terminated input string.
26 | \return Number of characters in the string.
27 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
28 | */
29 | template
30 | inline SizeType StrLen(const Ch* s) {
31 | const Ch* p = s;
32 | while (*p) ++p;
33 | return SizeType(p - s);
34 | }
35 |
36 | } // namespace internal
37 | RAPIDJSON_NAMESPACE_END
38 |
39 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_
40 |
--------------------------------------------------------------------------------
/ImageProc/processor_pulsedetect.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 | #include "opencv2/imgproc/imgproc.hpp"
3 |
4 | class PulseDetectionProcessor : public Processor {
5 | public:
6 | PulseDetectionProcessor() :
7 | level(4), r1(0.4), r2(0.05) // , alpha(50.0), chromAttenuation(1.0)
8 | {};
9 | cv::Mat operator()(cv::Mat);
10 | private:
11 | int level;
12 | double r1;
13 | double r2;
14 | // double alpha;
15 | // double chromAttenuation;
16 | cv::Mat prevFrame1;
17 | cv::Mat prevFrame2;
18 | };
19 |
20 | cv::Mat PulseDetectionProcessor::operator()(cv::Mat im) {
21 | cv::Mat dest;
22 | // Convert to YCrCb color space
23 | // cv::cvtColor( im, dest, CV_YCrCb2RGB);
24 |
25 | // Gaussian blur using image pyramid
26 | for (auto i=0; i("Pulse Detection (experimental)");
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/MonteCarlo/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2013 The Native Client 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 | #
6 | # GNU Make based build file. For details on GNU Make see:
7 | # http://www.gnu.org/software/make/manual/make.html
8 | #
9 |
10 | # Project Build flags
11 | WARNINGS := -Wno-long-long -Wall -Wswitch-enum -pedantic -Werror
12 | CXXFLAGS := -pthread -std=gnu++11 $(WARNINGS)
13 |
14 | #
15 | # Compute tool paths
16 | #
17 | GETOS := python $(NACL_SDK_ROOT)/tools/getos.py
18 | OSHELPERS = python $(NACL_SDK_ROOT)/tools/oshelpers.py
19 | OSNAME := $(shell $(GETOS))
20 | RM := $(OSHELPERS) rm
21 |
22 | PNACL_TC_PATH := $(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_pnacl)
23 | PNACL_CXX := $(PNACL_TC_PATH)/bin/pnacl-clang++
24 | PNACL_FINALIZE := $(PNACL_TC_PATH)/bin/pnacl-finalize
25 | CXXFLAGS := -I$(NACL_SDK_ROOT)/include $(CXXFLAGS)
26 | LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi
27 |
28 | # Declare the ALL target first, to make the 'all' target the default build
29 | all: monte_carlo.pexe
30 |
31 | test_mc: monte_carlo.hpp test_mc.cpp
32 | $(CXX) -o test_mc test_mc.cpp -std=c++11
33 |
34 | clean:
35 | $(RM) monte_carlo.pexe monte_carlo.bc
36 |
37 | monte_carlo.bc: monte_carlo.cpp monte_carlo.hpp instance_factory.hpp mc_instance.hpp singleton_factory.hpp model_circle.cpp model_parabola.cpp
38 | $(PNACL_CXX) -o $@ $< model_circle.cpp model_parabola.cpp -O2 $(CXXFLAGS) $(LDFLAGS)
39 |
40 | monte_carlo.pexe: monte_carlo.bc
41 | $(PNACL_FINALIZE) -o $@ $<
42 |
43 | serve:
44 | python -m SimpleHTTPServer 8000
45 |
--------------------------------------------------------------------------------
/ImageProc/processor_gblur.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 | #include "opencv2/imgproc/imgproc.hpp"
3 | #include "include/rapidjson/document.h"
4 | #include
5 |
6 | class GBlurProcessor : public Processor {
7 | public:
8 | GBlurProcessor() : level(4) {};
9 | GBlurProcessor(int level_) : level(level_) {};
10 | cv::Mat operator()(cv::Mat);
11 | void init(const char* json);
12 | std::string getParameters();
13 | private:
14 | int level;
15 | };
16 |
17 | void GBlurProcessor::init(const char* json) {
18 | // Read json string to set properties
19 | using namespace rapidjson;
20 | Document document;
21 | document.Parse(json);
22 | assert(document.IsObject());
23 | assert(document.HasMember("level"));
24 | level = document["level"].GetInt();
25 | }
26 |
27 | std::string GBlurProcessor::getParameters() {
28 | std::ostringstream os;
29 | os << "{\"level\":" << level << "}";
30 | return os.str();
31 | }
32 |
33 | cv::Mat GBlurProcessor::operator()(cv::Mat im) {
34 | cv::Mat dest;
35 | const int in_rows = im.rows;
36 | const int in_cols = im.cols;
37 | // for (auto i=0; i("Gaussian Blur");
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/ImageProc/processor_laplacian.cpp:
--------------------------------------------------------------------------------
1 | #include "singleton_factory.hpp"
2 | #include "opencv2/imgproc/imgproc.hpp"
3 | #include
4 |
5 | // OpenCV Laplacian Derivative example from doc
6 | // http://docs.opencv.org/doc/tutorials/imgtrans/laplace_operator/laplace_operator.html
7 | class LaplacianProcessor : public Processor {
8 | public:
9 | cv::Mat operator()(cv::Mat);
10 | private:
11 | static void createOutput(cv::Mat&, cv::Mat&);
12 | };
13 |
14 | cv::Mat LaplacianProcessor::operator()(cv::Mat im) {
15 |
16 | cv::Mat grey;
17 | // Remove noise by blurring with Gaussian
18 | cv::GaussianBlur(im, im, cv::Size(3,3), 0,0, cv::BORDER_DEFAULT);
19 | cv::cvtColor( im, grey, CV_BGR2GRAY );
20 |
21 | int kernel_size = 3;
22 | int scale = 1;
23 | int delta = 0;
24 | int ddepth = CV_16S;
25 | cv::Mat lap;
26 | cv::Laplacian(grey, lap, ddepth, kernel_size, scale, delta, cv::BORDER_DEFAULT);
27 |
28 | // Scaled abs laplacian
29 | cv::Mat absLap;
30 |
31 | cv::convertScaleAbs(lap, absLap);
32 |
33 | // Display intermediate images for debugging
34 | cv::Mat dest;
35 | createOutput( absLap, dest );
36 | return dest;
37 | }
38 |
39 | void LaplacianProcessor::createOutput( cv::Mat& src, cv::Mat& dest )
40 | {
41 | // Show intermediate images - need to expand CV_8UC1 to RGBA
42 | cv::Mat fullAlpha = cv::Mat( src.size(), CV_8UC1, cv::Scalar(255));
43 | std::vector rgba_out;
44 | rgba_out.push_back( src );
45 | rgba_out.push_back( src );
46 | rgba_out.push_back( src );
47 | rgba_out.push_back( fullAlpha );
48 |
49 | cv::merge( rgba_out, dest);
50 | }
51 |
52 | namespace {
53 | auto scProcReg = ProcessorRegister("Laplacian");
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/ImageProc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | OpenCV in Chrome using NaCl
5 |
6 |
7 |
8 |
9 |
OpenCV in Chrome using NaCl
10 |
11 |
This page uses
13 | Google Native Client to tie in to the C++ OpenCV computer vision library.
15 | This allows realtime image processing of the webcam feed from within the
16 | browser.
17 |
18 | NB: No data is sent back to this website.
19 |
20 |
21 |
Requires Chrome web browser version 44 or above (not Android app)
96 |
97 |
98 |
--------------------------------------------------------------------------------
/ImageProc/include/rapidjson/internal/pow10.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_POW10_
16 | #define RAPIDJSON_POW10_
17 |
18 | #include "../rapidjson.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 | namespace internal {
22 |
23 | //! Computes integer powers of 10 in double (10.0^n).
24 | /*! This function uses lookup table for fast and accurate results.
25 | \param n non-negative exponent. Must <= 308.
26 | \return 10.0^n
27 | */
28 | inline double Pow10(int n) {
29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
30 | 1e+0,
31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
47 | };
48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308);
49 | return e[n];
50 | }
51 |
52 | } // namespace internal
53 | RAPIDJSON_NAMESPACE_END
54 |
55 | #endif // RAPIDJSON_POW10_
56 |
--------------------------------------------------------------------------------
/ImageProc/README.md:
--------------------------------------------------------------------------------
1 | Image Processing
2 | ================
3 | Image processing using Native Client. The goal of this project is to use
4 | the C++ OpenCV image processing library to do realtime image processing of
5 | the webcam feed.
6 |
7 | Implementation
8 | --------------
9 | Rough plan for next few commits:
10 |
11 | - [x] Hidden HTML5 __video__ element sourced from navigator.getUserMedia (webcam).
12 | - [x] Canvas element samples video every 20ms and draws on the canvas.
13 | - [x] Send canvas image as ArrayBuffer to Native Client.
14 | - [x] NaCl echoes image that has been received.
15 | - [x] Javascript puts echoed image to __processed__ canvas.
16 | - [x] Start playing with OpenCV image processing.
17 | - [x] Use strategy pattern on the C++ side to register new image
18 | processors.
19 | - [x] Modify NaCl getVersion interface to return list of available processors.
20 | - [x] Use returned list of processors to populate js list selector.
21 | - [ ] Get the [Pulse Detection](http://people.csail.mit.edu/mrub/vidmag/) filter working.
22 | - [x] Get the [Detecting
23 | Barcodes](http://www.pyimagesearch.com/2014/11/24/detecting-barcodes-images-python-opencv) demo working.
24 | - [x] Simple cartoon filter.
25 | - [x] Face detection.
26 |
27 | [Try it out!](https://www.matt-mcdonnell.com/code/NaCl/ImageProc/index.html) - you may need
28 | to clear the cache to see any updates. To do this open Chrome Developer Tools (Ctrl-Shift-i or F12),
29 | then click and hold Reload, choose "Empty Cache and Hard Reload" from the popup menu. Popup menu may
30 | only appear if you have a cached page i.e. have previously visited.
31 |
32 | Build Setup
33 | -----------
34 | UPDATED: Please see setup.txt in parent directory for a step by step setup on a new Ubuntu server.
35 |
36 | There are a few steps needed to configure in order to use OpenCV with NaCl.
37 | Fortunately, once you become aware of the existence of [NaCl Ports](https://code.google.com/p/naclports/)
38 | they are fairly straight forward.
39 |
40 | 1. Install [Depo Tools](http://dev.chromium.org/developers/how-tos/install-depot-tools).
41 | 2. [Check out the NaCl Ports](https://code.google.com/p/naclports/wiki/HowTo_Checkout).
42 | 2. ~~Follow the [Install guide for SDL](https://code.google.com/p/naclports/wiki/InstallingSDL),
43 | replacing __sdl__ with __opencv__ and choosing pnacl as the architecture to
44 | build.~~
45 | Seems like the original instructions have been deleted, and didn't cover
46 | which branch to use in any event. cd to the dir where you've checked
47 | out nacl_ports (for me ~/Work/ExternCode/nacl_ports/src ) with depotools
48 | then change to the branch that matches NACL_SDK_ROOT
49 |
50 | git checkout pepper_40
51 | NACL_ARCH=pnacl make opencv
52 |
53 | The build itself took about 15 minutes on my Intel i3 dual core laptop.
54 |
55 | 3. Add the opencv libraries and zlib to the build arguments:
56 |
57 | LDFLAGS := -L$(NACL_SDK_ROOT)/lib/pnacl/Release -lppapi_cpp -lppapi -lopencv_core -lz
58 |
59 | Updating NaCl and NaCl Ports
60 | ----------------------------
61 | NaCl updates on around the same release cycle as the Chrome browser.
62 | Chrome itself is backwards compatible but it's still a good idea to keep
63 | roughly up to date.
64 |
65 | Here we assume that the NaCl SDK has been installed in NACL_ROOT
66 | (NACL_SDK_ROOT will be under this), and NaCl ports has been installed in
67 | PORTS_ROOT. On my machine these are ~/Work/ExternCode/nacl_sdk and
68 | ~/Work/ExternCode/nacl_ports respectively.
69 |
70 | 1. Update NaCl SDK
71 | - cd NACL_ROOT
72 | - ./naclsdk update
73 | 2. Update NACL_SDK_ROOT environment variable e.g. NACL_ROOT/pepper_41
74 | 3. Update ports
75 | - cd PORTS_ROOT
76 | - cd src
77 | - git checkout -b pepper_41 origin/pepper_41
78 | - gclient sync
79 | - (If that fails, cd .. vim .gclient and set managed=False)
80 |
81 | LICENSE
82 | -------
83 | BSD
84 |
--------------------------------------------------------------------------------
/ImageProc/include/rapidjson/error/en.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making RapidJSON available.
2 | //
3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 | //
5 | // Licensed under the MIT License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // http://opensource.org/licenses/MIT
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef RAPIDJSON_ERROR_EN_H__
16 | #define RAPIDJSON_ERROR_EN_H__
17 |
18 | #include "error.h"
19 |
20 | RAPIDJSON_NAMESPACE_BEGIN
21 |
22 | //! Maps error code of parsing into error message.
23 | /*!
24 | \ingroup RAPIDJSON_ERRORS
25 | \param parseErrorCode Error code obtained in parsing.
26 | \return the error message.
27 | \note User can make a copy of this function for localization.
28 | Using switch-case is safer for future modification of error codes.
29 | */
30 | inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
31 | switch (parseErrorCode) {
32 | case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
33 |
34 | case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
35 | case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values.");
36 |
37 | case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
38 |
39 | case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
40 | case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
41 | case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
42 |
43 | case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
44 |
45 | case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
46 | case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
47 | case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
48 | case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
49 | case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
50 |
51 | case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
52 | case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
53 | case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
54 |
55 | case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
56 | case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
57 |
58 | default:
59 | return RAPIDJSON_ERROR_STRING("Unknown error.");
60 | }
61 | }
62 |
63 | RAPIDJSON_NAMESPACE_END
64 |
65 | #endif // RAPIDJSON_ERROR_EN_H__
66 |
--------------------------------------------------------------------------------
/ImageProc/url_loader_handler.hpp:
--------------------------------------------------------------------------------
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 | #ifndef URL_LOADER_HANDLER_H_
6 | #define URL_LOADER_HANDLER_H_
7 |
8 | #include
9 | #include "ppapi/cpp/completion_callback.h"
10 | #include "ppapi/cpp/instance.h"
11 | #include "ppapi/cpp/url_loader.h"
12 | #include "ppapi/cpp/url_request_info.h"
13 | #include "ppapi/utility/completion_callback_factory.h"
14 | #define READ_BUFFER_SIZE 32768
15 |
16 | // URLLoaderHandler is used to download data from |url|. When download is
17 | // finished or when an error occurs, it posts a message back to the browser
18 | // with the results encoded in the message as a string and self-destroys.
19 | //
20 | // pp::URLLoader.GetDownloadProgress() is used to to allocate the memory
21 | // required for url_response_body_ before the download starts. (This is not so
22 | // much of a performance improvement, but it saves some memory since
23 | // std::string.insert() typically grows the string's capacity by somewhere
24 | // between 50% to 100% when it needs more memory, depending on the
25 | // implementation.) Other performance improvements made as outlined in this
26 | // bug: http://code.google.com/p/chromium/issues/detail?id=103947
27 | //
28 | // EXAMPLE USAGE:
29 | // URLLoaderHandler* handler* = URLLoaderHandler::Create(instance,url);
30 | // handler->Start();
31 | //
32 | class URLLoaderHandler {
33 | public:
34 | // Creates instance of URLLoaderHandler on the heap.
35 | // URLLoaderHandler objects shall be created only on the heap (they
36 | // self-destroy when all data is in).
37 | static URLLoaderHandler* Create(pp::Instance* instance_,
38 | const std::string& url);
39 | // Initiates page (URL) download.
40 | void Start();
41 |
42 | private:
43 | URLLoaderHandler(pp::Instance* instance_, const std::string& url);
44 | ~URLLoaderHandler();
45 |
46 | // Callback for the pp::URLLoader::Open().
47 | // Called by pp::URLLoader when response headers are received or when an
48 | // error occurs (in response to the call of pp::URLLoader::Open()).
49 | // Look at and
50 | // for more information about pp::URLLoader.
51 | void OnOpen(int32_t result);
52 |
53 | // Callback for the pp::URLLoader::ReadResponseBody().
54 | // |result| contains the number of bytes read or an error code.
55 | // Appends data from this->buffer_ to this->url_response_body_.
56 | void OnRead(int32_t result);
57 |
58 | // Reads the response body (asynchronously) into this->buffer_.
59 | // OnRead() will be called when bytes are received or when an error occurs.
60 | void ReadBody();
61 |
62 | // Append data bytes read from the URL onto the internal buffer. Does
63 | // nothing if |num_bytes| is 0.
64 | void AppendDataBytes(const char* buffer, int32_t num_bytes);
65 |
66 | // Post a message back to the browser with the download results.
67 | void ReportResult(const std::string& fname,
68 | const std::string& text,
69 | bool success);
70 | // Post a message back to the browser with the download results and
71 | // self-destroy. |this| is no longer valid when this method returns.
72 | void ReportResultAndDie(const std::string& fname,
73 | const std::string& text,
74 | bool success);
75 |
76 | pp::Instance* instance_; // Weak pointer.
77 | std::string url_; // URL to be downloaded.
78 | pp::URLRequestInfo url_request_;
79 | pp::URLLoader url_loader_; // URLLoader provides an API to download URLs.
80 | char* buffer_; // Temporary buffer for reads.
81 | std::string url_response_body_; // Contains accumulated downloaded data.
82 | pp::CompletionCallbackFactory cc_factory_;
83 |
84 | URLLoaderHandler(const URLLoaderHandler&);
85 | void operator=(const URLLoaderHandler&);
86 | };
87 |
88 | #endif // URL_LOADER_HANDLER_H_
89 |
--------------------------------------------------------------------------------
/ImageProc/video_img.js:
--------------------------------------------------------------------------------
1 | function make_image_source(useVideo, fileList) {
2 |
3 | var videoSourceId;
4 | var selectedSource;
5 |
6 | var imageData;
7 |
8 | function getVideoSources(cbFun) {
9 | // Populate list of video sources e.g. laptop camera and USB webcam
10 | MediaStreamTrack.getSources(
11 | function( srcInfo ) {
12 | videoSourceId = srcInfo
13 | .filter( function(s) { return s.kind == "video"; } );
14 | selectedSource = videoSourceId[0].id;
15 | if (typeof cbFun !== 'undefined') {
16 | cbFun(videoSourceId);
17 | }
18 | }
19 | );
20 | }
21 |
22 | function setVideoInput(cbFun) {
23 | navigator.webkitGetUserMedia(
24 | {video: { optional:[{sourceId : selectedSource}] }, audio:false},
25 | cbFun,
26 | function (err) {
27 | console.log("Unable to get media stream:" + err.Code );
28 | });
29 | }
30 |
31 | return {
32 | init : getVideoSources,
33 | getSourceIds : function(){ return videoSourceId; },
34 | setSource : function(srcId) { selectedSource = srcId;},
35 | getSource : function() { return selectedSource;},
36 | setVideoInput: setVideoInput
37 | }
38 | }
39 |
40 | function make_image_source_view(image_source) {
41 | // DOM nodes
42 | var videoSelect;
43 | var video;
44 | var display;
45 | var context;
46 |
47 | var src = image_source;
48 | var samplePeriod = 40; // ms
49 | var averageFramePeriod = samplePeriod;
50 | var ewmaSmooth = 0.3;
51 |
52 | var isRunning = false;
53 | var isReadyToReceive = false;
54 |
55 | function setVideoCb () {
56 | console.log("camera changed from " +
57 | src.getSource() + " to " + videoSelect.value);
58 | src.setSource(videoSelect.value);
59 | src.setVideoInput(drawCb);
60 | }
61 |
62 | function drawCb(stream) {
63 | video.src = window.URL.createObjectURL(stream);
64 | start();
65 | }
66 |
67 | function start() {
68 | isRunning = true;
69 | draw();
70 | }
71 |
72 | function draw() {
73 | if (!isRunning) return; // Early exit
74 | // Draw from video v to canvas context c
75 | context.drawImage(video, 0, 0);
76 | setTimeout( draw, samplePeriod, video, context);
77 | }
78 |
79 | function setVideoSelectList(videoSourceId) {
80 | videoSourceId.map( function(s, ind) {
81 | // Set up list of cameras
82 | var option = document.createElement( "option" );
83 | option.text = "camera " + ind;
84 | option.value= s.id;
85 | videoSelect.appendChild( option );
86 | return s.id; } );
87 | setVideoCb();
88 | videoSelect.onchange = setVideoCb;
89 | videoSelect.hidden = false;
90 | }
91 |
92 | function getImageData( id ) {
93 | // Get image data from specified canvas
94 | var cv;
95 | if (typeof id === 'undefined') {
96 | cv = display;
97 | } else {
98 | cv = document.getElementById( id );
99 | }
100 | var ctx = cv.getContext( "2d" );
101 | var height = cv.height;
102 | var width = cv.width;
103 | var nBytes = height * width * 4;
104 | var pixels = ctx.getImageData(0, 0, width, height);
105 | var imData = { width: width, height: height,
106 | data: pixels.data.buffer };
107 | return imData;
108 | }
109 |
110 | function initControls(videoId, canvasId, selectId) {
111 | // DOM Nodes for controls
112 | video = document.getElementById( videoId );
113 | display = document.getElementById( canvasId );
114 | videoSelect = document.getElementById( selectId );
115 | context = display.getContext("2d");
116 | src.init(setVideoSelectList);
117 | }
118 |
119 | return {
120 | init: initControls,
121 | stop: function() { isRunning = false; },
122 | start: start,
123 | setSamplePeriod: function (period) {
124 | samplePeriod = Math.max(period,0); },
125 | getSamplePeriod: function () { return samplePeriod; },
126 | getImageData: getImageData,
127 | isRunning: function() { return isRunning; }
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/ImageProc/image_proc.cpp:
--------------------------------------------------------------------------------
1 | #include "improc_instance.hpp"
2 | #include "singleton_factory.hpp"
3 | #include "url_loader_handler.hpp"
4 | #include
5 | #include
6 | #include
7 |
8 | pp::Module* pp::CreateModule()
9 | {
10 | return new InstanceFactory();
11 | }
12 |
13 | void ImageProcInstance::Process( cv::Mat im)
14 | {
15 | auto result = (*processor)( im );
16 | auto nBytes = result.elemSize() * result.total();
17 | pp::VarDictionary msg;
18 | pp::VarArrayBuffer data(nBytes);
19 | uint8_t* copy = static_cast( data.Map());
20 | memcpy( copy, result.data, nBytes );
21 |
22 | msg.Set( "Type", "completed" );
23 | msg.Set( "Data", data );
24 | msg.Set( "Parameters", processor->getParameters());
25 | PostMessage( msg );
26 | }
27 |
28 | void ImageProcInstance::PostTest()
29 | {
30 | pp::VarDictionary msg;
31 | msg.Set( "Type", "completed" );
32 | msg.Set( "Data", "Processed ok" );
33 | PostMessage( msg );
34 | }
35 |
36 | void ImageProcInstance::SendStatus(const std::string& status)
37 | {
38 | pp::VarDictionary msg;
39 | msg.Set( "Type", "status" );
40 | msg.Set( "Message", status );
41 | PostMessage( msg );
42 | }
43 |
44 |
45 | void ImageProcInstance::HandleMessage( const pp::Var& var_message )
46 | {
47 | // Interface: receive a { cmd: ..., args... } dictionary
48 | pp::VarDictionary var_dict( var_message );
49 | auto cmd = var_dict.Get( "cmd" ).AsString();
50 | if ( cmd == "process" ) {
51 |
52 | // Message is number of simulations to run
53 | auto width = var_dict.Get("width").AsInt();
54 | auto height = var_dict.Get("height").AsInt();
55 | auto data = pp::VarArrayBuffer( var_dict.Get("data") );
56 | auto selectedProcessor = var_dict.Get("processor").AsString();
57 | bool newProcessor = selectedProcessor != processorName;
58 | if ( newProcessor ) {
59 | SendStatus("Creating processor factory");
60 | auto processorFactory = SingletonFactory<
61 | std::function()> >::getInstance();
62 | SendStatus("Creating processor");
63 | processor = processorFactory.getObject( selectedProcessor )();
64 | processorName = selectedProcessor;
65 | } else {
66 | SendStatus("Reusing processor");
67 | }
68 | // Convert data to CMat
69 | // SendStatus("Casting to byte array");
70 | uint8_t* byteData = static_cast(data.Map());
71 | // SendStatus("Creating cv::Mat");
72 | auto Img = cv::Mat(height, width, CV_8UC4, byteData );
73 | // SendStatus("Calling processing");
74 |
75 | // Special case: Smiley
76 | if ( (selectedProcessor == "Smiley!") && newProcessor ) {
77 | // Only send the image data for overlay on the first time we change
78 | // processor
79 | pp::VarDictionary sm_var_dict( var_dict.Get( "args" ));
80 | auto sm_width = sm_var_dict.Get("width").AsInt();
81 | auto sm_height = sm_var_dict.Get("height").AsInt();
82 | auto sm_data = pp::VarArrayBuffer( sm_var_dict.Get("data") );
83 | uint8_t* sm_byteData = static_cast(sm_data.Map());
84 | auto sm_Img = cv::Mat(sm_height, sm_width, CV_8UC4, sm_byteData );
85 | processor->init( sm_Img );
86 | } else if ( var_dict.HasKey( "args" ) ) {
87 | // Args key is json string that processor will parse
88 | auto json = var_dict.Get("args").AsString();
89 | processor->init( json.c_str() );
90 | }
91 | Process( Img );
92 | } else if ( cmd == "test" ) {
93 | PostTest();
94 | } else if ( cmd == "echo" ) {
95 | auto data = pp::VarArrayBuffer( var_dict.Get("data") );
96 | // auto result = data.is_array_buffer();
97 | pp::VarDictionary msg;
98 | msg.Set( "Type", "completed" );
99 | msg.Set( "Data", data );
100 | PostMessage( msg );
101 | } else if ( cmd == "load" ) {
102 | // Load resource URL
103 | auto url = var_dict.Get( "url" ).AsString();
104 | URLLoaderHandler* handler = URLLoaderHandler::Create(this, url);
105 | if (handler != NULL) {
106 | // Starts asynchronous download. When download is finished or when an
107 | // error occurs, |handler| posts the results back to the browser
108 | // vis PostMessage and self-destroys.
109 | handler->Start();
110 | }
111 | } else {
112 | // Disable simulation - background thread will see this at start of
113 | // next iteration and terminate early
114 | run_simulation_ = false;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/GettingStarted/hello_tutorial.cc:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 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 | /// @file hello_tutorial.cc
6 | /// This example demonstrates loading, running and scripting a very simple NaCl
7 | /// module. To load the NaCl module, the browser first looks for the
8 | /// CreateModule() factory method (at the end of this file). It calls
9 | /// CreateModule() once to load the module code. After the code is loaded,
10 | /// CreateModule() is not called again.
11 | ///
12 | /// Once the code is loaded, the browser calls the CreateInstance()
13 | /// method on the object returned by CreateModule(). It calls CreateInstance()
14 | /// each time it encounters an