Linus Unnebäck
9 years ago
17 changed files with 300 additions and 361 deletions
@ -1,29 +0,0 @@ |
|||
|
|||
/*! |
|||
* Canvas - PixelArray |
|||
* Copyright (c) 2010 LearnBoost <tj@learnboost.com> |
|||
* MIT Licensed |
|||
*/ |
|||
|
|||
/** |
|||
* Module dependencies. |
|||
*/ |
|||
|
|||
var Canvas = require('./bindings') |
|||
, PixelArray = Canvas.CanvasPixelArray; |
|||
|
|||
/** |
|||
* Custom inspect. |
|||
*/ |
|||
|
|||
PixelArray.prototype.inspect = function(){ |
|||
var buf = '[PixelArray '; |
|||
for (var i = 0, len = this.length; i < len; i += 4) { |
|||
buf += '\n ' + i + ': rgba(' |
|||
+ this[i + 0] + ',' |
|||
+ this[i + 1] + ',' |
|||
+ this[i + 2] + ',' |
|||
+ this[i + 3] + ')'; |
|||
} |
|||
return buf + '\n]'; |
|||
}; |
@ -1,163 +0,0 @@ |
|||
|
|||
//
|
|||
// PixelArray.cc
|
|||
//
|
|||
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|||
//
|
|||
|
|||
#include "PixelArray.h" |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
Persistent<FunctionTemplate> PixelArray::constructor; |
|||
|
|||
/*
|
|||
* Initialize PixelArray. |
|||
*/ |
|||
|
|||
void |
|||
PixelArray::Initialize(Handle<Object> target) { |
|||
NanScope(); |
|||
|
|||
// Constructor
|
|||
Local<FunctionTemplate> ctor = NanNew<FunctionTemplate>(PixelArray::New); |
|||
NanAssignPersistent(constructor, ctor); |
|||
ctor->InstanceTemplate()->SetInternalFieldCount(1); |
|||
ctor->SetClassName(NanNew("CanvasPixelArray")); |
|||
|
|||
// Prototype
|
|||
Local<ObjectTemplate> proto = ctor->InstanceTemplate(); |
|||
proto->SetAccessor(NanNew("length"), GetLength); |
|||
target->Set(NanNew("CanvasPixelArray"), ctor->GetFunction()); |
|||
} |
|||
|
|||
/*
|
|||
* Initialize a new PixelArray. |
|||
*/ |
|||
|
|||
NAN_METHOD(PixelArray::New) { |
|||
NanScope(); |
|||
PixelArray *arr; |
|||
Local<Object> obj = args[0]->ToObject(); |
|||
|
|||
switch (args.Length()) { |
|||
// width, height
|
|||
case 2: |
|||
arr = new PixelArray( |
|||
args[0]->Int32Value() |
|||
, args[1]->Int32Value()); |
|||
break; |
|||
// canvas, x, y, width, height
|
|||
case 5: { |
|||
if (!NanHasInstance(Canvas::constructor, obj)) |
|||
return NanThrowTypeError("Canvas expected"); |
|||
|
|||
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(obj); |
|||
arr = new PixelArray( |
|||
canvas |
|||
, args[1]->Int32Value() |
|||
, args[2]->Int32Value() |
|||
, args[3]->Int32Value() |
|||
, args[4]->Int32Value()); |
|||
} |
|||
break; |
|||
default: |
|||
return NanThrowTypeError("invalid arguments"); |
|||
} |
|||
|
|||
// Let v8 handle accessors (and clamping)
|
|||
args.This()->SetIndexedPropertiesToPixelData( |
|||
arr->data() |
|||
, arr->length()); |
|||
|
|||
arr->Wrap(args.This()); |
|||
NanReturnValue(args.This()); |
|||
} |
|||
|
|||
/*
|
|||
* Get length. |
|||
*/ |
|||
|
|||
NAN_GETTER(PixelArray::GetLength) { |
|||
NanScope(); |
|||
NanReturnValue(NanNew<Number>(args.This()->GetIndexedPropertiesPixelDataLength())); |
|||
} |
|||
|
|||
/*
|
|||
* 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
|
|||
uint8_t *dst = alloc(); |
|||
uint8_t *src = canvas->data(); |
|||
int srcStride = canvas->stride() |
|||
, dstStride = stride(); |
|||
|
|||
if (sx < 0) width += sx, sx = 0; |
|||
if (sy < 0) height += sy, sy = 0; |
|||
if (sx + width > canvas->width) width = canvas->width - sx; |
|||
if (sy + height > canvas->height) height = canvas->height - sy; |
|||
if (width <= 0 || height <= 0) return; |
|||
|
|||
// Normalize data (argb -> rgba)
|
|||
for (int y = 0; y < height; ++y) { |
|||
uint32_t *row = (uint32_t *)(src + srcStride * (y + sy)); |
|||
for (int x = 0; x < width; ++x) { |
|||
int bx = x * 4; |
|||
uint32_t *pixel = row + x + sx; |
|||
uint8_t a = *pixel >> 24; |
|||
uint8_t r = *pixel >> 16; |
|||
uint8_t g = *pixel >> 8; |
|||
uint8_t b = *pixel; |
|||
dst[bx + 3] = a; |
|||
|
|||
// Performance optimization: fully transparent/opaque pixels
|
|||
// can be processed more efficiently
|
|||
if (a != 0 && a != 255) { |
|||
float alpha = (float) a / 255; |
|||
dst[bx + 0] = (int)((float) r / alpha); |
|||
dst[bx + 1] = (int)((float) g / alpha); |
|||
dst[bx + 2] = (int)((float) b / alpha); |
|||
} else { |
|||
dst[bx + 0] = r; |
|||
dst[bx + 1] = g; |
|||
dst[bx + 2] = b; |
|||
} |
|||
} |
|||
dst += dstStride; |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* Initialize an empty PixelArray with the given dimensions. |
|||
*/ |
|||
|
|||
PixelArray::PixelArray(int width, int height): |
|||
_width(width), _height(height) { |
|||
alloc(); |
|||
} |
|||
|
|||
/*
|
|||
* Allocate / zero data buffer. Hint mem adjustment. |
|||
*/ |
|||
|
|||
uint8_t * |
|||
PixelArray::alloc() { |
|||
int len = length(); |
|||
_data = (uint8_t *) calloc(1, len); |
|||
NanAdjustExternalMemory(len); |
|||
return _data; |
|||
} |
|||
|
|||
/*
|
|||
* Hint mem adjustment. |
|||
*/ |
|||
|
|||
PixelArray::~PixelArray() { |
|||
NanAdjustExternalMemory(-length()); |
|||
free(_data); |
|||
} |
@ -1,33 +0,0 @@ |
|||
|
|||
//
|
|||
// PixelArray.h
|
|||
//
|
|||
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
|||
//
|
|||
|
|||
#ifndef __NODE_PIXEL_ARRAY_H__ |
|||
#define __NODE_PIXEL_ARRAY_H__ |
|||
|
|||
#include "Canvas.h" |
|||
|
|||
class PixelArray: public node::ObjectWrap { |
|||
public: |
|||
static Persistent<FunctionTemplate> constructor; |
|||
static void Initialize(Handle<Object> target); |
|||
static NAN_METHOD(New); |
|||
static NAN_GETTER(GetLength); |
|||
inline int length(){ return _width * _height * 4; } |
|||
inline int width(){ return _width; } |
|||
inline int height(){ return _height; } |
|||
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: |
|||
uint8_t *alloc(); |
|||
uint8_t *_data; |
|||
int _width, _height; |
|||
}; |
|||
|
|||
#endif |
Loading…
Reference in new issue