From f43d5cacc2ccc9a5657e267e75f2c0a6c89d954f Mon Sep 17 00:00:00 2001 From: Michael Martinez Date: Tue, 29 Sep 2015 16:20:29 -0500 Subject: [PATCH] new build --- bower.json | 4 +- package.json | 2 +- release/1.2.1/lossless-min.js | 1 + release/1.2.1/lossless.js | 1680 +++++++++++++++++++++++++++++++ release/current/lossless-min.js | 2 +- release/current/lossless.js | 30 +- 6 files changed, 1708 insertions(+), 11 deletions(-) create mode 100644 release/1.2.1/lossless-min.js create mode 100644 release/1.2.1/lossless.js diff --git a/bower.json b/bower.json index ba3193d..c1b589e 100644 --- a/bower.json +++ b/bower.json @@ -1,8 +1,8 @@ { "name": "jpeg-lossless-decoder-js", - "version": "1.2.0", + "version": "1.2.1", "description": "A JavaScript JPEG Lossless decoder.", - "main" : "release/1.2/lossless.js", + "main" : "release/1.2.1/lossless.js", "ignore": [ "src", "tests", diff --git a/package.json b/package.json index 8e629d8..910ac76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "JPEGLosslessDecoderJS", - "version": "1.2.0", + "version": "1.2.1", "description": "A JavaScript JPEG Lossless decoder.", "main": "src/decoder.js", "directories": { diff --git a/release/1.2.1/lossless-min.js b/release/1.2.1/lossless-min.js new file mode 100644 index 0000000..05f281e --- /dev/null +++ b/release/1.2.1/lossless-min.js @@ -0,0 +1 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jpeg=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>4!==4092||current===65476){switch(current){case 65476:this.huffTable.read(this.stream,this.HuffTab);break;case 65484:throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)");case 65499:this.quantTable.read(this.stream,jpeg.lossless.Decoder.TABLE);break;case 65501:this.restartInterval=this.readNumber();break;case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:this.readApp();break;case 65534:this.readComment();break;default:if(current>>8!==255){throw new Error("ERROR: format throw new IOException! (decode)")}}current=this.stream.get16()}if(current<65472||current>65479){throw new Error("ERROR: could not handle arithmetic code!")}this.frame.read(this.stream);current=this.stream.get16();do{while(current!==65498){switch(current){case 65476:this.huffTable.read(this.stream,this.HuffTab);break;case 65484:throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)");case 65499:this.quantTable.read(this.stream,jpeg.lossless.Decoder.TABLE);break;case 65501:this.restartInterval=this.readNumber();break;case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:this.readApp();break;case 65534:this.readComment();break;default:if(current>>8!==255){throw new Error("ERROR: format throw new IOException! (Parser.decode)")}}current=this.stream.get16()}this.precision=this.frame.precision;this.components=this.frame.components;if(!this.numBytes){this.numBytes=parseInt(this.precision/8)}this.scan.read(this.stream);this.numComp=this.scan.numComp;this.selection=this.scan.selection;if(this.numBytes===1){if(this.numComp===3){this.getter=this.getValueRGB;this.setter=this.setValueRGB;this.output=this.outputRGB}else{this.getter=this.getValue8;this.setter=this.setValue8;this.output=this.outputSingle}}else{this.getter=this.getValue16;this.setter=this.setValue16;this.output=this.outputSingle}switch(this.selection){case 2:this.selector=this.select2;break;case 3:this.selector=this.select3;break;case 4:this.selector=this.select4;break;case 5:this.selector=this.select5;break;case 6:this.selector=this.select6;break;case 7:this.selector=this.select7;break;default:this.selector=this.select1;break}this.scanComps=this.scan.components;this.quantTables=this.quantTable.quantTables;for(i=0;i=jpeg.lossless.Decoder.RESTART_MARKER_BEGIN&¤t<=jpeg.lossless.Decoder.RESTART_MARKER_END)){break}}if(current===65500&&scanNum===1){this.readNumber();current=this.stream.get16()}}while(current!==65497&&(this.xLoc>1)};jpeg.lossless.Decoder.prototype.select6=function(compOffset){return this.getPreviousY(compOffset)+(this.getPreviousX(compOffset)-this.getPreviousXY(compOffset)>>1)};jpeg.lossless.Decoder.prototype.select7=function(compOffset){return(this.getPreviousX(compOffset)+this.getPreviousY(compOffset))/2};jpeg.lossless.Decoder.prototype.decodeRGB=function(prev,temp,index){var value,actab,dctab,qtab,ctrC,i,k,j;prev[0]=this.selector(0);prev[1]=this.selector(1);prev[2]=this.selector(2);for(ctrC=0;ctrC=65280){return value}prev[ctrC]=this.IDCT_Source[0]=prev[ctrC]+this.getn(index,value,temp,index);this.IDCT_Source[0]*=qtab[0];for(j=1;j<64;j+=1){value=this.getHuffmanValue(actab,temp,index);if(value>=65280){return value}j+=value>>4;if((value&15)===0){if(value>>4===0){break}}else{this.IDCT_Source[jpeg.lossless.Decoder.IDCT_P[j]]=this.getn(index,value&15,temp,index)*qtab[j]}}}}return 0};jpeg.lossless.Decoder.prototype.decodeSingle=function(prev,temp,index){var value,i,n,nRestart;if(this.restarting){this.restarting=false;prev[0]=1<=65280){return value}n=this.getn(prev,value,temp,index);nRestart=n>>8;if(nRestart>=jpeg.lossless.Decoder.RESTART_MARKER_BEGIN&&nRestart<=jpeg.lossless.Decoder.RESTART_MARKER_END){return nRestart}prev[0]+=n}return 0};jpeg.lossless.Decoder.prototype.getHuffmanValue=function(table,temp,index){var code,input,mask;mask=65535;if(index[0]<8){temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input}else{index[0]-=8}code=table[temp[0]>>index[0]];if((code&jpeg.lossless.Decoder.MSB)!==0){if(this.markerIndex!==0){this.markerIndex=0;return 65280|this.marker}temp[0]&=mask>>16-index[0];temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;code=table[(code&255)*256+(temp[0]>>index[0])];index[0]+=8}index[0]+=8-(code>>8);if(index[0]<0){throw new Error("index="+index[0]+" temp="+temp[0]+" code="+code+" in HuffmanValue()")}if(index[0]>16-index[0];return code&255};jpeg.lossless.Decoder.prototype.getn=function(PRED,n,temp,index){var result,one,n_one,mask,input;one=1;n_one=-1;mask=65535;if(n===0){return 0}if(n===16){if(PRED[0]>=0){return-32768}else{return 32768}}index[0]-=n;if(index[0]>=0){if(index[0]>index[0];temp[0]&=mask>>16-index[0]}else{temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;index[0]+=8;if(index[0]<0){if(this.markerIndex!==0){this.markerIndex=0;return(65280|this.marker)<<8}temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;index[0]+=8}if(index[0]<0){throw new Error("index="+index[0]+" in getn()")}if(index[0]>index[0];temp[0]&=mask>>16-index[0]}if(result0){return this.getter(this.yLoc*this.xDim+this.xLoc-1,compOffset)}else if(this.yLoc>0){return this.getPreviousY(compOffset)}else{return 1<0&&this.yLoc>0){return this.getter((this.yLoc-1)*this.xDim+this.xLoc-1,compOffset)}else{return this.getPreviousY(compOffset)}};jpeg.lossless.Decoder.prototype.getPreviousY=function(compOffset){if(this.yLoc>0){return this.getter((this.yLoc-1)*this.xDim+this.xLoc,compOffset)}else{return this.getPreviousX(compOffset)}};jpeg.lossless.Decoder.prototype.isLastPixel=function(){return this.xLoc===this.xDim-1&&this.yLoc===this.yDim-1};jpeg.lossless.Decoder.prototype.outputSingle=function(PRED){if(this.xLoc=this.xDim){this.yLoc+=1;this.xLoc=0}}};jpeg.lossless.Decoder.prototype.outputRGB=function(PRED){var offset=this.yLoc*this.xDim+this.xLoc;if(this.xLoc=this.xDim){this.yLoc+=1;this.xLoc=0}}};jpeg.lossless.Decoder.prototype.setValue16=function(index,val){this.outputData.setInt16(index*2,val,true)};jpeg.lossless.Decoder.prototype.getValue16=function(index){return this.outputData.getInt16(index*2,true)};jpeg.lossless.Decoder.prototype.setValue8=function(index,val){this.outputData.setInt8(index,val)};jpeg.lossless.Decoder.prototype.getValue8=function(index){return this.outputData.getInt8(index)};jpeg.lossless.Decoder.prototype.setValueRGB=function(index,val,compOffset){this.outputData.setUint8(index*3+compOffset,val)};jpeg.lossless.Decoder.prototype.getValueRGB=function(index,compOffset){return this.outputData.getUint8(index*3+compOffset)};jpeg.lossless.Decoder.prototype.readApp=function(){var count=0,length=this.stream.get16();count+=2;while(countlength){throw new Error("ERROR: frame format error")}c=data.get8();count+=1;if(count>=length){throw new Error("ERROR: frame format error [c>=Lf]")}temp=data.get8();count+=1;if(!this.components[c]){this.components[c]=new jpeg.lossless.ComponentSpec}this.components[c].hSamp=temp>>4;this.components[c].vSamp=temp&15;this.components[c].quantTableSel=data.get8();count+=1}if(count!==length){throw new Error("ERROR: frame format error [Lf!=count]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.FrameHeader}},{"./component-spec.js":1,"./data-stream.js":2}],5:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);jpeg.lossless.HuffmanTable=jpeg.lossless.HuffmanTable||function(){this.l=jpeg.lossless.Utils.createArray(4,2,16);this.th=[];this.v=jpeg.lossless.Utils.createArray(4,2,16,200);this.tc=jpeg.lossless.Utils.createArray(4,2);this.tc[0][0]=0;this.tc[1][0]=0;this.tc[2][0]=0;this.tc[3][0]=0;this.tc[0][1]=0;this.tc[1][1]=0;this.tc[2][1]=0;this.tc[3][1]=0;this.th[0]=0;this.th[1]=0;this.th[2]=0;this.th[3]=0};jpeg.lossless.HuffmanTable.MSB=2147483648;jpeg.lossless.HuffmanTable.prototype.read=function(data,HuffTab){var count=0,length,temp,t,c,i,j;length=data.get16();count+=2;while(count3){throw new Error("ERROR: Huffman table ID > 3")}c=temp>>4;if(c>2){throw new Error("ERROR: Huffman table [Table class > 2 ]")}this.th[t]=1;this.tc[t][c]=1;for(i=0;i<16;i+=1){this.l[t][c][i]=data.get8();count+=1}for(i=0;i<16;i+=1){for(j=0;jlength){throw new Error("ERROR: Huffman table format error [count>Lh]")}this.v[t][c][i][j]=data.get8();count+=1}}}if(count!==length){throw new Error("ERROR: Huffman table format error [count!=Lf]")}for(i=0;i<4;i+=1){for(j=0;j<2;j+=1){if(this.tc[i][j]!==0){this.buildHuffTable(HuffTab[i][j],this.l[i][j],this.v[i][j])}}}return 1};jpeg.lossless.HuffmanTable.prototype.buildHuffTable=function(tab,L,V){var currentTable,temp,k,i,j,n;temp=256;k=0;for(i=0;i<8;i+=1){for(j=0;j>i+1;n+=1){tab[k]=V[i][j]|i+1<<8;k+=1}}}for(i=1;k<256;i+=1,k+=1){tab[k]=i|jpeg.lossless.HuffmanTable.MSB}currentTable=1;k=0;for(i=8;i<16;i+=1){for(j=0;j>i-7;n+=1){tab[currentTable*256+k]=V[i][j]|i+1<<8;k+=1}if(k>=256){if(k>256){throw new Error("ERROR: Huffman table error(1)!")}k=0;currentTable+=1}}}};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.HuffmanTable}},{"./data-stream.js":2,"./utils.js":10}],6:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.ComponentSpec=jpeg.lossless.ComponentSpec||(typeof require!=="undefined"?require("./component-spec.js"):null);jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Decoder=jpeg.lossless.Decoder||(typeof require!=="undefined"?require("./decoder.js"):null);jpeg.lossless.FrameHeader=jpeg.lossless.FrameHeader||(typeof require!=="undefined"?require("./frame-header.js"):null);jpeg.lossless.HuffmanTable=jpeg.lossless.HuffmanTable||(typeof require!=="undefined"?require("./huffman-table.js"):null);jpeg.lossless.QuantizationTable=jpeg.lossless.QuantizationTable||(typeof require!=="undefined"?require("./quantization-table.js"):null);jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||(typeof require!=="undefined"?require("./scan-component.js"):null);jpeg.lossless.ScanHeader=jpeg.lossless.ScanHeader||(typeof require!=="undefined"?require("./scan-header.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg}},{"./component-spec.js":1,"./data-stream.js":2,"./decoder.js":3,"./frame-header.js":4,"./huffman-table.js":5,"./quantization-table.js":7,"./scan-component.js":8,"./scan-header.js":9,"./utils.js":10}],7:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);jpeg.lossless.QuantizationTable=jpeg.lossless.QuantizationTable||function(){this.precision=[];this.tq=[];this.quantTables=jpeg.lossless.Utils.createArray(4,64);this.tq[0]=0;this.tq[1]=0;this.tq[2]=0;this.tq[3]=0};jpeg.lossless.QuantizationTable.enhanceQuantizationTable=function(qtab,table){var i;for(i=0;i<8;i+=1){qtab[table[0*8+i]]*=90;qtab[table[4*8+i]]*=90;qtab[table[2*8+i]]*=118;qtab[table[6*8+i]]*=49;qtab[table[5*8+i]]*=71;qtab[table[1*8+i]]*=126;qtab[table[7*8+i]]*=25;qtab[table[3*8+i]]*=106}for(i=0;i<8;i+=1){qtab[table[0+8*i]]*=90;qtab[table[4+8*i]]*=90;qtab[table[2+8*i]]*=118;qtab[table[6+8*i]]*=49;qtab[table[5+8*i]]*=71;qtab[table[1+8*i]]*=126;qtab[table[7+8*i]]*=25;qtab[table[3+8*i]]*=106}for(i=0;i<64;i+=1){qtab[i]>>=6}};jpeg.lossless.QuantizationTable.prototype.read=function(data,table){var count=0,length,temp,t,i;length=data.get16();count+=2;while(count3){throw new Error("ERROR: Quantization table ID > 3")}this.precision[t]=temp>>4;if(this.precision[t]===0){this.precision[t]=8}else if(this.precision[t]===1){this.precision[t]=16}else{throw new Error("ERROR: Quantization table precision error")}this.tq[t]=1;if(this.precision[t]===8){for(i=0;i<64;i+=1){if(count>length){throw new Error("ERROR: Quantization table format error")}this.quantTables[t][i]=data.get8();count+=1}jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t],table)}else{for(i=0;i<64;i+=1){if(count>length){throw new Error("ERROR: Quantization table format error")}this.quantTables[t][i]=data.get16();count+=2}jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t],table)}}if(count!==length){throw new Error("ERROR: Quantization table error [count!=Lq]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.QuantizationTable}},{"./data-stream.js":2,"./utils.js":10}],8:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||function(){this.acTabSel=0;this.dcTabSel=0;this.scanCompSel=0};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.ScanComponent}},{}],9:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||(typeof require!=="undefined"?require("./scan-component.js"):null);jpeg.lossless.ScanHeader=jpeg.lossless.ScanHeader||function(){this.ah=0;this.al=0;this.numComp=0;this.selection=0;this.spectralEnd=0;this.components=[]};jpeg.lossless.ScanHeader.prototype.read=function(data){var count=0,length,i,temp;length=data.get16();count+=2;this.numComp=data.get8();count+=1;for(i=0;ilength){throw new Error("ERROR: scan header format error")}this.components[i].scanCompSel=data.get8();count+=1;temp=data.get8();count+=1;this.components[i].dcTabSel=temp>>4;this.components[i].acTabSel=temp&15}this.selection=data.get8();count+=1;this.spectralEnd=data.get8();count+=1;temp=data.get8();this.ah=temp>>4;this.al=temp&15;count+=1;if(count!==length){throw new Error("ERROR: scan header format error [count!=Ns]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.ScanHeader}},{"./data-stream.js":2,"./scan-component.js":8}],10:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.Utils=jpeg.lossless.Utils||{};jpeg.lossless.Utils.createArray=function(length){var arr=new Array(length||0),i=length;if(arguments.length>1){var args=Array.prototype.slice.call(arguments,1);while(i--)arr[length-1-i]=jpeg.lossless.Utils.createArray.apply(this,args)}return arr};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.Utils}},{}]},{},[6])(6)}); \ No newline at end of file diff --git a/release/1.2.1/lossless.js b/release/1.2.1/lossless.js new file mode 100644 index 0000000..c602524 --- /dev/null +++ b/release/1.2.1/lossless.js @@ -0,0 +1,1680 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jpeg = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 4) !== 0x0FFC) || (current === 0xFFC4))) { // SOF 0~15 + switch (current) { + case 0xFFC4: // DHT + this.huffTable.read(this.stream, this.HuffTab); + break; + case 0xFFCC: // DAC + throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)"); + case 0xFFDB: + this.quantTable.read(this.stream, jpeg.lossless.Decoder.TABLE); + break; + case 0xFFDD: + this.restartInterval = this.readNumber(); + break; + case 0xFFE0: + case 0xFFE1: + case 0xFFE2: + case 0xFFE3: + case 0xFFE4: + case 0xFFE5: + case 0xFFE6: + case 0xFFE7: + case 0xFFE8: + case 0xFFE9: + case 0xFFEA: + case 0xFFEB: + case 0xFFEC: + case 0xFFED: + case 0xFFEE: + case 0xFFEF: + this.readApp(); + break; + case 0xFFFE: + this.readComment(); + break; + default: + if ((current >> 8) !== 0xFF) { + throw new Error("ERROR: format throw new IOException! (decode)"); + } + } + + current = this.stream.get16(); + } + + if ((current < 0xFFC0) || (current > 0xFFC7)) { + throw new Error("ERROR: could not handle arithmetic code!"); + } + + this.frame.read(this.stream); + current = this.stream.get16(); + + do { + while (current !== 0x0FFDA) { // SOS + switch (current) { + case 0xFFC4: // DHT + this.huffTable.read(this.stream, this.HuffTab); + break; + case 0xFFCC: // DAC + throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)"); + case 0xFFDB: + this.quantTable.read(this.stream, jpeg.lossless.Decoder.TABLE); + break; + case 0xFFDD: + this.restartInterval = this.readNumber(); + break; + case 0xFFE0: + case 0xFFE1: + case 0xFFE2: + case 0xFFE3: + case 0xFFE4: + case 0xFFE5: + case 0xFFE6: + case 0xFFE7: + case 0xFFE8: + case 0xFFE9: + case 0xFFEA: + case 0xFFEB: + case 0xFFEC: + case 0xFFED: + case 0xFFEE: + case 0xFFEF: + this.readApp(); + break; + case 0xFFFE: + this.readComment(); + break; + default: + if ((current >> 8) !== 0xFF) { + throw new Error("ERROR: format throw new IOException! (Parser.decode)"); + } + } + + current = this.stream.get16(); + } + + this.precision = this.frame.precision; + this.components = this.frame.components; + + if (!this.numBytes) { + this.numBytes = parseInt(this.precision / 8); + } + + this.scan.read(this.stream); + this.numComp = this.scan.numComp; + this.selection = this.scan.selection; + + if (this.numBytes === 1) { + if (this.numComp === 3) { + this.getter = this.getValueRGB; + this.setter = this.setValueRGB; + this.output = this.outputRGB; + } else { + this.getter = this.getValue8; + this.setter = this.setValue8; + this.output = this.outputSingle; + } + } else { + this.getter = this.getValue16; + this.setter = this.setValue16; + this.output = this.outputSingle; + } + + switch (this.selection) { + case 2: + this.selector = this.select2; + break; + case 3: + this.selector = this.select3; + break; + case 4: + this.selector = this.select4; + break; + case 5: + this.selector = this.select5; + break; + case 6: + this.selector = this.select6; + break; + case 7: + this.selector = this.select7; + break; + default: + this.selector = this.select1; + break; + } + + this.scanComps = this.scan.components; + this.quantTables = this.quantTable.quantTables; + + for (i = 0; i < this.numComp; i+=1) { + compN = this.scanComps[i].scanCompSel; + this.qTab[i] = this.quantTables[this.components[compN].quantTableSel]; + this.nBlock[i] = this.components[compN].vSamp * this.components[compN].hSamp; + this.dcTab[i] = this.HuffTab[this.scanComps[i].dcTabSel][0]; + this.acTab[i] = this.HuffTab[this.scanComps[i].acTabSel][1]; + } + + this.xDim = this.frame.dimX; + this.yDim = this.frame.dimY; + this.outputData = new DataView(new ArrayBuffer(this.xDim * this.yDim * this.numBytes * this.numComp)); + + scanNum+=1; + + while (true) { // Decode one scan + temp[0] = 0; + index[0] = 0; + + for (i = 0; i < 10; i+=1) { + pred[i] = (1 << (this.precision - 1)); + } + + if (this.restartInterval === 0) { + current = this.decodeUnit(pred, temp, index); + + while ((current === 0) && ((this.xLoc < this.xDim) && (this.yLoc < this.yDim))) { + this.output(pred); + current = this.decodeUnit(pred, temp, index); + } + + break; //current=MARKER + } + + for (mcuNum = 0; mcuNum < this.restartInterval; mcuNum+=1) { + this.restarting = (mcuNum == 0); + current = this.decodeUnit(pred, temp, index); + this.output(pred); + + if (current !== 0) { + break; + } + } + + if (current === 0) { + if (this.markerIndex !== 0) { + current = (0xFF00 | this.marker); + this.markerIndex = 0; + } else { + current = this.stream.get16(); + } + } + + if (!((current >= jpeg.lossless.Decoder.RESTART_MARKER_BEGIN) && + (current <= jpeg.lossless.Decoder.RESTART_MARKER_END))) { + break; //current=MARKER + } + } + + if ((current === 0xFFDC) && (scanNum === 1)) { //DNL + this.readNumber(); + current = this.stream.get16(); + } + } while ((current !== 0xFFD9) && ((this.xLoc < this.xDim) && (this.yLoc < this.yDim)) && (scanNum === 0)); + + return this.outputData; +}; + + + +jpeg.lossless.Decoder.prototype.decodeUnit = function (prev, temp, index) { + if (this.numComp == 1) { + return this.decodeSingle(prev, temp, index); + } else if (this.numComp == 3) { + return this.decodeRGB(prev, temp, index); + } else { + return -1; + } +}; + + + +jpeg.lossless.Decoder.prototype.select1 = function (compOffset) { + return this.getPreviousX(compOffset); +}; + + + +jpeg.lossless.Decoder.prototype.select2 = function (compOffset) { + return this.getPreviousY(compOffset); +}; + + + +jpeg.lossless.Decoder.prototype.select3 = function (compOffset) { + return this.getPreviousXY(compOffset); +}; + + + +jpeg.lossless.Decoder.prototype.select4 = function (compOffset) { + return (this.getPreviousX(compOffset) + this.getPreviousY(compOffset)) - this.getPreviousXY(compOffset); +}; + + + +jpeg.lossless.Decoder.prototype.select5 = function (compOffset) { + return this.getPreviousX(compOffset) + ((this.getPreviousY(compOffset) - this.getPreviousXY(compOffset)) >> 1); +}; + + + +jpeg.lossless.Decoder.prototype.select6 = function (compOffset) { + return this.getPreviousY(compOffset) + ((this.getPreviousX(compOffset) - this.getPreviousXY(compOffset)) >> 1); +}; + + + +jpeg.lossless.Decoder.prototype.select7 = function (compOffset) { + return ((this.getPreviousX(compOffset) + this.getPreviousY(compOffset)) / 2); +}; + + + +jpeg.lossless.Decoder.prototype.decodeRGB = function (prev, temp, index) { + /*jslint bitwise: true */ + + var value, actab, dctab, qtab, ctrC, i, k, j; + + prev[0] = this.selector(0); + prev[1] = this.selector(1); + prev[2] = this.selector(2); + + for (ctrC = 0; ctrC < this.numComp; ctrC+=1) { + qtab = this.qTab[ctrC]; + actab = this.acTab[ctrC]; + dctab = this.dcTab[ctrC]; + for (i = 0; i < this.nBlock[ctrC]; i+=1) { + for (k = 0; k < this.IDCT_Source.length; k+=1) { + this.IDCT_Source[k] = 0; + } + + value = this.getHuffmanValue(dctab, temp, index); + + if (value >= 0xFF00) { + return value; + } + + prev[ctrC] = this.IDCT_Source[0] = prev[ctrC] + this.getn(index, value, temp, index); + this.IDCT_Source[0] *= qtab[0]; + + for (j = 1; j < 64; j+=1) { + value = this.getHuffmanValue(actab, temp, index); + + if (value >= 0xFF00) { + return value; + } + + j += (value >> 4); + + if ((value & 0x0F) === 0) { + if ((value >> 4) === 0) { + break; + } + } else { + this.IDCT_Source[jpeg.lossless.Decoder.IDCT_P[j]] = this.getn(index, value & 0x0F, temp, index) * qtab[j]; + } + } + } + } + + return 0; +}; + + + +jpeg.lossless.Decoder.prototype.decodeSingle = function (prev, temp, index) { + /*jslint bitwise: true */ + + var value, i, n, nRestart; + + if (this.restarting) { + this.restarting = false; + prev[0] = (1 << (this.frame.precision - 1)); + } else { + prev[0] = this.selector(); + } + + for (i = 0; i < this.nBlock[0]; i+=1) { + value = this.getHuffmanValue(this.dcTab[0], temp, index); + if (value >= 0xFF00) { + return value; + } + + n = this.getn(prev, value, temp, index); + nRestart = (n >> 8); + + if ((nRestart >= jpeg.lossless.Decoder.RESTART_MARKER_BEGIN) && (nRestart <= jpeg.lossless.Decoder.RESTART_MARKER_END)) { + return nRestart; + } + + prev[0] += n; + } + + return 0; +}; + + + +// Huffman table for fast search: (HuffTab) 8-bit Look up table 2-layer search architecture, 1st-layer represent 256 node (8 bits) if codeword-length > 8 +// bits, then the entry of 1st-layer = (# of 2nd-layer table) | MSB and it is stored in the 2nd-layer Size of tables in each layer are 256. +// HuffTab[*][*][0-256] is always the only 1st-layer table. +// +// An entry can be: (1) (# of 2nd-layer table) | MSB , for code length > 8 in 1st-layer (2) (Code length) << 8 | HuffVal +// +// HuffmanValue(table HuffTab[x][y] (ex) HuffmanValue(HuffTab[1][0],...) +// ): +// return: Huffman Value of table +// 0xFF?? if it receives a MARKER +// Parameter: table HuffTab[x][y] (ex) HuffmanValue(HuffTab[1][0],...) +// temp temp storage for remainded bits +// index index to bit of temp +// in FILE pointer +// Effect: +// temp store new remainded bits +// index change to new index +// in change to new position +// NOTE: +// Initial by temp=0; index=0; +// NOTE: (explain temp and index) +// temp: is always in the form at calling time or returning time +// | byte 4 | byte 3 | byte 2 | byte 1 | +// | 0 | 0 | 00000000 | 00000??? | if not a MARKER +// ^index=3 (from 0 to 15) +// 321 +// NOTE (marker and marker_index): +// If get a MARKER from 'in', marker=the low-byte of the MARKER +// and marker_index=9 +// If marker_index=9 then index is always > 8, or HuffmanValue() +// will not be called +jpeg.lossless.Decoder.prototype.getHuffmanValue = function (table, temp, index) { + /*jslint bitwise: true */ + + var code, input, mask; + mask = 0xFFFF; + + if (index[0] < 8) { + temp[0] <<= 8; + input = this.stream.get8(); + if (input === 0xFF) { + this.marker = this.stream.get8(); + if (this.marker !== 0) { + this.markerIndex = 9; + } + } + temp[0] |= input; + } else { + index[0] -= 8; + } + + code = table[temp[0] >> index[0]]; + + if ((code & jpeg.lossless.Decoder.MSB) !== 0) { + if (this.markerIndex !== 0) { + this.markerIndex = 0; + return 0xFF00 | this.marker; + } + + temp[0] &= (mask >> (16 - index[0])); + temp[0] <<= 8; + input = this.stream.get8(); + + if (input === 0xFF) { + this.marker = this.stream.get8(); + if (this.marker !== 0) { + this.markerIndex = 9; + } + } + + temp[0] |= input; + code = table[((code & 0xFF) * 256) + (temp[0] >> index[0])]; + index[0] += 8; + } + + index[0] += 8 - (code >> 8); + + if (index[0] < 0) { + throw new Error("index=" + index[0] + " temp=" + temp[0] + " code=" + code + " in HuffmanValue()"); + } + + if (index[0] < this.markerIndex) { + this.markerIndex = 0; + return 0xFF00 | this.marker; + } + + temp[0] &= (mask >> (16 - index[0])); + return code & 0xFF; +}; + + + +jpeg.lossless.Decoder.prototype.getn = function (PRED, n, temp, index) { + /*jslint bitwise: true */ + + var result, one, n_one, mask, input; + one = 1; + n_one = -1; + mask = 0xFFFF; + + if (n === 0) { + return 0; + } + + if (n === 16) { + if (PRED[0] >= 0) { + return -32768; + } else { + return 32768; + } + } + + index[0] -= n; + + if (index[0] >= 0) { + if ((index[0] < this.markerIndex) && !this.isLastPixel()) { // this was corrupting the last pixel in some cases + this.markerIndex = 0; + return (0xFF00 | this.marker) << 8; + } + + result = temp[0] >> index[0]; + temp[0] &= (mask >> (16 - index[0])); + } else { + temp[0] <<= 8; + input = this.stream.get8(); + + if (input === 0xFF) { + this.marker = this.stream.get8(); + if (this.marker !== 0) { + this.markerIndex = 9; + } + } + + temp[0] |= input; + index[0] += 8; + + if (index[0] < 0) { + if (this.markerIndex !== 0) { + this.markerIndex = 0; + return (0xFF00 | this.marker) << 8; + } + + temp[0] <<= 8; + input = this.stream.get8(); + + if (input === 0xFF) { + this.marker = this.stream.get8(); + if (this.marker !== 0) { + this.markerIndex = 9; + } + } + + temp[0] |= input; + index[0] += 8; + } + + if (index[0] < 0) { + throw new Error("index=" + index[0] + " in getn()"); + } + + if (index[0] < this.markerIndex) { + this.markerIndex = 0; + return (0xFF00 | this.marker) << 8; + } + + result = temp[0] >> index[0]; + temp[0] &= (mask >> (16 - index[0])); + } + + if (result < (one << (n - 1))) { + result += (n_one << n) + 1; + } + + return result; +}; + + + +jpeg.lossless.Decoder.prototype.getPreviousX = function (compOffset) { + /*jslint bitwise: true */ + + if (this.xLoc > 0) { + return this.getter((((this.yLoc * this.xDim) + this.xLoc) - 1), compOffset); + } else if (this.yLoc > 0) { + return this.getPreviousY(compOffset); + } else { + return (1 << (this.frame.precision - 1)); + } +}; + + + +jpeg.lossless.Decoder.prototype.getPreviousXY = function (compOffset) { + /*jslint bitwise: true */ + + if ((this.xLoc > 0) && (this.yLoc > 0)) { + return this.getter(((((this.yLoc - 1) * this.xDim) + this.xLoc) - 1), compOffset); + } else { + return this.getPreviousY(compOffset); + } +}; + + + +jpeg.lossless.Decoder.prototype.getPreviousY = function (compOffset) { + /*jslint bitwise: true */ + + if (this.yLoc > 0) { + return this.getter((((this.yLoc - 1) * this.xDim) + this.xLoc), compOffset); + } else { + return this.getPreviousX(compOffset); + } +}; + + + +jpeg.lossless.Decoder.prototype.isLastPixel = function () { + return (this.xLoc === (this.xDim - 1)) && (this.yLoc === (this.yDim - 1)); +}; + + + +jpeg.lossless.Decoder.prototype.outputSingle = function (PRED) { + if ((this.xLoc < this.xDim) && (this.yLoc < this.yDim)) { + this.setter((((this.yLoc * this.xDim) + this.xLoc)), PRED[0]); + + this.xLoc+=1; + + if (this.xLoc >= this.xDim) { + this.yLoc+=1; + this.xLoc = 0; + } + } +}; + + + +jpeg.lossless.Decoder.prototype.outputRGB = function (PRED) { + var offset = ((this.yLoc * this.xDim) + this.xLoc); + + if ((this.xLoc < this.xDim) && (this.yLoc < this.yDim)) { + this.setter(offset, PRED[0], 0); + this.setter(offset, PRED[1], 1); + this.setter(offset, PRED[2], 2); + + this.xLoc+=1; + + if (this.xLoc >= this.xDim) { + this.yLoc+=1; + this.xLoc = 0; + } + } +}; + + + +jpeg.lossless.Decoder.prototype.setValue16 = function (index, val) { + this.outputData.setInt16(index * 2, val, true); +}; + + + +jpeg.lossless.Decoder.prototype.getValue16 = function (index) { + return this.outputData.getInt16(index * 2, true); +}; + + + +jpeg.lossless.Decoder.prototype.setValue8 = function (index, val) { + this.outputData.setInt8(index, val); +}; + + + +jpeg.lossless.Decoder.prototype.getValue8 = function (index) { + return this.outputData.getInt8(index); +}; + + + +jpeg.lossless.Decoder.prototype.setValueRGB = function (index, val, compOffset) { + this.outputData.setUint8(index * 3 + compOffset, val); +}; + + + +jpeg.lossless.Decoder.prototype.getValueRGB = function (index, compOffset) { + return this.outputData.getUint8(index * 3 + compOffset); +}; + + + +jpeg.lossless.Decoder.prototype.readApp = function() { + var count = 0, length = this.stream.get16(); + count += 2; + + while (count < length) { + this.stream.get8(); + count+=1; + } + + return length; +}; + + + +jpeg.lossless.Decoder.prototype.readComment = function () { + var sb = "", count = 0, length; + + length = this.stream.get16(); + count += 2; + + while (count < length) { + sb += this.stream.get8(); + count+=1; + } + + return sb; +}; + + + +jpeg.lossless.Decoder.prototype.readNumber = function() { + var Ld = this.stream.get16(); + + if (Ld !== 4) { + throw new Error("ERROR: Define number format throw new IOException [Ld!=4]"); + } + + return this.stream.get16(); +}; + + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.Decoder; +} + +},{"./data-stream.js":2,"./frame-header.js":4,"./huffman-table.js":5,"./quantization-table.js":7,"./scan-header.js":9,"./utils.js":10}],4:[function(require,module,exports){ +/* + * Copyright (C) 2015 Michael Martinez + * Changes: Added support for selection values 2-7, fixed minor bugs & + * warnings, split into multiple class files, and general clean up. + * + * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT. + */ + +/* + * Copyright (C) Helmut Dersch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; +jpeg.lossless.ComponentSpec = jpeg.lossless.ComponentSpec || ((typeof require !== 'undefined') ? require('./component-spec.js') : null); +jpeg.lossless.DataStream = jpeg.lossless.DataStream || ((typeof require !== 'undefined') ? require('./data-stream.js') : null); + + +/*** Constructor ***/ +jpeg.lossless.FrameHeader = jpeg.lossless.FrameHeader || function () { + this.components = []; // Components + this.dimX = 0; // Number of samples per line + this.dimY = 0; // Number of lines + this.numComp = 0; // Number of component in the frame + this.precision = 0; // Sample Precision (from the original image) +}; + + + +/*** Prototype Methods ***/ + +jpeg.lossless.FrameHeader.prototype.read = function (data) { + /*jslint bitwise: true */ + + var count = 0, length, i, c, temp; + + length = data.get16(); + count += 2; + + this.precision = data.get8(); + count+=1; + + this.dimY = data.get16(); + count += 2; + + this.dimX = data.get16(); + count += 2; + + this.numComp = data.get8(); + count+=1; + for (i = 1; i <= this.numComp; i+=1) { + if (count > length) { + throw new Error("ERROR: frame format error"); + } + + c = data.get8(); + count+=1; + + if (count >= length) { + throw new Error("ERROR: frame format error [c>=Lf]"); + } + + temp = data.get8(); + count+=1; + + if (!this.components[c]) { + this.components[c] = new jpeg.lossless.ComponentSpec(); + } + + this.components[c].hSamp = temp >> 4; + this.components[c].vSamp = temp & 0x0F; + this.components[c].quantTableSel = data.get8(); + count+=1; + } + + if (count !== length) { + throw new Error("ERROR: frame format error [Lf!=count]"); + } + + return 1; +}; + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.FrameHeader; +} + +},{"./component-spec.js":1,"./data-stream.js":2}],5:[function(require,module,exports){ +/* + * Copyright (C) 2015 Michael Martinez + * Changes: Added support for selection values 2-7, fixed minor bugs & + * warnings, split into multiple class files, and general clean up. + * + * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT. + */ + +/* + * Copyright (C) Helmut Dersch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; +jpeg.lossless.DataStream = jpeg.lossless.DataStream || ((typeof require !== 'undefined') ? require('./data-stream.js') : null); +jpeg.lossless.Utils = jpeg.lossless.Utils || ((typeof require !== 'undefined') ? require('./utils.js') : null); + + +/*** Constructor ***/ +jpeg.lossless.HuffmanTable = jpeg.lossless.HuffmanTable || function () { + this.l = jpeg.lossless.Utils.createArray(4, 2, 16); + this.th = []; + this.v = jpeg.lossless.Utils.createArray(4, 2, 16, 200); + this.tc = jpeg.lossless.Utils.createArray(4, 2); + + this.tc[0][0] = 0; + this.tc[1][0] = 0; + this.tc[2][0] = 0; + this.tc[3][0] = 0; + this.tc[0][1] = 0; + this.tc[1][1] = 0; + this.tc[2][1] = 0; + this.tc[3][1] = 0; + this.th[0] = 0; + this.th[1] = 0; + this.th[2] = 0; + this.th[3] = 0; +}; + + + +/*** Static Pseudo-constants ***/ + +jpeg.lossless.HuffmanTable.MSB = 0x80000000; + + +/*** Prototype Methods ***/ + +jpeg.lossless.HuffmanTable.prototype.read = function(data, HuffTab) { + /*jslint bitwise: true */ + + var count = 0, length, temp, t, c, i, j; + + length = data.get16(); + count += 2; + + while (count < length) { + temp = data.get8(); + count+=1; + t = temp & 0x0F; + if (t > 3) { + throw new Error("ERROR: Huffman table ID > 3"); + } + + c = temp >> 4; + if (c > 2) { + throw new Error("ERROR: Huffman table [Table class > 2 ]"); + } + + this.th[t] = 1; + this.tc[t][c] = 1; + + for (i = 0; i < 16; i+=1) { + this.l[t][c][i] = data.get8(); + count+=1; + } + + for (i = 0; i < 16; i+=1) { + for (j = 0; j < this.l[t][c][i]; j+=1) { + if (count > length) { + throw new Error("ERROR: Huffman table format error [count>Lh]"); + } + + this.v[t][c][i][j] = data.get8(); + count+=1; + } + } + } + + if (count !== length) { + throw new Error("ERROR: Huffman table format error [count!=Lf]"); + } + + for (i = 0; i < 4; i+=1) { + for (j = 0; j < 2; j+=1) { + if (this.tc[i][j] !== 0) { + this.buildHuffTable(HuffTab[i][j], this.l[i][j], this.v[i][j]); + } + } + } + + return 1; +}; + + + +// Build_HuffTab() +// Parameter: t table ID +// c table class ( 0 for DC, 1 for AC ) +// L[i] # of codewords which length is i +// V[i][j] Huffman Value (length=i) +// Effect: +// build up HuffTab[t][c] using L and V. +jpeg.lossless.HuffmanTable.prototype.buildHuffTable = function(tab, L, V) { + /*jslint bitwise: true */ + + var currentTable, temp, k, i, j, n; + temp = 256; + k = 0; + + for (i = 0; i < 8; i+=1) { // i+1 is Code length + for (j = 0; j < L[i]; j+=1) { + for (n = 0; n < (temp >> (i + 1)); n+=1) { + tab[k] = V[i][j] | ((i + 1) << 8); + k+=1; + } + } + } + + for (i = 1; k < 256; i+=1, k+=1) { + tab[k] = i | jpeg.lossless.HuffmanTable.MSB; + } + + currentTable = 1; + k = 0; + + for (i = 8; i < 16; i+=1) { // i+1 is Code length + for (j = 0; j < L[i]; j+=1) { + for (n = 0; n < (temp >> (i - 7)); n+=1) { + tab[(currentTable * 256) + k] = V[i][j] | ((i + 1) << 8); + k+=1; + } + + if (k >= 256) { + if (k > 256) { + throw new Error("ERROR: Huffman table error(1)!"); + } + + k = 0; + currentTable+=1; + } + } + } +}; + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.HuffmanTable; +} + +},{"./data-stream.js":2,"./utils.js":10}],6:[function(require,module,exports){ +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; +jpeg.lossless.ComponentSpec = jpeg.lossless.ComponentSpec || ((typeof require !== 'undefined') ? require('./component-spec.js') : null); +jpeg.lossless.DataStream = jpeg.lossless.DataStream || ((typeof require !== 'undefined') ? require('./data-stream.js') : null); +jpeg.lossless.Decoder = jpeg.lossless.Decoder || ((typeof require !== 'undefined') ? require('./decoder.js') : null); +jpeg.lossless.FrameHeader = jpeg.lossless.FrameHeader || ((typeof require !== 'undefined') ? require('./frame-header.js') : null); +jpeg.lossless.HuffmanTable = jpeg.lossless.HuffmanTable || ((typeof require !== 'undefined') ? require('./huffman-table.js') : null); +jpeg.lossless.QuantizationTable = jpeg.lossless.QuantizationTable || ((typeof require !== 'undefined') ? require('./quantization-table.js') : null); +jpeg.lossless.ScanComponent = jpeg.lossless.ScanComponent || ((typeof require !== 'undefined') ? require('./scan-component.js') : null); +jpeg.lossless.ScanHeader = jpeg.lossless.ScanHeader || ((typeof require !== 'undefined') ? require('./scan-header.js') : null); +jpeg.lossless.Utils = jpeg.lossless.Utils || ((typeof require !== 'undefined') ? require('./utils.js') : null); + + +/*** Exports ***/ +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg; +} + +},{"./component-spec.js":1,"./data-stream.js":2,"./decoder.js":3,"./frame-header.js":4,"./huffman-table.js":5,"./quantization-table.js":7,"./scan-component.js":8,"./scan-header.js":9,"./utils.js":10}],7:[function(require,module,exports){ +/* + * Copyright (C) 2015 Michael Martinez + * Changes: Added support for selection values 2-7, fixed minor bugs & + * warnings, split into multiple class files, and general clean up. + * + * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT. + */ + +/* + * Copyright (C) Helmut Dersch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; +jpeg.lossless.DataStream = jpeg.lossless.DataStream || ((typeof require !== 'undefined') ? require('./data-stream.js') : null); +jpeg.lossless.Utils = jpeg.lossless.Utils || ((typeof require !== 'undefined') ? require('./utils.js') : null); + + +/*** Constructor ***/ +jpeg.lossless.QuantizationTable = jpeg.lossless.QuantizationTable || function () { + this.precision = []; // Quantization precision 8 or 16 + this.tq = []; // 1: this table is presented + this.quantTables = jpeg.lossless.Utils.createArray(4, 64); // Tables + + this.tq[0] = 0; + this.tq[1] = 0; + this.tq[2] = 0; + this.tq[3] = 0; +}; + + + +/*** Static Methods ***/ + +jpeg.lossless.QuantizationTable.enhanceQuantizationTable = function(qtab, table) { + /*jslint bitwise: true */ + + var i; + + for (i = 0; i < 8; i+=1) { + qtab[table[(0 * 8) + i]] *= 90; + qtab[table[(4 * 8) + i]] *= 90; + qtab[table[(2 * 8) + i]] *= 118; + qtab[table[(6 * 8) + i]] *= 49; + qtab[table[(5 * 8) + i]] *= 71; + qtab[table[(1 * 8) + i]] *= 126; + qtab[table[(7 * 8) + i]] *= 25; + qtab[table[(3 * 8) + i]] *= 106; + } + + for (i = 0; i < 8; i+=1) { + qtab[table[0 + (8 * i)]] *= 90; + qtab[table[4 + (8 * i)]] *= 90; + qtab[table[2 + (8 * i)]] *= 118; + qtab[table[6 + (8 * i)]] *= 49; + qtab[table[5 + (8 * i)]] *= 71; + qtab[table[1 + (8 * i)]] *= 126; + qtab[table[7 + (8 * i)]] *= 25; + qtab[table[3 + (8 * i)]] *= 106; + } + + for (i = 0; i < 64; i+=1) { + qtab[i] >>= 6; + } +}; + + +/*** Prototype Methods ***/ + +jpeg.lossless.QuantizationTable.prototype.read = function (data, table) { + /*jslint bitwise: true */ + + var count = 0, length, temp, t, i; + + length = data.get16(); + count += 2; + + while (count < length) { + temp = data.get8(); + count+=1; + t = temp & 0x0F; + + if (t > 3) { + throw new Error("ERROR: Quantization table ID > 3"); + } + + this.precision[t] = temp >> 4; + + if (this.precision[t] === 0) { + this.precision[t] = 8; + } else if (this.precision[t] === 1) { + this.precision[t] = 16; + } else { + throw new Error("ERROR: Quantization table precision error"); + } + + this.tq[t] = 1; + + if (this.precision[t] === 8) { + for (i = 0; i < 64; i+=1) { + if (count > length) { + throw new Error("ERROR: Quantization table format error"); + } + + this.quantTables[t][i] = data.get8(); + count+=1; + } + + jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t], table); + } else { + for (i = 0; i < 64; i+=1) { + if (count > length) { + throw new Error("ERROR: Quantization table format error"); + } + + this.quantTables[t][i] = data.get16(); + count += 2; + } + + jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t], table); + } + } + + if (count !== length) { + throw new Error("ERROR: Quantization table error [count!=Lq]"); + } + + return 1; +}; + + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.QuantizationTable; +} + +},{"./data-stream.js":2,"./utils.js":10}],8:[function(require,module,exports){ +/* + * Copyright (C) 2015 Michael Martinez + * Changes: Added support for selection values 2-7, fixed minor bugs & + * warnings, split into multiple class files, and general clean up. + * + * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT. + */ + +/* + * Copyright (C) Helmut Dersch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; + + +/*** Constructor ***/ +jpeg.lossless.ScanComponent = jpeg.lossless.ScanComponent || function () { + this.acTabSel = 0; // AC table selector + this.dcTabSel = 0; // DC table selector + this.scanCompSel = 0; // Scan component selector +}; + + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.ScanComponent; +} + +},{}],9:[function(require,module,exports){ +/* + * Copyright (C) 2015 Michael Martinez + * Changes: Added support for selection values 2-7, fixed minor bugs & + * warnings, split into multiple class files, and general clean up. + * + * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT. + */ + +/* + * Copyright (C) Helmut Dersch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; +jpeg.lossless.DataStream = jpeg.lossless.DataStream || ((typeof require !== 'undefined') ? require('./data-stream.js') : null); +jpeg.lossless.ScanComponent = jpeg.lossless.ScanComponent || ((typeof require !== 'undefined') ? require('./scan-component.js') : null); + + +/*** Constructor ***/ +jpeg.lossless.ScanHeader = jpeg.lossless.ScanHeader || function () { + this.ah = 0; + this.al = 0; + this.numComp = 0; // Number of components in the scan + this.selection = 0; // Start of spectral or predictor selection + this.spectralEnd = 0; // End of spectral selection + this.components = []; +}; + + +/*** Prototype Methods ***/ + +jpeg.lossless.ScanHeader.prototype.read = function(data) { + /*jslint bitwise: true */ + + var count = 0, length, i, temp; + + length = data.get16(); + count += 2; + + this.numComp = data.get8(); + count+=1; + + for (i = 0; i < this.numComp; i+=1) { + this.components[i] = new jpeg.lossless.ScanComponent(); + + if (count > length) { + throw new Error("ERROR: scan header format error"); + } + + this.components[i].scanCompSel = data.get8(); + count+=1; + + temp = data.get8(); + count+=1; + + this.components[i].dcTabSel = (temp >> 4); + this.components[i].acTabSel = (temp & 0x0F); + } + + this.selection = data.get8(); + count+=1; + + this.spectralEnd = data.get8(); + count+=1; + + temp = data.get8(); + this.ah = (temp >> 4); + this.al = (temp & 0x0F); + count+=1; + + if (count !== length) { + throw new Error("ERROR: scan header format error [count!=Ns]"); + } + + return 1; +}; + + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.ScanHeader; +} + +},{"./data-stream.js":2,"./scan-component.js":8}],10:[function(require,module,exports){ +/* + * Copyright (C) 2015 Michael Martinez + * Changes: Added support for selection values 2-7, fixed minor bugs & + * warnings, split into multiple class files, and general clean up. + * + * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT. + */ + +/* + * Copyright (C) Helmut Dersch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/*jslint browser: true, node: true */ +/*global require, module */ + +"use strict"; + +/*** Imports ***/ +var jpeg = jpeg || {}; +jpeg.lossless = jpeg.lossless || {}; + + +/*** Constructor ***/ +jpeg.lossless.Utils = jpeg.lossless.Utils || {}; + + +/*** Static methods ***/ + +// http://stackoverflow.com/questions/966225/how-can-i-create-a-two-dimensional-array-in-javascript +jpeg.lossless.Utils.createArray = function (length) { + var arr = new Array(length || 0), + i = length; + + if (arguments.length > 1) { + var args = Array.prototype.slice.call(arguments, 1); + while(i--) arr[length-1 - i] = jpeg.lossless.Utils.createArray.apply(this, args); + } + + return arr; +}; + + +/*** Exports ***/ + +var moduleType = typeof module; +if ((moduleType !== 'undefined') && module.exports) { + module.exports = jpeg.lossless.Utils; +} + +},{}]},{},[6])(6) +}); \ No newline at end of file diff --git a/release/current/lossless-min.js b/release/current/lossless-min.js index 2ca10ef..05f281e 100644 --- a/release/current/lossless-min.js +++ b/release/current/lossless-min.js @@ -1 +1 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jpeg=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>4!==4092||current===65476){switch(current){case 65476:this.huffTable.read(this.stream,this.HuffTab);break;case 65484:throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)");case 65499:this.quantTable.read(this.stream,jpeg.lossless.Decoder.TABLE);break;case 65501:this.restartInterval=this.readNumber();break;case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:this.readApp();break;case 65534:this.readComment();break;default:if(current>>8!==255){throw new Error("ERROR: format throw new IOException! (decode)")}}current=this.stream.get16()}if(current<65472||current>65479){throw new Error("ERROR: could not handle arithmetic code!")}this.frame.read(this.stream);current=this.stream.get16();do{while(current!==65498){switch(current){case 65476:this.huffTable.read(this.stream,this.HuffTab);break;case 65484:throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)");case 65499:this.quantTable.read(this.stream,jpeg.lossless.Decoder.TABLE);break;case 65501:this.restartInterval=this.readNumber();break;case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:this.readApp();break;case 65534:this.readComment();break;default:if(current>>8!==255){throw new Error("ERROR: format throw new IOException! (Parser.decode)")}}current=this.stream.get16()}this.precision=this.frame.precision;this.components=this.frame.components;if(!this.numBytes){this.numBytes=parseInt(this.precision/8)}this.scan.read(this.stream);this.numComp=this.scan.numComp;this.selection=this.scan.selection;if(this.numBytes===1){if(this.numComp===3){this.getter=this.getValueRGB;this.setter=this.setValueRGB;this.output=this.outputRGB}else{this.getter=this.getValue8;this.setter=this.setValue8;this.output=this.outputSingle}}else{this.getter=this.getValue16;this.setter=this.setValue16;this.output=this.outputSingle}switch(this.selection){case 2:this.selector=this.select2;break;case 3:this.selector=this.select3;break;case 4:this.selector=this.select4;break;case 5:this.selector=this.select5;break;case 6:this.selector=this.select6;break;case 7:this.selector=this.select7;break;default:this.selector=this.select1;break}this.scanComps=this.scan.components;this.quantTables=this.quantTable.quantTables;for(i=0;i=65488&¤t<=65495)){break}}if(current===65500&&scanNum===1){this.readNumber();current=this.stream.get16()}}while(current!==65497&&(this.xLoc>1)};jpeg.lossless.Decoder.prototype.select6=function(compOffset){return this.getPreviousY(compOffset)+(this.getPreviousX(compOffset)-this.getPreviousXY(compOffset)>>1)};jpeg.lossless.Decoder.prototype.select7=function(compOffset){return(this.getPreviousX(compOffset)+this.getPreviousY(compOffset))/2};jpeg.lossless.Decoder.prototype.decodeRGB=function(prev,temp,index){var value,actab,dctab,qtab,ctrC,i,k,j;prev[0]=this.selector(0);prev[1]=this.selector(1);prev[2]=this.selector(2);for(ctrC=0;ctrC=65280){return value}prev[ctrC]=this.IDCT_Source[0]=prev[ctrC]+this.getn(index,value,temp,index);this.IDCT_Source[0]*=qtab[0];for(j=1;j<64;j+=1){value=this.getHuffmanValue(actab,temp,index);if(value>=65280){return value}j+=value>>4;if((value&15)===0){if(value>>4===0){break}}else{this.IDCT_Source[jpeg.lossless.Decoder.IDCT_P[j]]=this.getn(index,value&15,temp,index)*qtab[j]}}}}return 0};jpeg.lossless.Decoder.prototype.decodeSingle=function(prev,temp,index){var value,i;prev[0]=this.selector();for(i=0;i=65280){return value}prev[0]+=this.getn(prev,value,temp,index)}return 0};jpeg.lossless.Decoder.prototype.getHuffmanValue=function(table,temp,index){var code,input,mask;mask=65535;if(index[0]<8){temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input}else{index[0]-=8}code=table[temp[0]>>index[0]];if((code&jpeg.lossless.Decoder.MSB)!==0){if(this.markerIndex!==0){this.markerIndex=0;return 65280|this.marker}temp[0]&=mask>>16-index[0];temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;code=table[(code&255)*256+(temp[0]>>index[0])];index[0]+=8}index[0]+=8-(code>>8);if(index[0]<0){throw new Error("index="+index[0]+" temp="+temp[0]+" code="+code+" in HuffmanValue()")}if(index[0]>16-index[0];return code&255};jpeg.lossless.Decoder.prototype.getn=function(PRED,n,temp,index){var result,one,n_one,mask,input;one=1;n_one=-1;mask=65535;if(n===0){return 0}if(n===16){if(PRED[0]>=0){return-32768}else{return 32768}}index[0]-=n;if(index[0]>=0){if(index[0]>index[0];temp[0]&=mask>>16-index[0]}else{temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;index[0]+=8;if(index[0]<0){if(this.markerIndex!==0){this.markerIndex=0;return(65280|this.marker)<<8}temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;index[0]+=8}if(index[0]<0){throw new Error("index="+index[0]+" in getn()")}if(index[0]>index[0];temp[0]&=mask>>16-index[0]}if(result0){return this.getter(this.yLoc*this.xDim+this.xLoc-1,compOffset)}else if(this.yLoc>0){return this.getPreviousY(compOffset)}else{return 1<0&&this.yLoc>0){return this.getter((this.yLoc-1)*this.xDim+this.xLoc-1,compOffset)}else{return this.getPreviousY(compOffset)}};jpeg.lossless.Decoder.prototype.getPreviousY=function(compOffset){if(this.yLoc>0){return this.getter((this.yLoc-1)*this.xDim+this.xLoc,compOffset)}else{return this.getPreviousX(compOffset)}};jpeg.lossless.Decoder.prototype.isLastPixel=function(){return this.xLoc===this.xDim-1&&this.yLoc===this.yDim-1};jpeg.lossless.Decoder.prototype.outputSingle=function(PRED){if(this.xLoc=this.xDim){this.yLoc+=1;this.xLoc=0}}};jpeg.lossless.Decoder.prototype.outputRGB=function(PRED){var offset=this.yLoc*this.xDim+this.xLoc;if(this.xLoc=this.xDim){this.yLoc+=1;this.xLoc=0}}};jpeg.lossless.Decoder.prototype.setValue16=function(index,val){this.outputData.setInt16(index*2,val,true)};jpeg.lossless.Decoder.prototype.getValue16=function(index){return this.outputData.getInt16(index*2,true)};jpeg.lossless.Decoder.prototype.setValue8=function(index,val){this.outputData.setInt8(index,val)};jpeg.lossless.Decoder.prototype.getValue8=function(index){return this.outputData.getInt8(index)};jpeg.lossless.Decoder.prototype.setValueRGB=function(index,val,compOffset){this.outputData.setUint8(index*3+compOffset,val)};jpeg.lossless.Decoder.prototype.getValueRGB=function(index,compOffset){return this.outputData.getUint8(index*3+compOffset)};jpeg.lossless.Decoder.prototype.readApp=function(){var count=0,length=this.stream.get16();count+=2;while(countlength){throw new Error("ERROR: frame format error")}c=data.get8();count+=1;if(count>=length){throw new Error("ERROR: frame format error [c>=Lf]")}temp=data.get8();count+=1;if(!this.components[c]){this.components[c]=new jpeg.lossless.ComponentSpec}this.components[c].hSamp=temp>>4;this.components[c].vSamp=temp&15;this.components[c].quantTableSel=data.get8();count+=1}if(count!==length){throw new Error("ERROR: frame format error [Lf!=count]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.FrameHeader}},{"./component-spec.js":1,"./data-stream.js":2}],5:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);jpeg.lossless.HuffmanTable=jpeg.lossless.HuffmanTable||function(){this.l=jpeg.lossless.Utils.createArray(4,2,16);this.th=[];this.v=jpeg.lossless.Utils.createArray(4,2,16,200);this.tc=jpeg.lossless.Utils.createArray(4,2);this.tc[0][0]=0;this.tc[1][0]=0;this.tc[2][0]=0;this.tc[3][0]=0;this.tc[0][1]=0;this.tc[1][1]=0;this.tc[2][1]=0;this.tc[3][1]=0;this.th[0]=0;this.th[1]=0;this.th[2]=0;this.th[3]=0};jpeg.lossless.HuffmanTable.MSB=2147483648;jpeg.lossless.HuffmanTable.prototype.read=function(data,HuffTab){var count=0,length,temp,t,c,i,j;length=data.get16();count+=2;while(count3){throw new Error("ERROR: Huffman table ID > 3")}c=temp>>4;if(c>2){throw new Error("ERROR: Huffman table [Table class > 2 ]")}this.th[t]=1;this.tc[t][c]=1;for(i=0;i<16;i+=1){this.l[t][c][i]=data.get8();count+=1}for(i=0;i<16;i+=1){for(j=0;jlength){throw new Error("ERROR: Huffman table format error [count>Lh]")}this.v[t][c][i][j]=data.get8();count+=1}}}if(count!==length){throw new Error("ERROR: Huffman table format error [count!=Lf]")}for(i=0;i<4;i+=1){for(j=0;j<2;j+=1){if(this.tc[i][j]!==0){this.buildHuffTable(HuffTab[i][j],this.l[i][j],this.v[i][j])}}}return 1};jpeg.lossless.HuffmanTable.prototype.buildHuffTable=function(tab,L,V){var currentTable,temp,k,i,j,n;temp=256;k=0;for(i=0;i<8;i+=1){for(j=0;j>i+1;n+=1){tab[k]=V[i][j]|i+1<<8;k+=1}}}for(i=1;k<256;i+=1,k+=1){tab[k]=i|jpeg.lossless.HuffmanTable.MSB}currentTable=1;k=0;for(i=8;i<16;i+=1){for(j=0;j>i-7;n+=1){tab[currentTable*256+k]=V[i][j]|i+1<<8;k+=1}if(k>=256){if(k>256){throw new Error("ERROR: Huffman table error(1)!")}k=0;currentTable+=1}}}};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.HuffmanTable}},{"./data-stream.js":2,"./utils.js":10}],6:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.ComponentSpec=jpeg.lossless.ComponentSpec||(typeof require!=="undefined"?require("./component-spec.js"):null);jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Decoder=jpeg.lossless.Decoder||(typeof require!=="undefined"?require("./decoder.js"):null);jpeg.lossless.FrameHeader=jpeg.lossless.FrameHeader||(typeof require!=="undefined"?require("./frame-header.js"):null);jpeg.lossless.HuffmanTable=jpeg.lossless.HuffmanTable||(typeof require!=="undefined"?require("./huffman-table.js"):null);jpeg.lossless.QuantizationTable=jpeg.lossless.QuantizationTable||(typeof require!=="undefined"?require("./quantization-table.js"):null);jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||(typeof require!=="undefined"?require("./scan-component.js"):null);jpeg.lossless.ScanHeader=jpeg.lossless.ScanHeader||(typeof require!=="undefined"?require("./scan-header.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg}},{"./component-spec.js":1,"./data-stream.js":2,"./decoder.js":3,"./frame-header.js":4,"./huffman-table.js":5,"./quantization-table.js":7,"./scan-component.js":8,"./scan-header.js":9,"./utils.js":10}],7:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);jpeg.lossless.QuantizationTable=jpeg.lossless.QuantizationTable||function(){this.precision=[];this.tq=[];this.quantTables=jpeg.lossless.Utils.createArray(4,64);this.tq[0]=0;this.tq[1]=0;this.tq[2]=0;this.tq[3]=0};jpeg.lossless.QuantizationTable.enhanceQuantizationTable=function(qtab,table){var i;for(i=0;i<8;i+=1){qtab[table[0*8+i]]*=90;qtab[table[4*8+i]]*=90;qtab[table[2*8+i]]*=118;qtab[table[6*8+i]]*=49;qtab[table[5*8+i]]*=71;qtab[table[1*8+i]]*=126;qtab[table[7*8+i]]*=25;qtab[table[3*8+i]]*=106}for(i=0;i<8;i+=1){qtab[table[0+8*i]]*=90;qtab[table[4+8*i]]*=90;qtab[table[2+8*i]]*=118;qtab[table[6+8*i]]*=49;qtab[table[5+8*i]]*=71;qtab[table[1+8*i]]*=126;qtab[table[7+8*i]]*=25;qtab[table[3+8*i]]*=106}for(i=0;i<64;i+=1){qtab[i]>>=6}};jpeg.lossless.QuantizationTable.prototype.read=function(data,table){var count=0,length,temp,t,i;length=data.get16();count+=2;while(count3){throw new Error("ERROR: Quantization table ID > 3")}this.precision[t]=temp>>4;if(this.precision[t]===0){this.precision[t]=8}else if(this.precision[t]===1){this.precision[t]=16}else{throw new Error("ERROR: Quantization table precision error")}this.tq[t]=1;if(this.precision[t]===8){for(i=0;i<64;i+=1){if(count>length){throw new Error("ERROR: Quantization table format error")}this.quantTables[t][i]=data.get8();count+=1}jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t],table)}else{for(i=0;i<64;i+=1){if(count>length){throw new Error("ERROR: Quantization table format error")}this.quantTables[t][i]=data.get16();count+=2}jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t],table)}}if(count!==length){throw new Error("ERROR: Quantization table error [count!=Lq]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.QuantizationTable}},{"./data-stream.js":2,"./utils.js":10}],8:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||function(){this.acTabSel=0;this.dcTabSel=0;this.scanCompSel=0};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.ScanComponent}},{}],9:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||(typeof require!=="undefined"?require("./scan-component.js"):null);jpeg.lossless.ScanHeader=jpeg.lossless.ScanHeader||function(){this.ah=0;this.al=0;this.numComp=0;this.selection=0;this.spectralEnd=0;this.components=[]};jpeg.lossless.ScanHeader.prototype.read=function(data){var count=0,length,i,temp;length=data.get16();count+=2;this.numComp=data.get8();count+=1;for(i=0;ilength){throw new Error("ERROR: scan header format error")}this.components[i].scanCompSel=data.get8();count+=1;temp=data.get8();count+=1;this.components[i].dcTabSel=temp>>4;this.components[i].acTabSel=temp&15}this.selection=data.get8();count+=1;this.spectralEnd=data.get8();count+=1;temp=data.get8();this.ah=temp>>4;this.al=temp&15;count+=1;if(count!==length){throw new Error("ERROR: scan header format error [count!=Ns]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.ScanHeader}},{"./data-stream.js":2,"./scan-component.js":8}],10:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.Utils=jpeg.lossless.Utils||{};jpeg.lossless.Utils.createArray=function(length){var arr=new Array(length||0),i=length;if(arguments.length>1){var args=Array.prototype.slice.call(arguments,1);while(i--)arr[length-1-i]=jpeg.lossless.Utils.createArray.apply(this,args)}return arr};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.Utils}},{}]},{},[6])(6)}); \ No newline at end of file +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jpeg=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>4!==4092||current===65476){switch(current){case 65476:this.huffTable.read(this.stream,this.HuffTab);break;case 65484:throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)");case 65499:this.quantTable.read(this.stream,jpeg.lossless.Decoder.TABLE);break;case 65501:this.restartInterval=this.readNumber();break;case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:this.readApp();break;case 65534:this.readComment();break;default:if(current>>8!==255){throw new Error("ERROR: format throw new IOException! (decode)")}}current=this.stream.get16()}if(current<65472||current>65479){throw new Error("ERROR: could not handle arithmetic code!")}this.frame.read(this.stream);current=this.stream.get16();do{while(current!==65498){switch(current){case 65476:this.huffTable.read(this.stream,this.HuffTab);break;case 65484:throw new Error("Program doesn't support arithmetic coding. (format throw new IOException)");case 65499:this.quantTable.read(this.stream,jpeg.lossless.Decoder.TABLE);break;case 65501:this.restartInterval=this.readNumber();break;case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:this.readApp();break;case 65534:this.readComment();break;default:if(current>>8!==255){throw new Error("ERROR: format throw new IOException! (Parser.decode)")}}current=this.stream.get16()}this.precision=this.frame.precision;this.components=this.frame.components;if(!this.numBytes){this.numBytes=parseInt(this.precision/8)}this.scan.read(this.stream);this.numComp=this.scan.numComp;this.selection=this.scan.selection;if(this.numBytes===1){if(this.numComp===3){this.getter=this.getValueRGB;this.setter=this.setValueRGB;this.output=this.outputRGB}else{this.getter=this.getValue8;this.setter=this.setValue8;this.output=this.outputSingle}}else{this.getter=this.getValue16;this.setter=this.setValue16;this.output=this.outputSingle}switch(this.selection){case 2:this.selector=this.select2;break;case 3:this.selector=this.select3;break;case 4:this.selector=this.select4;break;case 5:this.selector=this.select5;break;case 6:this.selector=this.select6;break;case 7:this.selector=this.select7;break;default:this.selector=this.select1;break}this.scanComps=this.scan.components;this.quantTables=this.quantTable.quantTables;for(i=0;i=jpeg.lossless.Decoder.RESTART_MARKER_BEGIN&¤t<=jpeg.lossless.Decoder.RESTART_MARKER_END)){break}}if(current===65500&&scanNum===1){this.readNumber();current=this.stream.get16()}}while(current!==65497&&(this.xLoc>1)};jpeg.lossless.Decoder.prototype.select6=function(compOffset){return this.getPreviousY(compOffset)+(this.getPreviousX(compOffset)-this.getPreviousXY(compOffset)>>1)};jpeg.lossless.Decoder.prototype.select7=function(compOffset){return(this.getPreviousX(compOffset)+this.getPreviousY(compOffset))/2};jpeg.lossless.Decoder.prototype.decodeRGB=function(prev,temp,index){var value,actab,dctab,qtab,ctrC,i,k,j;prev[0]=this.selector(0);prev[1]=this.selector(1);prev[2]=this.selector(2);for(ctrC=0;ctrC=65280){return value}prev[ctrC]=this.IDCT_Source[0]=prev[ctrC]+this.getn(index,value,temp,index);this.IDCT_Source[0]*=qtab[0];for(j=1;j<64;j+=1){value=this.getHuffmanValue(actab,temp,index);if(value>=65280){return value}j+=value>>4;if((value&15)===0){if(value>>4===0){break}}else{this.IDCT_Source[jpeg.lossless.Decoder.IDCT_P[j]]=this.getn(index,value&15,temp,index)*qtab[j]}}}}return 0};jpeg.lossless.Decoder.prototype.decodeSingle=function(prev,temp,index){var value,i,n,nRestart;if(this.restarting){this.restarting=false;prev[0]=1<=65280){return value}n=this.getn(prev,value,temp,index);nRestart=n>>8;if(nRestart>=jpeg.lossless.Decoder.RESTART_MARKER_BEGIN&&nRestart<=jpeg.lossless.Decoder.RESTART_MARKER_END){return nRestart}prev[0]+=n}return 0};jpeg.lossless.Decoder.prototype.getHuffmanValue=function(table,temp,index){var code,input,mask;mask=65535;if(index[0]<8){temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input}else{index[0]-=8}code=table[temp[0]>>index[0]];if((code&jpeg.lossless.Decoder.MSB)!==0){if(this.markerIndex!==0){this.markerIndex=0;return 65280|this.marker}temp[0]&=mask>>16-index[0];temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;code=table[(code&255)*256+(temp[0]>>index[0])];index[0]+=8}index[0]+=8-(code>>8);if(index[0]<0){throw new Error("index="+index[0]+" temp="+temp[0]+" code="+code+" in HuffmanValue()")}if(index[0]>16-index[0];return code&255};jpeg.lossless.Decoder.prototype.getn=function(PRED,n,temp,index){var result,one,n_one,mask,input;one=1;n_one=-1;mask=65535;if(n===0){return 0}if(n===16){if(PRED[0]>=0){return-32768}else{return 32768}}index[0]-=n;if(index[0]>=0){if(index[0]>index[0];temp[0]&=mask>>16-index[0]}else{temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;index[0]+=8;if(index[0]<0){if(this.markerIndex!==0){this.markerIndex=0;return(65280|this.marker)<<8}temp[0]<<=8;input=this.stream.get8();if(input===255){this.marker=this.stream.get8();if(this.marker!==0){this.markerIndex=9}}temp[0]|=input;index[0]+=8}if(index[0]<0){throw new Error("index="+index[0]+" in getn()")}if(index[0]>index[0];temp[0]&=mask>>16-index[0]}if(result0){return this.getter(this.yLoc*this.xDim+this.xLoc-1,compOffset)}else if(this.yLoc>0){return this.getPreviousY(compOffset)}else{return 1<0&&this.yLoc>0){return this.getter((this.yLoc-1)*this.xDim+this.xLoc-1,compOffset)}else{return this.getPreviousY(compOffset)}};jpeg.lossless.Decoder.prototype.getPreviousY=function(compOffset){if(this.yLoc>0){return this.getter((this.yLoc-1)*this.xDim+this.xLoc,compOffset)}else{return this.getPreviousX(compOffset)}};jpeg.lossless.Decoder.prototype.isLastPixel=function(){return this.xLoc===this.xDim-1&&this.yLoc===this.yDim-1};jpeg.lossless.Decoder.prototype.outputSingle=function(PRED){if(this.xLoc=this.xDim){this.yLoc+=1;this.xLoc=0}}};jpeg.lossless.Decoder.prototype.outputRGB=function(PRED){var offset=this.yLoc*this.xDim+this.xLoc;if(this.xLoc=this.xDim){this.yLoc+=1;this.xLoc=0}}};jpeg.lossless.Decoder.prototype.setValue16=function(index,val){this.outputData.setInt16(index*2,val,true)};jpeg.lossless.Decoder.prototype.getValue16=function(index){return this.outputData.getInt16(index*2,true)};jpeg.lossless.Decoder.prototype.setValue8=function(index,val){this.outputData.setInt8(index,val)};jpeg.lossless.Decoder.prototype.getValue8=function(index){return this.outputData.getInt8(index)};jpeg.lossless.Decoder.prototype.setValueRGB=function(index,val,compOffset){this.outputData.setUint8(index*3+compOffset,val)};jpeg.lossless.Decoder.prototype.getValueRGB=function(index,compOffset){return this.outputData.getUint8(index*3+compOffset)};jpeg.lossless.Decoder.prototype.readApp=function(){var count=0,length=this.stream.get16();count+=2;while(countlength){throw new Error("ERROR: frame format error")}c=data.get8();count+=1;if(count>=length){throw new Error("ERROR: frame format error [c>=Lf]")}temp=data.get8();count+=1;if(!this.components[c]){this.components[c]=new jpeg.lossless.ComponentSpec}this.components[c].hSamp=temp>>4;this.components[c].vSamp=temp&15;this.components[c].quantTableSel=data.get8();count+=1}if(count!==length){throw new Error("ERROR: frame format error [Lf!=count]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.FrameHeader}},{"./component-spec.js":1,"./data-stream.js":2}],5:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);jpeg.lossless.HuffmanTable=jpeg.lossless.HuffmanTable||function(){this.l=jpeg.lossless.Utils.createArray(4,2,16);this.th=[];this.v=jpeg.lossless.Utils.createArray(4,2,16,200);this.tc=jpeg.lossless.Utils.createArray(4,2);this.tc[0][0]=0;this.tc[1][0]=0;this.tc[2][0]=0;this.tc[3][0]=0;this.tc[0][1]=0;this.tc[1][1]=0;this.tc[2][1]=0;this.tc[3][1]=0;this.th[0]=0;this.th[1]=0;this.th[2]=0;this.th[3]=0};jpeg.lossless.HuffmanTable.MSB=2147483648;jpeg.lossless.HuffmanTable.prototype.read=function(data,HuffTab){var count=0,length,temp,t,c,i,j;length=data.get16();count+=2;while(count3){throw new Error("ERROR: Huffman table ID > 3")}c=temp>>4;if(c>2){throw new Error("ERROR: Huffman table [Table class > 2 ]")}this.th[t]=1;this.tc[t][c]=1;for(i=0;i<16;i+=1){this.l[t][c][i]=data.get8();count+=1}for(i=0;i<16;i+=1){for(j=0;jlength){throw new Error("ERROR: Huffman table format error [count>Lh]")}this.v[t][c][i][j]=data.get8();count+=1}}}if(count!==length){throw new Error("ERROR: Huffman table format error [count!=Lf]")}for(i=0;i<4;i+=1){for(j=0;j<2;j+=1){if(this.tc[i][j]!==0){this.buildHuffTable(HuffTab[i][j],this.l[i][j],this.v[i][j])}}}return 1};jpeg.lossless.HuffmanTable.prototype.buildHuffTable=function(tab,L,V){var currentTable,temp,k,i,j,n;temp=256;k=0;for(i=0;i<8;i+=1){for(j=0;j>i+1;n+=1){tab[k]=V[i][j]|i+1<<8;k+=1}}}for(i=1;k<256;i+=1,k+=1){tab[k]=i|jpeg.lossless.HuffmanTable.MSB}currentTable=1;k=0;for(i=8;i<16;i+=1){for(j=0;j>i-7;n+=1){tab[currentTable*256+k]=V[i][j]|i+1<<8;k+=1}if(k>=256){if(k>256){throw new Error("ERROR: Huffman table error(1)!")}k=0;currentTable+=1}}}};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.HuffmanTable}},{"./data-stream.js":2,"./utils.js":10}],6:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.ComponentSpec=jpeg.lossless.ComponentSpec||(typeof require!=="undefined"?require("./component-spec.js"):null);jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Decoder=jpeg.lossless.Decoder||(typeof require!=="undefined"?require("./decoder.js"):null);jpeg.lossless.FrameHeader=jpeg.lossless.FrameHeader||(typeof require!=="undefined"?require("./frame-header.js"):null);jpeg.lossless.HuffmanTable=jpeg.lossless.HuffmanTable||(typeof require!=="undefined"?require("./huffman-table.js"):null);jpeg.lossless.QuantizationTable=jpeg.lossless.QuantizationTable||(typeof require!=="undefined"?require("./quantization-table.js"):null);jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||(typeof require!=="undefined"?require("./scan-component.js"):null);jpeg.lossless.ScanHeader=jpeg.lossless.ScanHeader||(typeof require!=="undefined"?require("./scan-header.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg}},{"./component-spec.js":1,"./data-stream.js":2,"./decoder.js":3,"./frame-header.js":4,"./huffman-table.js":5,"./quantization-table.js":7,"./scan-component.js":8,"./scan-header.js":9,"./utils.js":10}],7:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.Utils=jpeg.lossless.Utils||(typeof require!=="undefined"?require("./utils.js"):null);jpeg.lossless.QuantizationTable=jpeg.lossless.QuantizationTable||function(){this.precision=[];this.tq=[];this.quantTables=jpeg.lossless.Utils.createArray(4,64);this.tq[0]=0;this.tq[1]=0;this.tq[2]=0;this.tq[3]=0};jpeg.lossless.QuantizationTable.enhanceQuantizationTable=function(qtab,table){var i;for(i=0;i<8;i+=1){qtab[table[0*8+i]]*=90;qtab[table[4*8+i]]*=90;qtab[table[2*8+i]]*=118;qtab[table[6*8+i]]*=49;qtab[table[5*8+i]]*=71;qtab[table[1*8+i]]*=126;qtab[table[7*8+i]]*=25;qtab[table[3*8+i]]*=106}for(i=0;i<8;i+=1){qtab[table[0+8*i]]*=90;qtab[table[4+8*i]]*=90;qtab[table[2+8*i]]*=118;qtab[table[6+8*i]]*=49;qtab[table[5+8*i]]*=71;qtab[table[1+8*i]]*=126;qtab[table[7+8*i]]*=25;qtab[table[3+8*i]]*=106}for(i=0;i<64;i+=1){qtab[i]>>=6}};jpeg.lossless.QuantizationTable.prototype.read=function(data,table){var count=0,length,temp,t,i;length=data.get16();count+=2;while(count3){throw new Error("ERROR: Quantization table ID > 3")}this.precision[t]=temp>>4;if(this.precision[t]===0){this.precision[t]=8}else if(this.precision[t]===1){this.precision[t]=16}else{throw new Error("ERROR: Quantization table precision error")}this.tq[t]=1;if(this.precision[t]===8){for(i=0;i<64;i+=1){if(count>length){throw new Error("ERROR: Quantization table format error")}this.quantTables[t][i]=data.get8();count+=1}jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t],table)}else{for(i=0;i<64;i+=1){if(count>length){throw new Error("ERROR: Quantization table format error")}this.quantTables[t][i]=data.get16();count+=2}jpeg.lossless.QuantizationTable.enhanceQuantizationTable(this.quantTables[t],table)}}if(count!==length){throw new Error("ERROR: Quantization table error [count!=Lq]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.QuantizationTable}},{"./data-stream.js":2,"./utils.js":10}],8:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||function(){this.acTabSel=0;this.dcTabSel=0;this.scanCompSel=0};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.ScanComponent}},{}],9:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.DataStream=jpeg.lossless.DataStream||(typeof require!=="undefined"?require("./data-stream.js"):null);jpeg.lossless.ScanComponent=jpeg.lossless.ScanComponent||(typeof require!=="undefined"?require("./scan-component.js"):null);jpeg.lossless.ScanHeader=jpeg.lossless.ScanHeader||function(){this.ah=0;this.al=0;this.numComp=0;this.selection=0;this.spectralEnd=0;this.components=[]};jpeg.lossless.ScanHeader.prototype.read=function(data){var count=0,length,i,temp;length=data.get16();count+=2;this.numComp=data.get8();count+=1;for(i=0;ilength){throw new Error("ERROR: scan header format error")}this.components[i].scanCompSel=data.get8();count+=1;temp=data.get8();count+=1;this.components[i].dcTabSel=temp>>4;this.components[i].acTabSel=temp&15}this.selection=data.get8();count+=1;this.spectralEnd=data.get8();count+=1;temp=data.get8();this.ah=temp>>4;this.al=temp&15;count+=1;if(count!==length){throw new Error("ERROR: scan header format error [count!=Ns]")}return 1};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.ScanHeader}},{"./data-stream.js":2,"./scan-component.js":8}],10:[function(require,module,exports){"use strict";var jpeg=jpeg||{};jpeg.lossless=jpeg.lossless||{};jpeg.lossless.Utils=jpeg.lossless.Utils||{};jpeg.lossless.Utils.createArray=function(length){var arr=new Array(length||0),i=length;if(arguments.length>1){var args=Array.prototype.slice.call(arguments,1);while(i--)arr[length-1-i]=jpeg.lossless.Utils.createArray.apply(this,args)}return arr};var moduleType=typeof module;if(moduleType!=="undefined"&&module.exports){module.exports=jpeg.lossless.Utils}},{}]},{},[6])(6)}); \ No newline at end of file diff --git a/release/current/lossless.js b/release/current/lossless.js index 47b33cb..c602524 100644 --- a/release/current/lossless.js +++ b/release/current/lossless.js @@ -195,8 +195,9 @@ jpeg.lossless.Decoder = jpeg.lossless.Decoder || function (buffer, numBytes) { this.yDim = 0; this.xLoc = 0; this.yLoc = 0; - this.numBytes = 0; - this.outputData = null; + this.numBytes = 0; + this.outputData = null; + this.restarting = false; if (typeof numBytes !== "undefined") { this.numBytes = numBytes; @@ -212,7 +213,8 @@ jpeg.lossless.Decoder.TABLE = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63]; jpeg.lossless.Decoder.MAX_HUFFMAN_SUBTREE = 50; jpeg.lossless.Decoder.MSB = 0x80000000; - +jpeg.lossless.Decoder.RESTART_MARKER_BEGIN = 0xFFD0; +jpeg.lossless.Decoder.RESTART_MARKER_END = 0xFFD7; /*** Prototype Methods ***/ @@ -430,6 +432,7 @@ jpeg.lossless.Decoder.prototype.decode = function (buffer, offset, length, numBy } for (mcuNum = 0; mcuNum < this.restartInterval; mcuNum+=1) { + this.restarting = (mcuNum == 0); current = this.decodeUnit(pred, temp, index); this.output(pred); @@ -447,7 +450,8 @@ jpeg.lossless.Decoder.prototype.decode = function (buffer, offset, length, numBy } } - if (!((current >= 0xFFD0) && (current <= 0xFFD7))) { + if (!((current >= jpeg.lossless.Decoder.RESTART_MARKER_BEGIN) && + (current <= jpeg.lossless.Decoder.RESTART_MARKER_END))) { break; //current=MARKER } } @@ -572,9 +576,14 @@ jpeg.lossless.Decoder.prototype.decodeRGB = function (prev, temp, index) { jpeg.lossless.Decoder.prototype.decodeSingle = function (prev, temp, index) { /*jslint bitwise: true */ - var value, i; + var value, i, n, nRestart; - prev[0] = this.selector(); + if (this.restarting) { + this.restarting = false; + prev[0] = (1 << (this.frame.precision - 1)); + } else { + prev[0] = this.selector(); + } for (i = 0; i < this.nBlock[0]; i+=1) { value = this.getHuffmanValue(this.dcTab[0], temp, index); @@ -582,7 +591,14 @@ jpeg.lossless.Decoder.prototype.decodeSingle = function (prev, temp, index) { return value; } - prev[0] += this.getn(prev, value, temp, index); + n = this.getn(prev, value, temp, index); + nRestart = (n >> 8); + + if ((nRestart >= jpeg.lossless.Decoder.RESTART_MARKER_BEGIN) && (nRestart <= jpeg.lossless.Decoder.RESTART_MARKER_END)) { + return nRestart; + } + + prev[0] += n; } return 0;