implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 1) /* BlinkenLib
BlinkenLib/BlinkenGif.c 2) Copyright 2004-2016 Stefan Schuermans <stefan@schuermans.info>
BlinkenLib/BlinkenGif.c 3) Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
BlinkenLib/BlinkenGif.c 4) a blinkenarea.org project */
BlinkenLib/BlinkenGif.c 5)
BlinkenLib/BlinkenGif.c 6) #include <gif_lib.h>
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 7) #include <stdlib.h>
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 8)
BlinkenLib/BlinkenGif.c 9) #include <BlinkenLib/config.h>
BlinkenLib/BlinkenGif.c 10) #include <BlinkenLib/BlinkenFrame.h>
BlinkenLib/BlinkenGif.c 11) #include <BlinkenLib/BlinkenMovie.h>
|
restructure directories
Stefan Schuermans authored 5 years ago
|
src/BlinkenGif.c 12)
src/BlinkenGif.c 13) #include "BlinkenConstants.h"
src/BlinkenGif.c 14) #include "BlinkenGif.h"
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 15)
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 16) #ifdef BLINKENLIB_CFG_GIF5
BlinkenLib/BlinkenGif.c 17) # define GIF5_err , &giferr
BlinkenLib/BlinkenGif.c 18) #else
BlinkenLib/BlinkenGif.c 19) # define GIF5_err
BlinkenLib/BlinkenGif.c 20) #endif
BlinkenLib/BlinkenGif.c 21)
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 22) // get color from GIF color map
BlinkenLib/BlinkenGif.c 23) static void BlinkenGifGetColor(ColorMapObject *pMap, int idx, int transparent,
BlinkenLib/BlinkenGif.c 24) unsigned char *r, unsigned char *g,
BlinkenLib/BlinkenGif.c 25) unsigned char *b, unsigned char *t)
BlinkenLib/BlinkenGif.c 26) {
BlinkenLib/BlinkenGif.c 27) if (transparent >= 0 && idx == transparent) {
BlinkenLib/BlinkenGif.c 28) *t = 1;
BlinkenLib/BlinkenGif.c 29) } else {
BlinkenLib/BlinkenGif.c 30) *t = 0;
BlinkenLib/BlinkenGif.c 31) }
BlinkenLib/BlinkenGif.c 32) if (pMap != NULL) {
BlinkenLib/BlinkenGif.c 33) if (idx >= 0 && idx < pMap->ColorCount) {
BlinkenLib/BlinkenGif.c 34) *r = pMap->Colors[idx].Red;
BlinkenLib/BlinkenGif.c 35) *g = pMap->Colors[idx].Green;
BlinkenLib/BlinkenGif.c 36) *b = pMap->Colors[idx].Blue;
BlinkenLib/BlinkenGif.c 37) } else {
BlinkenLib/BlinkenGif.c 38) *r = 0;
BlinkenLib/BlinkenGif.c 39) *g = 0;
BlinkenLib/BlinkenGif.c 40) *b = 0;
BlinkenLib/BlinkenGif.c 41) *t = 1;
BlinkenLib/BlinkenGif.c 42) }
BlinkenLib/BlinkenGif.c 43) } else {
BlinkenLib/BlinkenGif.c 44) *r = 0;
BlinkenLib/BlinkenGif.c 45) *g = 0;
BlinkenLib/BlinkenGif.c 46) *b = 0;
BlinkenLib/BlinkenGif.c 47) *t = 1;
BlinkenLib/BlinkenGif.c 48) }
BlinkenLib/BlinkenGif.c 49) }
BlinkenLib/BlinkenGif.c 50)
BlinkenLib/BlinkenGif.c 51) // set pixel to GIF color
BlinkenLib/BlinkenGif.c 52) static void BlinkenGifSetPixel(ColorMapObject *pMap, int idx, int transparent,
BlinkenLib/BlinkenGif.c 53) stBlinkenFrame *pFrame, int y, int x)
BlinkenLib/BlinkenGif.c 54) {
BlinkenLib/BlinkenGif.c 55) unsigned char r, g, b, t;
BlinkenLib/BlinkenGif.c 56)
BlinkenLib/BlinkenGif.c 57) if (pFrame != NULL) {
BlinkenLib/BlinkenGif.c 58) BlinkenGifGetColor(pMap, idx, transparent, &r, &g, &b, &t);
BlinkenLib/BlinkenGif.c 59) if (! t) {
BlinkenLib/BlinkenGif.c 60) BlinkenFrameSetPixel(pFrame, y, x, 0, r);
BlinkenLib/BlinkenGif.c 61) BlinkenFrameSetPixel(pFrame, y, x, 1, g);
BlinkenLib/BlinkenGif.c 62) BlinkenFrameSetPixel(pFrame, y, x, 2, b);
BlinkenLib/BlinkenGif.c 63) }
BlinkenLib/BlinkenGif.c 64) }
BlinkenLib/BlinkenGif.c 65) }
BlinkenLib/BlinkenGif.c 66)
BlinkenLib/BlinkenGif.c 67) // load a GIF file as BlinkenMovie
BlinkenLib/BlinkenGif.c 68) stBlinkenMovie *BlinkenGifLoad(const char *pFilename)
BlinkenLib/BlinkenGif.c 69) {
BlinkenLib/BlinkenGif.c 70) GifFileType *gif;
|
support reading interlaced...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 71) struct sPass { int ofs, stride; };
BlinkenLib/BlinkenGif.c 72) static struct sPass const passes_linear[] = { { 0, 1 }, { 0, 0 } };
BlinkenLib/BlinkenGif.c 73) static struct sPass const passes_interlaced[] = {
BlinkenLib/BlinkenGif.c 74) { 0, 8 }, { 4, 8 }, { 2, 4 }, { 1, 2 }
BlinkenLib/BlinkenGif.c 75) };
BlinkenLib/BlinkenGif.c 76) struct sPass const *pass;
BlinkenLib/BlinkenGif.c 77) int height, width, frameCnt, frameIdx, i, y, x, y1, x1,
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 78) bg, disposal, delay, transp, idx;
BlinkenLib/BlinkenGif.c 79) ColorMapObject *pGlobalMap, *pMap;
BlinkenLib/BlinkenGif.c 80) SavedImage *pImg;
BlinkenLib/BlinkenGif.c 81) GifImageDesc *pDesc;
BlinkenLib/BlinkenGif.c 82) ExtensionBlock *pEx;
BlinkenLib/BlinkenGif.c 83) stBlinkenMovie *pMovie;
BlinkenLib/BlinkenGif.c 84) stBlinkenFrame *pBack, *pFrame;
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 85) #ifdef BLINKENLIB_CFG_GIF5
BlinkenLib/BlinkenGif.c 86) int giferr;
BlinkenLib/BlinkenGif.c 87) #endif
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 88)
BlinkenLib/BlinkenGif.c 89) if (pFilename == NULL)
BlinkenLib/BlinkenGif.c 90) return NULL;
BlinkenLib/BlinkenGif.c 91)
BlinkenLib/BlinkenGif.c 92) // open GIF file for decoding
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 93) gif = DGifOpenFileName(pFilename GIF5_err);
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 94) if (gif == NULL) {
BlinkenLib/BlinkenGif.c 95) return NULL;
BlinkenLib/BlinkenGif.c 96) }
BlinkenLib/BlinkenGif.c 97)
BlinkenLib/BlinkenGif.c 98) // read GIF file
BlinkenLib/BlinkenGif.c 99) if (DGifSlurp(gif) != GIF_OK) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 100) DGifCloseFile(gif GIF5_err);
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 101) return NULL;
BlinkenLib/BlinkenGif.c 102) }
BlinkenLib/BlinkenGif.c 103) height = gif->SHeight;
BlinkenLib/BlinkenGif.c 104) width = gif->SWidth;
BlinkenLib/BlinkenGif.c 105) frameCnt = gif->ImageCount;
BlinkenLib/BlinkenGif.c 106) pGlobalMap = gif->SColorMap;
BlinkenLib/BlinkenGif.c 107) bg = gif->SBackGroundColor;
BlinkenLib/BlinkenGif.c 108)
BlinkenLib/BlinkenGif.c 109) // create movie
BlinkenLib/BlinkenGif.c 110) pMovie = BlinkenMovieNew(height, width, 3, 255);
BlinkenLib/BlinkenGif.c 111) if (! pMovie) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 112) DGifCloseFile(gif GIF5_err);
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 113) return NULL;
BlinkenLib/BlinkenGif.c 114) }
BlinkenLib/BlinkenGif.c 115)
BlinkenLib/BlinkenGif.c 116) // create background frame and set it to background color
BlinkenLib/BlinkenGif.c 117) pBack = BlinkenFrameNew(height, width, 3, 255, 1);
BlinkenLib/BlinkenGif.c 118) if (! pBack) {
BlinkenLib/BlinkenGif.c 119) BlinkenMovieFree(pMovie);
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 120) DGifCloseFile(gif GIF5_err);
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 121) return NULL;
BlinkenLib/BlinkenGif.c 122) }
BlinkenLib/BlinkenGif.c 123) for (y = 0; y < height; ++y) {
BlinkenLib/BlinkenGif.c 124) for (x = 0; x < width; ++x) {
BlinkenLib/BlinkenGif.c 125) BlinkenGifSetPixel(pGlobalMap, bg, -1, pBack, y, x);
BlinkenLib/BlinkenGif.c 126) }
BlinkenLib/BlinkenGif.c 127) }
BlinkenLib/BlinkenGif.c 128)
BlinkenLib/BlinkenGif.c 129) // process all frames
BlinkenLib/BlinkenGif.c 130) for (frameIdx = 0; frameIdx < frameCnt; ++frameIdx) {
BlinkenLib/BlinkenGif.c 131) pImg = &gif->SavedImages[frameIdx];
BlinkenLib/BlinkenGif.c 132) pDesc = &pImg->ImageDesc;
BlinkenLib/BlinkenGif.c 133)
BlinkenLib/BlinkenGif.c 134) // get local color map
BlinkenLib/BlinkenGif.c 135) pMap = pDesc->ColorMap != NULL ? pDesc->ColorMap : pGlobalMap;
BlinkenLib/BlinkenGif.c 136)
BlinkenLib/BlinkenGif.c 137) // get disposal mode, delay and transparent color
BlinkenLib/BlinkenGif.c 138) disposal = 0;
BlinkenLib/BlinkenGif.c 139) delay = 100;
BlinkenLib/BlinkenGif.c 140) transp = -1;
BlinkenLib/BlinkenGif.c 141) for (i = 0; i < pImg->ExtensionBlockCount; ++i) {
BlinkenLib/BlinkenGif.c 142) pEx = &pImg->ExtensionBlocks[i];
BlinkenLib/BlinkenGif.c 143) if (pEx->Function == GRAPHICS_EXT_FUNC_CODE && pEx->ByteCount == 4) {
BlinkenLib/BlinkenGif.c 144) disposal = pEx->Bytes[0] >> 2 & 0x07;
BlinkenLib/BlinkenGif.c 145) delay = (unsigned int)(unsigned char)pEx->Bytes[1] |
BlinkenLib/BlinkenGif.c 146) (unsigned int)(unsigned char)pEx->Bytes[2] << 8;
BlinkenLib/BlinkenGif.c 147) transp = pEx->Bytes[0] & 0x01 ? (int)(unsigned char)pEx->Bytes[3] : -1;
BlinkenLib/BlinkenGif.c 148) }
BlinkenLib/BlinkenGif.c 149) }
BlinkenLib/BlinkenGif.c 150)
BlinkenLib/BlinkenGif.c 151) // draw new frame based on background frame, maybe update background frame
BlinkenLib/BlinkenGif.c 152) if (delay > 0) {
BlinkenLib/BlinkenGif.c 153) pFrame = BlinkenFrameClone(pBack);
BlinkenLib/BlinkenGif.c 154) BlinkenFrameSetDuration(pFrame, delay * 10); // GIF delay is in 10ms
BlinkenLib/BlinkenGif.c 155) } else {
BlinkenLib/BlinkenGif.c 156) // frames with no duration -> only effect on background
BlinkenLib/BlinkenGif.c 157) pFrame = NULL;
BlinkenLib/BlinkenGif.c 158) }
|
support reading interlaced...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 159) for (pass = pDesc->Interlace ? passes_interlaced : passes_linear;
BlinkenLib/BlinkenGif.c 160) pass->stride > 0; ++pass) {
BlinkenLib/BlinkenGif.c 161) for (y = pass->ofs, y1 = pDesc->Top + pass->ofs, i = 0;
BlinkenLib/BlinkenGif.c 162) y < pDesc->Height; y += pass->stride, y1 += pass->stride) {
BlinkenLib/BlinkenGif.c 163) for (x = 0, x1 = pDesc->Left; x < pDesc->Width; ++x, ++x1, ++i) {
BlinkenLib/BlinkenGif.c 164) idx = pImg->RasterBits[i];
BlinkenLib/BlinkenGif.c 165) switch (disposal) {
BlinkenLib/BlinkenGif.c 166) // undefined
BlinkenLib/BlinkenGif.c 167) case 0:
BlinkenLib/BlinkenGif.c 168) case 4:
BlinkenLib/BlinkenGif.c 169) case 5:
BlinkenLib/BlinkenGif.c 170) case 6:
BlinkenLib/BlinkenGif.c 171) case 7:
BlinkenLib/BlinkenGif.c 172) // do not dispose -> draw to frame and update background
BlinkenLib/BlinkenGif.c 173) case 1:
BlinkenLib/BlinkenGif.c 174) BlinkenGifSetPixel(pMap, idx, transp, pFrame, y1, x1);
BlinkenLib/BlinkenGif.c 175) BlinkenGifSetPixel(pMap, idx, transp, pBack, y1, x1);
BlinkenLib/BlinkenGif.c 176) break;
BlinkenLib/BlinkenGif.c 177) // restore background -> draw to frame and reset background
BlinkenLib/BlinkenGif.c 178) case 2:
BlinkenLib/BlinkenGif.c 179) BlinkenGifSetPixel(pMap, idx, transp, pFrame, y1, x1);
BlinkenLib/BlinkenGif.c 180) BlinkenGifSetPixel(pMap, bg, transp, pBack, y1, x1);
BlinkenLib/BlinkenGif.c 181) break;
BlinkenLib/BlinkenGif.c 182) // restore previous -> draw to frame only
BlinkenLib/BlinkenGif.c 183) case 3:
BlinkenLib/BlinkenGif.c 184) BlinkenGifSetPixel(pMap, idx, transp, pFrame, y1, x1);
BlinkenLib/BlinkenGif.c 185) break;
BlinkenLib/BlinkenGif.c 186) } // switch disposal
BlinkenLib/BlinkenGif.c 187) } // for x
BlinkenLib/BlinkenGif.c 188) } // for y
BlinkenLib/BlinkenGif.c 189) } // for pass
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 190)
BlinkenLib/BlinkenGif.c 191) // append frame to movie
BlinkenLib/BlinkenGif.c 192) if (pFrame) {
BlinkenLib/BlinkenGif.c 193) if (BlinkenMovieAppendFrame(pMovie, pFrame) != 0) {
BlinkenLib/BlinkenGif.c 194) BlinkenFrameFree(pFrame);
BlinkenLib/BlinkenGif.c 195) }
BlinkenLib/BlinkenGif.c 196) }
BlinkenLib/BlinkenGif.c 197)
BlinkenLib/BlinkenGif.c 198) } // for frameIdx
BlinkenLib/BlinkenGif.c 199)
BlinkenLib/BlinkenGif.c 200) // delete background frame
BlinkenLib/BlinkenGif.c 201) BlinkenFrameFree(pBack);
BlinkenLib/BlinkenGif.c 202)
BlinkenLib/BlinkenGif.c 203) // close GIF file
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 204) DGifCloseFile(gif GIF5_err);
|
implement reading GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 205)
BlinkenLib/BlinkenGif.c 206) return pMovie;
BlinkenLib/BlinkenGif.c 207) }
BlinkenLib/BlinkenGif.c 208)
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 209) int BlinkenGifSave(stBlinkenMovie *pMovie, const char *pFilename)
BlinkenLib/BlinkenGif.c 210) {
BlinkenLib/BlinkenGif.c 211) GifFileType *gif;
BlinkenLib/BlinkenGif.c 212) int frameCnt, height, width, channels, maxval, channels_new, maxval_new,
|
fix creation of color map
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 213) r, g, b, i, frame, y, x, c, y1, x1, y2, x2, v, ret;
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 214) unsigned int delay;
BlinkenLib/BlinkenGif.c 215) stBlinkenMovie *pOutMovie;
BlinkenLib/BlinkenGif.c 216) stBlinkenFrame *pFrame, *pLast;
BlinkenLib/BlinkenGif.c 217) SavedImage *pImg;
BlinkenLib/BlinkenGif.c 218) GifImageDesc *pDesc;
BlinkenLib/BlinkenGif.c 219) ExtensionBlock *pEx;
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 220) #ifdef BLINKENLIB_CFG_GIF5
BlinkenLib/BlinkenGif.c 221) int giferr;
BlinkenLib/BlinkenGif.c 222) #endif
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 223)
BlinkenLib/BlinkenGif.c 224) if (pMovie == NULL || pFilename == NULL)
BlinkenLib/BlinkenGif.c 225) return -1; // error
BlinkenLib/BlinkenGif.c 226)
BlinkenLib/BlinkenGif.c 227) frameCnt = BlinkenMovieGetFrameCnt(pMovie);
BlinkenLib/BlinkenGif.c 228) height = BlinkenMovieGetHeight(pMovie);
BlinkenLib/BlinkenGif.c 229) width = BlinkenMovieGetWidth(pMovie);
BlinkenLib/BlinkenGif.c 230) channels = BlinkenMovieGetChannels(pMovie);
BlinkenLib/BlinkenGif.c 231) maxval = BlinkenMovieGetMaxval(pMovie);
BlinkenLib/BlinkenGif.c 232)
BlinkenLib/BlinkenGif.c 233) // convert movie to suitable color depth (i.e. at most 256 colors)
BlinkenLib/BlinkenGif.c 234) if (channels > 3)
BlinkenLib/BlinkenGif.c 235) channels_new = 3;
BlinkenLib/BlinkenGif.c 236) else
BlinkenLib/BlinkenGif.c 237) channels_new = channels;
BlinkenLib/BlinkenGif.c 238) switch (channels) {
|
fix creation of color map
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 239) case 1: maxval_new = 255; break;
BlinkenLib/BlinkenGif.c 240) case 2: maxval_new = 15; break;
BlinkenLib/BlinkenGif.c 241) case 3: maxval_new = 5; break;
BlinkenLib/BlinkenGif.c 242) default: maxval_new = 255; break;
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 243) }
BlinkenLib/BlinkenGif.c 244) pOutMovie = BlinkenMovieClone(pMovie);
BlinkenLib/BlinkenGif.c 245) if (pOutMovie == NULL)
BlinkenLib/BlinkenGif.c 246) return -1; // error
BlinkenLib/BlinkenGif.c 247) if (channels_new != channels || maxval_new != maxval) {
BlinkenLib/BlinkenGif.c 248) BlinkenMovieResize(pOutMovie, height, width, channels_new, maxval_new);
BlinkenLib/BlinkenGif.c 249) channels = channels_new;
BlinkenLib/BlinkenGif.c 250) maxval = maxval_new;
BlinkenLib/BlinkenGif.c 251) }
BlinkenLib/BlinkenGif.c 252)
BlinkenLib/BlinkenGif.c 253) // open GIF file for encoding
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 254) gif = EGifOpenFileName(pFilename, 0 GIF5_err);
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 255) if (gif == NULL) {
BlinkenLib/BlinkenGif.c 256) BlinkenMovieFree(pOutMovie);
BlinkenLib/BlinkenGif.c 257) return -1; // error
BlinkenLib/BlinkenGif.c 258) }
BlinkenLib/BlinkenGif.c 259)
BlinkenLib/BlinkenGif.c 260) // set global GIF config
BlinkenLib/BlinkenGif.c 261) gif->SWidth = width;
BlinkenLib/BlinkenGif.c 262) gif->SHeight = height;
|
fix creation of color map
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 263) gif->SColorResolution = 256;
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 264) gif->SBackGroundColor = 0;
BlinkenLib/BlinkenGif.c 265) gif->SColorMap = NULL;
BlinkenLib/BlinkenGif.c 266) gif->ImageCount = frameCnt;
BlinkenLib/BlinkenGif.c 267) gif->Image.Left = 0;
BlinkenLib/BlinkenGif.c 268) gif->Image.Top = 0;
BlinkenLib/BlinkenGif.c 269) gif->Image.Width = width;
BlinkenLib/BlinkenGif.c 270) gif->Image.Height = height;
BlinkenLib/BlinkenGif.c 271) gif->Image.ColorMap = NULL;
BlinkenLib/BlinkenGif.c 272) gif->SavedImages = NULL;
BlinkenLib/BlinkenGif.c 273) gif->UserData = NULL;
BlinkenLib/BlinkenGif.c 274)
BlinkenLib/BlinkenGif.c 275) // create color map
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 276) #ifdef BLINKENLIB_CFG_GIF5
BlinkenLib/BlinkenGif.c 277) gif->SColorMap = GifMakeMapObject(256, NULL);
BlinkenLib/BlinkenGif.c 278) #else
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 279) gif->SColorMap = MakeMapObject(256, NULL);
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 280) #endif
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 281) if (gif->SColorMap == NULL) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 282) EGifCloseFile(gif GIF5_err);
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 283) BlinkenMovieFree(pOutMovie);
BlinkenLib/BlinkenGif.c 284) return -1; // error
BlinkenLib/BlinkenGif.c 285) }
|
fix creation of color map
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 286) i = 0;
BlinkenLib/BlinkenGif.c 287) switch (channels) {
BlinkenLib/BlinkenGif.c 288) case 1:
BlinkenLib/BlinkenGif.c 289) for (r = 0; r <= maxval; ++r) {
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 290) gif->SColorMap->Colors[i].Red = ((int)r * 255 + maxval / 2) / maxval;
|
fix creation of color map
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 291) gif->SColorMap->Colors[i].Green = gif->SColorMap->Colors[i].Red;
BlinkenLib/BlinkenGif.c 292) gif->SColorMap->Colors[i].Blue = gif->SColorMap->Colors[i].Red;
BlinkenLib/BlinkenGif.c 293) ++i;
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 294) }
|
fix creation of color map
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 295) break;
BlinkenLib/BlinkenGif.c 296) case 2:
BlinkenLib/BlinkenGif.c 297) for (g = 0; g <= maxval; ++g) {
BlinkenLib/BlinkenGif.c 298) for (r = 0; r <= maxval; ++r) {
BlinkenLib/BlinkenGif.c 299) gif->SColorMap->Colors[i].Red = ((int)r * 255 + maxval / 2) / maxval;
BlinkenLib/BlinkenGif.c 300) gif->SColorMap->Colors[i].Green = ((int)g * 255 + maxval / 2) / maxval;
BlinkenLib/BlinkenGif.c 301) gif->SColorMap->Colors[i].Blue = gif->SColorMap->Colors[i].Green;
BlinkenLib/BlinkenGif.c 302) ++i;
BlinkenLib/BlinkenGif.c 303) }
BlinkenLib/BlinkenGif.c 304) }
BlinkenLib/BlinkenGif.c 305) break;
BlinkenLib/BlinkenGif.c 306) case 3:
BlinkenLib/BlinkenGif.c 307) for (b = 0; b <= maxval; ++b) {
BlinkenLib/BlinkenGif.c 308) for (g = 0; g <= maxval; ++g) {
BlinkenLib/BlinkenGif.c 309) for (r = 0; r <= maxval; ++r) {
BlinkenLib/BlinkenGif.c 310) gif->SColorMap->Colors[i].Red = ((int)r * 255 + maxval / 2) / maxval;
BlinkenLib/BlinkenGif.c 311) gif->SColorMap->Colors[i].Green = ((int)g * 255 + maxval / 2) / maxval;
BlinkenLib/BlinkenGif.c 312) gif->SColorMap->Colors[i].Blue = ((int)b * 255 + maxval / 2) / maxval;
BlinkenLib/BlinkenGif.c 313) ++i;
BlinkenLib/BlinkenGif.c 314) }
BlinkenLib/BlinkenGif.c 315) }
BlinkenLib/BlinkenGif.c 316) }
BlinkenLib/BlinkenGif.c 317) break;
BlinkenLib/BlinkenGif.c 318) } // switch channels
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 319) for (; i < 256; ++i) {
BlinkenLib/BlinkenGif.c 320) gif->SColorMap->Colors[i].Red = 0;
BlinkenLib/BlinkenGif.c 321) gif->SColorMap->Colors[i].Green = 0;
BlinkenLib/BlinkenGif.c 322) gif->SColorMap->Colors[i].Blue = 0;
BlinkenLib/BlinkenGif.c 323) }
BlinkenLib/BlinkenGif.c 324)
BlinkenLib/BlinkenGif.c 325) // create space for saved images
BlinkenLib/BlinkenGif.c 326) gif->SavedImages = calloc(frameCnt, sizeof(SavedImage));
BlinkenLib/BlinkenGif.c 327) if (gif->SavedImages == NULL) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 328) EGifCloseFile(gif GIF5_err);
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 329) BlinkenMovieFree(pOutMovie);
BlinkenLib/BlinkenGif.c 330) return -1; // error
BlinkenLib/BlinkenGif.c 331) }
BlinkenLib/BlinkenGif.c 332)
BlinkenLib/BlinkenGif.c 333) // put frames into GIF structure
BlinkenLib/BlinkenGif.c 334) pLast = NULL;
BlinkenLib/BlinkenGif.c 335) for (frame = 0; frame < frameCnt; ++frame) {
BlinkenLib/BlinkenGif.c 336) pFrame = BlinkenMovieGetFrame(pOutMovie, frame);
BlinkenLib/BlinkenGif.c 337) pImg = &gif->SavedImages[frame];
BlinkenLib/BlinkenGif.c 338) pDesc = &pImg->ImageDesc;
BlinkenLib/BlinkenGif.c 339)
BlinkenLib/BlinkenGif.c 340) // find smallest rectangle with changes
BlinkenLib/BlinkenGif.c 341) if (pLast != NULL) {
BlinkenLib/BlinkenGif.c 342) y1 = height - 1;
BlinkenLib/BlinkenGif.c 343) x1 = width - 1;
BlinkenLib/BlinkenGif.c 344) y2 = 0;
BlinkenLib/BlinkenGif.c 345) x2 = 0;
BlinkenLib/BlinkenGif.c 346) for (y = 0; y < height; ++y) {
BlinkenLib/BlinkenGif.c 347) for (x = 0; x < width; ++x) {
BlinkenLib/BlinkenGif.c 348) for (c = 0; c < channels; ++c) {
BlinkenLib/BlinkenGif.c 349) if (BlinkenFrameGetPixel(pFrame, y, x, c) !=
BlinkenLib/BlinkenGif.c 350) BlinkenFrameGetPixel(pLast, y, x, c))
BlinkenLib/BlinkenGif.c 351) break;
BlinkenLib/BlinkenGif.c 352) }
BlinkenLib/BlinkenGif.c 353) if (c < channels) { // change detected at x,y
BlinkenLib/BlinkenGif.c 354) if (y < y1) y1 = y;
BlinkenLib/BlinkenGif.c 355) if (x < x1) x1 = x;
BlinkenLib/BlinkenGif.c 356) if (y > y2) y2 = y;
BlinkenLib/BlinkenGif.c 357) if (x > x2) x2 = x;
BlinkenLib/BlinkenGif.c 358) }
BlinkenLib/BlinkenGif.c 359) } // for x
BlinkenLib/BlinkenGif.c 360) } // for y
BlinkenLib/BlinkenGif.c 361) if (y1 <= y2 && x1 <= x2) {
BlinkenLib/BlinkenGif.c 362) // changes detected -> encode changed rectangle
BlinkenLib/BlinkenGif.c 363) pDesc->Left = x1;
BlinkenLib/BlinkenGif.c 364) pDesc->Top = y1;
BlinkenLib/BlinkenGif.c 365) pDesc->Width = x2 - x1 + 1;
BlinkenLib/BlinkenGif.c 366) pDesc->Height = y2 - y1 + 1;
BlinkenLib/BlinkenGif.c 367) } else {
BlinkenLib/BlinkenGif.c 368) // no changes detected -> encode top left pixel (empty does not work)
BlinkenLib/BlinkenGif.c 369) pDesc->Left = 0;
BlinkenLib/BlinkenGif.c 370) pDesc->Top = 0;
BlinkenLib/BlinkenGif.c 371) pDesc->Width = 1;
BlinkenLib/BlinkenGif.c 372) pDesc->Height = 1;
BlinkenLib/BlinkenGif.c 373) }
BlinkenLib/BlinkenGif.c 374) } else { // if pLast
BlinkenLib/BlinkenGif.c 375) // no last frame -> encode full frame
BlinkenLib/BlinkenGif.c 376) pDesc->Left = 0;
BlinkenLib/BlinkenGif.c 377) pDesc->Top = 0;
BlinkenLib/BlinkenGif.c 378) pDesc->Width = width;
BlinkenLib/BlinkenGif.c 379) pDesc->Height = height;
BlinkenLib/BlinkenGif.c 380) } // if pLast ... else
BlinkenLib/BlinkenGif.c 381) pDesc->Interlace = 0;
BlinkenLib/BlinkenGif.c 382) pDesc->ColorMap = NULL;
BlinkenLib/BlinkenGif.c 383)
BlinkenLib/BlinkenGif.c 384) // allocate pixel buffer
BlinkenLib/BlinkenGif.c 385) pImg->RasterBits = calloc(pDesc->Width * pDesc->Height,
BlinkenLib/BlinkenGif.c 386) sizeof(unsigned char));
BlinkenLib/BlinkenGif.c 387) if (pImg->RasterBits == NULL) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 388) EGifCloseFile(gif GIF5_err);
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 389) BlinkenMovieFree(pOutMovie);
BlinkenLib/BlinkenGif.c 390) return -1; // error
BlinkenLib/BlinkenGif.c 391) }
BlinkenLib/BlinkenGif.c 392)
BlinkenLib/BlinkenGif.c 393) // fill pixel buffer
BlinkenLib/BlinkenGif.c 394) for (y = 0, y1 = pDesc->Top, i = 0; y < pDesc->Height; ++y, ++y1) {
BlinkenLib/BlinkenGif.c 395) for (x = 0, x1 = pDesc->Left; x < pDesc->Width; ++x, ++x1, ++i) {
BlinkenLib/BlinkenGif.c 396) v = 0;
BlinkenLib/BlinkenGif.c 397) for (c = channels - 1; c >= 0; --c) {
BlinkenLib/BlinkenGif.c 398) v *= (maxval + 1);
BlinkenLib/BlinkenGif.c 399) v += BlinkenFrameGetPixel(pFrame, y1, x1, c);
BlinkenLib/BlinkenGif.c 400) }
BlinkenLib/BlinkenGif.c 401) pImg->RasterBits[i] = v;
BlinkenLib/BlinkenGif.c 402) } // for x
BlinkenLib/BlinkenGif.c 403) } // for y
BlinkenLib/BlinkenGif.c 404)
BlinkenLib/BlinkenGif.c 405) // allocate and fill extension block with delay and disposal mode
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 406) #ifndef BLINKENLIB_CFG_GIF5
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 407) pImg->Function = 0;
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 408) #endif
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 409) pImg->ExtensionBlockCount = 1;
BlinkenLib/BlinkenGif.c 410) pImg->ExtensionBlocks = calloc(1, sizeof(ExtensionBlock));
BlinkenLib/BlinkenGif.c 411) if (pImg->ExtensionBlocks == NULL) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 412) EGifCloseFile(gif GIF5_err);
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 413) BlinkenMovieFree(pOutMovie);
BlinkenLib/BlinkenGif.c 414) return -1; // error
BlinkenLib/BlinkenGif.c 415) }
BlinkenLib/BlinkenGif.c 416) pEx = pImg->ExtensionBlocks;
BlinkenLib/BlinkenGif.c 417) pEx->Function = GRAPHICS_EXT_FUNC_CODE;
BlinkenLib/BlinkenGif.c 418) pEx->ByteCount = 4;
BlinkenLib/BlinkenGif.c 419) pEx->Bytes = calloc(pEx->ByteCount, sizeof (unsigned char));
BlinkenLib/BlinkenGif.c 420) if (pEx->Bytes == NULL) {
|
support for giflib 5.x (unt...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 421) EGifCloseFile(gif GIF5_err);
|
implement writing GIFs
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 422) BlinkenMovieFree(pOutMovie);
BlinkenLib/BlinkenGif.c 423) return -1; // error
BlinkenLib/BlinkenGif.c 424) }
BlinkenLib/BlinkenGif.c 425) pEx->Bytes[0] = 1 << 2; // disposal mode: do not dispose
BlinkenLib/BlinkenGif.c 426) delay = (BlinkenFrameGetDuration(pFrame) + 5) / 10;
BlinkenLib/BlinkenGif.c 427) if (delay <= 0)
BlinkenLib/BlinkenGif.c 428) delay = 1;
BlinkenLib/BlinkenGif.c 429) pEx->Bytes[1] = delay & 0xFF;
BlinkenLib/BlinkenGif.c 430) pEx->Bytes[2] = delay >> 8 & 0xFF;
BlinkenLib/BlinkenGif.c 431) pEx->Bytes[3] = 0xFF;
BlinkenLib/BlinkenGif.c 432) // transparent color (Bytes[3]) not used, flag 0x01 in Bytes[0] not set
BlinkenLib/BlinkenGif.c 433)
BlinkenLib/BlinkenGif.c 434) pLast = pFrame;
BlinkenLib/BlinkenGif.c 435) } // for frame
BlinkenLib/BlinkenGif.c 436)
|
fix double free: EGifSpew c...
Stefan Schuermans authored 8 years ago
|
BlinkenLib/BlinkenGif.c 437) // encode GIF file (closes GIF file)
|