diff --git a/mediapipe/tasks/ios/components/containers/utils/BUILD b/mediapipe/tasks/ios/components/containers/utils/BUILD index 923a8e01..64ca29b8 100644 --- a/mediapipe/tasks/ios/components/containers/utils/BUILD +++ b/mediapipe/tasks/ios/components/containers/utils/BUILD @@ -38,3 +38,26 @@ objc_library( "//mediapipe/tasks/ios/components/containers:MPPClassificationResult", ], ) + +objc_library( + name = "MPPEmbeddingHelpers", + srcs = ["sources/MPPEmbedding+Helpers.mm"], + hdrs = ["sources/MPPEmbedding+Helpers.h"], + deps = [ + "//mediapipe/tasks/cc/components/containers/proto:embeddings_cc_proto", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/components/containers:MPPEmbedding", + ], +) + +objc_library( + name = "MPPEmbeddingResultHelpers", + srcs = ["sources/MPPEmbeddingResult+Helpers.mm"], + hdrs = ["sources/MPPEmbeddingResult+Helpers.h"], + deps = [ + ":MPPEmbeddingHelpers", + "//mediapipe/tasks/cc/components/containers/proto:embeddings_cc_proto", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/components/containers:MPPEmbeddingResult", + ], +) diff --git a/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.h b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.h new file mode 100644 index 00000000..33fb3839 --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.h @@ -0,0 +1,27 @@ +// Copyright 2023 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 "mediapipe/tasks/cc/components/containers/proto/embeddings.pb.h" +#import "mediapipe/tasks/ios/components/containers/sources/MPPEmbedding.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPEmbedding (Helpers) + ++ (MPPEmbedding *)embeddingWithProto: + (const ::mediapipe::tasks::components::containers::proto::Embedding &)embeddingProto; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.mm b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.mm new file mode 100644 index 00000000..76bb7503 --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.mm @@ -0,0 +1,60 @@ +// Copyright 2023 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. + +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.h" + +#include + +namespace { +using EmbeddingProto = ::mediapipe::tasks::components::containers::proto::Embedding; +} + +@implementation MPPEmbedding (Helpers) + ++ (MPPEmbedding *)embeddingWithProto:(const EmbeddingProto &)embeddingProto { + + NSMutableArray *floatEmbedding; + NSMutableArray *quantizedEmbedding; + NSString *headName; + + if (embeddingProto.has_float_embedding()) { + floatEmbedding = + [NSMutableArray arrayWithCapacity:embeddingProto.float_embedding().values_size()]; + + for (const auto value : embeddingProto.float_embedding().values()) { + [floatEmbedding addObject:[NSNumber numberWithFloat:value]]; + } + } + + if (embeddingProto.has_quantized_embedding()) { + const std::string &cppQuantizedEmbedding = embeddingProto.quantized_embedding().values(); + quantizedEmbedding = [NSMutableArray arrayWithCapacity:cppQuantizedEmbedding.length()]; + + for (char ch : cppQuantizedEmbedding) { + [quantizedEmbedding addObject:[NSNumber numberWithChar:ch]]; + } + } + + if (embeddingProto.has_head_name()) { + headName = [NSString stringWithCppString:embeddingProto.head_name()]; + } + + return [[MPPEmbedding alloc] initWithFloatEmbedding:floatEmbedding + quantizedEmbedding:quantizedEmbedding + headIndex:embeddingProto.head_index() + headName:headName]; +} + +@end diff --git a/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.h b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.h new file mode 100644 index 00000000..cc53c3e2 --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.h @@ -0,0 +1,28 @@ +// Copyright 2023 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 "mediapipe/tasks/cc/components/containers/proto/embeddings.pb.h" +#import "mediapipe/tasks/ios/components/containers/sources/MPPEmbeddingResult.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPEmbeddingResult (Helpers) + ++ (MPPEmbeddingResult *)embeddingResultWithProto: + (const ::mediapipe::tasks::components::containers::proto::EmbeddingResult &) + embeddingResultProto; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.mm b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.mm new file mode 100644 index 00000000..f9863e9c --- /dev/null +++ b/mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.mm @@ -0,0 +1,42 @@ +// Copyright 2023 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. + +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.h" + +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbedding+Helpers.h" + +namespace { +using EmbeddingResultProto = ::mediapipe::tasks::components::containers::proto::EmbeddingResult; +} + +@implementation MPPEmbeddingResult (Helpers) + ++ (MPPEmbeddingResult *)embeddingResultWithProto: + (const EmbeddingResultProto &)embeddingResultProto { + NSMutableArray *embeddings = + [NSMutableArray arrayWithCapacity:(NSUInteger)embeddingResultProto.embeddings_size()]; + for (const auto &embeddingProto : embeddingResultProto.embeddings()) { + [embeddings addObject:[MPPEmbedding embeddingWithProto:embeddingProto]]; + } + + NSInteger timestampMs = 0; + if (embeddingResultProto.has_timestamp_ms()) { + timestampMs = (NSInteger)embeddingResultProto.timestamp_ms(); + } + + return [[MPPEmbeddingResult alloc] initWithEmbeddings:embeddings timestampMs:timestampMs]; +} + +@end diff --git a/mediapipe/tasks/ios/text/text_embedder/BUILD b/mediapipe/tasks/ios/text/text_embedder/BUILD index 143f0a58..21226b01 100644 --- a/mediapipe/tasks/ios/text/text_embedder/BUILD +++ b/mediapipe/tasks/ios/text/text_embedder/BUILD @@ -32,3 +32,29 @@ objc_library( "//mediapipe/tasks/ios/core:MPPTaskResult", ], ) + +objc_library( + name = "MPPTextEmbedder", + srcs = ["sources/MPPTextEmbedder.mm"], + hdrs = ["sources/MPPTextEmbedder.h"], + copts = [ + "-ObjC++", + "-std=c++17", + "-x objective-c++", + ], + module_name = "MPPTextEmbedder", + deps = [ + ":MPPTextEmbedderOptions", + ":MPPTextEmbedderResult", + "//mediapipe/tasks/cc/text/text_embedder:text_embedder_graph", + "//mediapipe/tasks/ios/common/utils:MPPCommonUtils", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/core:MPPTaskInfo", + "//mediapipe/tasks/ios/core:MPPTaskOptions", + "//mediapipe/tasks/ios/core:MPPTextPacketCreator", + "//mediapipe/tasks/ios/text/core:MPPTextTaskRunner", + "//mediapipe/tasks/ios/text/text_embedder/utils:MPPTextEmbedderOptionsHelpers", + "//mediapipe/tasks/ios/text/text_embedder/utils:MPPTextEmbedderResultHelpers", + "@com_google_absl//absl/status:statusor", + ], +) diff --git a/mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.h b/mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.h new file mode 100644 index 00000000..b3f2ebe9 --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.h @@ -0,0 +1,93 @@ +// Copyright 2023 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. + +#import + +#import "mediapipe/tasks/ios/core/sources/MPPTaskOptions.h" +#import "mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedderOptions.h" +#import "mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedderResult.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * @brief Performs embedding extraction on text. + * + * This API expects a TFLite model with (optional) [TFLite Model + * Metadata](https://www.tensorflow.org/lite/convert/metadata"). + * + * Metadata is required for models with int32 input tensors because it contains the input process + * unit for the model's Tokenizer. No metadata is required for models with string input tensors. + * + * Input tensors: + * - Three input tensors `kTfLiteInt32` of shape `[batch_size x bert_max_seq_len]` + * representing the input ids, mask ids, and segment ids. This input signature requires + * a Bert Tokenizer process unit in the model metadata. + * - Or one input tensor `kTfLiteInt32` of shape `[batch_size x max_seq_len]` representing + * the input ids. This input signature requires a Regex Tokenizer process unit in the + * model metadata. + * - Or one input tensor (`kTfLiteString`) that is shapeless or has shape `[1]` containing + * the input string. + * + * At least one output tensor (`kTfLiteFloat32`/`kTfLiteUint8`) with shape `[1 x N]` where `N` is + * the number of dimensions in the produced embeddings. + */ +NS_SWIFT_NAME(TextEmbedder) +@interface MPPTextEmbedder : NSObject + +/** + * Creates a new instance of `MPPTextEmbedder` from an absolute path to a TensorFlow Lite + * model file stored locally on the device and the default `MPPTextEmbedderOptions`. + * + * @param modelPath An absolute path to a TensorFlow Lite model file stored locally on the device. + * @param error An optional error parameter populated when there is an error in initializing the + * text embedder. + * + * @return A new instance of `MPPTextEmbedder` with the given model path. `nil` if there is an + * error in initializing the text embedder. + */ +- (nullable instancetype)initWithModelPath:(NSString *)modelPath error:(NSError **)error; + +/** + * Creates a new instance of `MPPTextEmbedder` from the given `MPPTextEmbedderOptions`. + * + * @param options The options of type `MPPTextEmbedderOptions` to use for configuring the + * `MPPTextEmbedder`. + * @param error An optional error parameter populated when there is an error in initializing the + * text embedder. + * + * @return A new instance of `MPPTextEmbedder` with the given options. `nil` if there is an + * error in initializing the text embedder. + */ +- (nullable instancetype)initWithOptions:(MPPTextEmbedderOptions *)options + error:(NSError **)error NS_DESIGNATED_INITIALIZER; + +/** + * Performs embedding extraction on the input text. + * + * @param text The `NSString` on which embedding extraction is to be performed. + * @param error An optional error parameter populated when there is an error in performing + * embedding extraction on the input text. + * + * @return A `MPPTextEmbedderResult` object that contains a list of embeddings. + */ +- (nullable MPPTextEmbedderResult *)embedText:(NSString *)text + error:(NSError **)error NS_SWIFT_NAME(embed(text:)); + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.mm b/mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.mm new file mode 100644 index 00000000..a9c811cd --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.mm @@ -0,0 +1,96 @@ +// Copyright 2023 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. + +#import "mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedder.h" + +#import "mediapipe/tasks/ios/common/utils/sources/MPPCommonUtils.h" +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/core/sources/MPPTaskInfo.h" +#import "mediapipe/tasks/ios/core/sources/MPPTextPacketCreator.h" +#import "mediapipe/tasks/ios/text/core/sources/MPPTextTaskRunner.h" +#import "mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.h" +#import "mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.h" + +#include "absl/status/statusor.h" + +namespace { +using ::mediapipe::Packet; +using ::mediapipe::tasks::core::PacketMap; +} // namespace + +static NSString *const kEmbeddingsOutStreamName = @"embeddings_out"; +static NSString *const kEmbeddingsTag = @"EMBEDDINGS"; +static NSString *const kTextInStreamName = @"text_in"; +static NSString *const kTextTag = @"TEXT"; +static NSString *const kTaskGraphName = @"mediapipe.tasks.text.text_embedder.TextEmbedderGraph"; + +@interface MPPTextEmbedder () { + /** iOS Text Task Runner */ + MPPTextTaskRunner *_textTaskRunner; +} +@end + +@implementation MPPTextEmbedder + +- (instancetype)initWithOptions:(MPPTextEmbedderOptions *)options error:(NSError **)error { + self = [super init]; + if (self) { + MPPTaskInfo *taskInfo = [[MPPTaskInfo alloc] + initWithTaskGraphName:kTaskGraphName + inputStreams:@[ [NSString stringWithFormat:@"%@:%@", kTextTag, kTextInStreamName] ] + outputStreams:@[ [NSString stringWithFormat:@"%@:%@", kEmbeddingsTag, + kEmbeddingsOutStreamName] ] + taskOptions:options + enableFlowLimiting:NO + error:error]; + + if (!taskInfo) { + return nil; + } + + _textTaskRunner = + [[MPPTextTaskRunner alloc] initWithCalculatorGraphConfig:[taskInfo generateGraphConfig] + error:error]; + + if (!_textTaskRunner) { + return nil; + } + } + return self; +} + +- (instancetype)initWithModelPath:(NSString *)modelPath error:(NSError **)error { + MPPTextEmbedderOptions *options = [[MPPTextEmbedderOptions alloc] init]; + + options.baseOptions.modelAssetPath = modelPath; + + return [self initWithOptions:options error:error]; +} + +- (nullable MPPTextEmbedderResult *)embedText:(NSString *)text error:(NSError **)error { + Packet packet = [MPPTextPacketCreator createWithText:text]; + + std::map packetMap = {{kTextInStreamName.cppString, packet}}; + absl::StatusOr statusOrOutputPacketMap = [_textTaskRunner process:packetMap]; + + if (![MPPCommonUtils checkCppError:statusOrOutputPacketMap.status() toError:error]) { + return nil; + } + + return [MPPTextEmbedderResult + textEmbedderResultWithOutputPacket:statusOrOutputPacketMap + .value()[kEmbeddingsOutStreamName.cppString]]; +} + +@end diff --git a/mediapipe/tasks/ios/text/text_embedder/utils/BUILD b/mediapipe/tasks/ios/text/text_embedder/utils/BUILD new file mode 100644 index 00000000..eeb4981f --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/utils/BUILD @@ -0,0 +1,44 @@ +# Copyright 2023 The MediaPipe Authors. All Rights Reserved. +# +# 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. + +package(default_visibility = ["//mediapipe/tasks:internal"]) + +licenses(["notice"]) + +objc_library( + name = "MPPTextEmbedderOptionsHelpers", + srcs = ["sources/MPPTextEmbedderOptions+Helpers.mm"], + hdrs = ["sources/MPPTextEmbedderOptions+Helpers.h"], + deps = [ + "//mediapipe/framework:calculator_options_cc_proto", + "//mediapipe/tasks/cc/components/processors/proto:embedder_options_cc_proto", + "//mediapipe/tasks/cc/text/text_embedder/proto:text_embedder_graph_options_cc_proto", + "//mediapipe/tasks/ios/common/utils:NSStringHelpers", + "//mediapipe/tasks/ios/core:MPPTaskOptionsProtocol", + "//mediapipe/tasks/ios/core/utils:MPPBaseOptionsHelpers", + "//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedderOptions", + ], +) + +objc_library( + name = "MPPTextEmbedderResultHelpers", + srcs = ["sources/MPPTextEmbedderResult+Helpers.mm"], + hdrs = ["sources/MPPTextEmbedderResult+Helpers.h"], + deps = [ + "//mediapipe/framework:packet", + "//mediapipe/tasks/cc/components/containers/proto:embeddings_cc_proto", + "//mediapipe/tasks/ios/components/containers/utils:MPPEmbeddingResultHelpers", + "//mediapipe/tasks/ios/text/text_embedder:MPPTextEmbedderResult", + ], +) diff --git a/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.h b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.h new file mode 100644 index 00000000..7f3d1c95 --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.h @@ -0,0 +1,27 @@ +// Copyright 2023 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 "mediapipe/framework/calculator_options.pb.h" +#import "mediapipe/tasks/ios/core/sources/MPPTaskOptionsProtocol.h" +#import "mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedderOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPTextEmbedderOptions (Helpers) + +- (void)copyToProto:(::mediapipe::CalculatorOptions *)optionsProto; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.mm b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.mm new file mode 100644 index 00000000..e17b6e8d --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.mm @@ -0,0 +1,44 @@ +// Copyright 2023 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. + +#import "mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderOptions+Helpers.h" + +#import "mediapipe/tasks/ios/common/utils/sources/NSString+Helpers.h" +#import "mediapipe/tasks/ios/core/utils/sources/MPPBaseOptions+Helpers.h" + +#include "mediapipe/tasks/cc/components/processors/proto/embedder_options.pb.h" +#include "mediapipe/tasks/cc/text/text_embedder/proto/text_embedder_graph_options.pb.h" + +namespace { +using CalculatorOptionsProto = ::mediapipe::CalculatorOptions; +using TextEmbedderGraphOptionsProto = + ::mediapipe::tasks::text::text_embedder::proto::TextEmbedderGraphOptions; +using EmbedderOptionsProto = ::mediapipe::tasks::components::processors::proto::EmbedderOptions; +} // namespace + +@implementation MPPTextEmbedderOptions (Helpers) + +- (void)copyToProto:(CalculatorOptionsProto *)optionsProto { + TextEmbedderGraphOptionsProto *graphOptions = + optionsProto->MutableExtension(TextEmbedderGraphOptionsProto::ext); + [self.baseOptions copyToProto:graphOptions->mutable_base_options()]; + + EmbedderOptionsProto *embedderOptionsProto = graphOptions->mutable_embedder_options(); + embedderOptionsProto->Clear(); + + embedderOptionsProto->set_l2_normalize(self.l2Normalize ? true : false); + embedderOptionsProto->set_quantize(self.quantize ? true : false); +} + +@end diff --git a/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.h b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.h new file mode 100644 index 00000000..0a808a54 --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.h @@ -0,0 +1,27 @@ +// Copyright 2023 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. + +#import "mediapipe/tasks/ios/text/text_embedder/sources/MPPTextEmbedderResult.h" + +#include "mediapipe/framework/packet.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MPPTextEmbedderResult (Helpers) + ++ (MPPTextEmbedderResult *)textEmbedderResultWithOutputPacket:(const mediapipe::Packet &)packet; + +@end + +NS_ASSUME_NONNULL_END diff --git a/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.mm b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.mm new file mode 100644 index 00000000..b769292c --- /dev/null +++ b/mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.mm @@ -0,0 +1,41 @@ +// Copyright 2023 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. + +#import "mediapipe/tasks/ios/components/containers/utils/sources/MPPEmbeddingResult+Helpers.h" +#import "mediapipe/tasks/ios/text/text_embedder/utils/sources/MPPTextEmbedderResult+Helpers.h" + +#include "mediapipe/tasks/cc/components/containers/proto/embeddings.pb.h" + +static const int kMicroSecondsPerMilliSecond = 1000; + +namespace { +using EmbeddingResultProto = ::mediapipe::tasks::components::containers::proto::EmbeddingResult; +using ::mediapipe::Packet; +} // namespace + +#define int kMicroSecondsPerMilliSecond = 1000; + +@implementation MPPTextEmbedderResult (Helpers) + ++ (MPPTextEmbedderResult *)textEmbedderResultWithOutputPacket:(const Packet &)packet { + MPPEmbeddingResult *embeddingResult = + [MPPEmbeddingResult embeddingResultWithProto:packet.Get()]; + + return [[MPPTextEmbedderResult alloc] + initWithEmbeddingResult:embeddingResult + timestampMs:(NSInteger)(packet.Timestamp().Value() / + kMicroSecondsPerMilliSecond)]; +} + +@end