Skip to content

Commit e362022

Browse files
dkalinowskiatobiszei
authored andcommitted
v1 img2img
* save * load pipelines * save * image generated * save to disk * final
1 parent 035abff commit e362022

16 files changed

+547
-46
lines changed

WORKSPACE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ new_git_repository(
613613
build_file_content = """
614614
cc_library(
615615
name = "image",
616-
hdrs = ["stb_image.h"],
616+
hdrs = ["stb_image.h", "stb_image_write.h"],
617617
visibility = ["//visibility:public"],
618618
local_defines = [
619619
],

src/BUILD

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ cc_library(
608608
}) + select({
609609
"//conditions:default": [],
610610
"//:not_disable_mediapipe" : [
611+
"//src/image_gen:image_gen_calculator",
611612
"//src/llm:openai_completions_api_handler",
612613
"//src/embeddings:embeddingscalculator",
613614
"//src/rerank:rerankcalculator",
@@ -2611,6 +2612,27 @@ cc_library(
26112612
linkopts = LINKOPTS_ADJUSTED,
26122613
)
26132614

2615+
cc_library(
2616+
name = "libimage_conversion",
2617+
hdrs = [
2618+
"image_conversion.hpp",
2619+
],
2620+
srcs = [
2621+
"image_conversion.cpp",
2622+
],
2623+
deps = [
2624+
"@stb//:image",
2625+
"@com_google_absl//absl/strings",
2626+
"//third_party:openvino",
2627+
"//src:libovmslogging",
2628+
"//src:libovmsprofiler",
2629+
],
2630+
visibility = ["//visibility:public",],
2631+
local_defines = COMMON_LOCAL_DEFINES,
2632+
copts = COPTS_ADJUSTED,
2633+
linkopts = LINKOPTS_ADJUSTED,
2634+
)
2635+
26142636
# HTTP Server implementation using net_http of tensorflow
26152637
# To use other library simply create new target and implementation of libhttp_async_writer_interface
26162638
cc_library(

src/image_conversion.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//****************************************************************************
2+
// Copyright 2025 Intel Corporation
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//*****************************************************************************
16+
#include "image_conversion.hpp"
17+
18+
#include <iostream>
19+
20+
#define STB_IMAGE_IMPLEMENTATION
21+
#define STB_IMAGE_WRITE_IMPLEMENTATION
22+
#include "logging.hpp"
23+
#include "profiler.hpp"
24+
#pragma warning(push)
25+
#pragma warning(disable : 6262)
26+
#include "stb_image.h" // NOLINT
27+
#include "stb_image_write.h" // NOLINT
28+
#pragma warning(default : 6262)
29+
#pragma warning(disable : 6001 4324 6385 6386)
30+
#include "absl/strings/escaping.h"
31+
#include "absl/strings/str_cat.h"
32+
#pragma warning(pop)
33+
34+
namespace ovms {
35+
36+
void hello() {
37+
std::cout << "Hello, World!" << std::endl;
38+
}
39+
40+
ov::Tensor load_image_stbi(const std::string& imageBytes) {
41+
int x = 0, y = 0, channelsInFile = 0;
42+
constexpr int desiredChannels = 3;
43+
unsigned char* image = stbi_load_from_memory(
44+
(const unsigned char*)imageBytes.data(), imageBytes.size(),
45+
&x, &y, &channelsInFile, desiredChannels);
46+
if (!image) {
47+
std::stringstream errorMessage;
48+
errorMessage << "Failed to load the image";
49+
throw std::runtime_error{errorMessage.str()};
50+
}
51+
struct SharedImageAllocator {
52+
unsigned char* image;
53+
int channels, height, width;
54+
void* allocate(size_t bytes, size_t) const {
55+
if (image && channels * height * width == bytes) {
56+
return image;
57+
}
58+
throw std::runtime_error{"Unexpected number of bytes was requested to allocate."};
59+
}
60+
void deallocate(void*, size_t bytes, size_t) {
61+
if (channels * height * width != bytes) {
62+
throw std::runtime_error{"Unexpected number of bytes was requested to deallocate."};
63+
}
64+
if (image != nullptr) {
65+
stbi_image_free(image);
66+
image = nullptr;
67+
}
68+
}
69+
bool is_equal(const SharedImageAllocator& other) const noexcept { return this == &other; }
70+
};
71+
return ov::Tensor(
72+
ov::element::u8,
73+
ov::Shape{1, size_t(y), size_t(x), size_t(desiredChannels)},
74+
SharedImageAllocator{image, desiredChannels, y, x});
75+
}
76+
77+
std::string save_image_stbi(ov::Tensor tensor) {
78+
// Validate tensor properties
79+
if (tensor.get_element_type() != ov::element::u8) {
80+
throw std::runtime_error{"Only U8 tensor element type is supported for image saving"};
81+
}
82+
83+
if (tensor.get_shape().size() != 4 || tensor.get_shape()[0] != 1) {
84+
throw std::runtime_error{"Tensor must be in NHWC format with batch size 1"};
85+
}
86+
87+
size_t height = tensor.get_shape()[1];
88+
size_t width = tensor.get_shape()[2];
89+
size_t channels = tensor.get_shape()[3];
90+
91+
if (channels != 3 && channels != 1) {
92+
throw std::runtime_error{"Only 1 or 3 channel images are supported for saving"};
93+
}
94+
95+
// Get pointer to image data
96+
unsigned char* image_data = tensor.data<unsigned char>();
97+
98+
// Create a memory buffer to hold the PNG data
99+
std::vector<unsigned char> png_buffer;
100+
101+
// Define the write function that will store data in our buffer
102+
auto write_func = [](void* context, void* data, int size) {
103+
std::vector<unsigned char>* buffer = static_cast<std::vector<unsigned char>*>(context);
104+
unsigned char* bytes = static_cast<unsigned char*>(data);
105+
buffer->insert(buffer->end(), bytes, bytes + size);
106+
};
107+
108+
// Write PNG to memory using our buffer
109+
int success = stbi_write_png_to_func(
110+
write_func, // Our write function
111+
&png_buffer, // Context (our buffer)
112+
width, // Image width
113+
height, // Image height
114+
channels, // Number of channels
115+
image_data, // Image data
116+
width * channels); // Stride (bytes per row)
117+
118+
if (!success) {
119+
throw std::runtime_error{"Failed to encode image to PNG format"};
120+
}
121+
122+
// Convert the buffer to a string
123+
return std::string(png_buffer.begin(), png_buffer.end());
124+
}
125+
126+
} // namespace ovms

src/image_conversion.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//*****************************************************************************
2+
// Copyright 2025 Intel Corporation
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//*****************************************************************************
16+
#pragma once
17+
18+
#include <string>
19+
20+
#include <openvino/runtime/tensor.hpp>
21+
22+
namespace ovms {
23+
24+
void hello();
25+
26+
ov::Tensor load_image_stbi(const std::string& imageBytes);
27+
std::string save_image_stbi(ov::Tensor tensor);
28+
29+
} // namespace ovms

src/image_gen/BUILD

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#
2+
# Copyright (c) 2024 Intel Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
load("@mediapipe//mediapipe/framework/port:build_config.bzl", "mediapipe_cc_proto_library", "mediapipe_proto_library")
18+
load("//:common_settings.bzl",
19+
"COMMON_STATIC_LIBS_COPTS", "COMMON_STATIC_LIBS_LINKOPTS", "COMMON_FUZZER_COPTS", "COMMON_FUZZER_LINKOPTS", "COMMON_LOCAL_DEFINES", "PYBIND_DEPS")
20+
21+
COPTS_ADJUSTED = COMMON_STATIC_LIBS_COPTS + select({
22+
"//conditions:default": [],
23+
"//:fuzzer_build" : COMMON_FUZZER_COPTS,
24+
})
25+
26+
LINKOPTS_ADJUSTED = COMMON_STATIC_LIBS_LINKOPTS + select({
27+
"//conditions:default": [],
28+
"//:fuzzer_build" : COMMON_FUZZER_LINKOPTS,
29+
})
30+
31+
cc_library(
32+
name = "llm_engine", # in fact this is genai library, includes image gen, TODO: Change name?
33+
srcs = [],
34+
deps = ["@llm_engine//:llm_engine"],
35+
visibility = ["//visibility:public"],
36+
copts = COPTS_ADJUSTED,
37+
linkopts = LINKOPTS_ADJUSTED,
38+
alwayslink = 1,
39+
)
40+
41+
cc_library(
42+
name = "pipelines",
43+
hdrs = ["pipelines.hpp"],
44+
srcs = ["pipelines.cpp"],
45+
deps = select({
46+
"//conditions:default": ["//third_party:genai", ":llm_engine"],
47+
"//:not_genai_bin" : [":llm_engine"],
48+
}),
49+
visibility = ["//visibility:public"],
50+
local_defines = COMMON_LOCAL_DEFINES,
51+
copts = COPTS_ADJUSTED,
52+
linkopts = LINKOPTS_ADJUSTED,
53+
alwayslink = 1,
54+
)
55+
56+
cc_library(
57+
name = "image_gen_calculator",
58+
srcs = ["http_image_gen_calculator.cc"],
59+
deps = [
60+
"@mediapipe//mediapipe/framework:calculator_framework",
61+
"//src:httppayload",
62+
"//src:libovmslogging",
63+
"image_gen_calculator_cc_proto",
64+
":pipelines",
65+
"//src:libimage_conversion",
66+
]+ select({
67+
"//conditions:default": ["//third_party:genai", ":llm_engine"],
68+
"//:not_genai_bin" : [":llm_engine"],
69+
}),
70+
visibility = ["//visibility:public"],
71+
local_defines = COMMON_LOCAL_DEFINES,
72+
copts = COPTS_ADJUSTED,
73+
linkopts = LINKOPTS_ADJUSTED,
74+
alwayslink = 1,
75+
)
76+
77+
mediapipe_proto_library(
78+
name = "image_gen_calculator_proto",
79+
srcs = ["image_gen_calculator.proto"],
80+
visibility = ["//visibility:private"],
81+
deps = [
82+
"@mediapipe//mediapipe/framework:calculator_options_proto",
83+
"@mediapipe//mediapipe/framework:calculator_proto",
84+
],
85+
)

0 commit comments

Comments
 (0)