Skip to content
Browse files

animated gifs can now also be written to file via setOutputFile

  • Loading branch information...
1 parent 726cf38 commit 48ace7762b2a8c38203af7a4067ba16155541f9a @pkrumins committed Aug 7, 2010
Showing with 97 additions and 2 deletions.
  1. +32 −0 src/animated_gif.cpp
  2. +2 −0 src/animated_gif.h
  3. +14 −2 src/gif_encoder.cpp
  4. +5 −0 src/gif_encoder.h
  5. +44 −0 tests/animated-gif/animated-gif-file-writer.js
View
32 src/animated_gif.cpp
@@ -17,6 +17,8 @@ AnimatedGif::Initialize(Handle<Object> target)
NODE_SET_PROTOTYPE_METHOD(t, "push", Push);
NODE_SET_PROTOTYPE_METHOD(t, "endPush", EndPush);
NODE_SET_PROTOTYPE_METHOD(t, "getGif", GetGif);
+ NODE_SET_PROTOTYPE_METHOD(t, "end", End);
+ NODE_SET_PROTOTYPE_METHOD(t, "setOutputFile", SetOutputFile);
target->Set(String::NewSymbol("AnimatedGif"), t->GetFunction());
}
@@ -207,3 +209,33 @@ AnimatedGif::GetGif(const Arguments &args)
);
}
+Handle<Value>
+AnimatedGif::End(const Arguments &args)
+{
+ HandleScope scope;
+
+ AnimatedGif *gif = ObjectWrap::Unwrap<AnimatedGif>(args.This());
+ gif->gif_encoder.finish();
+
+ return Undefined();
+}
+
+Handle<Value>
+AnimatedGif::SetOutputFile(const Arguments &args)
+{
+ HandleScope scope;
+
+ if (args.Length() != 1)
+ return VException("One argument required - path to output file.");
+
+ if (!args[0]->IsString())
+ return VException("First argument must be string.");
+
+ String::AsciiValue file_name(args[0]->ToString());
+
+ AnimatedGif *gif = ObjectWrap::Unwrap<AnimatedGif>(args.This());
+ gif->gif_encoder.set_output_file(*file_name);
+
+ return Undefined();
+}
+
View
2 src/animated_gif.h
@@ -25,7 +25,9 @@ class AnimatedGif : public node::ObjectWrap {
static v8::Handle<v8::Value> New(const v8::Arguments &args);
static v8::Handle<v8::Value> Push(const v8::Arguments &args);
static v8::Handle<v8::Value> EndPush(const v8::Arguments &args);
+ static v8::Handle<v8::Value> End(const v8::Arguments &args);
static v8::Handle<v8::Value> GetGif(const v8::Arguments &args);
+ static v8::Handle<v8::Value> SetOutputFile(const v8::Arguments &args);
};
#endif
View
16 src/gif_encoder.cpp
@@ -281,8 +281,14 @@ void
AnimatedGifEncoder::new_frame(unsigned char *data, int delay)
{
if (!gif_file) {
- gif_file = EGifOpen(&gif, gif_writer);
- if (!gif_file) throw "EGifOpen in AnimatedGifEncoder::new_frame failed";
+ if (file_name.empty()) { // memory writer
+ gif_file = EGifOpen(&gif, gif_writer);
+ if (!gif_file) throw "EGifOpen in AnimatedGifEncoder::new_frame failed";
+ }
+ else {
+ gif_file = EGifOpenFileName(file_name.c_str(), FALSE);
+ if (!gif_file) throw "EGifOpenFileName in AnimatedGifEncoder::new_frame failed";
+ }
output_color_map = MakeMapObject(color_map_size, ext_web_safe_palette);
if (!output_color_map) throw "MakeMapObject in AnimatedGifEncoder::new_frame failed";
@@ -386,3 +392,9 @@ AnimatedGifEncoder::get_gif_len() const
return gif.size;
}
+void
+AnimatedGifEncoder::set_output_file(const char *ffile_name)
+{
+ file_name = ffile_name;
+}
+
View
5 src/gif_encoder.h
@@ -1,6 +1,7 @@
#ifndef GIF_ENCODER_H
#define GIF_ENCODER_H
+#include <string>
#include <gif_lib.h>
#include "common.h"
@@ -46,6 +47,8 @@ class AnimatedGifEncoder {
bool headers_set;
Color transparency_color;
+ std::string file_name;
+
void end_encoding();
public:
AnimatedGifEncoder(int wwidth, int hheight, buffer_type bbuf_type);
@@ -57,6 +60,8 @@ class AnimatedGifEncoder {
void set_transparency_color(unsigned char r, unsigned char g, unsigned char b);
void set_transparency_color(const Color &c);
+ void set_output_file(const char *ffile_name);
+
const unsigned char *get_gif() const;
const int get_gif_len() const;
};
View
44 tests/animated-gif/animated-gif-file-writer.js
@@ -0,0 +1,44 @@
+var GifLib = require('gif');
+var Buffer = require('buffer').Buffer;
+var fs = require('fs');
+var sys = require('sys');
+
+var chunkDirs = fs.readdirSync('.').sort().filter(
+ function (f) {
+ //return /^\d+$/.test(f) && parseInt(f,10)<=2
+ return /^\d+$/.test(f)
+ }
+);
+
+function baseName(fileName) {
+ return fileName.slice(0, fileName.indexOf('.'));
+}
+
+function rectDim(fileName) {
+ var m = fileName.match(/^\d+-rgb-(\d+)-(\d+)-(\d+)-(\d+).dat$/);
+ var dim = [m[1], m[2], m[3], m[4]].map(function (n) {
+ return parseInt(n, 10);
+ });
+ return { x: dim[0], y: dim[1], w: dim[2], h: dim[3] }
+}
+
+var animatedGif = new GifLib.AnimatedGif(720,400);
+animatedGif.setOutputFile('animated-filewriter.gif');
+
+chunkDirs.forEach(function (dir) {
+ console.log(dir);
+ var chunkFiles = fs.readdirSync(dir).sort().filter(
+ function (f) {
+ return /^\d+-rgb-\d+-\d+-\d+-\d+.dat/.test(f);
+ }
+ );
+ chunkFiles.forEach(function (chunkFile) {
+ var dims = rectDim(chunkFile);
+ var rgb = fs.readFileSync(dir + '/' + chunkFile); // returns buffer
+ animatedGif.push(rgb, dims.x, dims.y, dims.w, dims.h);
+ });
+ animatedGif.endPush();
+});
+
+animatedGif.end();
+

0 comments on commit 48ace77

Please sign in to comment.
Something went wrong with that request. Please try again.