1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * JSUnzip 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (c) 2011 by Erik Moller 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * All Rights Reserved 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This software is provided 'as-is', without any express 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * or implied warranty. In no event will the authors be 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * held liable for any damages arising from the use of 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * this software. 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Permission is granted to anyone to use this software 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for any purpose, including commercial applications, 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and to alter it and redistribute it freely, subject to 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the following restrictions: 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1. The origin of this software must not be 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * misrepresented; you must not claim that you 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * wrote the original software. If you use this 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * software in a product, an acknowledgment in 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the product documentation would be appreciated 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but is not required. 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2. Altered source versions must be plainly marked 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * as such, and must not be misrepresented as 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * being the original software. 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 3. This notice may not be removed or altered from 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * any source distribution. 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvar tinf; 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfunction JSUnzip() { 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.getInt = function(offset, size) { 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (size) { 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 4: 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return (this.data.charCodeAt(offset + 3) & 0xff) << 24 | 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (this.data.charCodeAt(offset + 2) & 0xff) << 16 | 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (this.data.charCodeAt(offset + 1) & 0xff) << 8 | 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (this.data.charCodeAt(offset + 0) & 0xff); 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 2: 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return (this.data.charCodeAt(offset + 1) & 0xff) << 8 | 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (this.data.charCodeAt(offset + 0) & 0xff); 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return this.data.charCodeAt(offset) & 0xff; 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.getDOSDate = function(dosdate, dostime) { 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var day = dosdate & 0x1f; 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var month = ((dosdate >> 5) & 0xf) - 1; 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var year = 1980 + ((dosdate >> 9) & 0x7f) 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var second = (dostime & 0x1f) * 2; 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var minute = (dostime >> 5) & 0x3f; 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hour = (dostime >> 11) & 0x1f; 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return new Date(year, month, day, hour, minute, second); 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.open = function(data) { 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.data = data; 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.files = []; 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (this.data.length < 22) 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Invalid data' }; 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var endOfCentralDirectory = this.data.length - 22; 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (endOfCentralDirectory >= 0 && this.getInt(endOfCentralDirectory, 4) != 0x06054b50) 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat --endOfCentralDirectory; 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (endOfCentralDirectory < 0) 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Invalid data' }; 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (this.getInt(endOfCentralDirectory + 4, 2) != 0 || this.getInt(endOfCentralDirectory + 6, 2) != 0) 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'No multidisk support' }; 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var entriesInThisDisk = this.getInt(endOfCentralDirectory + 8, 2); 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var centralDirectoryOffset = this.getInt(endOfCentralDirectory + 16, 4); 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var globalCommentLength = this.getInt(endOfCentralDirectory + 20, 2); 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.comment = this.data.slice(endOfCentralDirectory + 22, endOfCentralDirectory + 22 + globalCommentLength); 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var fileOffset = centralDirectoryOffset; 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (var i = 0; i < entriesInThisDisk; ++i) { 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (this.getInt(fileOffset + 0, 4) != 0x02014b50) 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Invalid data' }; 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (this.getInt(fileOffset + 6, 2) > 20) 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Unsupported version' }; 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (this.getInt(fileOffset + 8, 2) & 1) 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Encryption not implemented' }; 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var compressionMethod = this.getInt(fileOffset + 10, 2); 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (compressionMethod != 0 && compressionMethod != 8) 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Unsupported compression method' }; 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var lastModFileTime = this.getInt(fileOffset + 12, 2); 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var lastModFileDate = this.getInt(fileOffset + 14, 2); 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var lastModifiedDate = this.getDOSDate(lastModFileDate, lastModFileTime); 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var crc = this.getInt(fileOffset + 16, 4); 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat // TODO: crc 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var compressedSize = this.getInt(fileOffset + 20, 4); 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var uncompressedSize = this.getInt(fileOffset + 24, 4); 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var fileNameLength = this.getInt(fileOffset + 28, 2); 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var extraFieldLength = this.getInt(fileOffset + 30, 2); 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var fileCommentLength = this.getInt(fileOffset + 32, 2); 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var relativeOffsetOfLocalHeader = this.getInt(fileOffset + 42, 4); 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var fileName = this.data.slice(fileOffset + 46, fileOffset + 46 + fileNameLength); 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var fileComment = this.data.slice(fileOffset + 46 + fileNameLength + extraFieldLength, fileOffset + 46 + fileNameLength + extraFieldLength + fileCommentLength); 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (this.getInt(relativeOffsetOfLocalHeader + 0, 4) != 0x04034b50) 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : 'Invalid data' }; 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var localFileNameLength = this.getInt(relativeOffsetOfLocalHeader + 26, 2); 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var localExtraFieldLength = this.getInt(relativeOffsetOfLocalHeader + 28, 2); 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var localFileContent = relativeOffsetOfLocalHeader + 30 + localFileNameLength + localExtraFieldLength; 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.files[fileName] = 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 'fileComment' : fileComment, 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 'compressionMethod' : compressionMethod, 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 'compressedSize' : compressedSize, 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 'uncompressedSize' : uncompressedSize, 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 'localFileContent' : localFileContent, 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 'lastModifiedDate' : lastModifiedDate 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fileOffset += 46 + fileNameLength + extraFieldLength + fileCommentLength; 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : true } 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.read = function(fileName) { 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var fileInfo = this.files[fileName]; 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fileInfo) { 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (fileInfo.compressionMethod == 8) { 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!tinf) { 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tinf = new TINF(); 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat tinf.init(); 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var result = tinf.uncompress(this.data, fileInfo.localFileContent); 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (result.status == tinf.OK) 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : true, 'data' : result.data }; 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : result.error }; 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : true, 'data' : this.data.slice(fileInfo.localFileContent, fileInfo.localFileContent + fileInfo.uncompressedSize) }; 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : false, 'error' : "File '" + fileName + "' doesn't exist in zip" }; 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat }; 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * tinflate - tiny inflate 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (c) 2003 by Joergen Ibsen / Jibz 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * All Rights Reserved 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * http://www.ibsensoftware.com/ 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This software is provided 'as-is', without any express 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * or implied warranty. In no event will the authors be 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * held liable for any damages arising from the use of 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * this software. 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Permission is granted to anyone to use this software 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * for any purpose, including commercial applications, 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and to alter it and redistribute it freely, subject to 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the following restrictions: 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 1. The origin of this software must not be 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * misrepresented; you must not claim that you 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * wrote the original software. If you use this 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * software in a product, an acknowledgment in 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the product documentation would be appreciated 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but is not required. 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 2. Altered source versions must be plainly marked 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * as such, and must not be misrepresented as 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * being the original software. 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 3. This notice may not be removed or altered from 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * any source distribution. 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * tinflate javascript port by Erik Moller in May 2011. 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * emoller@opera.com 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * read_bits() patched by mike@imidio.com to allow 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * reading more then 8 bits (needed in some zlib streams) 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat"use strict"; 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfunction TINF() { 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.OK = 0; 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.DATA_ERROR = (-3); 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.WINDOW_SIZE = 32768; 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* ------------------------------ * 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -- internal data structures -- * 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ------------------------------ */ 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.TREE = function() { 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.table = new Array(16); /* table of code length counts */ 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.trans = new Array(288); /* code -> symbol translation table */ 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.DATA = function(that) { 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.source = ''; 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.sourceIndex = 0; 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.tag = 0; 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.bitcount = 0; 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.dest = []; 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.history = []; 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.ltree = new that.TREE(); /* dynamic length/symbol tree */ 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.dtree = new that.TREE(); /* dynamic distance tree */ 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* --------------------------------------------------- * 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -- uninitialized global data (static structures) -- * 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * --------------------------------------------------- */ 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.sltree = new this.TREE(); /* fixed length/symbol tree */ 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.sdtree = new this.TREE(); /* fixed distance tree */ 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* extra bits and base tables for length codes */ 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.length_bits = new Array(30); 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.length_base = new Array(30); 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* extra bits and base tables for distance codes */ 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.dist_bits = new Array(30); 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.dist_base = new Array(30); 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* special ordering of code length codes */ 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.clcidx = [ 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 16, 17, 18, 0, 8, 7, 9, 6, 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 10, 5, 11, 4, 12, 3, 13, 2, 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 14, 1, 15 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat]; 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* ----------------------- * 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -- utility functions -- * 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ----------------------- */ 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* build extra bits and base tables */ 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.build_bits_base = function(bits, base, delta, first) 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var i, sum; 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build bits table */ 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < delta; ++i) bits[i] = 0; 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 30 - delta; ++i) bits[i + delta] = Math.floor(i / delta); 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build base table */ 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (sum = first, i = 0; i < 30; ++i) 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat base[i] = sum; 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sum += 1 << bits[i]; 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* build the fixed huffman trees */ 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.build_fixed_trees = function(lt, dt) 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var i; 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build fixed length tree */ 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 7; ++i) lt.table[i] = 0; 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lt.table[7] = 24; 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lt.table[8] = 152; 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lt.table[9] = 112; 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 24; ++i) lt.trans[i] = 256 + i; 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 144; ++i) lt.trans[24 + i] = i; 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 8; ++i) lt.trans[24 + 144 + i] = 280 + i; 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 112; ++i) lt.trans[24 + 144 + 8 + i] = 144 + i; 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build fixed distance tree */ 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 5; ++i) dt.table[i] = 0; 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dt.table[5] = 32; 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 32; ++i) dt.trans[i] = i; 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* given an array of code lengths, build a tree */ 303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.build_tree = function(t, lengths, loffset, num) 304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var offs = new Array(16); 306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var i, sum; 307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* clear code length count table */ 309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 16; ++i) t.table[i] = 0; 310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* scan symbol lengths, and sum code length counts */ 312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < num; ++i) t.table[lengths[loffset + i]]++; 313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat t.table[0] = 0; 315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* compute offset table for distribution sort */ 317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (sum = 0, i = 0; i < 16; ++i) 318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat offs[i] = sum; 320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sum += t.table[i]; 321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* create code->symbol translation table (symbols sorted by code) */ 324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < num; ++i) 325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (lengths[loffset + i]) t.trans[offs[lengths[loffset + i]]++] = i; 327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* ---------------------- * 331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -- decode functions -- * 332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ---------------------- */ 333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* get one bit from source stream */ 335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.getbit = function(d) 336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var bit; 338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* check if tag is empty */ 340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!d.bitcount--) 341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* load next tag */ 343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.tag = d.source[d.sourceIndex++] & 0xff; 344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.bitcount = 7; 345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* shift bit out of tag */ 348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bit = d.tag & 0x01; 349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.tag >>= 1; 350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return bit; 352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* read a num bit value from a stream and add base */ 3551d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartmanfunction read_bits_direct(source, bitcount, tag, idx, num) 3561d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman{ 3571d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman var val = 0; 3581d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman while (bitcount < 24) { 3591d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman tag = tag | (source[idx++] & 0xff) << bitcount; 3601d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman bitcount += 8; 3611d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman } 3621d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman val = tag & (0xffff >> (16 - num)); 3631d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman tag >>= num; 3641d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman bitcount -= num; 3651d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return [bitcount, tag, idx, val]; 3661d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman} 367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.read_bits = function(d, num, base) 368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!num) 370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return base; 371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 3721d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman var ret = read_bits_direct(d.source, d.bitcount, d.tag, d.sourceIndex, num); 3731d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman d.bitcount = ret[0]; 3741d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman d.tag = ret[1]; 3751d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman d.sourceIndex = ret[2]; 3761d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman return ret[3] + base; 377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* given a data stream and a tree, decode a symbol */ 380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.decode_symbol = function(d, t) 381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (d.bitcount < 16) { 383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.tag = d.tag | (d.source[d.sourceIndex++] & 0xff) << d.bitcount; 384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.bitcount += 8; 385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var sum = 0, cur = 0, len = 0; 388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat do { 389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cur = 2 * cur + ((d.tag & (1 << len)) >> len); 390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ++len; 392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sum += t.table[len]; 394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cur -= t.table[len]; 395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } while (cur >= 0); 397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.tag >>= len; 399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.bitcount -= len; 400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return t.trans[sum + cur]; 402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* given a data stream, decode dynamic trees from it */ 405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.decode_trees = function(d, lt, dt) 406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var code_tree = new this.TREE(); 408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var lengths = new Array(288+32); 409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var hlit, hdist, hclen; 410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var i, num, length; 411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get 5 bits HLIT (257-286) */ 413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hlit = this.read_bits(d, 5, 257); 414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get 5 bits HDIST (1-32) */ 416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hdist = this.read_bits(d, 5, 1); 417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get 4 bits HCLEN (4-19) */ 419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat hclen = this.read_bits(d, 4, 4); 420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < 19; ++i) lengths[i] = 0; 422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read code lengths for code length alphabet */ 424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = 0; i < hclen; ++i) 425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get 3 bits code length (0-7) */ 427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var clen = this.read_bits(d, 3, 0); 428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lengths[this.clcidx[i]] = clen; 430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build code length tree */ 433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.build_tree(code_tree, lengths, 0, 19); 434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decode code lengths for the dynamic trees */ 436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (num = 0; num < hlit + hdist; ) 437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var sym = this.decode_symbol(d, code_tree); 439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (sym) 441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 16: 443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* copy previous code length 3-6 times (read 2 bits) */ 444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var prev = lengths[num - 1]; 446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (length = this.read_bits(d, 2, 3); length; --length) 447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lengths[num++] = prev; 449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 17: 453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* repeat code length 0 for 3-10 times (read 3 bits) */ 454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (length = this.read_bits(d, 3, 3); length; --length) 455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lengths[num++] = 0; 457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 18: 460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* repeat code length 0 for 11-138 times (read 7 bits) */ 461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (length = this.read_bits(d, 7, 11); length; --length) 462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lengths[num++] = 0; 464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* values 0-15 represent the actual code lengths */ 468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lengths[num++] = sym; 469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build dynamic trees */ 474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.build_tree(lt, lengths, 0, hlit); 475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.build_tree(dt, lengths, hlit, hdist); 476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* ----------------------------- * 479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -- block inflate functions -- * 480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ----------------------------- */ 481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* given a stream and two trees, inflate a block of data */ 483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.inflate_block_data = function(d, lt, dt) 484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat // js optimization. 486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var ddest = d.dest; 487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var ddestlength = ddest.length; 488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (1) 490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var sym = this.decode_symbol(d, lt); 492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* check for end of block */ 494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sym == 256) 495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return this.OK; 497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (sym < 256) 500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ddest[ddestlength++] = sym; // ? String.fromCharCode(sym); 502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.history.push(sym); 503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var length, dist, offs; 506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var i; 507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat sym -= 257; 509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* possibly get more bits from length code */ 511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length = this.read_bits(d, this.length_bits[sym], this.length_base[sym]); 512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat dist = this.decode_symbol(d, dt); 514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* possibly get more bits from distance code */ 516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat offs = d.history.length - this.read_bits(d, this.dist_bits[dist], this.dist_base[dist]); 517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (offs < 0) 519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat throw ("Invalid zlib offset " + offs); 520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* copy match */ 522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = offs; i < offs + length; ++i) { 523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat //ddest[ddestlength++] = ddest[i]; 524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat ddest[ddestlength++] = d.history[i]; 525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.history.push(d.history[i]); 526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* inflate an uncompressed block of data */ 532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.inflate_uncompressed_block = function(d) 533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var length, invlength; 535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var i; 536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (d.bitcount > 7) { 538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var overflow = Math.floor(d.bitcount / 8); 539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.sourceIndex -= overflow; 540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.bitcount = 0; 541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.tag = 0; 542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get length */ 545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length = d.source[d.sourceIndex+1]; 546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat length = 256*length + d.source[d.sourceIndex]; 547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* get one's complement of length */ 549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat invlength = d.source[d.sourceIndex+3]; 550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat invlength = 256*invlength + d.source[d.sourceIndex+2]; 551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* check length */ 553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (length != (~invlength & 0x0000ffff)) return this.DATA_ERROR; 554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.sourceIndex += 4; 556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* copy block */ 558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for (i = length; i; --i) { 559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.history.push(d.source[d.sourceIndex]); 560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.dest[d.dest.length] = d.source[d.sourceIndex++]; 561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* make sure we start next block on a byte boundary */ 564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.bitcount = 0; 565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return this.OK; 567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* inflate a block of data compressed with fixed huffman trees */ 570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.inflate_fixed_block = function(d) 571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decode block using fixed trees */ 573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return this.inflate_block_data(d, this.sltree, this.sdtree); 574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* inflate a block of data compressed with dynamic huffman trees */ 577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.inflate_dynamic_block = function(d) 578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decode trees from stream */ 580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.decode_trees(d, d.ltree, d.dtree); 581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decode block using decoded trees */ 583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return this.inflate_block_data(d, d.ltree, d.dtree); 584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* ---------------------- * 587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * -- public functions -- * 588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * ---------------------- */ 589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* initialize global (static) data */ 591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.init = function() 592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build fixed huffman trees */ 594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.build_fixed_trees(this.sltree, this.sdtree); 595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* build extra bits and base tables */ 597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.build_bits_base(this.length_bits, this.length_base, 4, 3); 598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.build_bits_base(this.dist_bits, this.dist_base, 2, 1); 599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* fix a special case */ 601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.length_bits[28] = 0; 602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.length_base[28] = 258; 603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.reset(); 605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.reset = function() 608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.d = new this.DATA(this); 610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat delete this.header; 611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* inflate stream from source to dest */ 614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthis.uncompress = function(source, offset) 615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var d = this.d; 618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var bfinal; 619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* initialise data */ 621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.source = source; 622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.sourceIndex = offset; 623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.bitcount = 0; 624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.dest = []; 626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat // Skip zlib header at start of stream 628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (typeof this.header == 'undefined') { 629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat this.header = this.read_bits(d, 16, 0); 630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* byte 0: 0x78, 7 = 32k window size, 8 = deflate */ 631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* byte 1: check bits for header and other flags */ 632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var blocks = 0; 635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat do { 637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var btype; 639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat var res; 640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read final block flag */ 642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bfinal = this.getbit(d); 643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* read block type (2 bits) */ 645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat btype = this.read_bits(d, 2, 0); 646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decompress block */ 648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (btype) 649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 0: 651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decompress uncompressed block */ 652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat res = this.inflate_uncompressed_block(d); 653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 1: 655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decompress block with fixed huffman trees */ 656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat res = this.inflate_fixed_block(d); 657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 2: 659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* decompress block with dynamic huffman trees */ 660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat res = this.inflate_dynamic_block(d); 661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : this.DATA_ERROR }; 664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (res != this.OK) return { 'status' : this.DATA_ERROR }; 667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat blocks++; 668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } while (!bfinal && d.sourceIndex < d.source.length); 670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat d.history = d.history.slice(-this.WINDOW_SIZE); 672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return { 'status' : this.OK, 'data' : d.dest }; 674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}; 677