diff --git a/lib/context2d.js b/lib/context2d.js index 56ae0e4..c7aa714 100644 --- a/lib/context2d.js +++ b/lib/context2d.js @@ -466,4 +466,18 @@ Context2d.prototype.__defineGetter__('textAlign', function(){ Context2d.prototype.getImageData = function(x, y, width, height){ var arr = new PixelArray(this.canvas, x, y, width, height); return new ImageData(arr); +}; + +/** + * Create `ImageData` with the given dimensions. + * + * @param {Number} width + * @param {Number} height + * @return {ImageData} + * @api public + */ + +Context2d.prototype.createImageData = function(width, height){ + var arr = new PixelArray(width, height); + return new ImageData(arr); }; \ No newline at end of file diff --git a/src/PixelArray.cc b/src/PixelArray.cc index 5a99c58..1f9ad7a 100644 --- a/src/PixelArray.cc +++ b/src/PixelArray.cc @@ -75,21 +75,21 @@ PixelArray::GetLength(Local prop, const AccessorInfo &info) { } /* - * Initialize a new PixelArray. + * Initialize a new PixelArray copying data + * from the canvas surface using the given rect. */ PixelArray::PixelArray(Canvas *canvas, int sx, int sy, int width, int height): _width(width), _height(height) { // Alloc space for our new data - _stride = width * 4; - uint8_t *dst = _data = (uint8_t *) malloc(length()); - memset(_data, 0, length()); + uint8_t *dst = alloc(); uint8_t *src = canvas->data(); + int s = stride(); // Normalize data (argb -> rgba) for (int y = 0; y < height; ++y) { - uint32_t *row = (uint32_t *)(src + _stride * y); + uint32_t *row = (uint32_t *)(src + s * y); for (int x = 0; x < width; ++x) { int bx = x * 4; uint32_t *pixel = row + x; @@ -101,14 +101,28 @@ PixelArray::PixelArray(Canvas *canvas, int sx, int sy, int width, int height): dst[bx + 1] = (*pixel >> 8) * 255 / a; dst[bx + 2] = *pixel * 255 / a; } - dst += _stride; + dst += s; } } +/* + * Initialize an empty PixelArray with the given dimensions. + */ + PixelArray::PixelArray(int width, int height): _width(width), _height(height) { - // TODO: error handling - // TODO: implement + alloc(); +} + +/* + * Allocate / zero data buffer. + */ + +uint8_t * +PixelArray::alloc() { + _data = (uint8_t *) malloc(length()); + memset(_data, 0, length()); + return _data; } PixelArray::~PixelArray() { diff --git a/src/PixelArray.h b/src/PixelArray.h index c0ace9b..21a899a 100644 --- a/src/PixelArray.h +++ b/src/PixelArray.h @@ -18,13 +18,13 @@ class PixelArray: public node::ObjectWrap { inline int length(){ return _width * _height * 4; } inline int width(){ return _width; } inline int height(){ return _height; } - inline int stride(){ return _stride; } + inline int stride(){ return _width * 4; } inline uint8_t *data(){ return _data; } PixelArray(Canvas *canvas, int x, int y, int width, int height); PixelArray(int width, int height); ~PixelArray(); private: - int _stride; + uint8_t *alloc(); uint8_t *_data; int _width, _height; };