diff --git a/src/Image.cc b/src/Image.cc index 2b1a122..8338469 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -203,7 +203,6 @@ EIO_AfterLoad(eio_req *req) { void Image::load() { - printf("%d\n", extension(filename)); if (LOADING != state) { // TODO: use node IO // Ref(); @@ -271,10 +270,60 @@ Image::error(Local err) { cairo_status_t Image::loadSurface() { - _surface = cairo_image_surface_create_from_png(filename); - width = cairo_image_surface_get_width(_surface); - height = cairo_image_surface_get_height(_surface); - return cairo_surface_status(_surface); + switch (extension(filename)) { + case Image::PNG: + _surface = cairo_image_surface_create_from_png(filename); + width = cairo_image_surface_get_width(_surface); + height = cairo_image_surface_get_height(_surface); + return cairo_surface_status(_surface); + break; + case Image::JPEG: { + // TODO: error handling + // TODO: move to node IO + FILE *stream = fopen(filename, "r"); + struct jpeg_decompress_struct info; + struct jpeg_error_mgr err; + info.err = jpeg_std_error(&err); + jpeg_create_decompress(&info); + jpeg_stdio_src(&info, stream); + jpeg_read_header(&info, 1); + jpeg_start_decompress(&info); + width = info.output_width; + height = info.output_height; + + uint8_t *data = (uint8_t *) malloc(width * height * 4); + uint8_t *src = (uint8_t *) malloc(width * 3); + + for (int y = 0; y < height; ++y) { + jpeg_read_scanlines(&info, &src, 1); + uint32_t *row = (uint32_t *)(data + (width * 4)); + for (int x = 0; x < width; ++x) { + uint32_t *pixel = row + x; + uint8_t r = src[x]; + uint8_t g = src[x + 1]; + uint8_t b = src[x + 2]; + *pixel = 255 << 24 + | r << 16 + | g << 8 + | b; + } + } + + _surface = cairo_image_surface_create_for_data( + data + , CAIRO_FORMAT_ARGB32 + , width + , height + , width * 4); + + fclose(stream); + jpeg_finish_decompress(&info); + jpeg_destroy_decompress(&info); + return cairo_surface_status(_surface); + } + break; + } + return CAIRO_STATUS_READ_ERROR; } /* @@ -289,4 +338,4 @@ Image::extension(const char *filename) { if (0 == strcmp(".jpg", filename - 4)) return Image::JPEG; if (0 == strcmp(".png", filename - 4)) return Image::PNG; return Image::UNKNOWN; -} \ No newline at end of file +} diff --git a/wscript b/wscript index 1469995..96b614a 100644 --- a/wscript +++ b/wscript @@ -11,6 +11,7 @@ def configure(conf): conf.check_tool('compiler_cxx') conf.check_tool('node_addon') conf.env.append_value('CPPFLAGS', '-DNDEBUG') + conf.check(lib='jpeg', uselib_store='JPEG') conf.check_cfg(package='cairo', mandatory=1, args='--cflags --libs') flags = ['-O3', '-Wall'] conf.env.append_value('CCFLAGS', flags) @@ -20,4 +21,4 @@ def build(bld): obj = bld.new_task_gen('cxx', 'shlib', 'node_addon') obj.target = 'canvas' obj.source = bld.glob('src/*.cc') - obj.uselib = ['CAIRO'] \ No newline at end of file + obj.uselib = ['CAIRO', 'JPEG'] \ No newline at end of file