Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Gif class is now async

  • Loading branch information...
commit e1af308fa0b06d7f37222f314ab88a6756b79459 1 parent 9321221
@pkrumins pkrumins authored
View
11 src/common.cpp
@@ -5,13 +5,20 @@
using namespace v8;
Handle<Value>
+ErrorException(const char *msg)
+{
+ HandleScope scope;
+ return Exception::Error(String::New(msg));
+}
+
+Handle<Value>
VException(const char *msg) {
HandleScope scope;
- return ThrowException(Exception::Error(String::New(msg)));
+ return ThrowException(ErrorException(msg));
}
bool str_eq(const char *s1, const char *s2)
{
- return strcmp(s1, s2) == 0;
+ return strcmp(s1, s2) == 0;
}
View
1  src/common.h
@@ -4,6 +4,7 @@
#include <node.h>
#include <cstring>
+v8::Handle<v8::Value> ErrorException(const char *msg);
v8::Handle<v8::Value> VException(const char *msg);
struct Point {
View
116 src/gif.cpp
@@ -1,3 +1,5 @@
+#include <cstdlib>
+#include <cstring>
#include "common.h"
#include "gif_encoder.h"
#include "gif.h"
@@ -12,7 +14,8 @@ Gif::Initialize(Handle<Object> target)
Local<FunctionTemplate> t = FunctionTemplate::New(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
- NODE_SET_PROTOTYPE_METHOD(t, "encode", GifEncode);
+ NODE_SET_PROTOTYPE_METHOD(t, "encode", GifEncodeAsync);
+ NODE_SET_PROTOTYPE_METHOD(t, "encodeSync", GifEncodeSync);
NODE_SET_PROTOTYPE_METHOD(t, "setTransparencyColor", SetTransparencyColor);
target->Set(String::NewSymbol("Gif"), t->GetFunction());
}
@@ -21,7 +24,7 @@ Gif::Gif(Buffer *ddata, int wwidth, int hheight, buffer_type bbuf_type) :
data(ddata), width(wwidth), height(hheight), buf_type(bbuf_type) {}
Handle<Value>
-Gif::GifEncode()
+Gif::GifEncodeSync()
{
HandleScope scope;
@@ -99,12 +102,12 @@ Gif::New(const Arguments &args)
}
Handle<Value>
-Gif::GifEncode(const Arguments &args)
+Gif::GifEncodeSync(const Arguments &args)
{
HandleScope scope;
Gif *gif = ObjectWrap::Unwrap<Gif>(args.This());
- return gif->GifEncode();
+ return scope.Close(gif->GifEncodeSync());
}
Handle<Value>
@@ -132,3 +135,108 @@ Gif::SetTransparencyColor(const Arguments &args)
return Undefined();
}
+struct encode_request {
+ v8::Persistent<v8::Function> callback;
+ void *gif_obj;
+ char *gif;
+ int gif_len;
+ char *error;
+};
+
+int
+Gif::EIO_GifEncode(eio_req *req)
+{
+ encode_request *enc_req = (encode_request *)req->data;
+ Gif *gif = (Gif *)enc_req->gif_obj;
+
+ try {
+ GifEncoder encoder((unsigned char *)gif->data->data(), gif->width, gif->height, gif->buf_type);
+ if (gif->transparency_color.color_present) {
+ encoder.set_transparency_color(gif->transparency_color);
+ }
+ encoder.encode();
+ enc_req->gif_len = encoder.get_gif_len();
+ enc_req->gif = (char *)malloc(sizeof(*enc_req->gif)*enc_req->gif_len);
+ if (!enc_req->gif) {
+ enc_req->error = strdup("malloc in Gif::EIO_GifEncode failed.");
+ return 0;
+ }
+ else {
+ memcpy(enc_req->gif, encoder.get_gif(), enc_req->gif_len);
+ }
+ }
+ catch (const char *err) {
+ enc_req->error = strdup(err);
+ }
+
+ return 0;
+}
+
+int
+Gif::EIO_GifEncodeAfter(eio_req *req)
+{
+ HandleScope scope;
+
+ ev_unref(EV_DEFAULT_UC);
+ encode_request *enc_req = (encode_request *)req->data;
+
+ Handle<Value> argv[2];
+
+ if (enc_req->error) {
+ argv[0] = Undefined();
+ argv[1] = ErrorException(enc_req->error);
+ }
+ else {
+ argv[0] = Local<Value>::New(Encode(enc_req->gif, enc_req->gif_len, BINARY));
+ argv[1] = Undefined();
+ }
+
+ TryCatch try_catch; // don't quite see the necessity of this
+
+ enc_req->callback->Call(Context::GetCurrent()->Global(), 2, argv);
+
+ if (try_catch.HasCaught())
+ FatalException(try_catch);
+
+ enc_req->callback.Dispose();
+ free(enc_req->gif);
+ free(enc_req->error);
+
+ ((Gif *)enc_req->gif_obj)->Unref();
+ free(enc_req);
+
+ return 0;
+}
+
+Handle<Value>
+Gif::GifEncodeAsync(const Arguments &args)
+{
+ HandleScope scope;
+
+ if (args.Length() != 1)
+ return VException("One argument required - callback function.");
+
+ if (!args[0]->IsFunction())
+ return VException("First argument must be a function.");
+
+ Local<Function> callback = Local<Function>::Cast(args[0]);
+ Gif *gif = ObjectWrap::Unwrap<Gif>(args.This());
+
+ encode_request *enc_req = (encode_request *)malloc(sizeof(*enc_req));
+ if (!enc_req)
+ return VException("malloc in Gif::GifEncodeAsync failed.");
+
+ enc_req->callback = Persistent<Function>::New(callback);
+ enc_req->gif_obj = gif;
+ enc_req->gif = NULL;
+ enc_req->gif_len = 0;
+ enc_req->error = NULL;
+
+ eio_custom(EIO_GifEncode, EIO_PRI_DEFAULT, EIO_GifEncodeAfter, enc_req);
+
+ ev_ref(EV_DEFAULT_UC);
+ gif->Ref();
+
+ return Undefined();
+}
+
View
8 src/gif.h
@@ -12,14 +12,18 @@ class Gif : public node::ObjectWrap {
buffer_type buf_type;
Color transparency_color;
+ static int EIO_GifEncode(eio_req *req);
+ static int EIO_GifEncodeAfter(eio_req *req);
+
public:
static void Initialize(v8::Handle<v8::Object> target);
Gif(node::Buffer *ddata, int wwidth, int hheight, buffer_type bbuf_type);
- v8::Handle<v8::Value> GifEncode();
+ v8::Handle<v8::Value> GifEncodeSync();
void SetTransparencyColor(unsigned char r, unsigned char g, unsigned char b);
static v8::Handle<v8::Value> New(const v8::Arguments &args);
- static v8::Handle<v8::Value> GifEncode(const v8::Arguments &args);
+ static v8::Handle<v8::Value> GifEncodeSync(const v8::Arguments &args);
+ static v8::Handle<v8::Value> GifEncodeAsync(const v8::Arguments &args);
static v8::Handle<v8::Value> SetTransparencyColor(const v8::Arguments &args);
};
View
1  wscript
@@ -19,6 +19,7 @@ def build(bld):
obj.target = "gif"
obj.source = "src/common.cpp src/palette.cpp src/quantize.cpp src/gif_encoder.cpp src/gif.cpp src/dynamic_gif_stack.cpp src/animated_gif.cpp src/module.cpp"
obj.uselib = "GIF"
+ obj.cxxflags = ["-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE"]
def shutdown():
if Options.commands['clean']:
Please sign in to comment.
Something went wrong with that request. Please try again.