From abfcd8ec1dfc54631f083405f8d4f0972adba839 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 1 Mar 2023 13:47:06 -0800 Subject: [PATCH] Make LoadBinaryContent work on Windows PiperOrigin-RevId: 513330348 --- mediapipe/tasks/cc/core/BUILD | 3 ++- mediapipe/tasks/cc/core/external_file_handler.cc | 4 ++++ .../cc/core/model_asset_bundle_resources_test.cc | 2 ++ mediapipe/tasks/cc/core/model_resources_test.cc | 12 ++++++++++++ mediapipe/tasks/cc/core/utils.cc | 14 +++++++------- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/mediapipe/tasks/cc/core/BUILD b/mediapipe/tasks/cc/core/BUILD index 9deb38f40..3d01639ce 100644 --- a/mediapipe/tasks/cc/core/BUILD +++ b/mediapipe/tasks/cc/core/BUILD @@ -332,9 +332,11 @@ cc_library( "//mediapipe/tasks:internal", ], deps = [ + ":external_file_handler", "//mediapipe/calculators/core:flow_limiter_calculator_cc_proto", "//mediapipe/framework:calculator_cc_proto", "//mediapipe/framework/api2:builder", + "//mediapipe/tasks/cc/core/proto:external_file_cc_proto", "//mediapipe/tasks/metadata:metadata_schema_cc", "@com_google_absl//absl/strings", "@flatbuffers//:runtime_cc", @@ -375,6 +377,5 @@ cc_test( "//mediapipe/tasks/cc:common", "//mediapipe/tasks/cc/core/proto:external_file_cc_proto", "//mediapipe/tasks/cc/metadata/utils:zip_utils", - "@org_tensorflow//tensorflow/lite/c:common", ], ) diff --git a/mediapipe/tasks/cc/core/external_file_handler.cc b/mediapipe/tasks/cc/core/external_file_handler.cc index a95b8e744..6081ac1cd 100644 --- a/mediapipe/tasks/cc/core/external_file_handler.cc +++ b/mediapipe/tasks/cc/core/external_file_handler.cc @@ -102,9 +102,13 @@ absl::StatusOr PathToResourceAsFile(std::string path) { #else if (absl::StartsWith(path, "./")) { path = "mediapipe" + path.substr(1); + } else if (path[0] != '/') { + path = "mediapipe/" + 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) { diff --git a/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc b/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc index bcf88713c..359deef91 100644 --- a/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc +++ b/mediapipe/tasks/cc/core/model_asset_bundle_resources_test.cc @@ -88,6 +88,7 @@ TEST(ModelAssetBundleResourcesTest, CreateFromFile) { .status()); } +#ifndef _WIN32 TEST(ModelAssetBundleResourcesTest, CreateFromFileDescriptor) { const int model_file_descriptor = open(kTestModelBundlePath, O_RDONLY); auto model_file = std::make_unique(); @@ -103,6 +104,7 @@ TEST(ModelAssetBundleResourcesTest, CreateFromFileDescriptor) { model_bundle_resources->GetModelFile("dummy_gesture_recognizer.tflite") .status()); } +#endif // _WIN32 TEST(ModelAssetBundleResourcesTest, CreateFromFilePointer) { auto file_content = LoadBinaryContent(kTestModelBundlePath); diff --git a/mediapipe/tasks/cc/core/model_resources_test.cc b/mediapipe/tasks/cc/core/model_resources_test.cc index de480c5a4..3bc5ff062 100644 --- a/mediapipe/tasks/cc/core/model_resources_test.cc +++ b/mediapipe/tasks/cc/core/model_resources_test.cc @@ -136,6 +136,7 @@ TEST_F(ModelResourcesTest, CreateFromFile) { CheckModelResourcesPackets(model_resources.get()); } +#ifndef _WIN32 TEST_F(ModelResourcesTest, CreateFromFileDescriptor) { const int model_file_descriptor = open(kTestModelPath, O_RDONLY); auto model_file = std::make_unique(); @@ -145,6 +146,7 @@ TEST_F(ModelResourcesTest, CreateFromFileDescriptor) { ModelResources::Create(kTestModelResourcesTag, std::move(model_file))); CheckModelResourcesPackets(model_resources.get()); } +#endif // _WIN32 TEST_F(ModelResourcesTest, CreateFromInvalidFile) { auto model_file = std::make_unique(); @@ -168,6 +170,15 @@ TEST_F(ModelResourcesTest, CreateFromInvalidFileDescriptor) { auto status_or_model_resources = ModelResources::Create(kTestModelResourcesTag, std::move(model_file)); +#ifdef _WIN32 + EXPECT_EQ(status_or_model_resources.status().code(), + absl::StatusCode::kFailedPrecondition); + EXPECT_THAT( + status_or_model_resources.status().message(), + testing::HasSubstr("File descriptors are not supported on Windows.")); + AssertStatusHasMediaPipeTasksStatusCode(status_or_model_resources.status(), + MediaPipeTasksStatus::kFileReadError); +#else EXPECT_EQ(status_or_model_resources.status().code(), absl::StatusCode::kInvalidArgument); EXPECT_THAT( @@ -176,6 +187,7 @@ TEST_F(ModelResourcesTest, CreateFromInvalidFileDescriptor) { AssertStatusHasMediaPipeTasksStatusCode( status_or_model_resources.status(), MediaPipeTasksStatus::kInvalidArgumentError); +#endif // _WIN32 } TEST_F(ModelResourcesTest, CreateFailWithCorruptedFile) { diff --git a/mediapipe/tasks/cc/core/utils.cc b/mediapipe/tasks/cc/core/utils.cc index a840ba623..1e44109c3 100644 --- a/mediapipe/tasks/cc/core/utils.cc +++ b/mediapipe/tasks/cc/core/utils.cc @@ -23,6 +23,8 @@ limitations under the License. #include "absl/strings/string_view.h" #include "flatbuffers/flatbuffers.h" #include "mediapipe/calculators/core/flow_limiter_calculator.pb.h" +#include "mediapipe/tasks/cc/core/external_file_handler.h" +#include "mediapipe/tasks/cc/core/proto/external_file.pb.h" namespace mediapipe { namespace tasks { @@ -34,13 +36,11 @@ constexpr char kFlowLimiterCalculatorName[] = "FlowLimiterCalculator"; } // namespace std::string LoadBinaryContent(const char* filename) { - std::ifstream input_file(filename, std::ios::binary | std::ios::ate); - // Find buffer size from input file, and load the buffer. - size_t buffer_size = input_file.tellg(); - std::string buffer(buffer_size, '\0'); - input_file.seekg(0, std::ios::beg); - input_file.read(const_cast(buffer.c_str()), buffer_size); - return buffer; + proto::ExternalFile external_file; + external_file.set_file_name(filename); + auto file_handler = + ExternalFileHandler::CreateFromExternalFile(&external_file); + return std::string{(*file_handler)->GetFileContent()}; } int FindTensorIndexByMetadataName(