PageRenderTime 5783ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 0ms

/src/stream.js

http://github.com/tobeytailor/gordon
JavaScript | 452 lines | 414 code | 38 blank | 0 comment | 58 complexity | 853d6b0ea6fd97bb0f72baca1fd9ae40 MD5 | raw file
  1. (function(){
  2. var DEFLATE_CODE_LENGTH_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],
  3. DEFLATE_CODE_LENGHT_MAP = [
  4. [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10], [1, 11], [1, 13], [1, 15], [1, 17],
  5. [2, 19], [2, 23], [2, 27], [2, 31], [3, 35], [3, 43], [3, 51], [3, 59], [4, 67], [4, 83], [4, 99],
  6. [4, 115], [5, 131], [5, 163], [5, 195], [5, 227], [0, 258]
  7. ],
  8. DEFLATE_DISTANCE_MAP = [
  9. [0, 1], [0, 2], [0, 3], [0, 4], [1, 5], [1, 7], [2, 9], [2, 13], [3, 17], [3, 25], [4, 33], [4, 49],
  10. [5, 65], [5, 97], [6, 129], [6, 193], [7, 257], [7, 385], [8, 513], [8, 769], [9, 1025], [9, 1537],
  11. [10, 2049], [10, 3073], [11, 4097], [11, 6145], [12, 8193], [12, 12289], [13, 16385], [13, 24577]
  12. ];
  13. Gordon.Stream = function(data){
  14. var buff = [],
  15. t = this,
  16. i = t.length = data.length;
  17. t.offset = 0;
  18. for(var i = 0; data[i]; i++){ buff.push(fromCharCode(data.charCodeAt(i) & 0xff)); }
  19. t._buffer = buff.join('');
  20. t._bitBuffer = null;
  21. t._bitOffset = 8;
  22. };
  23. Gordon.Stream.prototype = {
  24. readByteAt: function(pos){
  25. return this._buffer.charCodeAt(pos);
  26. },
  27. readNumber: function(numBytes, bigEnd){
  28. var t = this,
  29. val = 0;
  30. if(bigEnd){
  31. while(numBytes--){ val = (val << 8) | t.readByteAt(t.offset++); }
  32. }else{
  33. var o = t.offset,
  34. i = o + numBytes;
  35. while(i > o){ val = (val << 8) | t.readByteAt(--i); }
  36. t.offset += numBytes;
  37. }
  38. t.align();
  39. return val;
  40. },
  41. readSNumber: function(numBytes, bigEnd){
  42. var val = this.readNumber(numBytes, bigEnd),
  43. numBits = numBytes * 8;
  44. if(val >> (numBits - 1)){ val -= Math.pow(2, numBits); }
  45. return val;
  46. },
  47. readSI8: function(){
  48. return this.readSNumber(1);
  49. },
  50. readSI16: function(bigEnd){
  51. return this.readSNumber(2, bigEnd);
  52. },
  53. readSI32: function(bigEnd){
  54. return this.readSNumber(4, bigEnd);
  55. },
  56. readUI8: function(){
  57. return this.readNumber(1);
  58. },
  59. readUI16: function(bigEnd){
  60. return this.readNumber(2, bigEnd);
  61. },
  62. readUI24: function(bigEnd){
  63. return this.readNumber(3, bigEnd);
  64. },
  65. readUI32: function(bigEnd){
  66. return this.readNumber(4, bigEnd);
  67. },
  68. readFixed: function(){
  69. return this._readFixedPoint(32, 16);
  70. },
  71. _readFixedPoint: function(numBits, precision){
  72. return this.readSB(numBits) * Math.pow(2, -precision);
  73. },
  74. readFixed8: function(){
  75. return this._readFixedPoint(16, 8);
  76. },
  77. readFloat: function(){
  78. return this._readFloatingPoint(8, 23);
  79. },
  80. _readFloatingPoint: function(numEBits, numSBits){
  81. var numBits = 1 + numEBits + numSBits,
  82. numBytes = numBits / 8,
  83. t = this,
  84. val = 0.0;
  85. if(numBytes > 4){
  86. var i = Math.ceil(numBytes / 4);
  87. while(i--){
  88. var buff = [],
  89. o = t.offset,
  90. j = o + (numBytes >= 4 ? 4 : numBytes % 4);
  91. while(j > o){
  92. buff.push(t.readByteAt(--j));
  93. numBytes--;
  94. t.offset++;
  95. }
  96. }
  97. var s = new Gordon.Stream(fromCharCode.apply(String, buff)),
  98. sign = s.readUB(1),
  99. expo = s.readUB(numEBits),
  100. mantis = 0,
  101. i = numSBits;
  102. while(i--){
  103. if(s.readBool()){ mantis += Math.pow(2, i); }
  104. }
  105. }else{
  106. var sign = t.readUB(1),
  107. expo = t.readUB(numEBits),
  108. mantis = t.readUB(numSBits);
  109. }
  110. if(sign || expo || mantis){
  111. var maxExpo = Math.pow(2, numEBits),
  112. bias = ~~((maxExpo - 1) / 2),
  113. scale = Math.pow(2, numSBits),
  114. fract = mantis / scale;
  115. if(bias){
  116. if(bias < maxExpo){ val = Math.pow(2, expo - bias) * (1 + fract); }
  117. else if(fract){ val = NaN; }
  118. else{ val = Infinity; }
  119. }else if(fract){ val = Math.pow(2, 1 - bias) * fract; }
  120. if(NaN != val && sign){ val *= -1; }
  121. }
  122. return val;
  123. },
  124. readFloat16: function(){
  125. return this._readFloatingPoint(5, 10);
  126. },
  127. readDouble: function(){
  128. return this._readFloatingPoint(11, 52);
  129. },
  130. readEncodedU32: function(){
  131. var val = 0;
  132. for(var i = 0; i < 5; i++){
  133. var num = this.readByteAt(this._offset++);
  134. val = val | ((num & 0x7f) << (7 * i));
  135. if(!(num & 0x80)){ break; }
  136. }
  137. return val;
  138. },
  139. readSB: function(numBits){
  140. var val = this.readUB(numBits);
  141. if(val >> (numBits - 1)){ val -= Math.pow(2, numBits); }
  142. return val;
  143. },
  144. readUB: function(numBits, lsb){
  145. var t = this,
  146. val = 0;
  147. for(var i = 0; i < numBits; i++){
  148. if(8 == t._bitOffset){
  149. t._bitBuffer = t.readUI8();
  150. t._bitOffset = 0;
  151. }
  152. if(lsb){ val |= (t._bitBuffer & (0x01 << t._bitOffset++) ? 1 : 0) << i; }
  153. else{ val = (val << 1) | (t._bitBuffer & (0x80 >> t._bitOffset++) ? 1 : 0); }
  154. }
  155. return val;
  156. },
  157. readFB: function(numBits){
  158. return this._readFixedPoint(numBits, 16);
  159. },
  160. readString: function(numChars){
  161. var t = this,
  162. b = t._buffer;
  163. if(undefined != numChars){
  164. var str = b.substr(t.offset, numChars);
  165. t.offset += numChars;
  166. }else{
  167. var chars = [],
  168. i = t.length - t.offset;
  169. while(i--){
  170. var code = t.readByteAt(t.offset++);
  171. if(code){ chars.push(fromCharCode(code)); }
  172. else{ break; }
  173. }
  174. var str = chars.join('');
  175. }
  176. return str;
  177. },
  178. readBool: function(numBits){
  179. return !!this.readUB(numBits || 1);
  180. },
  181. seek: function(offset, absolute){
  182. var t = this;
  183. t.offset = (absolute ? 0 : t.offset) + offset;
  184. t.align();
  185. return t;
  186. },
  187. align: function(){
  188. this._bitBuffer = null;
  189. this._bitOffset = 8;
  190. return this;
  191. },
  192. readLanguageCode: function(){
  193. return this.readUI8();
  194. },
  195. readRGB: function(){
  196. return {
  197. red: this.readUI8(),
  198. green: this.readUI8(),
  199. blue: this.readUI8()
  200. }
  201. },
  202. readRGBA: function(){
  203. var rgba = this.readRGB();
  204. rgba.alpha = this.readUI8() / 255;
  205. return rgba;
  206. },
  207. readARGB: function(){
  208. var alpha = this.readUI8() / 255,
  209. rgba = this.readRGB();
  210. rgba.alpha = alpha;
  211. return rgba;
  212. },
  213. readRect: function(){
  214. var t = this;
  215. numBits = t.readUB(5),
  216. rect = {
  217. left: t.readSB(numBits),
  218. right: t.readSB(numBits),
  219. top: t.readSB(numBits),
  220. bottom: t.readSB(numBits)
  221. };
  222. t.align();
  223. return rect;
  224. },
  225. readMatrix: function(){
  226. var t = this,
  227. hasScale = t.readBool();
  228. if(hasScale){
  229. var numBits = t.readUB(5),
  230. scaleX = t.readFB(numBits),
  231. scaleY = t.readFB(numBits);
  232. }else{ var scaleX = scaleY = 1.0; }
  233. var hasRotation = t.readBool();
  234. if(hasRotation){
  235. var numBits = t.readUB(5),
  236. skewX = t.readFB(numBits),
  237. skewY = t.readFB(numBits);
  238. }else{ var skewX = skewY = 0.0; }
  239. var numBits = t.readUB(5);
  240. matrix = {
  241. scaleX: scaleX, scaleY: scaleY,
  242. skewX: skewX, skewY: skewY,
  243. moveX: t.readSB(numBits), moveY: t.readSB(numBits)
  244. };
  245. t.align();
  246. return matrix;
  247. },
  248. readCxform: function(){
  249. return this._readCxf();
  250. },
  251. readCxformA: function(){
  252. return this._readCxf(true);
  253. },
  254. _readCxf: function(withAlpha){
  255. var t = this;
  256. hasAddTerms = t.readBool(),
  257. hasMultTerms = t.readBool(),
  258. numBits = t.readUB(4);
  259. if(hasMultTerms){
  260. var multR = t.readSB(numBits) / 256,
  261. multG = t.readSB(numBits) / 256,
  262. multB = t.readSB(numBits) / 256,
  263. multA = withAlpha ? t.readSB(numBits) / 256 : 1;
  264. }else{ var multR = multG = multB = multA = 1; }
  265. if(hasAddTerms){
  266. var addR = t.readSB(numBits),
  267. addG = t.readSB(numBits),
  268. addB = t.readSB(numBits),
  269. addA = withAlpha ? t.readSB(numBits) / 256 : 0;
  270. }else{ var addR = addG = addB = addA = 0; }
  271. var cxform = {
  272. multR: multR, multG: multG, multB: multB, multA: multA,
  273. addR: addR, addG: addG, addB: addB, addA: addA
  274. }
  275. t.align();
  276. return cxform;
  277. },
  278. decompress: function(){
  279. var t = this,
  280. b = t._buffer,
  281. o = t.offset,
  282. data = b.substr(0, o) + t.unzip();
  283. t.length = data.length;
  284. t.offset = o;
  285. t._buffer = data;
  286. return t;
  287. },
  288. unzip: function uz(raw){
  289. var t = this,
  290. buff = [],
  291. o = DEFLATE_CODE_LENGTH_ORDER,
  292. m = DEFLATE_CODE_LENGHT_MAP,
  293. d = DEFLATE_DISTANCE_MAP;
  294. t.seek(2);
  295. do{
  296. var isFinal = t.readUB(1, true),
  297. type = t.readUB(2, true);
  298. if(type){
  299. if(1 == type){
  300. var distTable = uz.fixedDistTable,
  301. litTable = uz.fixedLitTable;
  302. if(!distTable){
  303. var bitLengths = [];
  304. for(var i = 0; i < 32; i++){ bitLengths.push(5); }
  305. distTable = uz.fixedDistTable = buildHuffTable(bitLengths);
  306. }
  307. if(!litTable){
  308. var bitLengths = [];
  309. for(var i = 0; i <= 143; i++){ bitLengths.push(8); }
  310. for(; i <= 255; i++){ bitLengths.push(9); }
  311. for(; i <= 279; i++){ bitLengths.push(7); }
  312. for(; i <= 287; i++){ bitLengths.push(8); }
  313. litTable = uz.fixedLitTable = buildHuffTable(bitLengths);
  314. }
  315. }else{
  316. var numLitLengths = t.readUB(5, true) + 257,
  317. numDistLengths = t.readUB(5, true) + 1,
  318. numCodeLenghts = t.readUB(4, true) + 4,
  319. codeLengths = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
  320. for(var i = 0; i < numCodeLenghts; i++){ codeLengths[o[i]] = t.readUB(3, true); }
  321. var codeTable = buildHuffTable(codeLengths),
  322. litLengths = [],
  323. prevCodeLen = 0,
  324. maxLengths = numLitLengths + numDistLengths;
  325. while(litLengths.length < maxLengths){
  326. var sym = decodeSymbol(t, codeTable);
  327. switch(sym){
  328. case 16:
  329. var i = t.readUB(2, true) + 3;
  330. while(i--){ litLengths.push(prevCodeLen); }
  331. break;
  332. case 17:
  333. var i = t.readUB(3, true) + 3;
  334. while(i--){ litLengths.push(0); }
  335. break;
  336. case 18:
  337. var i = t.readUB(7, true) + 11;
  338. while(i--){ litLengths.push(0); }
  339. break;
  340. default:
  341. if(sym <= 15){
  342. litLengths.push(sym);
  343. prevCodeLen = sym;
  344. }
  345. }
  346. }
  347. var distTable = buildHuffTable(litLengths.splice(numLitLengths, numDistLengths)),
  348. litTable = buildHuffTable(litLengths);
  349. }
  350. do{
  351. var sym = decodeSymbol(t, litTable);
  352. if(sym < 256){ buff.push(raw ? sym : fromCharCode(sym)); }
  353. else if(sym > 256){
  354. var lengthMap = m[sym - 257],
  355. len = lengthMap[1] + t.readUB(lengthMap[0], true),
  356. distMap = d[decodeSymbol(t, distTable)],
  357. dist = distMap[1] + t.readUB(distMap[0], true),
  358. i = buff.length - dist;
  359. while(len--){ buff.push(buff[i++]); }
  360. }
  361. }while(256 != sym);
  362. }else{
  363. t.align();
  364. var len = t.readUI16(),
  365. nlen = t.readUI16();
  366. if(raw){ while(len--){ buff.push(t.readUI8()); } }
  367. else{ buff.push(t.readString(len)); }
  368. }
  369. }while(!isFinal);
  370. t.seek(4);
  371. return raw ? buff : buff.join('');
  372. }
  373. };
  374. function buildHuffTable(bitLengths){
  375. var numLengths = bitLengths.length,
  376. blCount = [],
  377. maxBits = max.apply(Math, bitLengths),
  378. nextCode = [],
  379. code = 0,
  380. table = {},
  381. i = numLengths;
  382. while(i--){
  383. var len = bitLengths[i];
  384. blCount[len] = (blCount[len] || 0) + (len > 0);
  385. }
  386. for(var i = 1; i <= maxBits; i++){
  387. var len = i - 1;
  388. if(undefined == blCount[len]){ blCount[len] = 0; }
  389. code = (code + blCount[i - 1]) << 1;
  390. nextCode[i] = code;
  391. }
  392. for(var i = 0; i < numLengths; i++){
  393. var len = bitLengths[i];
  394. if(len){
  395. table[nextCode[len]] = {
  396. length: len,
  397. symbol: i
  398. };
  399. nextCode[len]++;
  400. }
  401. }
  402. return table;
  403. }
  404. function decodeSymbol(s, table) {
  405. var code = 0,
  406. len = 0;
  407. while(true){
  408. code = (code << 1) | s.readUB(1, true);
  409. len++;
  410. var entry = table[code];
  411. if(undefined != entry && entry.length == len){ return entry.symbol }
  412. }
  413. }
  414. })();