@@ -491,6 +491,99 @@ static enum sample_method_t sampler_from_name(const std::string& sampler)
491491 }
492492}
493493
494+
495+ uint8_t * load_image_from_b64 (const std::string & b64str, int & width, int & height, int expected_width = 0 , int expected_height = 0 , int expected_channel = 3 )
496+ {
497+ std::vector<uint8_t > decoded_buf = kcpp_base64_decode (b64str);
498+ int c = 0 ;
499+ uint8_t * image_buffer = (uint8_t *)stbi_load_from_memory (decoded_buf.data (), decoded_buf.size (), &width, &height, &c, expected_channel);
500+
501+ if (image_buffer == NULL ) {
502+ fprintf (stderr, " load_image_from_b64 failed\n " );
503+ return NULL ;
504+ }
505+ if (c < expected_channel) {
506+ fprintf (stderr, " load_image_from_b64: the number of channels for the input image must be >= %d, but got %d channels\n " , expected_channel, c);
507+ free (image_buffer);
508+ return NULL ;
509+ }
510+ if (width <= 0 ) {
511+ fprintf (stderr, " load_image_from_b64 error: the width of image must be greater than 0\n " );
512+ free (image_buffer);
513+ return NULL ;
514+ }
515+ if (height <= 0 ) {
516+ fprintf (stderr, " load_image_from_b64 error: the height of image must be greater than 0\n " );
517+ free (image_buffer);
518+ return NULL ;
519+ }
520+
521+ // Resize input image ...
522+ if ((expected_width > 0 && expected_height > 0 ) && (height != expected_height || width != expected_width)) {
523+ float dst_aspect = (float )expected_width / (float )expected_height;
524+ float src_aspect = (float )width / (float )height;
525+
526+ int crop_x = 0 , crop_y = 0 ;
527+ int crop_w = width, crop_h = height;
528+
529+ if (src_aspect > dst_aspect) {
530+ crop_w = (int )(height * dst_aspect);
531+ crop_x = (width - crop_w) / 2 ;
532+ } else if (src_aspect < dst_aspect) {
533+ crop_h = (int )(width / dst_aspect);
534+ crop_y = (height - crop_h) / 2 ;
535+ }
536+
537+ if (crop_x != 0 || crop_y != 0 ) {
538+ if (!sd_is_quiet && sddebugmode==1 )
539+ {
540+ printf (" \n crop input image from %dx%d to %dx%d\n " , width, height, crop_w, crop_h);
541+ }
542+ uint8_t * cropped_image_buffer = (uint8_t *)malloc (crop_w * crop_h * expected_channel);
543+ if (cropped_image_buffer == NULL ) {
544+ fprintf (stderr, " \n error: allocate memory for crop\n " );
545+ free (image_buffer);
546+ return NULL ;
547+ }
548+ for (int row = 0 ; row < crop_h; row++) {
549+ uint8_t * src = image_buffer + ((crop_y + row) * width + crop_x) * expected_channel;
550+ uint8_t * dst = cropped_image_buffer + (row * crop_w) * expected_channel;
551+ memcpy (dst, src, crop_w * expected_channel);
552+ }
553+
554+ width = crop_w;
555+ height = crop_h;
556+ free (image_buffer);
557+ image_buffer = cropped_image_buffer;
558+ }
559+
560+ if (!sd_is_quiet && sddebugmode==1 )
561+ {
562+ printf (" \n resize input image from %dx%d to %dx%d\n " , width, height, expected_width, expected_height);
563+ }
564+ int resized_height = expected_height;
565+ int resized_width = expected_width;
566+
567+ uint8_t * resized_image_buffer = (uint8_t *)malloc (resized_height * resized_width * expected_channel);
568+ if (resized_image_buffer == NULL ) {
569+ fprintf (stderr, " \n error: allocate memory for resize input image\n " );
570+ free (image_buffer);
571+ return NULL ;
572+ }
573+ stbir_resize (image_buffer, width, height, 0 ,
574+ resized_image_buffer, resized_width, resized_height, 0 , STBIR_TYPE_UINT8,
575+ expected_channel, STBIR_ALPHA_CHANNEL_NONE, 0 ,
576+ STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP,
577+ STBIR_FILTER_BOX, STBIR_FILTER_BOX,
578+ STBIR_COLORSPACE_SRGB, nullptr );
579+ width = resized_width;
580+ height = resized_height;
581+ free (image_buffer);
582+ image_buffer = resized_image_buffer;
583+ }
584+ return image_buffer;
585+ }
586+
494587sd_generation_outputs sdtype_generate (const sd_generation_inputs inputs)
495588{
496589 sd_generation_outputs output;
@@ -583,8 +676,6 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
583676 sd_image_t input_image = {0 ,0 ,0 ,nullptr };
584677 std::vector<sd_image_t > extraimage_references;
585678 extraimage_references.reserve (max_extra_images);
586- std::vector<uint8_t > image_buffer;
587- std::vector<uint8_t > image_mask_buffer;
588679 std::vector<std::vector<uint8_t >> extraimage_buffers;
589680 extraimage_buffers.reserve (max_extra_images);
590681
@@ -594,8 +685,6 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
594685 int img2imgC = 3 ; // Assuming RGB image
595686 // because the reference image can be larger than the output image, allocate at least enough for 1024x1024
596687 const int imgMemNeed = std::max (img2imgW * img2imgH * img2imgC + 512 , 1024 * 1024 * img2imgC + 512 );
597- std::vector<uint8_t > resized_image_buf (imgMemNeed);
598- std::vector<uint8_t > resized_mask_buf (imgMemNeed);
599688 std::vector<std::vector<uint8_t >> resized_extraimage_bufs (max_extra_images, std::vector<uint8_t >(imgMemNeed));
600689
601690 std::string ts = get_timestamp_str ();
@@ -833,21 +922,14 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
833922 return output;
834923 }
835924
836- image_buffer = kcpp_base64_decode (img2img_data);
837925 if (input_image_buffer!=nullptr ) // just in time free old buffer
838926 {
839927 stbi_image_free (input_image_buffer);
840928 input_image_buffer = nullptr ;
841929 }
842- input_image_buffer = stbi_load_from_memory (image_buffer.data (), image_buffer.size (), &nx, &ny, &nc, 3 );
843930
844- if (nx < 64 || ny < 64 || nx > 2048 || ny > 2048 || nc!= 3 ) {
845- printf (" \n KCPP SD: bad input image dimensions %d x %d!\n " ,nx,ny);
846- output.data = " " ;
847- output.animated = 0 ;
848- output.status = 0 ;
849- return output;
850- }
931+ input_image_buffer = load_image_from_b64 (img2img_data,nx,ny,img2imgW,img2imgH,3 );
932+
851933 if (!input_image_buffer) {
852934 printf (" \n KCPP SD: load image from memory failed!\n " );
853935 output.data = " " ;
@@ -856,20 +938,6 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
856938 return output;
857939 }
858940
859- // Resize the image
860- if (!sd_is_quiet && sddebugmode==1 )
861- {
862- printf (" Resize Img2Img: %dx%d to %dx%d\n " ,nx,ny,img2imgW,img2imgH);
863- }
864- int resok = stbir_resize_uint8 (input_image_buffer, nx, ny, 0 , resized_image_buf.data (), img2imgW, img2imgH, 0 , img2imgC);
865- if (!resok) {
866- printf (" \n KCPP SD: resize image failed!\n " );
867- output.data = " " ;
868- output.animated = 0 ;
869- output.status = 0 ;
870- return output;
871- }
872-
873941 if (img2img_mask!=" " )
874942 {
875943 int nx2, ny2, nc2;
@@ -878,39 +946,26 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
878946 stbi_image_free (input_mask_buffer);
879947 input_mask_buffer = nullptr ;
880948 }
881- image_mask_buffer = kcpp_base64_decode (img2img_mask);
882- input_mask_buffer = stbi_load_from_memory (image_mask_buffer.data (), image_mask_buffer.size (), &nx2, &ny2, &nc2, 1 );
883- // Resize the image
884- if (!sd_is_quiet && sddebugmode==1 )
885- {
886- printf (" Resize Mask: %dx%d to %dx%d\n " ,nx2,ny2,img2imgW,img2imgH);
887- }
888- int resok = stbir_resize_uint8 (input_mask_buffer, nx2, ny2, 0 , resized_mask_buf.data (), img2imgW, img2imgH, 0 , 1 );
889- if (!resok) {
890- printf (" \n KCPP SD: resize image failed!\n " );
891- output.data = " " ;
892- output.animated = 0 ;
893- output.status = 0 ;
894- return output;
895- }
949+ input_mask_buffer = load_image_from_b64 (img2img_mask,nx2,ny2,img2imgW,img2imgH,1 );
950+
896951 if (inputs.flip_mask )
897952 {
898- int bufsiz = resized_mask_buf. size ();
953+ int bufsiz = nx2 * ny2 * 1 ; // 1 channel
899954 for (int i = 0 ; i < bufsiz; ++i) {
900- resized_mask_buf [i] = 255 - resized_mask_buf [i];
955+ input_mask_buffer [i] = 255 - input_mask_buffer [i];
901956 }
902957 }
903958 }
904959
905960 input_image.width = img2imgW;
906961 input_image.height = img2imgH;
907962 input_image.channel = img2imgC;
908- input_image.data = resized_image_buf. data () ;
963+ input_image.data = input_image_buffer ;
909964
910965 uint8_t * mask_image_buffer = NULL ;
911966 std::vector<uint8_t > default_mask_image_vec (img2imgW * img2imgH * img2imgC, 255 );
912967 if (img2img_mask != " " ) {
913- mask_image_buffer = resized_mask_buf. data () ;
968+ mask_image_buffer = input_mask_buffer ;
914969 } else {
915970 mask_image_buffer = default_mask_image_vec.data ();
916971 }
@@ -922,7 +977,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
922977 if (!sd_is_quiet && sddebugmode==1 )
923978 {
924979 std::stringstream ss;
925- ss << " \n nIMG2IMG PROMPT:" << params.prompt
980+ ss << " \n IMG2IMG PROMPT:" << params.prompt
926981 << " \n NPROMPT:" << params.negative_prompt
927982 << " \n CLPSKP:" << params.clip_skip
928983 << " \n CFGSCLE:" << params.sample_params .guidance .txt_cfg
0 commit comments