diff --git a/mediapipe/calculators/audio/spectrogram_calculator.cc b/mediapipe/calculators/audio/spectrogram_calculator.cc index 939e721ab..fbdbbab0a 100644 --- a/mediapipe/calculators/audio/spectrogram_calculator.cc +++ b/mediapipe/calculators/audio/spectrogram_calculator.cc @@ -433,9 +433,9 @@ absl::Status SpectrogramCalculator::ProcessVectorToOutput( absl::Status SpectrogramCalculator::ProcessVector(const Matrix& input_stream, CalculatorContext* cc) { switch (output_type_) { - // These blocks deliberately ignore clang-format to preserve the - // "silhouette" of the different cases. - // clang-format off + // These blocks deliberately ignore clang-format to preserve the + // "silhouette" of the different cases. + // clang-format off case SpectrogramCalculatorOptions::COMPLEX: { return ProcessVectorToOutput( input_stream, diff --git a/mediapipe/tasks/cc/core/BUILD b/mediapipe/tasks/cc/core/BUILD index 95cfdd15e..6f1daa580 100644 --- a/mediapipe/tasks/cc/core/BUILD +++ b/mediapipe/tasks/cc/core/BUILD @@ -61,15 +61,13 @@ cc_library( "//mediapipe/framework/port:status", "//mediapipe/tasks/cc:common", "//mediapipe/tasks/cc/core/proto:external_file_cc_proto", + "//mediapipe/util:resource_util", "@com_google_absl//absl/memory", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", - ] + select({ - "//mediapipe:windows": ["@bazel_tools//tools/cpp/runfiles"], - "//conditions:default": [], - }), + ], ) cc_library( diff --git a/mediapipe/tasks/cc/core/external_file_handler.cc b/mediapipe/tasks/cc/core/external_file_handler.cc index a56f03d55..27b579f97 100644 --- a/mediapipe/tasks/cc/core/external_file_handler.cc +++ b/mediapipe/tasks/cc/core/external_file_handler.cc @@ -43,10 +43,7 @@ limitations under the License. #include "mediapipe/framework/port/status_macros.h" #include "mediapipe/tasks/cc/common.h" #include "mediapipe/tasks/cc/core/proto/external_file.pb.h" - -#ifdef _WIN32 -#include "tools/cpp/runfiles/runfiles.h" -#endif // _WIN32 +#include "mediapipe/util/resource_util.h" namespace mediapipe { namespace tasks { @@ -96,30 +93,6 @@ ExternalFileHandler::CreateFromExternalFile( return handler; } -absl::StatusOr PathToResourceAsFile(std::string path) { -#ifndef _WIN32 - return path; -#else - std::string qualified_path = path; - if (absl::StartsWith(qualified_path, "./")) { - qualified_path = "mediapipe" + qualified_path.substr(1); - } else if (path[0] != '/') { - qualified_path = "mediapipe/" + qualified_path; - } - - std::string error; - // TODO: We should ideally use `CreateForTests` when this is - // accessed from unit tests. - std::unique_ptr<::bazel::tools::cpp::runfiles::Runfiles> runfiles( - ::bazel::tools::cpp::runfiles::Runfiles::Create("", &error)); - if (!runfiles) { - // Return the original path when Runfiles is not available (e.g. for Python) - return path; - } - return runfiles->Rlocation(qualified_path); -#endif // _WIN32 -} - absl::Status ExternalFileHandler::MapExternalFile() { if (!external_file_.file_content().empty()) { return absl::OkStatus(); diff --git a/mediapipe/tasks/cc/text/utils/BUILD b/mediapipe/tasks/cc/text/utils/BUILD index 15af7683b..cd8c7512c 100644 --- a/mediapipe/tasks/cc/text/utils/BUILD +++ b/mediapipe/tasks/cc/text/utils/BUILD @@ -25,6 +25,7 @@ cc_library( "vocab_utils.h", ], deps = [ + "//mediapipe/util:resource_util", "@com_google_absl//absl/container:node_hash_map", "@com_google_absl//absl/strings", ], diff --git a/mediapipe/tasks/cc/text/utils/vocab_utils.cc b/mediapipe/tasks/cc/text/utils/vocab_utils.cc index 068272f7f..a006da6d1 100644 --- a/mediapipe/tasks/cc/text/utils/vocab_utils.cc +++ b/mediapipe/tasks/cc/text/utils/vocab_utils.cc @@ -18,6 +18,7 @@ limitations under the License. #include #include "absl/strings/str_split.h" +#include "mediapipe/util/resource_util.h" namespace mediapipe { namespace tasks { @@ -34,7 +35,11 @@ void ReadIStreamLineByLine( std::string str; while (std::getline(*istream, str)) { if (!str.empty()) { - line_processor(str); + if (str.back() == '\r') { // Remove \r on Windows + line_processor(str.substr(0, str.length() - 1)); + } else { + line_processor(str); + } } } } @@ -64,7 +69,8 @@ std::vector ReadIStreamByLine(std::istream* istream) { std::vector LoadVocabFromFile(const std::string& path_to_vocab) { std::vector vocab_from_file; - std::ifstream in(path_to_vocab.c_str()); + std::string file_name = *PathToResourceAsFile(path_to_vocab); + std::ifstream in(file_name.c_str()); return ReadIStreamByLine(&in); } @@ -79,7 +85,8 @@ std::vector LoadVocabFromBuffer(const char* vocab_buffer_data, absl::node_hash_map LoadVocabAndIndexFromFile( const std::string& path_to_vocab) { absl::node_hash_map vocab_index_map; - std::ifstream in(path_to_vocab.c_str()); + std::string file_name = *PathToResourceAsFile(path_to_vocab); + std::ifstream in(file_name.c_str()); return ReadIStreamLineSplits(&in); } diff --git a/mediapipe/util/BUILD b/mediapipe/util/BUILD index cd82a850a..b0b7f3468 100644 --- a/mediapipe/util/BUILD +++ b/mediapipe/util/BUILD @@ -194,6 +194,7 @@ cc_library( "//mediapipe/framework:android_no_jni": ["resource_util_loonix.cc"], "//mediapipe:ios": ["resource_util_apple.cc"], "//mediapipe:macos": ["resource_util_default.cc"], + "//mediapipe:windows": ["resource_util_windows.cc"], }), hdrs = [ "resource_util.h", @@ -232,6 +233,10 @@ cc_library( "//mediapipe:macos": [ "@com_google_absl//absl/flags:flag", ], + "//mediapipe:windows": [ + "@bazel_tools//tools/cpp/runfiles", + "@com_google_absl//absl/flags:flag", + ], }), ) diff --git a/mediapipe/util/resource_util_windows.cc b/mediapipe/util/resource_util_windows.cc new file mode 100644 index 000000000..34806da49 --- /dev/null +++ b/mediapipe/util/resource_util_windows.cc @@ -0,0 +1,91 @@ +// Copyright 2019 The MediaPipe Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "absl/flags/flag.h" +#include "mediapipe/framework/deps/file_path.h" +#include "mediapipe/framework/port/file_helpers.h" +#include "mediapipe/framework/port/singleton.h" +#include "mediapipe/framework/port/statusor.h" +#include "tools/cpp/runfiles/runfiles.h" + +ABSL_FLAG( + std::string, resource_root_dir, "", + "The absolute path to the resource directory." + "If specified, resource_root_dir will be prepended to the original path."); + +namespace mediapipe { + +using mediapipe::file::GetContents; +using mediapipe::file::JoinPath; + +namespace { + +class RunfilesHolder { + public: + // TODO: We should ideally use `CreateForTests` when this is + // accessed from unit tests. + RunfilesHolder() + : runfiles_( + ::bazel::tools::cpp::runfiles::Runfiles::Create("", nullptr)) {} + + std::string Rlocation(const std::string& path) { + if (!runfiles_) { + // Return the original path when Runfiles is not available (e.g. for + // Python) + return JoinPath(absl::GetFlag(FLAGS_resource_root_dir), path); + } + return runfiles_->Rlocation(path); + } + + private: + std::unique_ptr<::bazel::tools::cpp::runfiles::Runfiles> runfiles_; +}; + +} // namespace + +namespace internal { + +std::string PathToResourceAsFileInternal(const std::string& path) { + return Singleton::get()->Rlocation(path); +} + +absl::Status DefaultGetResourceContents(const std::string& path, + std::string* output, + bool read_as_binary) { + std::string resource_path = PathToResourceAsFileInternal(path); + return GetContents(path, output, read_as_binary); +} + +} // namespace internal + +absl::StatusOr PathToResourceAsFile(const std::string& path) { + std::string qualified_path = path; + if (absl::StartsWith(qualified_path, "./")) { + qualified_path = "mediapipe" + qualified_path.substr(1); + } else if (path[0] != '/') { + qualified_path = "mediapipe/" + qualified_path; + } + + // Try to load the file from bazel-bin. If it does not exist, fall back to the + // resource folder. + auto bazel_path = internal::PathToResourceAsFileInternal(qualified_path); + if (file::Exists(bazel_path).ok()) { + return bazel_path; + } + return JoinPath(absl::GetFlag(FLAGS_resource_root_dir), path); +} + +} // namespace mediapipe