-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #50 from dloebl/interlaced
Add support for interlaced encoding
- Loading branch information
Showing
10 changed files
with
270 additions
and
2 deletions.
There are no files selected for viewing
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "cgif.h" | ||
|
||
#define WIDTH 40 | ||
#define HEIGHT 40 | ||
|
||
/* Small helper functions to initialize GIF- and frame-configuration */ | ||
static void initGIFConfig(CGIF_Config* pConfig, char* path, uint16_t width, uint16_t height, uint8_t* pPalette, uint16_t numColors) { | ||
memset(pConfig, 0, sizeof(CGIF_Config)); | ||
pConfig->width = width; | ||
pConfig->height = height; | ||
pConfig->pGlobalPalette = pPalette; | ||
pConfig->numGlobalPaletteEntries = numColors; | ||
pConfig->path = path; | ||
pConfig->attrFlags = CGIF_ATTR_IS_ANIMATED; | ||
} | ||
static void initFrameConfig(CGIF_FrameConfig* pConfig, uint8_t* pImageData, uint16_t delay) { | ||
memset(pConfig, 0, sizeof(CGIF_FrameConfig)); | ||
pConfig->delay = delay; | ||
pConfig->pImageData = pImageData; | ||
pConfig->attrFlags = CGIF_FRAME_ATTR_INTERLACED; | ||
pConfig->genFlags = CGIF_FRAME_GEN_USE_TRANSPARENCY | CGIF_FRAME_GEN_USE_DIFF_WINDOW; // use optimizations | ||
} | ||
|
||
/* This is an example code that creates a GIF-animation with a moving snake. */ | ||
int main(void) { | ||
CGIF* pGIF; // struct containing the GIF | ||
CGIF_Config gConfig; // global configuration parameters for the GIF | ||
CGIF_FrameConfig fConfig; // configuration parameters for a frame | ||
uint8_t* pImageData; // image data (an array of color-indices) | ||
int x,y,x1,y1; // position of snake beginning and end | ||
cgif_result r; | ||
uint8_t aPalette[] = {0xFF, 0x00, 0x00, // red | ||
0x00, 0xFF, 0x00, // green | ||
0x00, 0x00, 0xFF}; // blue | ||
uint8_t numColors = 3; // number of colors in aPalette (up to 256 possible) | ||
int numFrames = 37*4; // number of frames in the video | ||
|
||
// initialize the GIF-configuration and create a new GIF | ||
initGIFConfig(&gConfig, "animated_interlaced.gif", WIDTH, HEIGHT, aPalette, numColors); | ||
pGIF = cgif_newgif(&gConfig); | ||
if(pGIF == NULL) { | ||
fputs("failed to create new GIF via cgif_newgif()\n", stderr); | ||
return 1; | ||
} | ||
|
||
// create image frames and add them to GIF | ||
pImageData = malloc(WIDTH * HEIGHT); // allocate memory for image data | ||
memset(pImageData, 0, WIDTH * HEIGHT); // set the background color to 1st color in palette | ||
x = 1; // set start position... | ||
y = 1; | ||
x1 = 1; | ||
y1 = 15; | ||
for (int i = 1; i < 15; ++i) { // draw the snake | ||
pImageData[1 + i*WIDTH] = 1; | ||
} | ||
for (int f = 0; f < numFrames; ++f) { // loop over all frames | ||
pImageData[x + y*WIDTH] = 0; // remove end of the snake | ||
pImageData[x1 + y1*WIDTH] = 1; // moving pixel at snake head | ||
if (x==1 && y<WIDTH-2) { // rules for moving the snake... | ||
y++; | ||
} else if (y==WIDTH-2 && x<WIDTH-2){ | ||
x++; | ||
} else if (x==WIDTH-2 && y>1){ | ||
y--; | ||
} else{ | ||
x--; | ||
} | ||
if (x1==1 && y1<WIDTH-2) { | ||
y1++; | ||
} else if (y1==WIDTH-2 && x1<WIDTH-2){ | ||
x1++; | ||
} else if (x1==WIDTH-2 && y1>1){ | ||
y1--; | ||
} else{ | ||
x1--; | ||
} | ||
initFrameConfig(&fConfig, pImageData, 5); // initialize the frame-configuration | ||
r = cgif_addframe(pGIF, &fConfig); // append the new frame | ||
if(r != CGIF_OK) { | ||
break; | ||
} | ||
} | ||
free(pImageData); // free image data when all frames are added | ||
|
||
// close created GIF-file and free allocated space | ||
r = cgif_close(pGIF); | ||
|
||
// check for errors | ||
if(r != CGIF_OK) { | ||
fprintf(stderr, "failed to create GIF. error code: %d\n", r); | ||
return 2; | ||
} | ||
return 0; | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "cgif.h" | ||
|
||
#define WIDTH 700 | ||
#define HEIGHT 320 | ||
|
||
static uint64_t seed; | ||
|
||
int psdrand(void) { | ||
// simple pseudo random function from musl libc | ||
seed = 6364136223846793005ULL * seed + 1; | ||
return seed >> 33; | ||
} | ||
|
||
int main(void) { | ||
CGIF* pGIF; | ||
CGIF_Config gConfig; | ||
CGIF_FrameConfig fConfig; | ||
uint8_t* pImageData; | ||
cgif_result r; | ||
uint8_t aPalette[6 * 3]; | ||
|
||
seed = 42; | ||
for(int i = 0; i < 6; ++i) { | ||
aPalette[i * 3] = psdrand() % 256; | ||
aPalette[i * 3 + 1] = psdrand() % 256; | ||
aPalette[i * 3 + 2] = psdrand() % 256; | ||
} | ||
memset(&gConfig, 0, sizeof(CGIF_Config)); | ||
memset(&fConfig, 0, sizeof(CGIF_FrameConfig)); | ||
gConfig.width = WIDTH; | ||
gConfig.height = HEIGHT; | ||
gConfig.pGlobalPalette = aPalette; | ||
gConfig.numGlobalPaletteEntries = 6; | ||
gConfig.path = "noise6_interlaced.gif"; | ||
// | ||
// create new GIF | ||
pGIF = cgif_newgif(&gConfig); | ||
if(pGIF == NULL) { | ||
fputs("failed to create new GIF via cgif_newgif()\n", stderr); | ||
return 1; | ||
} | ||
// | ||
// add frames to GIF | ||
pImageData = malloc(WIDTH * HEIGHT); | ||
for(int i = 0; i < WIDTH * HEIGHT; ++i) pImageData[i] = psdrand() % 6; | ||
fConfig.pImageData = pImageData; | ||
fConfig.attrFlags = CGIF_FRAME_ATTR_INTERLACED; | ||
r = cgif_addframe(pGIF, &fConfig); | ||
free(pImageData); | ||
// | ||
// write GIF to file | ||
r = cgif_close(pGIF); // free allocated space at the end of the session | ||
|
||
// check for errors | ||
if(r != CGIF_OK) { | ||
fprintf(stderr, "failed to create GIF. error code: %d\n", r); | ||
return 2; | ||
} | ||
return 0; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
#include <stdio.h> | ||
|
||
#include "cgif.h" | ||
|
||
#define WIDTH 1000 | ||
#define HEIGHT 1000 | ||
|
||
/* horizontal stripe pattern with 1pixel linewidth, to test interlaced mode */ | ||
int main(void) { | ||
CGIF* pGIF; | ||
CGIF_Config gConfig; | ||
CGIF_FrameConfig fConfig; | ||
uint8_t* pImageData; | ||
cgif_result r; | ||
|
||
uint8_t aPalette[] = { | ||
0x00, 0xFF, 0x00, // green | ||
0xFF, 0x00, 0xFF, // purple | ||
}; | ||
memset(&gConfig, 0, sizeof(CGIF_Config)); | ||
memset(&fConfig, 0, sizeof(CGIF_FrameConfig)); | ||
gConfig.width = WIDTH; | ||
gConfig.height = HEIGHT; | ||
gConfig.pGlobalPalette = aPalette; | ||
gConfig.numGlobalPaletteEntries = 2; | ||
gConfig.path = "stripe_pattern_interlaced.gif"; | ||
// | ||
// create new GIF | ||
pGIF = cgif_newgif(&gConfig); | ||
if(pGIF == NULL) { | ||
fputs("failed to create new GIF via cgif_newgif()\n", stderr); | ||
return 1; | ||
} | ||
// | ||
// add frames to GIF | ||
pImageData = malloc(WIDTH * HEIGHT); | ||
for(int i = 0; i < HEIGHT; ++i){ | ||
memset(pImageData + i*WIDTH, i % 2, WIDTH); | ||
} | ||
fConfig.pImageData = pImageData; | ||
fConfig.attrFlags = CGIF_FRAME_ATTR_INTERLACED; | ||
r = cgif_addframe(pGIF, &fConfig); | ||
free(pImageData); | ||
// | ||
// write GIF to file | ||
r = cgif_close(pGIF); // free allocated space at the end of the session | ||
|
||
// check for errors | ||
if(r != CGIF_OK) { | ||
fprintf(stderr, "failed to create GIF. error code: %d\n", r); | ||
return 2; | ||
} | ||
return 0; | ||
} |
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