@@ -116,7 +116,8 @@ static int sddebugmode = 0;
116116static std::string recent_data = " " ;
117117static uint8_t * input_image_buffer = NULL ;
118118static uint8_t * input_mask_buffer = NULL ;
119- static uint8_t * input_extraimage_buffer = NULL ;
119+ static std::vector<uint8_t *> input_extraimage_buffers;
120+ const int max_extra_images = 4 ;
120121
121122static std::string sdplatformenv, sddeviceenv, sdvulkandeviceenv;
122123static int cfg_tiled_vae_threshold = 0 ;
@@ -288,8 +289,9 @@ bool sdtype_load_model(const sd_load_model_inputs inputs) {
288289 sd_ctx->sd ->apply_lora_from_file (lorafilename,inputs.lora_multiplier );
289290 }
290291
291- return true ;
292+ input_extraimage_buffers. reserve (max_extra_images) ;
292293
294+ return true ;
293295}
294296
295297std::string clean_input_prompt (const std::string& input) {
@@ -434,7 +436,12 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
434436 std::string cleannegprompt = clean_input_prompt (inputs.negative_prompt );
435437 std::string img2img_data = std::string (inputs.init_images );
436438 std::string img2img_mask = std::string (inputs.mask );
437- std::string extra_image_data = std::string (inputs.extra_image );
439+ std::vector<std::string> extra_image_data;
440+ for (int i=0 ;i<inputs.extra_images_len ;++i)
441+ {
442+ extra_image_data.push_back (std::string (inputs.extra_images [i]));
443+ }
444+
438445 std::string sampler = inputs.sample_method ;
439446
440447 sd_params->prompt = cleanprompt;
@@ -503,17 +510,20 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
503510
504511 // for img2img
505512 sd_image_t input_image = {0 ,0 ,0 ,nullptr };
506- sd_image_t extraimage_reference = {0 ,0 ,0 ,nullptr };
513+ std::vector<sd_image_t > extraimage_references;
514+ extraimage_references.reserve (max_extra_images);
507515 std::vector<uint8_t > image_buffer;
508516 std::vector<uint8_t > image_mask_buffer;
509- std::vector<uint8_t > extraimage_buffer;
517+ std::vector<std::vector<uint8_t >> extraimage_buffers;
518+ extraimage_buffers.reserve (max_extra_images);
519+
510520 int nx, ny, nc;
511521 int img2imgW = sd_params->width ; // for img2img input
512522 int img2imgH = sd_params->height ;
513523 int img2imgC = 3 ; // Assuming RGB image
514524 std::vector<uint8_t > resized_image_buf (img2imgW * img2imgH * img2imgC);
515525 std::vector<uint8_t > resized_mask_buf (img2imgW * img2imgH * img2imgC);
516- std::vector<uint8_t > resized_extraimage_buf ( img2imgW * img2imgH * img2imgC);
526+ std::vector<std::vector< uint8_t >> resized_extraimage_bufs (max_extra_images, std::vector< uint8_t >( img2imgW * img2imgH * img2imgC) );
517527
518528 std::string ts = get_timestamp_str ();
519529 if (!sd_is_quiet)
@@ -558,29 +568,39 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
558568 sd_params->sample_method = sample_method_t ::EULER_A;
559569 }
560570
561- if (extra_image_data!= " " )
571+ if (extra_image_data. size ()> 0 )
562572 {
563- if (input_extraimage_buffer!= nullptr ) // just in time free old buffer
573+ if (input_extraimage_buffers. size ()> 0 ) // just in time free old buffer
564574 {
565- stbi_image_free (input_extraimage_buffer);
566- input_extraimage_buffer = nullptr ;
575+ for (int i=0 ;i<input_extraimage_buffers.size ();++i)
576+ {
577+ stbi_image_free (input_extraimage_buffers[i]);
578+ }
579+ input_extraimage_buffers.clear ();
567580 }
568- int nx2, ny2, nc2;
569- int desiredchannels = 3 ;
570- extraimage_buffer = kcpp_base64_decode (extra_image_data);
571- input_extraimage_buffer = stbi_load_from_memory (extraimage_buffer.data (), extraimage_buffer.size (), &nx2, &ny2, &nc2, desiredchannels);
572- // Resize the image
573- int resok = stbir_resize_uint8 (input_extraimage_buffer, nx2, ny2, 0 , resized_extraimage_buf.data (), img2imgW, img2imgH, 0 , desiredchannels);
574- if (!resok) {
575- printf (" \n KCPP SD: resize extra image failed!\n " );
576- output.data = " " ;
577- output.status = 0 ;
578- return output;
581+ extraimage_buffers.clear ();
582+ extraimage_references.clear ();
583+ for (int i=0 ;i<extra_image_data.size () && i<max_extra_images;++i)
584+ {
585+ int nx2, ny2, nc2;
586+ int desiredchannels = 3 ;
587+ extraimage_buffers.push_back (kcpp_base64_decode (extra_image_data[i]));
588+ input_extraimage_buffers.push_back (stbi_load_from_memory (extraimage_buffers[i].data (), extraimage_buffers[i].size (), &nx2, &ny2, &nc2, desiredchannels));
589+ // Resize the image
590+ int resok = stbir_resize_uint8 (input_extraimage_buffers[i], nx2, ny2, 0 , resized_extraimage_bufs[i].data (), img2imgW, img2imgH, 0 , desiredchannels);
591+ if (!resok) {
592+ printf (" \n KCPP SD: resize extra image failed!\n " );
593+ output.data = " " ;
594+ output.status = 0 ;
595+ return output;
596+ }
597+ sd_image_t extraimage_reference;
598+ extraimage_reference.width = img2imgW;
599+ extraimage_reference.height = img2imgH;
600+ extraimage_reference.channel = desiredchannels;
601+ extraimage_reference.data = resized_extraimage_bufs[i].data ();
602+ extraimage_references.push_back (extraimage_reference);
579603 }
580- extraimage_reference.width = img2imgW;
581- extraimage_reference.height = img2imgH;
582- extraimage_reference.channel = desiredchannels;
583- extraimage_reference.data = resized_extraimage_buf.data ();
584604
585605 // ensure prompt has img keyword, otherwise append it
586606 if (photomaker_enabled)
@@ -595,9 +615,29 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
595615 }
596616
597617 std::vector<sd_image_t > kontext_imgs;
598- if (extra_image_data!= " " && loadedsdver==SDVersion::VERSION_FLUX && !sd_loaded_chroma ())
618+ if (extra_image_data. size ()> 0 && loadedsdver==SDVersion::VERSION_FLUX && !sd_loaded_chroma ())
599619 {
600- kontext_imgs.push_back (extraimage_reference);
620+ for (int i=0 ;i<extra_image_data.size ();++i)
621+ {
622+ kontext_imgs.push_back (extraimage_references[i]);
623+ }
624+ if (!sd_is_quiet && sddebugmode==1 )
625+ {
626+ printf (" \n Flux Kontext: Using %d reference images\n " ,kontext_imgs.size ());
627+ }
628+ }
629+
630+ std::vector<sd_image_t *> photomaker_imgs;
631+ if (photomaker_enabled && extra_image_data.size ()>0 )
632+ {
633+ for (int i=0 ;i<extra_image_data.size ();++i)
634+ {
635+ photomaker_imgs.push_back (&extraimage_references[i]);
636+ }
637+ if (!sd_is_quiet && sddebugmode==1 )
638+ {
639+ printf (" \n Photomaker: Using %d reference images\n " ,photomaker_imgs.size ());
640+ }
601641 }
602642
603643 if (sd_params->mode == TXT2IMG) {
@@ -644,7 +684,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
644684 sd_params->slg_scale ,
645685 sd_params->skip_layer_start ,
646686 sd_params->skip_layer_end ,
647- (photomaker_enabled && extra_image_data!= " " ?(&extraimage_reference): nullptr ) );
687+ photomaker_imgs );
648688 } else {
649689
650690 if (sd_params->width <= 0 || sd_params->width % 64 != 0 || sd_params->height <= 0 || sd_params->height % 64 != 0 ) {
@@ -769,7 +809,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
769809 sd_params->slg_scale ,
770810 sd_params->skip_layer_start ,
771811 sd_params->skip_layer_end ,
772- (photomaker_enabled && extra_image_data!= " " ?(&extraimage_reference): nullptr ) );
812+ photomaker_imgs );
773813 }
774814
775815 if (results == NULL ) {
0 commit comments