Created
July 30, 2021 06:41
-
-
Save Benau/39355417005ca06d5d00b94ecc695e1d to your computer and use it in GitHub Desktop.
tgs2gif
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc tgs2gif.c -o tgs2gif -lrlottie -O3 -lz `MagickWand-config --cppflags --cxxflags --ldflags --libs` | |
#include <rlottie_capi.h> | |
#include <MagickWand/MagickWand.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <zlib.h> | |
// Size of the block of memory to use for reading | |
#define LENGTH 0x1000 | |
char* readTGS(char* path) | |
{ | |
size_t cur_size = LENGTH * 2; | |
size_t cursor = 0; | |
char* result = (char*)calloc(cur_size, 1); | |
if (!result) | |
return NULL; | |
gzFile file = gzopen(path, "r"); | |
if (!file) | |
goto err; | |
while (1) | |
{ | |
char buffer[LENGTH]; | |
int bytes_read = gzread(file, buffer, LENGTH - 1); | |
buffer[bytes_read] = '\0'; | |
strncpy(result + cursor, buffer, bytes_read); | |
if (bytes_read < LENGTH - 1) | |
{ | |
if (gzeof (file)) | |
break; | |
else | |
goto err; | |
} | |
char* new_result = (char*)calloc(cur_size + LENGTH, 1); | |
memcpy(new_result, result, cur_size); | |
free(result); | |
result = new_result; | |
cur_size += LENGTH; | |
cursor += bytes_read; | |
} | |
gzclose(file); | |
return result; | |
err: | |
if (file) | |
gzclose(file); | |
free(result); | |
return NULL; | |
} | |
void lottie_configure_model_cache_size(size_t cache_size); | |
int main(int argc, char* argv[]) | |
{ | |
if (argc != 2) | |
{ | |
printf("Usage: tgs2gif path_to_tgs_file\n"); | |
return 1; | |
} | |
lottie_configure_model_cache_size(0); | |
char* tgs = readTGS(argv[1]); | |
Lottie_Animation* animation = lottie_animation_from_data(tgs, "", ""); | |
if (!animation) | |
{ | |
printf("Usage: Failed to import tgs\n"); | |
return 2; | |
} | |
free(tgs); | |
size_t w = 0; | |
size_t h = 0; | |
lottie_animation_get_size(animation, &w, &h); | |
void* buffer = malloc(w * h * 4); | |
if (!buffer) | |
{ | |
printf("Usage: Not enough memory\n"); | |
return 3; | |
} | |
size_t frame_count = lottie_animation_get_totalframe(animation); | |
double frame_rate = lottie_animation_get_framerate(animation); | |
MagickWandGenesis(); | |
MagickWand* wand = NewMagickWand(); | |
if (!wand) | |
{ | |
printf("Usage: Not enough memory\n"); | |
lottie_animation_destroy(animation); | |
return 3; | |
} | |
for (size_t i = 0; i < frame_count ; i++) | |
{ | |
lottie_animation_render(animation, i, buffer, w, h, w * 4); | |
MagickConstituteImage(wand, w, h, "BGRA", CharPixel, buffer); | |
MagickSetImageDispose(wand, BackgroundDispose); | |
MagickSetImageDelay(wand, (unsigned long)(1000. / frame_rate / 10.)); | |
} | |
free(buffer); | |
lottie_animation_destroy(animation); | |
MagickWand* optimized = MagickOptimizeImageLayers(wand); | |
DestroyMagickWand(wand); | |
MagickOptimizeImageTransparency(optimized); | |
MagickWriteImages(optimized, "output.gif", MagickTrue); | |
DestroyMagickWand(optimized); | |
MagickWandTerminus(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment