|
| 1 | +#include <stdlib.h> |
| 2 | +#include <stdint.h> |
| 3 | +#include <string.h> |
| 4 | +#include <stdio.h> |
| 5 | + |
| 6 | +#include "cgif.h" |
| 7 | + |
| 8 | +#define WIDTH 3840 // 4096 - 2 - 256 = 3838 (free lzw codes) +1 (to force dict reset: k pixels make adding k-1 codes) +1 to overflow if too litte is allocated in pLZWData |
| 9 | +#define HEIGHT 1 |
| 10 | + |
| 11 | +static uint64_t seed; |
| 12 | + |
| 13 | +int psdrand(void) { |
| 14 | + // simple pseudo random function from musl libc |
| 15 | + seed = 6364136223846793005ULL * seed + 1; |
| 16 | + return seed >> 33; |
| 17 | +} |
| 18 | + |
| 19 | +int main(void) { |
| 20 | + CGIF* pGIF; |
| 21 | + CGIF_Config gConfig; |
| 22 | + CGIF_FrameConfig fConfig; |
| 23 | + uint8_t* pImageData; |
| 24 | + cgif_result r; |
| 25 | + int palette_size = 256; |
| 26 | + uint8_t aPalette[palette_size * 3]; |
| 27 | + |
| 28 | + seed = 42; |
| 29 | + for(int i = 0; i < palette_size; ++i) { |
| 30 | + aPalette[i * 3] = psdrand() % 256; |
| 31 | + aPalette[i * 3 + 1] = psdrand() % 256; |
| 32 | + aPalette[i * 3 + 2] = psdrand() % 256; |
| 33 | + } |
| 34 | + memset(&gConfig, 0, sizeof(CGIF_Config)); |
| 35 | + memset(&fConfig, 0, sizeof(CGIF_FrameConfig)); |
| 36 | + gConfig.width = WIDTH; |
| 37 | + gConfig.height = HEIGHT; |
| 38 | + gConfig.pGlobalPalette = aPalette; |
| 39 | + gConfig.numGlobalPaletteEntries = palette_size; |
| 40 | + gConfig.path = "avoid_compression.gif"; |
| 41 | + // |
| 42 | + // create new GIF |
| 43 | + pGIF = cgif_newgif(&gConfig); |
| 44 | + if(pGIF == NULL) { |
| 45 | + fputs("failed to create new GIF via cgif_newgif()\n", stderr); |
| 46 | + return 1; |
| 47 | + } |
| 48 | + // |
| 49 | + // add frames to GIF |
| 50 | + uint8_t* code_dict = malloc(sizeof(uint8_t)*palette_size*palette_size); // to check if codes are used already, then avoid them |
| 51 | + memset(code_dict, 0, sizeof(uint8_t)*palette_size*palette_size); |
| 52 | + pImageData = malloc(WIDTH * HEIGHT); |
| 53 | + pImageData[0] = psdrand() % palette_size; |
| 54 | + for(int i = 1; i < WIDTH * HEIGHT; ++i){ |
| 55 | + uint8_t idx = 0; |
| 56 | + while (idx == 0 || code_dict[palette_size*idx + pImageData[i-1]]) idx = psdrand() % palette_size; |
| 57 | + pImageData[i] = idx; |
| 58 | + code_dict[palette_size*idx + pImageData[i-1]] = 1; //mark code as used |
| 59 | + } |
| 60 | + fConfig.pImageData = pImageData; |
| 61 | + r = cgif_addframe(pGIF, &fConfig); |
| 62 | + free(code_dict); |
| 63 | + free(pImageData); |
| 64 | + // |
| 65 | + // write GIF to file |
| 66 | + r = cgif_close(pGIF); // free allocated space at the end of the session |
| 67 | + |
| 68 | + // check for errors |
| 69 | + if(r != CGIF_OK) { |
| 70 | + fprintf(stderr, "failed to create GIF. error code: %d\n", r); |
| 71 | + return 2; |
| 72 | + } |
| 73 | + return 0; |
| 74 | +} |
0 commit comments