Commit 29334cc2 authored by junweifu's avatar junweifu Committed by Commit Bot

ShapeDetection: Start with the minimum Text Detection Win implementation

Load com base functions dynamically at runtime with core_winrt_util.
Text Detection only support Latin-1 text as documented in specification[1], the
service can't be connected if the language isn't supported on the system.
Create OcrEngine interface that provides optical character(OCR) functionality.
Add unittest to test the result of Creating OcrEngine.

[1] https://wicg.github.io/shape-detection-api/text.html#text-detection-api

BUG=790931

Cq-Include-Trybots: master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win10_chromium_x64_rel_ng
Change-Id: I4e171aad11a50197c7cfb64547defa24d0988f3e
Reviewed-on: https://chromium-review.googlesource.com/813237
Commit-Queue: Junwei Fu <junwei.fu@intel.com>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524016}
parent 4f5a3229
...@@ -37,7 +37,8 @@ source_set("lib") { ...@@ -37,7 +37,8 @@ source_set("lib") {
"face_detection_impl_win.h", "face_detection_impl_win.h",
"face_detection_provider_win.cc", "face_detection_provider_win.cc",
"face_detection_provider_win.h", "face_detection_provider_win.h",
"text_detection_impl.cc", "text_detection_impl_win.cc",
"text_detection_impl_win.h",
] ]
} else { } else {
sources += [ sources += [
...@@ -109,21 +110,19 @@ service_manifest("manifest") { ...@@ -109,21 +110,19 @@ service_manifest("manifest") {
source_set("tests") { source_set("tests") {
testonly = true testonly = true
sources = [] sources = [
"barcode_detection_impl_mac_unittest.mm",
"face_detection_impl_mac_unittest.mm",
"face_detection_impl_win_unittest.cc",
"text_detection_impl_mac_unittest.mm",
"text_detection_impl_win_unittest.cc",
]
if (is_mac) { if (is_mac) {
sources += [
"barcode_detection_impl_mac_unittest.mm",
"face_detection_impl_mac_unittest.mm",
"text_detection_impl_mac_unittest.mm",
]
libs = [ libs = [
"CoreFoundation.framework", "CoreFoundation.framework",
"CoreGraphics.framework", "CoreGraphics.framework",
"QuartzCore.framework", "QuartzCore.framework",
] ]
} else if (is_win) {
sources += [ "face_detection_impl_win_unittest.cc" ]
} }
deps = [ deps = [
......
...@@ -11,6 +11,7 @@ namespace shape_detection { ...@@ -11,6 +11,7 @@ namespace shape_detection {
class TextDetectionImpl { class TextDetectionImpl {
public: public:
// Binds TextDetection request to an implementation of mojom::TextDetection.
static void Create(mojom::TextDetectionRequest request); static void Create(mojom::TextDetectionRequest request);
private: private:
......
// Copyright 2017 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 "services/shape_detection/text_detection_impl_win.h"
#include <windows.globalization.h>
#include <memory>
#include <utility>
#include <vector>
#include "base/logging.h"
#include "base/win/core_winrt_util.h"
#include "base/win/scoped_hstring.h"
#include "base/win/windows_version.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/shape_detection/text_detection_impl.h"
namespace shape_detection {
using ABI::Windows::Globalization::ILanguageFactory;
using ABI::Windows::Media::Ocr::IOcrEngineStatics;
using base::win::GetActivationFactory;
using base::win::ScopedHString;
// static
void TextDetectionImpl::Create(mojom::TextDetectionRequest request) {
// OcrEngine class is only available in Win 10 onwards (v10.0.10240.0) that
// documents in
// https://docs.microsoft.com/en-us/uwp/api/windows.media.ocr.ocrengine.
if (base::win::GetVersion() < base::win::VERSION_WIN10) {
DVLOG(1) << "Optical character recognition not supported before Windows 10";
return;
}
DCHECK_GE(base::win::OSInfo::GetInstance()->version_number().build, 10240);
// Loads functions dynamically at runtime to prevent library dependencies.
if (!(base::win::ResolveCoreWinRTDelayload() &&
ScopedHString::ResolveCoreWinRTStringDelayload())) {
DLOG(ERROR) << "Failed loading functions from combase.dll";
return;
}
// Text Detection specification only supports Latin-1 text as documented in
// https://wicg.github.io/shape-detection-api/text.html#text-detection-api.
// TODO(junwei.fu): https://crbug.com/794097 consider supporting other Latin
// script language.
ScopedHString language_hstring = ScopedHString::Create("en");
if (!language_hstring.is_valid())
return;
Microsoft::WRL::ComPtr<ILanguageFactory> language_factory;
HRESULT hr =
GetActivationFactory<ILanguageFactory,
RuntimeClass_Windows_Globalization_Language>(
&language_factory);
if (FAILED(hr)) {
DLOG(ERROR) << "ILanguage factory failed: "
<< logging::SystemErrorCodeToString(hr);
return;
}
Microsoft::WRL::ComPtr<ABI::Windows::Globalization::ILanguage> language;
hr = language_factory->CreateLanguage(language_hstring.get(), &language);
if (FAILED(hr)) {
DLOG(ERROR) << "Create language failed: "
<< logging::SystemErrorCodeToString(hr);
return;
}
Microsoft::WRL::ComPtr<IOcrEngineStatics> engine_factory;
hr = GetActivationFactory<IOcrEngineStatics,
RuntimeClass_Windows_Media_Ocr_OcrEngine>(
&engine_factory);
if (FAILED(hr)) {
DLOG(ERROR) << "IOcrEngineStatics factory failed: "
<< logging::SystemErrorCodeToString(hr);
return;
}
boolean is_supported = false;
hr = engine_factory->IsLanguageSupported(language.Get(), &is_supported);
if (FAILED(hr) || !is_supported)
return;
Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine;
hr = engine_factory->TryCreateFromLanguage(language.Get(), &ocr_engine);
if (FAILED(hr)) {
DLOG(ERROR) << "Create engine failed from language: "
<< logging::SystemErrorCodeToString(hr);
return;
}
mojo::MakeStrongBinding(
std::make_unique<TextDetectionImplWin>(std::move(ocr_engine)),
std::move(request));
}
TextDetectionImplWin::TextDetectionImplWin(
Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine)
: ocr_engine_(std::move(ocr_engine)) {
DCHECK(ocr_engine_);
}
TextDetectionImplWin::~TextDetectionImplWin() = default;
void TextDetectionImplWin::Detect(const SkBitmap& bitmap,
DetectCallback callback) {
std::move(callback).Run(std::vector<mojom::TextDetectionResultPtr>());
}
} // namespace shape_detection
// Copyright 2017 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.
#ifndef SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_WIN_H_
#define SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_WIN_H_
#include <windows.media.ocr.h>
#include <wrl/client.h>
#include "base/macros.h"
#include "services/shape_detection/public/interfaces/textdetection.mojom.h"
class SkBitmap;
namespace shape_detection {
using ABI::Windows::Media::Ocr::IOcrEngine;
class TextDetectionImplWin : public mojom::TextDetection {
public:
explicit TextDetectionImplWin(Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine);
~TextDetectionImplWin() override;
// mojom::TextDetection implementation.
void Detect(const SkBitmap& bitmap,
mojom::TextDetection::DetectCallback callback) override;
private:
Microsoft::WRL::ComPtr<IOcrEngine> ocr_engine_;
DISALLOW_COPY_AND_ASSIGN(TextDetectionImplWin);
};
} // namespace shape_detection
#endif // SERVICES_SHAPE_DETECTION_TEXT_DETECTION_IMPL_WIN_H_
// Copyright 2017 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 <memory>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/win/scoped_com_initializer.h"
#include "base/win/windows_version.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/shape_detection/public/interfaces/textdetection.mojom.h"
#include "services/shape_detection/text_detection_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkImage.h"
namespace shape_detection {
namespace {
void DetectTextCallback(base::Closure quit_closure,
size_t* num_text_chunks,
std::vector<mojom::TextDetectionResultPtr> results) {
*num_text_chunks = results.size();
quit_closure.Run();
}
} // namespace
class TextDetectionImplWinTest : public testing::Test {
protected:
TextDetectionImplWinTest() = default;
~TextDetectionImplWinTest() override = default;
void SetUp() override {
scoped_com_initializer_ = std::make_unique<base::win::ScopedCOMInitializer>(
base::win::ScopedCOMInitializer::kMTA);
ASSERT_TRUE(scoped_com_initializer_->Succeeded());
}
private:
std::unique_ptr<base::win::ScopedCOMInitializer> scoped_com_initializer_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
DISALLOW_COPY_AND_ASSIGN(TextDetectionImplWinTest);
};
TEST_F(TextDetectionImplWinTest, ScanOnce) {
// OCR not supported before Windows 10
if (base::win::GetVersion() < base::win::VERSION_WIN10)
return;
mojom::TextDetectionPtr text_service;
auto request = mojo::MakeRequest(&text_service);
TextDetectionImpl::Create(std::move(request));
SkBitmap bitmap;
bitmap.allocN32Pixels(100, 100);
bitmap.eraseColor(SK_ColorBLUE);
base::RunLoop run_loop;
size_t num_text_chunks = 1u;
text_service->Detect(
bitmap, base::BindOnce(&DetectTextCallback, run_loop.QuitClosure(),
&num_text_chunks));
run_loop.Run();
EXPECT_EQ(0u, num_text_chunks);
}
} // namespace shape_detection
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment