// gcc tgs2gif.c -o tgs2gif -lrlottie -O3 -lz `MagickWand-config --cppflags --cxxflags --ldflags --libs` #include #include #include #include #include #include // 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; }