blob: 1268d40e9a2d56c401186ef5148c7b10932aba8d [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ml/image_content_annotation.h"
#include <string>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/native_library.h>
#include <ml_core/interface.h>
#include "chrome/knowledge/ica/ica.pb.h"
namespace ml {
ImageContentAnnotationLibrary::ImageContentAnnotationLibrary(
const base::FilePath& dso_path) {
// Load the library with an option preferring own symbols. Otherwise the
// library will try to call, e.g., external tflite, which leads to crash.
base::NativeLibraryOptions native_library_options;
native_library_options.prefer_own_symbols = true;
base::NativeLibraryLoadError error;
library_.reset(base::LoadNativeLibraryWithOptions(
dso_path, native_library_options, &error));
if (!library_.is_valid()) {
LOG(ERROR) << "Error loading library: " << error.ToString();
status_ = Status::kLoadLibraryFailed;
return;
}
#define ML_ICA_LOOKUP_FUNCTION(function_ptr, name) \
function_ptr = \
reinterpret_cast<name##Fn>(library_.GetFunctionPointer(#name)); \
if (function_ptr == NULL) { \
status_ = Status::kFunctionLookupFailed; \
return; \
}
// Look up the function pointers.
ML_ICA_LOOKUP_FUNCTION(create_image_content_annotator_,
CreateImageContentAnnotator);
ML_ICA_LOOKUP_FUNCTION(destroy_image_content_annotator_,
DestroyImageContentAnnotator);
ML_ICA_LOOKUP_FUNCTION(init_image_content_annotator_,
InitImageContentAnnotator);
ML_ICA_LOOKUP_FUNCTION(annotate_image_, AnnotateImage);
ML_ICA_LOOKUP_FUNCTION(annotate_encoded_image_, AnnotateEncodedImage);
ML_ICA_LOOKUP_FUNCTION(delete_annotate_image_result_,
DeleteAnnoteImageResult);
status_ = Status::kOk;
return;
}
ImageContentAnnotationLibrary* ImageContentAnnotationLibrary::GetInstance(
const base::FilePath& dso_path) {
static base::NoDestructor<ImageContentAnnotationLibrary> instance(dso_path);
return instance.get();
}
ImageContentAnnotationLibrary::Status ImageContentAnnotationLibrary::GetStatus()
const {
return status_;
}
ImageContentAnnotator*
ImageContentAnnotationLibrary::CreateImageContentAnnotator() {
DCHECK(status_ == Status::kOk);
return (*create_image_content_annotator_)();
}
void ImageContentAnnotationLibrary::DestroyImageContentAnnotator(
ImageContentAnnotator* annotator) {
DCHECK(status_ == Status::kOk);
(*destroy_image_content_annotator_)(annotator);
}
bool ImageContentAnnotationLibrary::InitImageContentAnnotator(
ImageContentAnnotator* annotator, const char* locale) {
DCHECK(status_ == Status::kOk);
return (*init_image_content_annotator_)(annotator, locale);
}
bool ImageContentAnnotationLibrary::AnnotateImage(
ImageContentAnnotator* annotator,
const uint8_t* rgb_bytes,
int width,
int height,
int line_stride,
chrome_knowledge::AnnotationScoreList* result) {
DCHECK(status_ == Status::kOk);
uint8_t* result_data = nullptr;
int32_t result_size = 0;
bool successful = (*annotate_image_)(annotator, rgb_bytes, width, height,
line_stride, &result_data, &result_size);
if (successful) {
result->Clear();
const bool parse_result_status =
result->ParseFromArray(result_data, result_size);
DCHECK(parse_result_status);
(*delete_annotate_image_result_)(result_data);
}
return successful;
}
bool ImageContentAnnotationLibrary::AnnotateEncodedImage(
ImageContentAnnotator* annotator,
const uint8_t* encoded_bytes,
int num_bytes,
chrome_knowledge::AnnotationScoreList* result) {
DCHECK(status_ == Status::kOk);
uint8_t* result_data = nullptr;
int32_t result_size = 0;
bool successful = (*annotate_encoded_image_)(
annotator, encoded_bytes, num_bytes, &result_data, &result_size);
if (successful) {
result->Clear();
const bool parse_result_status =
result->ParseFromArray(result_data, result_size);
DCHECK(parse_result_status);
(*delete_annotate_image_result_)(result_data);
}
return successful;
}
} // namespace ml