14 changed files with 326 additions and 12 deletions
@ -0,0 +1,29 @@ |
|||||
|
|
||||
|
/*! |
||||
|
* Canvas - PixelArray |
||||
|
* Copyright (c) 2010 LearnBoost <tj@learnboost.com> |
||||
|
* MIT Licensed |
||||
|
*/ |
||||
|
|
||||
|
/** |
||||
|
* Module dependencies. |
||||
|
*/ |
||||
|
|
||||
|
var Canvas = require('../build/default/canvas') |
||||
|
, 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]'; |
||||
|
}; |
@ -0,0 +1,61 @@ |
|||||
|
|
||||
|
//
|
||||
|
// ImageData.cc
|
||||
|
//
|
||||
|
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
||||
|
//
|
||||
|
|
||||
|
#include "ImageData.h" |
||||
|
|
||||
|
/*
|
||||
|
* Initialize ImageData. |
||||
|
*/ |
||||
|
|
||||
|
void |
||||
|
ImageData::Initialize(Handle<Object> target) { |
||||
|
HandleScope scope; |
||||
|
Local<FunctionTemplate> t = FunctionTemplate::New(ImageData::New); |
||||
|
t->InstanceTemplate()->SetInternalFieldCount(1); |
||||
|
t->SetClassName(String::NewSymbol("ImageData")); |
||||
|
|
||||
|
// Prototype
|
||||
|
Local<ObjectTemplate> proto = t->PrototypeTemplate(); |
||||
|
proto->SetAccessor(String::NewSymbol("width"), GetWidth); |
||||
|
proto->SetAccessor(String::NewSymbol("height"), GetHeight); |
||||
|
target->Set(String::NewSymbol("ImageData"), t->GetFunction()); |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Initialize a new ImageData object. |
||||
|
*/ |
||||
|
|
||||
|
Handle<Value> |
||||
|
ImageData::New(const Arguments &args) { |
||||
|
HandleScope scope; |
||||
|
// TODO: arg assertions
|
||||
|
PixelArray *arr = ObjectWrap::Unwrap<PixelArray>(args[0]->ToObject()); |
||||
|
ImageData *imageData = new ImageData(arr); |
||||
|
args.This()->Set(String::NewSymbol("data"), args[0]); |
||||
|
imageData->Wrap(args.This()); |
||||
|
return args.This(); |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Get width. |
||||
|
*/ |
||||
|
|
||||
|
Handle<Value> |
||||
|
ImageData::GetWidth(Local<String> prop, const AccessorInfo &info) { |
||||
|
ImageData *imageData = ObjectWrap::Unwrap<ImageData>(info.This()); |
||||
|
return Number::New(imageData->pixelArray()->width()); |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Get height. |
||||
|
*/ |
||||
|
|
||||
|
Handle<Value> |
||||
|
ImageData::GetHeight(Local<String> prop, const AccessorInfo &info) { |
||||
|
ImageData *imageData = ObjectWrap::Unwrap<ImageData>(info.This()); |
||||
|
return Number::New(imageData->pixelArray()->height()); |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
|
||||
|
//
|
||||
|
// ImageData.h
|
||||
|
//
|
||||
|
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
||||
|
//
|
||||
|
|
||||
|
#ifndef __NODE_IMAGE_DATA_H__ |
||||
|
#define __NODE_IMAGE_DATA_H__ |
||||
|
|
||||
|
#include "Canvas.h" |
||||
|
#include "PixelArray.h" |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
class ImageData: public node::ObjectWrap { |
||||
|
public: |
||||
|
static void Initialize(Handle<Object> target); |
||||
|
static Handle<Value> New(const Arguments &args); |
||||
|
static Handle<Value> GetWidth(Local<String> prop, const AccessorInfo &info); |
||||
|
static Handle<Value> GetHeight(Local<String> prop, const AccessorInfo &info); |
||||
|
inline PixelArray *pixelArray(){ return _arr; } |
||||
|
ImageData(PixelArray *arr): _arr(arr) {} |
||||
|
private: |
||||
|
PixelArray *_arr; |
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,130 @@ |
|||||
|
|
||||
|
//
|
||||
|
// PixelArray.cc
|
||||
|
//
|
||||
|
// Copyright (c) 2010 LearnBoost <tj@learnboost.com>
|
||||
|
//
|
||||
|
|
||||
|
#include "PixelArray.h" |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
|
||||
|
/*
|
||||
|
* Initialize PixelArray. |
||||
|
*/ |
||||
|
|
||||
|
void |
||||
|
PixelArray::Initialize(Handle<Object> target) { |
||||
|
HandleScope scope; |
||||
|
Local<FunctionTemplate> t = FunctionTemplate::New(PixelArray::New); |
||||
|
t->InstanceTemplate()->SetInternalFieldCount(1); |
||||
|
t->SetClassName(String::NewSymbol("CanvasPixelArray")); |
||||
|
|
||||
|
Local<ObjectTemplate> proto = t->InstanceTemplate(); |
||||
|
proto->SetAccessor(String::NewSymbol("length"), GetLength); |
||||
|
target->Set(String::NewSymbol("CanvasPixelArray"), t->GetFunction()); |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Initialize a new PixelArray. |
||||
|
*/ |
||||
|
|
||||
|
Handle<Value> |
||||
|
PixelArray::New(const Arguments &args) { |
||||
|
HandleScope scope; |
||||
|
PixelArray *arr; |
||||
|
// TODO: arg handling
|
||||
|
|
||||
|
switch (args.Length()) { |
||||
|
// width, height
|
||||
|
case 2: |
||||
|
arr = new PixelArray( |
||||
|
args[0]->Int32Value() |
||||
|
, args[1]->Int32Value()); |
||||
|
break; |
||||
|
// canvas, x, y, width, height
|
||||
|
case 5: { |
||||
|
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(args[0]->ToObject()); |
||||
|
arr = new PixelArray( |
||||
|
canvas |
||||
|
, args[1]->Int32Value() |
||||
|
, args[2]->Int32Value() |
||||
|
, args[3]->Int32Value() |
||||
|
, args[4]->Int32Value()); |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
return ThrowException(Exception::TypeError(String::New("invalid arguments"))); |
||||
|
} |
||||
|
// Let v8 handle accessors (and clamping)
|
||||
|
args.This()->SetIndexedPropertiesToPixelData( |
||||
|
arr->data() |
||||
|
, arr->length()); |
||||
|
|
||||
|
arr->Wrap(args.This()); |
||||
|
return args.This(); |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Get length. |
||||
|
*/ |
||||
|
|
||||
|
Handle<Value> |
||||
|
PixelArray::GetLength(Local<String> prop, const AccessorInfo &info) { |
||||
|
return Number::New(info.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 s = stride(); |
||||
|
|
||||
|
// Normalize data (argb -> rgba)
|
||||
|
for (int y = 0; y < height; ++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; |
||||
|
|
||||
|
// premultiplied
|
||||
|
uint8_t a = *pixel >> 24; |
||||
|
dst[bx + 3] = a; |
||||
|
dst[bx + 0] = (*pixel >> 16) * 255 / a; |
||||
|
dst[bx + 1] = (*pixel >> 8) * 255 / a; |
||||
|
dst[bx + 2] = *pixel * 255 / a; |
||||
|
} |
||||
|
dst += s; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Initialize an empty PixelArray with the given dimensions. |
||||
|
*/ |
||||
|
|
||||
|
PixelArray::PixelArray(int width, int height): |
||||
|
_width(width), _height(height) { |
||||
|
alloc(); |
||||
|
} |
||||
|
|
||||
|
/*
|
||||
|
* Allocate / zero data buffer. |
||||
|
*/ |
||||
|
|
||||
|
uint8_t * |
||||
|
PixelArray::alloc() { |
||||
|
_data = (uint8_t *) malloc(length()); |
||||
|
memset(_data, 0, length()); |
||||
|
return _data; |
||||
|
} |
||||
|
|
||||
|
PixelArray::~PixelArray() { |
||||
|
free(_data); |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
|
||||
|
//
|
||||
|
// 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 void Initialize(Handle<Object> target); |
||||
|
static Handle<Value> New(const Arguments &args); |
||||
|
static Handle<Value> GetLength(Local<String> prop, const AccessorInfo &info); |
||||
|
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