|
|
@ -29,13 +29,13 @@ init_closure_destination(j_compress_ptr cinfo){ |
|
|
|
|
|
|
|
boolean |
|
|
|
empty_closure_output_buffer(j_compress_ptr cinfo){ |
|
|
|
closure_destination_mgr * dest = (closure_destination_mgr *) cinfo->dest; |
|
|
|
closure_destination_mgr *dest = (closure_destination_mgr *) cinfo->dest; |
|
|
|
Local<Buffer> buf = Buffer::New(dest->bufsize); |
|
|
|
memcpy(Buffer::Data(buf->handle_), dest->buffer, dest->bufsize); |
|
|
|
Local<Value> argv[3] = { |
|
|
|
Local<Value>::New(Null()), |
|
|
|
Local<Value>::New(buf->handle_), |
|
|
|
Integer::New(dest->bufsize) |
|
|
|
Local<Value>::New(Null()) |
|
|
|
, Local<Value>::New(buf->handle_) |
|
|
|
, Integer::New(dest->bufsize) |
|
|
|
}; |
|
|
|
dest->closure->fn->Call(Context::GetCurrent()->Global(), 3, argv); |
|
|
|
cinfo->dest->next_output_byte = dest->buffer; |
|
|
@ -45,23 +45,27 @@ empty_closure_output_buffer(j_compress_ptr cinfo){ |
|
|
|
|
|
|
|
void |
|
|
|
term_closure_destination(j_compress_ptr cinfo){ |
|
|
|
closure_destination_mgr * dest = (closure_destination_mgr *) cinfo->dest; |
|
|
|
closure_destination_mgr *dest = (closure_destination_mgr *) cinfo->dest; |
|
|
|
/* emit remaining data */ |
|
|
|
size_t remaining = dest->bufsize - cinfo->dest->free_in_buffer; |
|
|
|
Local<Buffer> buf = Buffer::New(remaining); |
|
|
|
memcpy(Buffer::Data(buf->handle_), dest->buffer, remaining); |
|
|
|
|
|
|
|
Local<Value> data_argv[3] = { |
|
|
|
Local<Value>::New(Null()), |
|
|
|
Local<Value>::New(buf->handle_), |
|
|
|
Integer::New(remaining) |
|
|
|
Local<Value>::New(Null()) |
|
|
|
, Local<Value>::New(buf->handle_) |
|
|
|
, Integer::New(remaining) |
|
|
|
}; |
|
|
|
|
|
|
|
dest->closure->fn->Call(Context::GetCurrent()->Global(), 3, data_argv); |
|
|
|
/* emit 'end' */ |
|
|
|
|
|
|
|
// emit "end"
|
|
|
|
Local<Value> end_argv[3] = { |
|
|
|
Local<Value>::New(Null()), |
|
|
|
Local<Value>::New(Null()), |
|
|
|
Integer::New(0) |
|
|
|
Local<Value>::New(Null()) |
|
|
|
, Local<Value>::New(Null()) |
|
|
|
, Integer::New(0) |
|
|
|
}; |
|
|
|
|
|
|
|
dest->closure->fn->Call(Context::GetCurrent()->Global(), 3, end_argv); |
|
|
|
} |
|
|
|
|
|
|
@ -72,10 +76,10 @@ jpeg_closure_dest(j_compress_ptr cinfo, closure_t * closure, int bufsize){ |
|
|
|
/* The destination object is made permanent so that multiple JPEG images
|
|
|
|
* can be written to the same buffer without re-executing jpeg_mem_dest. |
|
|
|
*/ |
|
|
|
if (cinfo->dest == NULL) { /* first time for this JPEG object? */ |
|
|
|
if (cinfo->dest == NULL) { /* first time for this JPEG object? */ |
|
|
|
cinfo->dest = (struct jpeg_destination_mgr *) |
|
|
|
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, |
|
|
|
sizeof(closure_destination_mgr)); |
|
|
|
sizeof(closure_destination_mgr)); |
|
|
|
} |
|
|
|
|
|
|
|
dest = (closure_destination_mgr *) cinfo->dest; |
|
|
@ -93,33 +97,29 @@ jpeg_closure_dest(j_compress_ptr cinfo, closure_t * closure, int bufsize){ |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, closure_t * closure){ |
|
|
|
/*
|
|
|
|
libjs code adapted from the Cairo R graphics project: |
|
|
|
http://www.rforge.net/Cairo/
|
|
|
|
*/ |
|
|
|
write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, closure_t *closure){ |
|
|
|
int w = cairo_image_surface_get_width(surface); |
|
|
|
int h = cairo_image_surface_get_height(surface); |
|
|
|
struct jpeg_compress_struct cinfo; |
|
|
|
struct jpeg_error_mgr jerr; |
|
|
|
|
|
|
|
JSAMPROW slr; |
|
|
|
cinfo.err = jpeg_std_error(&jerr); |
|
|
|
jpeg_create_compress(&cinfo); |
|
|
|
cinfo.in_color_space = JCS_RGB; |
|
|
|
cinfo.input_components = 3; |
|
|
|
cinfo.image_width = w; |
|
|
|
cinfo.image_height = h; |
|
|
|
jpeg_set_defaults(&cinfo); |
|
|
|
jpeg_set_quality(&cinfo, quality, (quality<25)?0:1); |
|
|
|
struct jpeg_compress_struct cinfo; |
|
|
|
struct jpeg_error_mgr jerr; |
|
|
|
|
|
|
|
JSAMPROW slr; |
|
|
|
cinfo.err = jpeg_std_error(&jerr); |
|
|
|
jpeg_create_compress(&cinfo); |
|
|
|
cinfo.in_color_space = JCS_RGB; |
|
|
|
cinfo.input_components = 3; |
|
|
|
cinfo.image_width = w; |
|
|
|
cinfo.image_height = h; |
|
|
|
jpeg_set_defaults(&cinfo); |
|
|
|
jpeg_set_quality(&cinfo, quality, (quality<25)?0:1); |
|
|
|
jpeg_closure_dest(&cinfo, closure, bufsize); |
|
|
|
|
|
|
|
jpeg_start_compress(&cinfo, TRUE); |
|
|
|
jpeg_start_compress(&cinfo, TRUE); |
|
|
|
unsigned char *dst; |
|
|
|
unsigned int *src = (unsigned int*)cairo_image_surface_get_data(surface); |
|
|
|
unsigned int *src = (unsigned int *) cairo_image_surface_get_data(surface); |
|
|
|
int sl = 0; |
|
|
|
dst = (unsigned char*) malloc(w*3); |
|
|
|
while (sl<h) { |
|
|
|
dst = (unsigned char *) malloc(w * 3); |
|
|
|
while (sl < h) { |
|
|
|
unsigned char *dp = dst; |
|
|
|
int x = 0; |
|
|
|
while (x < w) { |
|
|
@ -135,8 +135,8 @@ write_to_jpeg_stream(cairo_surface_t *surface, int bufsize, int quality, closure |
|
|
|
sl++; |
|
|
|
} |
|
|
|
free(dst); |
|
|
|
jpeg_finish_compress(&cinfo); |
|
|
|
jpeg_destroy_compress(&cinfo); |
|
|
|
jpeg_finish_compress(&cinfo); |
|
|
|
jpeg_destroy_compress(&cinfo); |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|