From 8be64dc83dd39af890e4c89a4baf3dace7d2092e Mon Sep 17 00:00:00 2001 From: Michael Nutt Date: Fri, 18 Mar 2011 15:01:29 -0400 Subject: [PATCH] upgrade to node 0.3 --- .gitignore | 3 ++ src/animated_gif.cpp | 18 ++++++------ src/async_animated_gif.cpp | 22 ++++++++------- src/buffer_compat.cpp | 58 ++++++++++++++++++++++++++++++++++++++ src/buffer_compat.h | 15 ++++++++++ src/common.h | 1 + src/dynamic_gif_stack.cpp | 22 +++++++++------ src/dynamic_gif_stack.h | 2 +- src/gif.cpp | 37 ++++++++++++++++-------- src/gif.h | 3 +- wscript | 4 +-- 11 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 .gitignore create mode 100644 src/buffer_compat.cpp create mode 100644 src/buffer_compat.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fdcbcea --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/gif.node +/build/ +.lock-wscript diff --git a/src/animated_gif.cpp b/src/animated_gif.cpp index d067c76..dcba839 100644 --- a/src/animated_gif.cpp +++ b/src/animated_gif.cpp @@ -3,6 +3,7 @@ #include "common.h" #include "gif_encoder.h" #include "animated_gif.h" +#include "buffer_compat.h" using namespace v8; using namespace node; @@ -105,7 +106,7 @@ AnimatedGif::New(const Arguments &args) { return VException("Third argument must be 'rgb', 'bgr', 'rgba' or 'bgra'."); } - + if (str_eq(*bts, "rgb")) buf_type = BUF_RGB; else if (str_eq(*bts, "bgr")) @@ -148,7 +149,6 @@ AnimatedGif::Push(const Arguments &args) return VException("Fifth argument must be integer h."); AnimatedGif *gif = ObjectWrap::Unwrap(args.This()); - Buffer *data_buf = ObjectWrap::Unwrap(args[0]->ToObject()); int x = args[1]->Int32Value(); int y = args[2]->Int32Value(); int w = args[3]->Int32Value(); @@ -162,17 +162,19 @@ AnimatedGif::Push(const Arguments &args) return VException("Width smaller than 0."); if (h < 0) return VException("Height smaller than 0."); - if (x >= gif->width) + if (x >= gif->width) return VException("Coordinate x exceeds AnimatedGif's dimensions."); - if (y >= gif->height) + if (y >= gif->height) return VException("Coordinate y exceeds AnimatedGif's dimensions."); - if (x+w > gif->width) + if (x+w > gif->width) return VException("Pushed fragment exceeds AnimatedGif's width."); - if (y+h > gif->height) + if (y+h > gif->height) return VException("Pushed fragment exceeds AnimatedGif's height."); try { - gif->Push((unsigned char *)data_buf->data(), x, y, w, h); + char *buf_data = BufferData(args[0]->ToObject()); + + gif->Push((unsigned char*)buf_data, x, y, w, h); } catch (const char *err) { return VException(err); @@ -206,7 +208,7 @@ AnimatedGif::GetGif(const Arguments &args) gif->gif_encoder.finish(); int gif_len = gif->gif_encoder.get_gif_len(); Buffer *retbuf = Buffer::New(gif_len); - memcpy(retbuf->data(), gif->gif_encoder.get_gif(), gif_len); + memcpy(BufferData(retbuf), gif->gif_encoder.get_gif(), gif_len); return scope.Close(retbuf->handle_); } diff --git a/src/async_animated_gif.cpp b/src/async_animated_gif.cpp index c0250ed..5354ad9 100644 --- a/src/async_animated_gif.cpp +++ b/src/async_animated_gif.cpp @@ -5,6 +5,7 @@ #include "utils.h" #include "gif_encoder.h" #include "async_animated_gif.h" +#include "buffer_compat.h" #include "loki/ScopeGuard.h" @@ -81,7 +82,7 @@ int AsyncAnimatedGif::EIO_PushAfter(eio_req *req) { ev_unref(EV_DEFAULT_UC); - + push_request *push_req = (push_request *)req->data; free(push_req->data); free(push_req); @@ -156,7 +157,7 @@ AsyncAnimatedGif::New(const Arguments &args) { return VException("Third argument must be 'rgb', 'bgr', 'rgba' or 'bgra'."); } - + if (str_eq(*bts, "rgb")) buf_type = BUF_RGB; else if (str_eq(*bts, "bgr")) @@ -199,8 +200,8 @@ AsyncAnimatedGif::Push(const Arguments &args) return VException("Fifth argument must be integer h."); AsyncAnimatedGif *gif = ObjectWrap::Unwrap(args.This()); - Buffer *data_buf = ObjectWrap::Unwrap(args[0]->ToObject()); - unsigned char *buf = (unsigned char *)data_buf->data(); + // Buffer *data_buf = ObjectWrap::Unwrap(args[0]->ToObject()); + // unsigned char *buf = (unsigned char *)data_buf->data(); int x = args[1]->Int32Value(); int y = args[2]->Int32Value(); int w = args[3]->Int32Value(); @@ -214,17 +215,18 @@ AsyncAnimatedGif::Push(const Arguments &args) return VException("Width smaller than 0."); if (h < 0) return VException("Height smaller than 0."); - if (x >= gif->width) + if (x >= gif->width) return VException("Coordinate x exceeds AsyncAnimatedGif's dimensions."); - if (y >= gif->height) + if (y >= gif->height) return VException("Coordinate y exceeds AsyncAnimatedGif's dimensions."); - if (x+w > gif->width) + if (x+w > gif->width) return VException("Pushed fragment exceeds AsyncAnimatedGif's width."); - if (y+h > gif->height) + if (y+h > gif->height) return VException("Pushed fragment exceeds AsyncAnimatedGif's height."); try { - gif->Push(buf, x, y, w, h); + char *buf_data = BufferData(args[0]->ToObject()); + gif->Push((unsigned char*)buf_data, x, y, w, h); } catch (const char *err) { return VException(err); @@ -368,7 +370,7 @@ AsyncAnimatedGif::EIO_Encode(eio_req *req) return 0; } Rect dims = rect_dims(fragments[i]); - push_fragment(frame, gif->width, gif->height, gif->buf_type, + push_fragment(frame, gif->width, gif->height, gif->buf_type, data, dims.x, dims.y, dims.w, dims.h); } encoder.new_frame(frame); diff --git a/src/buffer_compat.cpp b/src/buffer_compat.cpp new file mode 100644 index 0000000..24dac9c --- /dev/null +++ b/src/buffer_compat.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include "buffer_compat.h" + + +#if NODE_MINOR_VERSION < 3 + + +char *BufferData(node::Buffer *b) { + return b->data(); +} + + +size_t BufferLength(node::Buffer *b) { + return b->length(); +} + + +char *BufferData(v8::Local buf_obj) { + v8::HandleScope scope; + node::Buffer *buf = node::ObjectWrap::Unwrap(buf_obj); + return buf->data(); +} + + +size_t BufferLength(v8::Local buf_obj) { + v8::HandleScope scope; + node::Buffer *buf = node::ObjectWrap::Unwrap(buf_obj); + return buf->length(); +} + +#else // NODE_VERSION + + +char *BufferData(node::Buffer *b) { + return node::Buffer::Data(b->handle_); +} + + +size_t BufferLength(node::Buffer *b) { + return node::Buffer::Length(b->handle_); +} + + +char *BufferData(v8::Local buf_obj) { + v8::HandleScope scope; + return node::Buffer::Data(buf_obj); +} + + +size_t BufferLength(v8::Local buf_obj) { + v8::HandleScope scope; + return node::Buffer::Length(buf_obj); +} + +#endif // NODE_VERSION diff --git a/src/buffer_compat.h b/src/buffer_compat.h new file mode 100644 index 0000000..fa7c61c --- /dev/null +++ b/src/buffer_compat.h @@ -0,0 +1,15 @@ +#ifndef buffer_compat_h +#define buffer_compat_h + +#include +#include +#include + +char *BufferData(node::Buffer *b); +size_t BufferLength(node::Buffer *b); + +char *BufferData(v8::Local buf_obj); +size_t BufferLength(v8::Local buf_obj); + + +#endif // buffer_compat_h diff --git a/src/common.h b/src/common.h index 0f70e26..59610a4 100644 --- a/src/common.h +++ b/src/common.h @@ -38,6 +38,7 @@ struct encode_request { char *gif; int gif_len; char *error; + char *buf_data; }; #endif diff --git a/src/dynamic_gif_stack.cpp b/src/dynamic_gif_stack.cpp index 64f7829..c101ff2 100644 --- a/src/dynamic_gif_stack.cpp +++ b/src/dynamic_gif_stack.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "gif_encoder.h" #include "dynamic_gif_stack.h" +#include "buffer_compat.h" using namespace v8; using namespace node; @@ -93,11 +94,10 @@ DynamicGifStack::~DynamicGifStack() } Handle -DynamicGifStack::Push(Buffer *buf, int x, int y, int w, int h) +DynamicGifStack::Push(unsigned char *buf_data, size_t buf_len, int x, int y, int w, int h) { try { - GifUpdate *gif_update = - new GifUpdate((unsigned char *)buf->data(), buf->length(), x, y, w, h); + GifUpdate *gif_update = new GifUpdate(buf_data, buf_len, x, y, w, h); gif_stack.push_back(gif_update); return Undefined(); } @@ -137,7 +137,7 @@ DynamicGifStack::GifEncodeSync() free(data); int gif_len = encoder.get_gif_len(); Buffer *retbuf = Buffer::New(gif_len); - memcpy(retbuf->data(), encoder.get_gif(), gif_len); + memcpy(BufferData(retbuf), encoder.get_gif(), gif_len); return scope.Close(retbuf->handle_); } catch (const char *err) { @@ -175,7 +175,7 @@ DynamicGifStack::New(const Arguments &args) { return VException("First argument must be 'rgb', 'bgr', 'rgba' or 'bgra'."); } - + if (str_eq(*bts, "rgb")) buf_type = BUF_RGB; else if (str_eq(*bts, "bgr")) @@ -209,7 +209,6 @@ DynamicGifStack::Push(const Arguments &args) if (!args[4]->IsInt32()) return VException("Fifth argument must be integer h."); - Buffer *data = ObjectWrap::Unwrap(args[0]->ToObject()); int x = args[1]->Int32Value(); int y = args[2]->Int32Value(); int w = args[3]->Int32Value(); @@ -225,7 +224,12 @@ DynamicGifStack::Push(const Arguments &args) return VException("Height smaller than 0."); DynamicGifStack *gif_stack = ObjectWrap::Unwrap(args.This()); - return scope.Close(gif_stack->Push(data, x, y, w, h)); + + Local buf_obj = args[0]->ToObject(); + char *buf_data = BufferData(buf_obj); + size_t buf_len = BufferLength(buf_obj); + + return scope.Close(gif_stack->Push((unsigned char*)buf_data, buf_len, x, y, w, h)); } Handle @@ -299,7 +303,7 @@ DynamicGifStack::EIO_GifEncode(eio_req *req) return 0; } -int +int DynamicGifStack::EIO_GifEncodeAfter(eio_req *req) { HandleScope scope; @@ -317,7 +321,7 @@ DynamicGifStack::EIO_GifEncodeAfter(eio_req *req) } else { Buffer *buf = Buffer::New(enc_req->gif_len); - memcpy(buf->data(), enc_req->gif, enc_req->gif_len); + memcpy(BufferData(buf), enc_req->gif, enc_req->gif_len); argv[0] = buf->handle_; argv[1] = gif->Dimensions(); argv[2] = Undefined(); diff --git a/src/dynamic_gif_stack.h b/src/dynamic_gif_stack.h index 6ffbfc9..7306d4d 100644 --- a/src/dynamic_gif_stack.h +++ b/src/dynamic_gif_stack.h @@ -48,7 +48,7 @@ class DynamicGifStack : public node::ObjectWrap { DynamicGifStack(buffer_type bbuf_type); ~DynamicGifStack(); - v8::Handle Push(node::Buffer *buf, int x, int y, int w, int h); + v8::Handle Push(unsigned char *buf_data, size_t buf_len, int x, int y, int w, int h); v8::Handle Dimensions(); v8::Handle GifEncodeSync(); diff --git a/src/gif.cpp b/src/gif.cpp index c96a725..31411d5 100644 --- a/src/gif.cpp +++ b/src/gif.cpp @@ -3,6 +3,7 @@ #include "common.h" #include "gif_encoder.h" #include "gif.h" +#include "buffer_compat.h" using namespace v8; using namespace node; @@ -20,23 +21,27 @@ Gif::Initialize(Handle target) target->Set(String::NewSymbol("Gif"), t->GetFunction()); } -Gif::Gif(Buffer *ddata, int wwidth, int hheight, buffer_type bbuf_type) : - data(ddata), width(wwidth), height(hheight), buf_type(bbuf_type) {} +Gif::Gif(int wwidth, int hheight, buffer_type bbuf_type) : + width(wwidth), height(hheight), buf_type(bbuf_type) {} Handle Gif::GifEncodeSync() { HandleScope scope; + Local buf_val = handle_->GetHiddenValue(String::New("buffer")); + + char *buf_data = BufferData(buf_val->ToObject()); + try { - GifEncoder encoder((unsigned char *)data->data(), width, height, buf_type); + GifEncoder encoder((unsigned char*)buf_data, width, height, buf_type); if (transparency_color.color_present) { encoder.set_transparency_color(transparency_color); } encoder.encode(); int gif_len = encoder.get_gif_len(); Buffer *retbuf = Buffer::New(gif_len); - memcpy(retbuf->data(), encoder.get_gif(), gif_len); + memcpy(BufferData(retbuf), encoder.get_gif(), gif_len); return scope.Close(retbuf->handle_); } catch (const char *err) { @@ -75,7 +80,7 @@ Gif::New(const Arguments &args) { return VException("Fourth argument must be 'rgb', 'bgr', 'rgba' or 'bgra'."); } - + if (str_eq(*bts, "rgb")) buf_type = BUF_RGB; else if (str_eq(*bts, "bgr")) @@ -88,7 +93,7 @@ Gif::New(const Arguments &args) return VException("Fourth argument wasn't 'rgb', 'bgr', 'rgba' or 'bgra'."); } - Buffer *data = ObjectWrap::Unwrap(args[0]->ToObject()); + int w = args[1]->Int32Value(); int h = args[2]->Int32Value(); @@ -97,8 +102,12 @@ Gif::New(const Arguments &args) if (h < 0) return VException("Height smaller than 0."); - Gif *gif = new Gif(data, w, h, buf_type); + Gif *gif = new Gif(w, h, buf_type); gif->Wrap(args.This()); + + // Save buffer. + gif->handle_->SetHiddenValue(String::New("buffer"), args[0]); + return args.This(); } @@ -125,7 +134,7 @@ Gif::SetTransparencyColor(const Arguments &args) return VException("Second argument must be integer green."); if (!args[2]->IsInt32()) return VException("Third argument must be integer blue."); - + unsigned char r = args[0]->Int32Value(); unsigned char g = args[1]->Int32Value(); unsigned char b = args[2]->Int32Value(); @@ -143,7 +152,7 @@ Gif::EIO_GifEncode(eio_req *req) Gif *gif = (Gif *)enc_req->gif_obj; try { - GifEncoder encoder((unsigned char *)gif->data->data(), gif->width, gif->height, gif->buf_type); + GifEncoder encoder((unsigned char *)enc_req->buf_data, gif->width, gif->height, gif->buf_type); if (gif->transparency_color.color_present) { encoder.set_transparency_color(gif->transparency_color); } @@ -165,7 +174,7 @@ Gif::EIO_GifEncode(eio_req *req) return 0; } -int +int Gif::EIO_GifEncodeAfter(eio_req *req) { HandleScope scope; @@ -181,7 +190,7 @@ Gif::EIO_GifEncodeAfter(eio_req *req) } else { Buffer *buf = Buffer::New(enc_req->gif_len); - memcpy(buf->data(), enc_req->gif, enc_req->gif_len); + memcpy(BufferData(buf), enc_req->gif, enc_req->gif_len); argv[0] = buf->handle_; argv[1] = Undefined(); } @@ -227,6 +236,12 @@ Gif::GifEncodeAsync(const Arguments &args) enc_req->gif_len = 0; enc_req->error = NULL; + // We need to pull out the buffer data before + // we go to the thread pool. + Local buf_val = gif->handle_->GetHiddenValue(String::New("buffer")); + + enc_req->buf_data = BufferData(buf_val->ToObject()); + eio_custom(EIO_GifEncode, EIO_PRI_DEFAULT, EIO_GifEncodeAfter, enc_req); ev_ref(EV_DEFAULT_UC); diff --git a/src/gif.h b/src/gif.h index e42909d..53ee813 100644 --- a/src/gif.h +++ b/src/gif.h @@ -8,7 +8,6 @@ class Gif : public node::ObjectWrap { int width, height; - node::Buffer *data; buffer_type buf_type; Color transparency_color; @@ -17,7 +16,7 @@ class Gif : public node::ObjectWrap { public: static void Initialize(v8::Handle target); - Gif(node::Buffer *ddata, int wwidth, int hheight, buffer_type bbuf_type); + Gif(int wwidth, int hheight, buffer_type bbuf_type); v8::Handle GifEncodeSync(); void SetTransparencyColor(unsigned char r, unsigned char g, unsigned char b); diff --git a/wscript b/wscript index aa7340e..3b06fc5 100644 --- a/wscript +++ b/wscript @@ -1,6 +1,6 @@ import Options from os import unlink, symlink, popen -from os.path import exists +from os.path import exists srcdir = "." blddir = "build" @@ -21,7 +21,7 @@ def configure(conf): def build(bld): obj = bld.new_task_gen("cxx", "shlib", "node_addon") obj.target = "gif" - obj.source = "src/common.cpp src/utils.cpp src/palette.cpp src/quantize.cpp src/gif_encoder.cpp src/gif.cpp src/dynamic_gif_stack.cpp src/animated_gif.cpp src/async_animated_gif.cpp src/module.cpp" + obj.source = "src/common.cpp src/utils.cpp src/palette.cpp src/quantize.cpp src/gif_encoder.cpp src/gif.cpp src/dynamic_gif_stack.cpp src/animated_gif.cpp src/async_animated_gif.cpp src/module.cpp src/buffer_compat.cpp" obj.uselib = "GIF" obj.cxxflags = ["-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE"]