mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2026-05-20 01:09:57 +00:00
generate both gif and pick smaller (+1 squashed commits)
Squashed commits: [09122d052] generate both gif and pick the smaller one
This commit is contained in:
parent
4117542eae
commit
9e4c29fda7
2 changed files with 122 additions and 3 deletions
|
|
@ -7,6 +7,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "stable-diffusion.h"
|
||||
#include "./gif.h" // charlietangora/gif-h
|
||||
|
||||
#ifndef MSF_GIF_IMPL
|
||||
#define MSF_GIF_IMPL
|
||||
|
|
@ -401,7 +402,7 @@ int create_mjpg_avi_membuf_from_sd_images(sd_image_t* images, int num_images, in
|
|||
// ---------------- Helper: create_gif_buf_from_sd_images ----------------
|
||||
// Builds a GIF in memory from an array of sd_image_t. Returns 0 on success, -1 on failure.
|
||||
// Caller must free(*out_data) when done.
|
||||
int create_gif_buf_from_sd_images(sd_image_t* images, int num_images, int fps, uint8_t** out_data, size_t *out_len)
|
||||
int create_gif_buf_from_sd_images_msf(sd_image_t* images, int num_images, int fps, uint8_t** out_data, size_t *out_len)
|
||||
{
|
||||
if(!images || num_images <= 0 || !out_data || !out_len) return -1;
|
||||
|
||||
|
|
@ -471,4 +472,96 @@ int create_gif_buf_from_sd_images(sd_image_t* images, int num_images, int fps,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int create_gif_buf_from_sd_images_gifh(sd_image_t* images, int num_images, int fps, uint8_t** out_data, size_t *out_len)
|
||||
{
|
||||
if(!images || num_images <= 0 || !out_data || !out_len) return -1;
|
||||
|
||||
// basic parameter heuristics
|
||||
if(fps <= 0) fps = 16;
|
||||
uint32_t delay = (uint32_t)(100 / fps); // hundredths of a second per frame
|
||||
|
||||
int bitDepth = 8;
|
||||
bool dither = false;
|
||||
|
||||
// assume all images same size; use first
|
||||
uint32_t width = images[0].width;
|
||||
uint32_t height = images[0].height;
|
||||
|
||||
GifWriter gw;
|
||||
memset(&gw, 0, sizeof(gw));
|
||||
|
||||
if(!GifBegin(&gw, width, height, delay, bitDepth, dither))
|
||||
{
|
||||
if(gw.oldImage) GIF_FREE(gw.oldImage);
|
||||
|
||||
fprintf(stderr, "Error: GifBegin failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Feed frames
|
||||
for (int i = 0; i < num_images; i++)
|
||||
{
|
||||
sd_image_t* img = &images[i];
|
||||
|
||||
if (img->width != width || img->height != height) {
|
||||
fprintf(stderr, "Frame %d has mismatched dimensions.\n", i);
|
||||
GifEnd(&gw);
|
||||
memfile_free(&gw.mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// gif-h expects 4 channels (RGBA) or 3 channels (RGB). It quantizes internally.
|
||||
// If your images have 3 channels, that’s fine. If 4 channels, it also works.
|
||||
int channels = img->channel;
|
||||
if (channels != 3 && channels != 4) {
|
||||
fprintf(stderr, "Unsupported channel count: %d\n", channels);
|
||||
GifEnd(&gw);
|
||||
memfile_free(&gw.mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// gif-h requires 4 channels (RGBA). If you only have RGB, add opaque alpha.
|
||||
uint8_t* frame_rgba = NULL;
|
||||
if (channels == 3) {
|
||||
frame_rgba = (uint8_t*)malloc(width * height * 4);
|
||||
for (int p = 0; p < width * height; p++) {
|
||||
frame_rgba[p*4+0] = img->data[p*3+0];
|
||||
frame_rgba[p*4+1] = img->data[p*3+1];
|
||||
frame_rgba[p*4+2] = img->data[p*3+2];
|
||||
frame_rgba[p*4+3] = 255;
|
||||
}
|
||||
} else {
|
||||
frame_rgba = img->data; // already RGBA
|
||||
}
|
||||
|
||||
if(!GifWriteFrame(&gw, frame_rgba, width, height, delay, bitDepth, dither))
|
||||
{
|
||||
fprintf(stderr, "GIF Write Failed\n");
|
||||
GifEnd(&gw);
|
||||
memfile_free(&gw.mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (channels == 3) {
|
||||
free(frame_rgba);
|
||||
}
|
||||
}
|
||||
|
||||
if(!GifEnd(&gw))
|
||||
{
|
||||
memfile_free(&gw.mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t* buf = memfile_detach(&gw.mem, out_len);
|
||||
if(!buf)
|
||||
{
|
||||
memfile_free(&gw.mem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out_data = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // __AVI_WRITER_H__
|
||||
|
|
@ -944,20 +944,46 @@ sd_generation_outputs sdtype_generate(const sd_generation_inputs inputs)
|
|||
uint8_t * out_data = nullptr;
|
||||
size_t out_len = 0;
|
||||
int status = 0;
|
||||
|
||||
if(vid_req_avi==1)
|
||||
{
|
||||
status = create_mjpg_avi_membuf_from_sd_images(results, generated_num_results, 16, 40, &out_data,&out_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = create_gif_buf_from_sd_images(results, generated_num_results, 16, &out_data,&out_len);
|
||||
uint8_t * out_data_a = nullptr;
|
||||
uint8_t * out_data_b = nullptr;
|
||||
int status_a = 0;
|
||||
int status_b = 0;
|
||||
size_t out_len_a = 0;
|
||||
size_t out_len_b = 0;
|
||||
status_a = create_gif_buf_from_sd_images_gifh(results, generated_num_results, 16, &out_data_a,&out_len_a);
|
||||
status_b = create_gif_buf_from_sd_images_msf(results, generated_num_results, 16, &out_data_b,&out_len_b);
|
||||
if(!sd_is_quiet && sddebugmode==1)
|
||||
{
|
||||
printf("GIF-H Len: %zu, MSF Len: %zu\n",out_len_a,out_len_b);
|
||||
}
|
||||
if(status_a==0 && out_len_a < out_len_b)
|
||||
{
|
||||
free(out_data_b);
|
||||
out_len = out_len_a;
|
||||
out_data = out_data_a;
|
||||
status = status_a;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(out_data_a);
|
||||
out_len = out_len_b;
|
||||
out_data = out_data_b;
|
||||
status = status_b;
|
||||
}
|
||||
}
|
||||
|
||||
if(!sd_is_quiet && sddebugmode==1)
|
||||
{
|
||||
if(status==0)
|
||||
{
|
||||
printf("Video Saved (Len %d)!\n",out_len);
|
||||
printf("Video Saved (Len %zu)!\n",out_len);
|
||||
}else{
|
||||
printf("Save Failed!\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue