Index: bower_components/gif.js/src/GIFEncoder.js |
diff --git a/bower_components/gif.js/src/GIFEncoder.js b/bower_components/gif.js/src/GIFEncoder.js |
deleted file mode 100644 |
index 4fa88557f95f312af807c41a496944a5e8a2c545..0000000000000000000000000000000000000000 |
--- a/bower_components/gif.js/src/GIFEncoder.js |
+++ /dev/null |
@@ -1,403 +0,0 @@ |
-/* |
- GIFEncoder.js |
- |
- Authors |
- Kevin Weiner (original Java version - kweiner@fmsware.com) |
- Thibault Imbert (AS3 version - bytearray.org) |
- Johan Nordberg (JS version - code@johan-nordberg.com) |
-*/ |
- |
-var NeuQuant = require('./TypedNeuQuant.js'); |
-var LZWEncoder = require('./LZWEncoder.js'); |
- |
-function ByteArray() { |
- this.page = -1; |
- this.pages = []; |
- this.newPage(); |
-} |
- |
-ByteArray.pageSize = 4096; |
-ByteArray.charMap = {}; |
- |
-for (var i = 0; i < 256; i++) |
- ByteArray.charMap[i] = String.fromCharCode(i); |
- |
-ByteArray.prototype.newPage = function() { |
- this.pages[++this.page] = new Uint8Array(ByteArray.pageSize); |
- this.cursor = 0; |
-}; |
- |
-ByteArray.prototype.getData = function() { |
- var rv = ''; |
- for (var p = 0; p < this.pages.length; p++) { |
- for (var i = 0; i < ByteArray.pageSize; i++) { |
- rv += ByteArray.charMap[this.pages[p][i]]; |
- } |
- } |
- return rv; |
-}; |
- |
-ByteArray.prototype.writeByte = function(val) { |
- if (this.cursor >= ByteArray.pageSize) this.newPage(); |
- this.pages[this.page][this.cursor++] = val; |
-}; |
- |
-ByteArray.prototype.writeUTFBytes = function(string) { |
- for (var l = string.length, i = 0; i < l; i++) |
- this.writeByte(string.charCodeAt(i)); |
-}; |
- |
-ByteArray.prototype.writeBytes = function(array, offset, length) { |
- for (var l = length || array.length, i = offset || 0; i < l; i++) |
- this.writeByte(array[i]); |
-}; |
- |
-function GIFEncoder(width, height) { |
- // image size |
- this.width = ~~width; |
- this.height = ~~height; |
- |
- // transparent color if given |
- this.transparent = null; |
- |
- // transparent index in color table |
- this.transIndex = 0; |
- |
- // -1 = no repeat, 0 = forever. anything else is repeat count |
- this.repeat = -1; |
- |
- // frame delay (hundredths) |
- this.delay = 0; |
- |
- this.image = null; // current frame |
- this.pixels = null; // BGR byte array from frame |
- this.indexedPixels = null; // converted frame indexed to palette |
- this.colorDepth = null; // number of bit planes |
- this.colorTab = null; // RGB palette |
- this.usedEntry = new Array(); // active palette entries |
- this.palSize = 7; // color table size (bits-1) |
- this.dispose = -1; // disposal code (-1 = use default) |
- this.firstFrame = true; |
- this.sample = 10; // default sample interval for quantizer |
- |
- this.out = new ByteArray(); |
-} |
- |
-/* |
- Sets the delay time between each frame, or changes it for subsequent frames |
- (applies to last frame added) |
-*/ |
-GIFEncoder.prototype.setDelay = function(milliseconds) { |
- this.delay = Math.round(milliseconds / 10); |
-}; |
- |
-/* |
- Sets frame rate in frames per second. |
-*/ |
-GIFEncoder.prototype.setFrameRate = function(fps) { |
- this.delay = Math.round(100 / fps); |
-}; |
- |
-/* |
- Sets the GIF frame disposal code for the last added frame and any |
- subsequent frames. |
- |
- Default is 0 if no transparent color has been set, otherwise 2. |
-*/ |
-GIFEncoder.prototype.setDispose = function(disposalCode) { |
- if (disposalCode >= 0) this.dispose = disposalCode; |
-}; |
- |
-/* |
- Sets the number of times the set of GIF frames should be played. |
- |
- -1 = play once |
- 0 = repeat indefinitely |
- |
- Default is -1 |
- |
- Must be invoked before the first image is added |
-*/ |
- |
-GIFEncoder.prototype.setRepeat = function(repeat) { |
- this.repeat = repeat; |
-}; |
- |
-/* |
- Sets the transparent color for the last added frame and any subsequent |
- frames. Since all colors are subject to modification in the quantization |
- process, the color in the final palette for each frame closest to the given |
- color becomes the transparent color for that frame. May be set to null to |
- indicate no transparent color. |
-*/ |
-GIFEncoder.prototype.setTransparent = function(color) { |
- this.transparent = color; |
-}; |
- |
-/* |
- Adds next GIF frame. The frame is not written immediately, but is |
- actually deferred until the next frame is received so that timing |
- data can be inserted. Invoking finish() flushes all frames. |
-*/ |
-GIFEncoder.prototype.addFrame = function(imageData) { |
- this.image = imageData; |
- |
- this.getImagePixels(); // convert to correct format if necessary |
- this.analyzePixels(); // build color table & map pixels |
- |
- if (this.firstFrame) { |
- this.writeLSD(); // logical screen descriptior |
- this.writePalette(); // global color table |
- if (this.repeat >= 0) { |
- // use NS app extension to indicate reps |
- this.writeNetscapeExt(); |
- } |
- } |
- |
- this.writeGraphicCtrlExt(); // write graphic control extension |
- this.writeImageDesc(); // image descriptor |
- if (!this.firstFrame) this.writePalette(); // local color table |
- this.writePixels(); // encode and write pixel data |
- |
- this.firstFrame = false; |
-}; |
- |
-/* |
- Adds final trailer to the GIF stream, if you don't call the finish method |
- the GIF stream will not be valid. |
-*/ |
-GIFEncoder.prototype.finish = function() { |
- this.out.writeByte(0x3b); // gif trailer |
-}; |
- |
-/* |
- Sets quality of color quantization (conversion of images to the maximum 256 |
- colors allowed by the GIF specification). Lower values (minimum = 1) |
- produce better colors, but slow processing significantly. 10 is the |
- default, and produces good color mapping at reasonable speeds. Values |
- greater than 20 do not yield significant improvements in speed. |
-*/ |
-GIFEncoder.prototype.setQuality = function(quality) { |
- if (quality < 1) quality = 1; |
- this.sample = quality; |
-}; |
- |
-/* |
- Writes GIF file header |
-*/ |
-GIFEncoder.prototype.writeHeader = function() { |
- this.out.writeUTFBytes("GIF89a"); |
-}; |
- |
-/* |
- Analyzes current frame colors and creates color map. |
-*/ |
-GIFEncoder.prototype.analyzePixels = function() { |
- var len = this.pixels.length; |
- var nPix = len / 3; |
- |
- this.indexedPixels = new Uint8Array(nPix); |
- |
- var imgq = new NeuQuant(this.pixels, this.sample); |
- imgq.buildColormap(); // create reduced palette |
- this.colorTab = imgq.getColormap(); |
- |
- // map image pixels to new palette |
- var k = 0; |
- for (var j = 0; j < nPix; j++) { |
- var index = imgq.lookupRGB( |
- this.pixels[k++] & 0xff, |
- this.pixels[k++] & 0xff, |
- this.pixels[k++] & 0xff |
- ); |
- this.usedEntry[index] = true; |
- this.indexedPixels[j] = index; |
- } |
- |
- this.pixels = null; |
- this.colorDepth = 8; |
- this.palSize = 7; |
- |
- // get closest match to transparent color if specified |
- if (this.transparent !== null) { |
- this.transIndex = this.findClosest(this.transparent); |
- } |
-}; |
- |
-/* |
- Returns index of palette color closest to c |
-*/ |
-GIFEncoder.prototype.findClosest = function(c) { |
- if (this.colorTab === null) return -1; |
- |
- var r = (c & 0xFF0000) >> 16; |
- var g = (c & 0x00FF00) >> 8; |
- var b = (c & 0x0000FF); |
- var minpos = 0; |
- var dmin = 256 * 256 * 256; |
- var len = this.colorTab.length; |
- |
- for (var i = 0; i < len;) { |
- var dr = r - (this.colorTab[i++] & 0xff); |
- var dg = g - (this.colorTab[i++] & 0xff); |
- var db = b - (this.colorTab[i] & 0xff); |
- var d = dr * dr + dg * dg + db * db; |
- var index = parseInt(i / 3); |
- if (this.usedEntry[index] && (d < dmin)) { |
- dmin = d; |
- minpos = index; |
- } |
- i++; |
- } |
- |
- return minpos; |
-}; |
- |
-/* |
- Extracts image pixels into byte array pixels |
- (removes alphachannel from canvas imagedata) |
-*/ |
-GIFEncoder.prototype.getImagePixels = function() { |
- var w = this.width; |
- var h = this.height; |
- this.pixels = new Uint8Array(w * h * 3); |
- |
- var data = this.image; |
- var count = 0; |
- |
- for (var i = 0; i < h; i++) { |
- for (var j = 0; j < w; j++) { |
- var b = (i * w * 4) + j * 4; |
- this.pixels[count++] = data[b]; |
- this.pixels[count++] = data[b+1]; |
- this.pixels[count++] = data[b+2]; |
- } |
- } |
-}; |
- |
-/* |
- Writes Graphic Control Extension |
-*/ |
-GIFEncoder.prototype.writeGraphicCtrlExt = function() { |
- this.out.writeByte(0x21); // extension introducer |
- this.out.writeByte(0xf9); // GCE label |
- this.out.writeByte(4); // data block size |
- |
- var transp, disp; |
- if (this.transparent === null) { |
- transp = 0; |
- disp = 0; // dispose = no action |
- } else { |
- transp = 1; |
- disp = 2; // force clear if using transparent color |
- } |
- |
- if (this.dispose >= 0) { |
- disp = dispose & 7; // user override |
- } |
- disp <<= 2; |
- |
- // packed fields |
- this.out.writeByte( |
- 0 | // 1:3 reserved |
- disp | // 4:6 disposal |
- 0 | // 7 user input - 0 = none |
- transp // 8 transparency flag |
- ); |
- |
- this.writeShort(this.delay); // delay x 1/100 sec |
- this.out.writeByte(this.transIndex); // transparent color index |
- this.out.writeByte(0); // block terminator |
-}; |
- |
-/* |
- Writes Image Descriptor |
-*/ |
-GIFEncoder.prototype.writeImageDesc = function() { |
- this.out.writeByte(0x2c); // image separator |
- this.writeShort(0); // image position x,y = 0,0 |
- this.writeShort(0); |
- this.writeShort(this.width); // image size |
- this.writeShort(this.height); |
- |
- // packed fields |
- if (this.firstFrame) { |
- // no LCT - GCT is used for first (or only) frame |
- this.out.writeByte(0); |
- } else { |
- // specify normal LCT |
- this.out.writeByte( |
- 0x80 | // 1 local color table 1=yes |
- 0 | // 2 interlace - 0=no |
- 0 | // 3 sorted - 0=no |
- 0 | // 4-5 reserved |
- this.palSize // 6-8 size of color table |
- ); |
- } |
-}; |
- |
-/* |
- Writes Logical Screen Descriptor |
-*/ |
-GIFEncoder.prototype.writeLSD = function() { |
- // logical screen size |
- this.writeShort(this.width); |
- this.writeShort(this.height); |
- |
- // packed fields |
- this.out.writeByte( |
- 0x80 | // 1 : global color table flag = 1 (gct used) |
- 0x70 | // 2-4 : color resolution = 7 |
- 0x00 | // 5 : gct sort flag = 0 |
- this.palSize // 6-8 : gct size |
- ); |
- |
- this.out.writeByte(0); // background color index |
- this.out.writeByte(0); // pixel aspect ratio - assume 1:1 |
-}; |
- |
-/* |
- Writes Netscape application extension to define repeat count. |
-*/ |
-GIFEncoder.prototype.writeNetscapeExt = function() { |
- this.out.writeByte(0x21); // extension introducer |
- this.out.writeByte(0xff); // app extension label |
- this.out.writeByte(11); // block size |
- this.out.writeUTFBytes('NETSCAPE2.0'); // app id + auth code |
- this.out.writeByte(3); // sub-block size |
- this.out.writeByte(1); // loop sub-block id |
- this.writeShort(this.repeat); // loop count (extra iterations, 0=repeat forever) |
- this.out.writeByte(0); // block terminator |
-}; |
- |
-/* |
- Writes color table |
-*/ |
-GIFEncoder.prototype.writePalette = function() { |
- this.out.writeBytes(this.colorTab); |
- var n = (3 * 256) - this.colorTab.length; |
- for (var i = 0; i < n; i++) |
- this.out.writeByte(0); |
-}; |
- |
-GIFEncoder.prototype.writeShort = function(pValue) { |
- this.out.writeByte(pValue & 0xFF); |
- this.out.writeByte((pValue >> 8) & 0xFF); |
-}; |
- |
-/* |
- Encodes and writes pixel data |
-*/ |
-GIFEncoder.prototype.writePixels = function() { |
- var enc = new LZWEncoder(this.width, this.height, this.indexedPixels, this.colorDepth); |
- enc.encode(this.out); |
-}; |
- |
-/* |
- Retrieves the GIF stream |
-*/ |
-GIFEncoder.prototype.stream = function() { |
- return this.out; |
-}; |
- |
-module.exports = GIFEncoder; |