Skip to content

Commit

Permalink
progress with gif encoder transparency
Browse files Browse the repository at this point in the history
  • Loading branch information
EyalAr committed Dec 10, 2014
1 parent b4dcfbf commit 331770b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
4 changes: 2 additions & 2 deletions gifdemo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var lwip = require('./'), i;
lwip.open('examples/lena.jpg',function(err, image){
lwip.open('tests/images/trans.png',function(err, image){
if (err) return console.log(err);
image.writeFile('examples/lena_e.gif',{colors:5, interlaced: true, transparency: false},function(err){
image.writeFile('trans.gif',{colors:256, interlaced: false, transparency: true},function(err){
if (err) console.log(err);
});
});
6 changes: 4 additions & 2 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
params.interlaced = params.interlaced || defs.defaults.PNG_DEF_INTERLACED;
if (typeof params.interlaced !== 'boolean')
throw Error('PNG \'interlaced\' must be boolean');
params.transparency = params.transparency || defs.defaults.PNG_DEF_TRANSPARENT;
if (params.transparency !== false)
params.transparency = params.transparency || defs.defaults.PNG_DEF_TRANSPARENT;
if (typeof params.transparency !== 'boolean'){
if (typeof params.transparency !== 'string' ||
params.transparency.toLowerCase() !== 'auto')
Expand All @@ -89,7 +90,8 @@
params.interlaced = params.interlaced || defs.defaults.GIF_DEF_INTERLACED;
if (typeof params.interlaced !== 'boolean')
throw Error('GIF \'interlaced\' must be boolean');
params.transparency = params.transparency || defs.defaults.GIF_DEF_TRANSPARENT;
if (params.transparency !== false)
params.transparency = params.transparency || defs.defaults.GIF_DEF_TRANSPARENT;
if (typeof params.transparency !== 'boolean'){
if (typeof params.transparency !== 'string' ||
params.transparency.toLowerCase() !== 'auto')
Expand Down
1 change: 1 addition & 0 deletions src/encoder/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ NAN_METHOD(encodeToPngBuffer);
NAN_METHOD(encodeToGifBuffer);
void pngWriteCB(png_structp png_ptr, png_bytep data, png_size_t length);
int gifWriteCB(GifFileType * gif, const GifByteType * chunk, int len);
void remapTransparentPixels(unsigned char * target, const unsigned char * map, size_t width, size_t height, int transColor, int threshold);
void initAll(Handle<Object> exports);

#endif
52 changes: 47 additions & 5 deletions src/encoder/gif_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,25 @@ EncodeToGifBufferWorker::EncodeToGifBufferWorker(
_gifbuf(NULL), _gifbufsize(0) {
SaveToPersistent("buff", buff); // make sure buff isn't GC'ed
_pixbuf = (unsigned char *) Buffer::Data(buff);
if (_trans){
// make room in the color table for a transparent color
if (_cmapSize == 256){
if (_colors == 256) _colors--;
} else if (_cmapSize == _colors){
_cmapSize *= 2;
}
}
}

EncodeToGifBufferWorker::~EncodeToGifBufferWorker() {}

void EncodeToGifBufferWorker::Execute () {

(void) _trans; // supress compiler warning TODO: remove

GifByteType
* redBuff = (GifByteType *) _pixbuf,
* greenBuff = (GifByteType *) _pixbuf + _width * _height,
* blueBuff = (GifByteType *) _pixbuf + 2 * _width * _height,
* alphaBuff = (GifByteType *) _pixbuf + 3 * _width * _height,
* gifimgbuf = (GifByteType *) malloc(_width * _height * sizeof(GifByteType)); // the indexed image
ColorMapObject *cmap;
SavedImage * simg;
Expand Down Expand Up @@ -56,6 +63,7 @@ void EncodeToGifBufferWorker::Execute () {
SetErrorMessage("Unable to quantize image");
return;
}
cmap->ColorCount = _colors;

int errcode;
gifWriteCbData buffinf = {NULL, 0};
Expand All @@ -72,9 +80,6 @@ void EncodeToGifBufferWorker::Execute () {

gif->SWidth = _width;
gif->SHeight = _height;
gif->SColorResolution = _colors;
gif->SBackGroundColor = 0;
gif->SColorMap = cmap;

simg = GifMakeSavedImage(gif, NULL);

Expand All @@ -90,8 +95,35 @@ void EncodeToGifBufferWorker::Execute () {
simg->ImageDesc.Width = _width;
simg->ImageDesc.Height = _height;
simg->ImageDesc.Interlace = _interlaced;
simg->ImageDesc.ColorMap = cmap;
simg->RasterBits = gifimgbuf;

printf("extblockcount %d\n", simg->ExtensionBlockCount);

// transperancy
if (_trans){
printf("yes, trans\n");
ExtensionBlock ext;
// 1. assign transparent color index in color table
GraphicsControlBlock gcb = {0, false, 0, _colors++};
// 2. replace transparent pixels above threshold with this color
remapTransparentPixels(gifimgbuf, alphaBuff, _width, _height, gcb.TransparentColor, 50);
// gif->SBackGroundColor = gcb.TransparentColor;
// 3. create a control block
size_t extlen = EGifGCBToExtension(&gcb, (GifByteType *) &ext);
if (GIF_ERROR == GifAddExtensionBlock(
&(gif->ExtensionBlockCount),
&(gif->ExtensionBlocks),
GRAPHICS_EXT_FUNC_CODE,
extlen,
(unsigned char *) &ext)
) {
EGifCloseFile(gif, &errcode);
SetErrorMessage("Out of memory");
return;
}
}

if (GIF_ERROR == EGifSpew(gif)){
EGifCloseFile(gif, &errcode);
SetErrorMessage(GifErrorString(gif->Error));
Expand Down Expand Up @@ -132,3 +164,13 @@ int gifWriteCB(GifFileType * gif, const GifByteType * chunk, int len) {

return len;
}

void remapTransparentPixels(unsigned char * target, const unsigned char * map, size_t width, size_t height, int transColor, int threshold){
// printf("transcolor: %d, threshold: %d\n", transColor, threshold);
size_t i = 0, len = width * height;
for (; i < len; i++){
if (map[i] < threshold) *(target + i) = transColor;
// printf("%d,", target[i]);
}
// printf("\n");
}

0 comments on commit 331770b

Please sign in to comment.