Browse Source

Added another optional argument for setting row filters.

v1.x
King Koopa 12 years ago
committed by TJ Holowaychuk
parent
commit
14d9f587b6
  1. 130
      src/Canvas.cc
  2. 1
      src/PNG.h
  3. 6
      src/closure.h

130
src/Canvas.cc

@ -45,6 +45,15 @@ Canvas::Initialize(Handle<Object> target) {
proto->SetAccessor(NanSymbol("type"), GetType);
proto->SetAccessor(NanSymbol("width"), GetWidth, SetWidth);
proto->SetAccessor(NanSymbol("height"), GetHeight, SetHeight);
proto->Set("PNG_NO_FILTERS", Uint32::New(PNG_NO_FILTERS));
proto->Set("PNG_FILTER_NONE", Uint32::New(PNG_FILTER_NONE));
proto->Set("PNG_FILTER_SUB", Uint32::New(PNG_FILTER_SUB));
proto->Set("PNG_FILTER_UP", Uint32::New(PNG_FILTER_UP));
proto->Set("PNG_FILTER_AVG", Uint32::New(PNG_FILTER_AVG));
proto->Set("PNG_FILTER_PAETH", Uint32::New(PNG_FILTER_PAETH));
proto->Set("PNG_ALL_FILTERS", Uint32::New(PNG_ALL_FILTERS));
target->Set(NanSymbol("Canvas"), ctor->GetFunction());
}
@ -225,6 +234,7 @@ NAN_METHOD(Canvas::ToBuffer) {
NanScope();
cairo_status_t status;
uint32_t compression_level = 6;
uint32_t filter = PNG_ALL_FILTERS;
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(args.This());
// TODO: async / move this out
@ -236,38 +246,48 @@ NAN_METHOD(Canvas::ToBuffer) {
NanReturnValue(buf);
}
if (args.Length() == 2 && !args[1]->StrictEquals(Undefined())) {
bool good = true;
if (args[1]->IsNumber()) {
compression_level = args[1]->Uint32Value();
} else if (args[1]->IsString()) {
if (args[1]->StrictEquals(String::New("0"))) {
compression_level = 0;
} else {
uint32_t tmp = args[1]->Uint32Value();
if (tmp == 0) {
good = false;
if (args.Length() > 1 && !(args[1]->StrictEquals(Undefined()) && args[2]->StrictEquals(Undefined()))) {
if (!args[1]->StrictEquals(Undefined())) {
bool good = true;
if (args[1]->IsNumber()) {
compression_level = args[1]->Uint32Value();
} else if (args[1]->IsString()) {
if (args[1]->StrictEquals(String::New("0"))) {
compression_level = 0;
} else {
compression_level = tmp;
uint32_t tmp = args[1]->Uint32Value();
if (tmp == 0) {
good = false;
} else {
compression_level = tmp;
}
}
}
} else {
good = false;
}
if (good) {
if (compression_level > 9) {
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9].");
} else {
good = false;
}
if (good) {
if (compression_level > 9) {
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9].");
}
} else {
return NanThrowTypeError("Compression level must be a number.");
}
} else {
return NanThrowTypeError("Compression level must be a number.");
}
}
if (!args[2]->StrictEquals(Undefined())) {
if (args[2]->IsUint32()) {
filter = args[1]->Uint32Value();
} else {
return NanThrowTypeError("Invalid filter value.");
}
}
}
// Async
if (args[0]->IsFunction()) {
closure_t *closure = (closure_t *) malloc(sizeof(closure_t));
status = closure_init(closure, canvas, compression_level);
status = closure_init(closure, canvas, compression_level, filter);
// ensure closure is ok
if (status) {
@ -293,7 +313,7 @@ NAN_METHOD(Canvas::ToBuffer) {
// Sync
} else {
closure_t closure;
status = closure_init(&closure, canvas, compression_level);
status = closure_init(&closure, canvas, compression_level, filter);
// ensure closure is ok
if (status) {
@ -342,36 +362,47 @@ streamPNG(void *c, const uint8_t *data, unsigned len) {
NAN_METHOD(Canvas::StreamPNGSync) {
NanScope();
uint32_t compression_level = 6;
uint32_t filter = PNG_ALL_FILTERS;
// TODO: async as well
if (!args[0]->IsFunction())
return NanThrowTypeError("callback function required");
if (args.Length() == 2 && !args[1]->StrictEquals(Undefined())) {
bool good = true;
if (args[1]->IsNumber()) {
compression_level = args[1]->Uint32Value();
} else if (args[1]->IsString()) {
if (args[1]->StrictEquals(String::New("0"))) {
compression_level = 0;
} else {
uint32_t tmp = args[1]->Uint32Value();
if (tmp == 0) {
good = false;
if (args.Length() > 1 && !(args[1]->StrictEquals(Undefined()) && args[2]->StrictEquals(Undefined()))) {
if (!args[1]->StrictEquals(Undefined())) {
bool good = true;
if (args[1]->IsNumber()) {
compression_level = args[1]->Uint32Value();
} else if (args[1]->IsString()) {
if (args[1]->StrictEquals(String::New("0"))) {
compression_level = 0;
} else {
compression_level = tmp;
uint32_t tmp = args[1]->Uint32Value();
if (tmp == 0) {
good = false;
} else {
compression_level = tmp;
}
}
}
} else {
good = false;
}
if (good) {
if (compression_level > 9) {
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9].");
} else {
good = false;
}
if (good) {
if (compression_level > 9) {
return NanThrowRangeError("Allowed compression levels lie in the range [0, 9].");
}
} else {
return NanThrowTypeError("Compression level must be a number.");
}
} else {
return NanThrowTypeError("Compression level must be a number.");
}
}
if (!args[2]->StrictEquals(Undefined())) {
if (args[2]->IsUint32()) {
filter = args[1]->Uint32Value();
} else {
return NanThrowTypeError("Invalid filter value.");
}
}
}
@ -379,6 +410,7 @@ NAN_METHOD(Canvas::StreamPNGSync) {
closure_t closure;
closure.fn = Handle<Function>::Cast(args[0]);
closure.compression_level = compression_level;
closure.filter = filter;
TryCatch try_catch;
@ -443,7 +475,7 @@ Canvas::Canvas(int w, int h, canvas_type_t t): ObjectWrap() {
if (CANVAS_TYPE_PDF == t) {
_closure = malloc(sizeof(closure_t));
assert(_closure);
cairo_status_t status = closure_init((closure_t *) _closure, this, 0);
cairo_status_t status = closure_init((closure_t *) _closure, this, 0, PNG_NO_FILTERS);
assert(status == CAIRO_STATUS_SUCCESS);
_surface = cairo_pdf_surface_create_for_stream(toBuffer, _closure, w, h);
} else {

1
src/PNG.h

@ -129,6 +129,7 @@ static cairo_status_t canvas_write_png(cairo_surface_t *surface, png_rw_ptr writ
png_set_write_fn(png, closure, write_func, canvas_png_flush);
png_set_compression_level(png, ((closure_t *) ((canvas_png_write_closure_t *) closure)->closure)->compression_level);
png_set_filter(png, 0, ((closure_t *) ((canvas_png_write_closure_t *) closure)->closure)->filter);
switch (cairo_image_surface_get_format(surface)) {
case CAIRO_FORMAT_ARGB32:

6
src/closure.h

@ -30,7 +30,8 @@ typedef struct {
uint8_t *data;
Canvas *canvas;
cairo_status_t status;
unsigned int compression_level;
uint32_t compression_level;
uint32_t filter;
} closure_t;
/*
@ -38,12 +39,13 @@ typedef struct {
*/
cairo_status_t
closure_init(closure_t *closure, Canvas *canvas, unsigned int compression_level) {
closure_init(closure_t *closure, Canvas *canvas, unsigned int compression_level, unsigned int filter) {
closure->len = 0;
closure->canvas = canvas;
closure->data = (uint8_t *) malloc(closure->max_len = PAGE_SIZE);
if (!closure->data) return CAIRO_STATUS_NO_MEMORY;
closure->compression_level = compression_level;
closure->filter = filter;
return CAIRO_STATUS_SUCCESS;
}

Loading…
Cancel
Save