@@ -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+
373462int 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