From 2937fdd823dd103576c65584ab0b61e1244bdad3 Mon Sep 17 00:00:00 2001 From: Concedo <39025047+LostRuins@users.noreply.github.com> Date: Sun, 24 May 2026 18:34:24 +0800 Subject: [PATCH] make send as reference image default for img2img, but with smart fallback for older models. --- embd_res/kcpp_sdui.embd | 32 +++---- otherarch/sdcpp/kcpp_sd_extensions.h | 1 + otherarch/sdcpp/sdtype_adapter.cpp | 119 ++++++++++++++++----------- otherarch/sdcpp/stable-diffusion.cpp | 1 + 4 files changed, 87 insertions(+), 66 deletions(-) diff --git a/embd_res/kcpp_sdui.embd b/embd_res/kcpp_sdui.embd index 56926be44..5bb2deb33 100644 --- a/embd_res/kcpp_sdui.embd +++ b/embd_res/kcpp_sdui.embd @@ -5,18 +5,18 @@ Stable UI for KoboldCpp - diff --git a/otherarch/sdcpp/kcpp_sd_extensions.h b/otherarch/sdcpp/kcpp_sd_extensions.h index 5369d788c..cdf3d194a 100644 --- a/otherarch/sdcpp/kcpp_sd_extensions.h +++ b/otherarch/sdcpp/kcpp_sd_extensions.h @@ -15,6 +15,7 @@ namespace kcpp_sd { bool is_sd1; bool is_sd2; bool is_sdxs; + bool is_sdxl; bool is_wan; bool is_zimage; int vae_scale_factor; diff --git a/otherarch/sdcpp/sdtype_adapter.cpp b/otherarch/sdcpp/sdtype_adapter.cpp index fd5787f7e..0d3ca91c7 100644 --- a/otherarch/sdcpp/sdtype_adapter.cpp +++ b/otherarch/sdcpp/sdtype_adapter.cpp @@ -974,6 +974,12 @@ static std::string raw_image_to_png_base64(const sd_image_t& img, std::string pa return result; } +bool supports_reference_images(kcpp_sd::model_info info) +{ + bool supported = (info.is_wan || info.is_qwenimg || info.is_flux2 || info.is_kontext || photomaker_enabled); + return supported; +} + sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) { if(sd_ctx == nullptr || sd_params == nullptr) @@ -1055,6 +1061,16 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) } } + //if a single extra image is provided, mask is NOT provided, and img2img image is NOT provided + //and it's a (SD1.5, SDXL) model that doesn't support extra images (see extra_image_data later) + //swap extra image data into img2img instead (graceful fallback) + if(!supports_reference_images(info) && extra_image_data.size()==1 && !is_img2img && img2img_mask=="") + { + is_img2img = true; + img2img_data = extra_image_data[0]; + extra_image_data.clear(); + } + if(info.is_wan && extra_image_data.size()==0 && is_img2img) { extra_image_data.push_back(img2img_data); @@ -1135,42 +1151,11 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) { int nx2, ny2, nc2; int desiredchannels = 3; - if(info.is_wan) + if(supports_reference_images(info)) { - uint8_t * loaded = load_image_from_b64(extra_image_data[i],nx2,ny2,img2imgW,img2imgH,3); - if(loaded) + if(info.is_wan) { - input_extraimage_buffers.push_back(loaded); - sd_image_t extraimage_reference; - extraimage_reference.width = nx2; - extraimage_reference.height = ny2; - extraimage_reference.channel = desiredchannels; - extraimage_reference.data = loaded; - wan_imgs.push_back(extraimage_reference); - } - } - else if(info.is_qwenimg || info.is_flux2) - { - uint8_t * loaded = load_image_from_b64(extra_image_data[i],nx2,ny2); - if(loaded) - { - //kcpp fix: qwen image can stack overflow and crash when ref images exceed - // a total res of 512x512 = 262144, so we downscale if that's the case - // kcpp edit 2mar2026: this seems to be better now, so limit to 1024x1024 instead - int tgtx = nx2; - int tgty = ny2; - int res_lim_crash = 1024 * 1024; - if (nx2 * ny2 > res_lim_crash) - { - float factor = sqrtf((float)res_lim_crash / ((float)nx2 * (float)ny2)); - tgtx = (int)(nx2 * factor); - tgty = (int)(ny2 * factor); - if (!sd_is_quiet && sddebugmode == 1) - { - printf("\nResized RefImg %dx%d to %dx%d", nx2, ny2, tgtx, tgty); - } - loaded = resize_image(loaded, nx2, ny2, tgtx, tgty); - } + uint8_t * loaded = load_image_from_b64(extra_image_data[i],nx2,ny2,img2imgW,img2imgH,3); if(loaded) { input_extraimage_buffers.push_back(loaded); @@ -1179,28 +1164,62 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) extraimage_reference.height = ny2; extraimage_reference.channel = desiredchannels; extraimage_reference.data = loaded; - reference_imgs.push_back(extraimage_reference); + wan_imgs.push_back(extraimage_reference); } } - } - else if (info.is_kontext || photomaker_enabled) - { - uint8_t * loaded = load_image_from_b64(extra_image_data[i],nx2,ny2); - if(loaded) + else if(info.is_qwenimg || info.is_flux2) { - input_extraimage_buffers.push_back(loaded); - sd_image_t extraimage_reference; - extraimage_reference.width = nx2; - extraimage_reference.height = ny2; - extraimage_reference.channel = desiredchannels; - extraimage_reference.data = loaded; - if(info.is_kontext) + uint8_t * loaded = load_image_from_b64(extra_image_data[i],nx2,ny2); + if(loaded) { - reference_imgs.push_back(extraimage_reference); + //kcpp fix: qwen image can stack overflow and crash when ref images exceed + // a total res of 512x512 = 262144, so we downscale if that's the case + // kcpp edit 2mar2026: this seems to be better now, so limit to 1024x1024 instead + int tgtx = nx2; + int tgty = ny2; + int res_lim_crash = 1024 * 1024; + if (nx2 * ny2 > res_lim_crash) + { + float factor = sqrtf((float)res_lim_crash / ((float)nx2 * (float)ny2)); + tgtx = (int)(nx2 * factor); + tgty = (int)(ny2 * factor); + if (!sd_is_quiet && sddebugmode == 1) + { + printf("\nResized RefImg %dx%d to %dx%d", nx2, ny2, tgtx, tgty); + } + loaded = resize_image(loaded, nx2, ny2, tgtx, tgty); + } + if(loaded) + { + input_extraimage_buffers.push_back(loaded); + sd_image_t extraimage_reference; + extraimage_reference.width = nx2; + extraimage_reference.height = ny2; + extraimage_reference.channel = desiredchannels; + extraimage_reference.data = loaded; + reference_imgs.push_back(extraimage_reference); + } } - else + } + else if (info.is_kontext || photomaker_enabled) + { + uint8_t * loaded = load_image_from_b64(extra_image_data[i],nx2,ny2); + if(loaded) { - photomaker_imgs.push_back(extraimage_reference); + input_extraimage_buffers.push_back(loaded); + sd_image_t extraimage_reference; + extraimage_reference.width = nx2; + extraimage_reference.height = ny2; + extraimage_reference.channel = desiredchannels; + extraimage_reference.data = loaded; + if(info.is_kontext) + { + reference_imgs.push_back(extraimage_reference); + } + else + { + photomaker_imgs.push_back(extraimage_reference); + } } } } diff --git a/otherarch/sdcpp/stable-diffusion.cpp b/otherarch/sdcpp/stable-diffusion.cpp index fe4bcfff4..68b40c1b1 100644 --- a/otherarch/sdcpp/stable-diffusion.cpp +++ b/otherarch/sdcpp/stable-diffusion.cpp @@ -5637,6 +5637,7 @@ namespace kcpp_sd { res.is_sdxs = (loadedsdver == SDVersion::VERSION_SDXS_512_DS || loadedsdver == SDVersion::VERSION_SDXS_09); res.is_sd1 = (loadedsdver == SDVersion::VERSION_SD1); res.is_sd2 = (loadedsdver == SDVersion::VERSION_SD2); + res.is_sdxl = sd_version_is_sdxl((SDVersion)loadedsdver); res.vae_scale_factor = ctx->sd->get_vae_scale_factor(); res.spatial_multiple = get_spatial_multiple(ctx); return res;