Skip to content

Commit

Permalink
v.0.9.6, in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikos M committed Aug 28, 2016
1 parent cf73256 commit fd70f76
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 141 deletions.
193 changes: 128 additions & 65 deletions api-reference.md
Expand Up @@ -15,7 +15,8 @@ Change the dependencies file(s) to include your own selection of filters and plu
###Contents

* [Image](#image-class)
* [Image Loader](#loader--binaryloader--htmlimageloader-classes)
* [File Input Output](#file-input-output)
* [Codecs](#codecs)
* [Abstract Filter](#generic-abstract-filter)
* [Color Table Filter](#color-table-filter)
* [Color Matrix Filter](#color-matrix-filter) (analogous to the ActionScript filter)
Expand All @@ -35,7 +36,6 @@ Change the dependencies file(s) to include your own selection of filters and plu
* [GLSL Filter](#glsl-filter) (glsl-based filters i.e webgl/node-gl, in progress)
* [SVG Filter](#svg-filter) (svg-based filters)
* [Plugins / Extra Filters](#plugins-and-extra-filters)
* [Codecs](#codecs)



Expand Down Expand Up @@ -89,21 +89,141 @@ __Methods:__



###Loader / BinaryLoader / HTMLImageLoader Classes
###File Input Output

`FILTER` lib includes a number of I/O (input/output) managers which can be included and used optionaly.

* **`FILTER.IO.HTMLImageLoader`**

````javascript
filterImageInstance = FILTER.IO.HTMLImageLoader.load( imageUrl:String [, onComplete:Function, onError:Function] );

// this is same as (factory-constructor pattern):

filterImageInstance = new FILTER.IO.HTMLImageLoader( ).load( imageUrl [, onComplete, onError] );
````

Loads an image url into a `FILTER.Image` instance using an HTMl Image as underlying loader (`browser` only).

**NOTE:** The same functionality to load a url into a `FILTER.Image` has been **removed from the `FILTER.Image` Class**. Use the `FILTER.IO.HTMLImageLoader` instead.


* **`FILTER.IO.FileManager`**

````javascript
filterImageInstance = FILTER.IO.HTMLImageLoader.load( imageUrl:String [, onLoad:Function, onError:Function] );
data = FILTER.IO.FileManager.read( path_or_url:String [, onComplete:Function, onError:Function] );
FILTER.IO.FileManager.write( path_or_url:String, data:Buffer|String [, onComplete:Function, onError:Function] );

// this is same as (factory-constructor pattern):

filterImageInstance = new FILTER.IO.HTMLImageLoader( ).load( imageUrl [, onLoad, onError] );
data = new FILTER.IO.FileManager( ).read( path_or_url:String [, onComplete:Function, onError:Function] );
new FILTER.IO.FileManager( ).write( path:String, data:Buffer|String [, onComplete:Function, onError:Function] );
````

This manager reads/writes files using generic data of any form (not necesarily images). Including local files (in `nodejs`) and/or remote/internet files (via `XmlHttpRequest`, `browser` and `nodejs`)


* **`FILTER.IO.BinaryManager`**

````javascript
filterImageInstance = FILTER.IO.BinaryManager( codec:Object ).read( path_or_url:String [, onComplete:Function, onError:Function] );
FILTER.IO.BinaryManager( codec:Object ).write( path_or_url:String, image:FILTER.Image [, onComplete:Function, onError:Function] );

// this is same as (factory-constructor pattern):

filterImageInstance = new FILTER.IO.BinaryManager( codec:Object|FILTER.Codec ).read( path_or_url:String [, onComplete:Function, onError:Function] );
new FILTER.IO.BinaryManager( codec:Object|FILTER.Codec ).write( path:String, image:FILTER.Image [, onComplete:Function, onError:Function] );
````

This manager is a subclass of `FILTER.IO.FileManager` and reads/writes **binary** data files directly into and from a `FILTER.Image` using appropriate `codec` (encoder/decoder). The `codec` parameter is an object having at least one of `encoder` and/or `decoder` methods. *(see below for more codec examples)*


###Codecs

Native javascript `codecs` (`encoders` / `decoders`) are included for various `image` formats (both `browser` and `nodejs`):

1. `RAW` (reads/writes the raw binary data as is)
2. `PNG` (adapted from https://github.com/devongovett/png.js/ and https://github.com/lukeapage/pngjs) (**encoder + decoder**)
3. `JPG`/`JPEG` (adapted from https://github.com/eugeneware/jpeg-js) (**encoder + decoder**)
4. `BMP` (adapted from https://github.com/shaozilee/bmp-js) (**encoder + decoder**)
5. `GIF` (adapted from: https://github.com/buzzfeed/libgif-js) (**decoder only**)
6. `TGA` (adapted from: https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js) (**decoder only**)
7. `RGBE`/`HDR` (adapted from: http://www.graphics.cornell.edu/~bjw/rgbe.html) (**encoder + decoder**)
8. Any object having at least one of `encoder` and/or `decoder` methods can be used on-the-fly as custom codec.

Instead of separate loaders per image format, only one `binary manager` (see above) is used, with the appropriate codec as parameter.
This makes code more flexible and shorter, loaders can be adapted for `nodejs` easier and custom codecs can be used on the fly.

**`PNG` example**
Loads an image url in PNG format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryManager( FILTER.Codec.PNG ).read( path [, onComplete, onError] );
````

**`JPG` example**
Loads an image url in JPG format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryManager( FILTER.Codec.JPG ).read( path [, onComplete, onError] );
FILTER.IO.BinaryManager( FILTER.Codec.JPG ).write( path, filterImageInstance [, onComplete, onError] );
````

**`GIF` example**
Loads an image url in GIF format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryManager( FILTER.Codec.GIF ).read( path [, onComplete, onError] );
````

Loads an image url into a `FILTER.Image` instance.
**`BMP` example**
Loads an image url in BMP format into a `FILTER.Image` instance.

The same functionality to load a url into a `FILTER.Image` has been **removed from the FILTER.Image Class**
````javascript
filterImageInstance = FILTER.IO.BinaryManager( FILTER.Codec.BMP ).read( path [, onComplete, onError] );
FILTER.IO.BinaryManager( FILTER.Codec.BMP ).write( path, filterImageInstance [, onComplete, onError] );
````

Use the `FILTER.IO.HTMLImageLoader` instead. In order to use the `FILTER.IO.BinaryLoader` to load and decode a custom image format, see below.
**`TGA` example**
Loads an image url in TGA format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryManager( FILTER.Codec.TGA ).read( path [, onComplete, onError] );
````

**`RGBE` example**
Loads an image url in RGBE format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryManager( FILTER.Codec.RGBE ).read( path [, onComplete, onError] );
FILTER.IO.BinaryManager( FILTER.Codec.RGBE ).write( path, filterImageInstance [, onComplete, onError] );
````


**custom example**

````javascript
var customFormat = FILTER.IO.BinaryManager({
decoder: function( buffer, metaData ) {
// your custom decoder here
// ..
return {
width: image_width,
height: image_height,
data: decoded_image_data
};
},
encoder: function( imageData ) {
// your custom encoder here
// ..
return write_buffer;
}
});
// NOTE: same instance can read and write data (if both encoder and decoder methods exist of course)
filterImageInstance = customFormat.read( path [, onComplete, onError] );
// maybe do some processing here.. then write result
customFormat.write( path, filterImageInstance [, onComplete, onError] );
````


###Generic Abstract Filter
Expand Down Expand Up @@ -941,60 +1061,3 @@ __Included Plugins__ (see examples for how to use)
<tr><td>LipContourExtractor</td> <td>extract lip shape contour using Enevo's Jumping Snake (active shape) algorithm (TO BE ADDED)</td></tr>
</tbody>
</table>

###Codecs


Native javascript `codecs` (`encoders` / `decoders`) are included for various `image` formats:

1. `PNG` (adapted from https://github.com/devongovett/png.js/) (**decoder only**)
2. `JPG`/`JPEG` (adapted from https://github.com/eugeneware/jpeg-js) (**encoder + decoder**)
3. `BMP` (adapted from https://github.com/shaozilee/bmp-js) (**encoder + decoder**)
4. `GIF` (adapted from: https://github.com/buzzfeed/libgif-js) (**decoder only**)
5. `TGA` (adapted from: https://github.com/vthibault/roBrowser/blob/master/src/Loaders/Targa.js) (**decoder only**)
6. `RGBE`/`HDR` (adapted from: http://www.graphics.cornell.edu/~bjw/rgbe.html) (**encoder + decoder**)

Instead of separate loaders per image format, only one `binary loader` is used, with the appropriate codecs as parameters.
This makes code more flexible and shorter, loaders can be adapted for nodejs easier and custom codecs can be used on the fly.

**`PNG` example**
Loads an image url in PNG format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryLoader( FILTER.Codec.PNG.decoder ).load( imageUrl [, onLoad, onError] );
````

**`JPG` example**
Loads an image url in JPG format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryLoader( FILTER.Codec.JPG.decoder ).load( imageUrl [, onLoad, onError] );
````

**`GIF` example**
Loads an image url in GIF format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryLoader( FILTER.Codec.GIF.decoder ).load( imageUrl [, onLoad, onError] );
````

**`BMP` example**
Loads an image url in BMP format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryLoader( FILTER.Codec.BMP.decoder ).load( imageUrl [, onLoad, onError] );
````

**`TGA` example**
Loads an image url in TGA format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryLoader( FILTER.Codec.TGA.decoder ).load( imageUrl [, onLoad, onError] );
````

**`RGBE` example**
Loads an image url in RGBE format into a `FILTER.Image` instance.

````javascript
filterImageInstance = FILTER.IO.BinaryLoader( FILTER.Codec.RGBE.decoder ).load( imageUrl [, onLoad, onError] );
````
1 change: 1 addition & 0 deletions readme.md
Expand Up @@ -156,6 +156,7 @@ Change the dependencies file(s) to include your own selection of filters and plu
* add `2d-fft` routines, frequency-domain filtering (todo)
* add `SVG`, `CSS` Filters interface support for some Filters (todo)
* add machine learning (image) segmentation/clustering algorithms (e.g `kmeans`, `kmedoids`, `connected components`, `deterministic annealing`, `svd`, `jade`, ..) [DONE partially]
* implement some numeric routines (e.g `blas`, `filter` routines) using faster [`asmjs`](http://asmjs.org/spec/latest/) (browser &amp; nodejs) and/or [simd.js](https://hacks.mozilla.org/2014/10/introducing-simd-js/) (TODO)
* make convolutions/statistics faster [DONE partially]
* add full support for `Node.js` [DONE]
* add (generic/native) codec support for image formats, e.g `.TGA`, `.HDR`/`.RGBE`, `.GIF`, `.BMP`, `.PNG`, `.JPG`/`.JPEG` etc.. [DONE]
Expand Down
4 changes: 2 additions & 2 deletions src/codecs/BMP.js
Expand Up @@ -269,7 +269,7 @@ function BmpEncoder( imgData )
self.data = imgData.data;
self.width = imgData.width;
self.height = imgData.height;
self.extraBytes = self.width%4;
self.extraBytes = self.width&3/*%4*/;
self.rgbSize = self.height*(3*self.width+self.extraBytes);
self.headerInfoSize = 40;

Expand Down Expand Up @@ -382,7 +382,7 @@ BmpEncoder.prototype = {
FILTER.Codec.BMP = {

encoder: function( imgData, metaData ) {
var quality = typeof metaData.quality === 'undefined' ? 100 : metaData.quality;
var quality = 'undefined' === typeof metaData.quality ? 100 : metaData.quality;
return new Buffer( new BmpEncoder( imgData ).encode( ) );
},

Expand Down
14 changes: 7 additions & 7 deletions src/codecs/GIF.js
Expand Up @@ -378,12 +378,11 @@ function parseGIF( st, handler )

FILTER.Codec.GIF = {

encoder: null,//FILTER.NotImplemented('GIF.encoder'),
encoder: FILTER.NotImplemented('GIF.encoder'),

decoder: function ( buffer, metaData ) {
var hdr, transparency = null,
image = {width: 0, height: 0, data: null}
;
image = {width: 0, height: 0, data: null};
// animated GIFs are not handled at this moment, needed??
parseGIF(new Stream(new Uint8Array( buffer )), {
hdr: function (_hdr) { hdr = _hdr; },
Expand All @@ -395,12 +394,13 @@ FILTER.Codec.GIF = {
//apply color table colors
img.pixels.forEach(function (pixel, i) {
// imgData.data === [R,G,B,A,R,G,B,A,...]
var index = i << 2;
if (pixel !== transparency)
{
cdd[(i << 2) + 0] = ct[pixel][0];
cdd[(i << 2) + 1] = ct[pixel][1];
cdd[(i << 2) + 2] = ct[pixel][2];
cdd[(i << 2) + 3] = 255; // Opaque.
cdd[index + 0] = ct[pixel][0];
cdd[index + 1] = ct[pixel][1];
cdd[index + 2] = ct[pixel][2];
cdd[index + 3] = 255; // Opaque.
}
});
image.width = img.width;
Expand Down
12 changes: 5 additions & 7 deletions src/codecs/RGBE.js
Expand Up @@ -437,22 +437,20 @@ FILTER.Codec.HDR = FILTER.Codec.RGBE = {
},

decoder: function( buffer, metaData ) {
var byteArray = new Uint8Array( buffer ),
byteLength = byteArray.byteLength;
var byteArray = new Uint8Array( buffer ), byteLength = byteArray.byteLength;
byteArray.pos = 0;
var rgbe_header_info = RGBE_ReadHeader( byteArray );

if ( RGBE_RETURN_FAILURE !== rgbe_header_info )
{
var w = rgbe_header_info.width,
h = rgbe_header_info.height
,image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray(byteArray.pos), w, h )
;
var w = rgbe_header_info.width, h = rgbe_header_info.height,
image_rgba_data = RGBE_ReadPixels_RLE( byteArray.subarray(byteArray.pos), w, h );

if ( RGBE_RETURN_FAILURE !== image_rgba_data )
{
if ( metaData )
{
metaData.header = rgbe_header_info.string;
//metaData.header = rgbe_header_info.string;
metaData.gamma = rgbe_header_info.gamma;
metaData.exposure = rgbe_header_info.exposure;
}
Expand Down
2 changes: 1 addition & 1 deletion src/codecs/TGA.js
Expand Up @@ -362,7 +362,7 @@ function getTgaRGBA( header, width, height, image, palette, use_grey )

FILTER.Codec.TGA = {

encoder: null,//FILTER.NotImplemented('TGA.encoder'),
encoder: FILTER.NotImplemented('TGA.encoder'),

decoder: function ( buffer, metaData ) {

Expand Down

0 comments on commit fd70f76

Please sign in to comment.