From 2fc31d36c045e23b406fd423862d7de96c599675 Mon Sep 17 00:00:00 2001 From: Concedo <39025047+LostRuins@users.noreply.github.com> Date: Wed, 1 Oct 2025 17:18:00 +0800 Subject: [PATCH] gif mime type for animated images --- expose.h | 1 + kcpp_sdui.embd | 36 ++++++++++++++--------------- koboldcpp.py | 37 +++++++++++++++++------------- otherarch/sdcpp/sdtype_adapter.cpp | 11 +++++++++ 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/expose.h b/expose.h index 659a0faa9..39d063dc5 100644 --- a/expose.h +++ b/expose.h @@ -209,6 +209,7 @@ struct sd_generation_inputs struct sd_generation_outputs { int status = -1; + int animated = 0; const char * data = ""; }; diff --git a/kcpp_sdui.embd b/kcpp_sdui.embd index e06ec9d8e..3ff138cd1 100644 --- a/kcpp_sdui.embd +++ b/kcpp_sdui.embd @@ -5,18 +5,18 @@ Stable UI for KoboldCpp - - diff --git a/koboldcpp.py b/koboldcpp.py index 166050960..fd0812550 100644 --- a/koboldcpp.py +++ b/koboldcpp.py @@ -322,6 +322,7 @@ class sd_generation_inputs(ctypes.Structure): class sd_generation_outputs(ctypes.Structure): _fields_ = [("status", ctypes.c_int), + ("animated", ctypes.c_int), ("data", ctypes.c_char_p)] class whisper_load_model_inputs(ctypes.Structure): @@ -1862,9 +1863,11 @@ def sd_generate(genparams): inputs.vid_req_avi = vid_req_avi ret = handle.sd_generate(inputs) outstr = "" + animated = False if ret.status==1: outstr = ret.data.decode("UTF-8","ignore") - return outstr + animated = True if ret.animated else False + return {"animated": animated, "data":outstr} def whisper_load_model(model_filename): @@ -4086,13 +4089,13 @@ Change Mode
if (api_format == 4 or api_format == 3) and "stream" in genparams and genparams["stream"]: sse_stream_flag = True - gen = asyncio.run(self.handle_request(genparams, api_format, sse_stream_flag)) + gendat = asyncio.run(self.handle_request(genparams, api_format, sse_stream_flag)) try: # Headers are already sent when streaming if not sse_stream_flag: self.send_response(200) - genresp = (json.dumps(gen).encode()) + genresp = (json.dumps(gendat).encode()) self.send_header('content-length', str(len(genresp))) self.end_headers(content_type='application/json') self.wfile.write(genresp) @@ -4104,7 +4107,7 @@ Change Mode
self.end_headers(content_type='text/event-stream') toolsdata_res = [] try: - toolsdata_res = gen['choices'][0]['message']['tool_calls'] + toolsdata_res = gendat['choices'][0]['message']['tool_calls'] if toolsdata_res and len(toolsdata_res)>0: toolsdata_res[0]["index"] = 0 # need to add an index for OWUI except Exception: @@ -4131,17 +4134,19 @@ Change Mode
elif is_oai_imggen: genparams = sd_oai_tranform_params(genparams) gen = sd_generate(genparams) + gendat = gen["data"] + genanim = gen["animated"] genresp = None if is_comfyui_imggen: - if gen: - lastgeneratedcomfyimg = base64.b64decode(gen) + if gendat: + lastgeneratedcomfyimg = base64.b64decode(gendat) else: lastgeneratedcomfyimg = b'' genresp = (json.dumps({"prompt_id": "12345678-0000-0000-0000-000000000001","number": 0,"node_errors":{}}).encode()) elif is_oai_imggen: - genresp = (json.dumps({"created":int(time.time()),"data":[{"b64_json":gen}],"background":"opaque","output_format":"png","size":"1024x1024","quality":"medium"}).encode()) + genresp = (json.dumps({"created":int(time.time()),"data":[{"b64_json":gendat}],"background":"opaque","output_format":"png","size":"1024x1024","quality":"medium"}).encode()) else: - genresp = (json.dumps({"images":[gen],"parameters":{},"info":""}).encode()) + genresp = (json.dumps({"images":[gendat],"parameters":{},"info":"","animated":genanim}).encode()) self.send_response(200) self.send_header('content-length', str(len(genresp))) self.end_headers(content_type='application/json') @@ -4153,8 +4158,8 @@ Change Mode
return elif is_transcribe: try: - gen = whisper_generate(genparams) - genresp = (json.dumps({"text":gen}).encode()) + gendat = whisper_generate(genparams) + genresp = (json.dumps({"text":gendat}).encode()) self.send_response(200) self.send_header('content-length', str(len(genresp))) self.end_headers(content_type='application/json') @@ -4166,10 +4171,10 @@ Change Mode
return elif is_tts: try: - gen = tts_generate(genparams) + gendat = tts_generate(genparams) wav_data = b'' - if gen: - wav_data = base64.b64decode(gen) # Decode the Base64 string into binary data + if gendat: + wav_data = base64.b64decode(gendat) # Decode the Base64 string into binary data self.send_response(200) self.send_header('content-length', str(len(wav_data))) # Set content length self.send_header('Content-Disposition', 'attachment; filename="output.wav"') @@ -4182,10 +4187,10 @@ Change Mode
return elif is_embeddings: try: - gen = embeddings_generate(genparams) + gendat = embeddings_generate(genparams) outdatas = [] odidx = 0 - for od in gen["data"]: + for od in gendat["data"]: if genparams.get("encoding_format", "")=="base64": binary_data = struct.pack('<' + 'f' * len(od), *od) b64_string = base64.b64encode(binary_data).decode('utf-8') @@ -4193,7 +4198,7 @@ Change Mode
else: outdatas.append({"object":"embedding","index":odidx,"embedding":od}) odidx += 1 - genresp = (json.dumps({"object":"list","data":outdatas,"model":friendlyembeddingsmodelname,"usage":{"prompt_tokens":gen["count"],"total_tokens":gen["count"]}}).encode()) + genresp = (json.dumps({"object":"list","data":outdatas,"model":friendlyembeddingsmodelname,"usage":{"prompt_tokens":gendat["count"],"total_tokens":gendat["count"]}}).encode()) self.send_response(200) self.send_header('content-length', str(len(genresp))) self.end_headers(content_type='application/json') diff --git a/otherarch/sdcpp/sdtype_adapter.cpp b/otherarch/sdcpp/sdtype_adapter.cpp index c95ed0a64..1fe7a43fc 100644 --- a/otherarch/sdcpp/sdtype_adapter.cpp +++ b/otherarch/sdcpp/sdtype_adapter.cpp @@ -499,6 +499,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) { printf("\nWarning: KCPP image generation not initialized!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } @@ -653,6 +654,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) if (!resok) { printf("\nKCPP SD: resize extra image failed!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } @@ -812,6 +814,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) if (params.width <= 0 || params.width % 64 != 0 || params.height <= 0 || params.height % 64 != 0) { printf("\nKCPP SD: bad request image dimensions!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } @@ -827,12 +830,14 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) if (nx < 64 || ny < 64 || nx > 2048 || ny > 2048 || nc!= 3) { printf("\nKCPP SD: bad input image dimensions %d x %d!\n",nx,ny); output.data = ""; + output.animated = 0; output.status = 0; return output; } if (!input_image_buffer) { printf("\nKCPP SD: load image from memory failed!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } @@ -846,6 +851,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) if (!resok) { printf("\nKCPP SD: resize image failed!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } @@ -869,6 +875,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) if (!resok) { printf("\nKCPP SD: resize image failed!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } @@ -924,10 +931,12 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) if (results == NULL) { printf("\nKCPP SD generate failed!\n"); output.data = ""; + output.animated = 0; output.status = 0; return output; } + bool wasanim = false; for (int i = 0; i < params.batch_count; i++) { if (results[i].data == NULL) { @@ -944,6 +953,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) uint8_t * out_data = nullptr; size_t out_len = 0; int status = 0; + wasanim = true; if(vid_req_avi==1) { @@ -1012,6 +1022,7 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs) free(results); output.data = recent_data.c_str(); + output.animated = (wasanim?1:0); output.status = 1; total_img_gens += 1; return output;