Skip to content

Commit 4ff2c8c

Browse files
authored
refactor: simplify logic for saving results (#1149)
1 parent 51bd9c8 commit 4ff2c8c

1 file changed

Lines changed: 91 additions & 95 deletions

File tree

examples/cli/main.cpp

Lines changed: 91 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,95 @@ std::string format_frame_idx(std::string pattern, int frame_idx) {
370370
return result;
371371
}
372372

373+
bool save_results(const SDCliParams& cli_params,
374+
const SDContextParams& ctx_params,
375+
const SDGenerationParams& gen_params,
376+
sd_image_t* results,
377+
int num_results) {
378+
if (results == nullptr || num_results <= 0) {
379+
return false;
380+
}
381+
382+
namespace fs = std::filesystem;
383+
fs::path out_path = cli_params.output_path;
384+
385+
if (!out_path.parent_path().empty()) {
386+
std::error_code ec;
387+
fs::create_directories(out_path.parent_path(), ec);
388+
if (ec) {
389+
LOG_ERROR("failed to create directory '%s': %s",
390+
out_path.parent_path().string().c_str(), ec.message().c_str());
391+
return false;
392+
}
393+
}
394+
395+
fs::path base_path = out_path;
396+
fs::path ext = out_path.has_extension() ? out_path.extension() : fs::path{};
397+
if (!ext.empty())
398+
base_path.replace_extension();
399+
400+
std::string ext_lower = ext.string();
401+
std::transform(ext_lower.begin(), ext_lower.end(), ext_lower.begin(), ::tolower);
402+
bool is_jpg = (ext_lower == ".jpg" || ext_lower == ".jpeg" || ext_lower == ".jpe");
403+
404+
int output_begin_idx = cli_params.output_begin_idx;
405+
if (output_begin_idx < 0) {
406+
output_begin_idx = 0;
407+
}
408+
409+
auto write_image = [&](const fs::path& path, int idx) {
410+
const sd_image_t& img = results[idx];
411+
if (!img.data)
412+
return;
413+
414+
std::string params = get_image_params(cli_params, ctx_params, gen_params, gen_params.seed + idx);
415+
int ok = 0;
416+
if (is_jpg) {
417+
ok = stbi_write_jpg(path.string().c_str(), img.width, img.height, img.channel, img.data, 90, params.c_str());
418+
} else {
419+
ok = stbi_write_png(path.string().c_str(), img.width, img.height, img.channel, img.data, 0, params.c_str());
420+
}
421+
LOG_INFO("save result image %d to '%s' (%s)", idx, path.string().c_str(), ok ? "success" : "failure");
422+
};
423+
424+
if (std::regex_search(cli_params.output_path, format_specifier_regex)) {
425+
if (!is_jpg && ext_lower != ".png")
426+
ext = ".png";
427+
fs::path pattern = base_path;
428+
pattern += ext;
429+
430+
for (int i = 0; i < num_results; ++i) {
431+
fs::path img_path = format_frame_idx(pattern.string(), output_begin_idx + i);
432+
write_image(img_path, i);
433+
}
434+
return true;
435+
}
436+
437+
if (cli_params.mode == VID_GEN && num_results > 1) {
438+
if (ext_lower != ".avi")
439+
ext = ".avi";
440+
fs::path video_path = base_path;
441+
video_path += ext;
442+
create_mjpg_avi_from_sd_images(video_path.string().c_str(), results, num_results, gen_params.fps);
443+
LOG_INFO("save result MJPG AVI video to '%s'", video_path.string().c_str());
444+
return true;
445+
}
446+
447+
if (!is_jpg && ext_lower != ".png")
448+
ext = ".png";
449+
450+
for (int i = 0; i < num_results; ++i) {
451+
fs::path img_path = base_path;
452+
if (num_results > 1) {
453+
img_path += "_" + std::to_string(output_begin_idx + i);
454+
}
455+
img_path += ext;
456+
write_image(img_path, i);
457+
}
458+
459+
return true;
460+
}
461+
373462
int main(int argc, const char* argv[]) {
374463
if (argc > 1 && std::string(argv[1]) == "--version") {
375464
std::cout << version_string() << "\n";
@@ -713,101 +802,8 @@ int main(int argc, const char* argv[]) {
713802
}
714803
}
715804

716-
// create directory if not exists
717-
{
718-
const fs::path out_path = cli_params.output_path;
719-
if (const fs::path out_dir = out_path.parent_path(); !out_dir.empty()) {
720-
std::error_code ec;
721-
fs::create_directories(out_dir, ec); // OK if already exists
722-
if (ec) {
723-
LOG_ERROR("failed to create directory '%s': %s",
724-
out_dir.string().c_str(), ec.message().c_str());
725-
return 1;
726-
}
727-
}
728-
}
729-
730-
std::string base_path;
731-
std::string file_ext;
732-
std::string file_ext_lower;
733-
bool is_jpg;
734-
size_t last_dot_pos = cli_params.output_path.find_last_of(".");
735-
size_t last_slash_pos = std::min(cli_params.output_path.find_last_of("/"),
736-
cli_params.output_path.find_last_of("\\"));
737-
if (last_dot_pos != std::string::npos && (last_slash_pos == std::string::npos || last_dot_pos > last_slash_pos)) { // filename has extension
738-
base_path = cli_params.output_path.substr(0, last_dot_pos);
739-
file_ext = file_ext_lower = cli_params.output_path.substr(last_dot_pos);
740-
std::transform(file_ext.begin(), file_ext.end(), file_ext_lower.begin(), ::tolower);
741-
is_jpg = (file_ext_lower == ".jpg" || file_ext_lower == ".jpeg" || file_ext_lower == ".jpe");
742-
} else {
743-
base_path = cli_params.output_path;
744-
file_ext = file_ext_lower = "";
745-
is_jpg = false;
746-
}
747-
748-
if (std::regex_search(cli_params.output_path, format_specifier_regex)) {
749-
std::string final_output_path = cli_params.output_path;
750-
if (cli_params.output_begin_idx == -1) {
751-
cli_params.output_begin_idx = 0;
752-
}
753-
// writing image sequence, default to PNG
754-
if (!is_jpg && file_ext_lower != ".png") {
755-
base_path += file_ext;
756-
file_ext = ".png";
757-
}
758-
final_output_path = base_path + file_ext;
759-
for (int i = 0; i < num_results; i++) {
760-
if (results[i].data == nullptr) {
761-
continue;
762-
}
763-
std::string final_image_path = format_frame_idx(final_output_path, cli_params.output_begin_idx + i);
764-
if (is_jpg) {
765-
int write_ok = stbi_write_jpg(final_image_path.c_str(), results[i].width, results[i].height, results[i].channel,
766-
results[i].data, 90, get_image_params(cli_params, ctx_params, gen_params, gen_params.seed + i).c_str());
767-
LOG_INFO("save result JPEG image %d to '%s' (%s)", i, final_image_path.c_str(), write_ok == 0 ? "failure" : "success");
768-
} else {
769-
int write_ok = stbi_write_png(final_image_path.c_str(), results[i].width, results[i].height, results[i].channel,
770-
results[i].data, 0, get_image_params(cli_params, ctx_params, gen_params, gen_params.seed + i).c_str());
771-
LOG_INFO("save result PNG image %d to '%s' (%s)", i, final_image_path.c_str(), write_ok == 0 ? "failure" : "success");
772-
}
773-
}
774-
} else if (cli_params.mode == VID_GEN && num_results > 1) {
775-
std::string final_output_path = cli_params.output_path;
776-
if (file_ext_lower != ".avi") {
777-
if (!is_jpg && file_ext_lower != ".png") {
778-
base_path += file_ext;
779-
}
780-
file_ext = ".avi";
781-
final_output_path = base_path + file_ext;
782-
}
783-
create_mjpg_avi_from_sd_images(final_output_path.c_str(), results, num_results, gen_params.fps);
784-
LOG_INFO("save result MJPG AVI video to '%s'\n", final_output_path.c_str());
785-
} else {
786-
// appending ".png" to absent or unknown extension
787-
if (!is_jpg && file_ext_lower != ".png") {
788-
base_path += file_ext;
789-
file_ext = ".png";
790-
}
791-
if (cli_params.output_begin_idx == -1) {
792-
cli_params.output_begin_idx = 1;
793-
}
794-
for (int i = 0; i < num_results; i++) {
795-
if (results[i].data == nullptr) {
796-
continue;
797-
}
798-
int write_ok;
799-
std::string final_image_path;
800-
final_image_path = i > 0 ? base_path + "_" + std::to_string(cli_params.output_begin_idx + i) + file_ext : base_path + file_ext;
801-
if (is_jpg) {
802-
write_ok = stbi_write_jpg(final_image_path.c_str(), results[i].width, results[i].height, results[i].channel,
803-
results[i].data, 90, get_image_params(cli_params, ctx_params, gen_params, gen_params.seed + i).c_str());
804-
LOG_INFO("save result JPEG image to '%s' (%s)", final_image_path.c_str(), write_ok == 0 ? "failure" : "success");
805-
} else {
806-
write_ok = stbi_write_png(final_image_path.c_str(), results[i].width, results[i].height, results[i].channel,
807-
results[i].data, 0, get_image_params(cli_params, ctx_params, gen_params, gen_params.seed + i).c_str());
808-
LOG_INFO("save result PNG image to '%s' (%s)", final_image_path.c_str(), write_ok == 0 ? "failure" : "success");
809-
}
810-
}
805+
if (!save_results(cli_params, ctx_params, gen_params, results, num_results)) {
806+
return 1;
811807
}
812808

813809
for (int i = 0; i < num_results; i++) {

0 commit comments

Comments
 (0)