├── dev ├── 1.gif ├── 1.png └── index.html ├── src ├── 1.gif ├── 1.png ├── css │ └── _fws │ │ └── _imagesData.scss ├── lib │ ├── _getExeName.es6 │ ├── _omggif.es6 │ └── _upng.es6 ├── demo.es6 ├── index.html └── PixiApngAndGif.es6 ├── dist ├── 1.gif ├── 1.png ├── index.html └── PixiApngAndGif.js ├── .gitignore ├── yarn.lock ├── package.json ├── fws_config.js └── README.md /dev/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbfkcel/pixi-apngAndGif/HEAD/dev/1.gif -------------------------------------------------------------------------------- /dev/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbfkcel/pixi-apngAndGif/HEAD/dev/1.png -------------------------------------------------------------------------------- /src/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbfkcel/pixi-apngAndGif/HEAD/src/1.gif -------------------------------------------------------------------------------- /src/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbfkcel/pixi-apngAndGif/HEAD/src/1.png -------------------------------------------------------------------------------- /dist/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbfkcel/pixi-apngAndGif/HEAD/dist/1.gif -------------------------------------------------------------------------------- /dist/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbfkcel/pixi-apngAndGif/HEAD/dist/1.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /.vscode/ 3 | .DS_Store 4 | .psd 5 | *.DS_Store 6 | *.psd 7 | project.config.json 8 | -------------------------------------------------------------------------------- /src/css/_fws/_imagesData.scss: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | //Updated by FWS. Tue Mar 10 2020 09:17:25 GMT+0800 (GMT+08:00) 3 | $_imagesData:() -------------------------------------------------------------------------------- /src/lib/_getExeName.es6: -------------------------------------------------------------------------------- 1 | export default (filePath)=>{ 2 | let aList = filePath.split('.'); 3 | return aList[aList.length - 1]; 4 | }; -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | pako@^1.0.6: 6 | version "1.0.11" 7 | resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" 8 | integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixi-apngandgif", 3 | "version": "1.0.2", 4 | "description": "Let pixi.js support apng, gif images", 5 | "main": "./dist/PixiApngAndGif.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/sbfkcel/pixi-apngAndGif.git" 12 | }, 13 | "keywords": [ 14 | "pixi", 15 | "apng", 16 | "png", 17 | "gif", 18 | "canvas" 19 | ], 20 | "author": "sbfkcel@163.com", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/sbfkcel/pixi-apngAndGif/issues" 24 | }, 25 | "homepage": "https://github.com/sbfkcel/pixi-apngAndGif#readme", 26 | "dependencies": { 27 | "pako": "^1.0.6" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fws_config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "author": "FWS", 3 | "mail": "china1099@qq.com", 4 | "projectName": "pixi-apngAndGi", 5 | "template": "default", 6 | "createTime": 1538119743322, 7 | "distReplace": { 8 | "*": [ 9 | { 10 | "find": "feutil.localstatic.com", 11 | "replace": "pic.my4399.com/re/cms/feUtil" 12 | }, 13 | { 14 | "find": "$$localhost/staticfile", 15 | "replace": "pic.my4399.com/re/cms/feUtil" 16 | } 17 | ] 18 | }, 19 | "srcSync": { 20 | "targetPath": "", 21 | "fileType": "*" 22 | }, 23 | "devSync": { 24 | "targetPath": "", 25 | "fileType": "*" 26 | }, 27 | "distSync": { 28 | "targetPath": "", 29 | "fileType": "*" 30 | } 31 | }; -------------------------------------------------------------------------------- /src/demo.es6: -------------------------------------------------------------------------------- 1 | import $apngAndGif from './PixiApngAndGif' 2 | 3 | const app = new PIXI.Application(); 4 | 5 | const loader = PIXI.Loader.shared, 6 | title = document.title, 7 | loadOption = { 8 | loadType: PIXI.LoaderResource.LOAD_TYPE.XHR, 9 | xhrType: PIXI.LoaderResource.XHR_RESPONSE_TYPE.BUFFER, 10 | crossOrigin:'' 11 | }, 12 | imgs = { 13 | gif:'http://isparta.github.io/compare/image/dongtai/gif/1.gif', 14 | apng:'http://isparta.github.io/compare/image/dongtai/apng/1.png' 15 | // gif:'./1.gif', 16 | // apng:'./1.png' 17 | }; 18 | 19 | 20 | loader.add(imgs.gif,loadOption); 21 | loader.add(imgs.apng,loadOption); 22 | 23 | loader.on('progress',(loader,resoure)=>{ 24 | document.title = Math.round(loader.progress); 25 | }).load((progress,resources)=>{ 26 | document.title = title; 27 | 28 | window.gif = new $apngAndGif(imgs.gif,resources); 29 | window.apng = new $apngAndGif(imgs.apng,resources); 30 | 31 | let gifSprite = window.gif.sprite, 32 | apngSprite = window.apng.sprite; 33 | 34 | gifSprite.x = 100; 35 | apngSprite.x = 450; 36 | 37 | gifSprite.y = 160; 38 | apngSprite.y = 160; 39 | 40 | app.stage.addChild(gifSprite); 41 | app.stage.addChild(apngSprite); 42 | }); 43 | 44 | document.body.appendChild(app.view); -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pixi-apngAndGif demo 8 | 9 | 10 |

gif:

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

apng:

20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pixi-apngAndGif demo 8 | 9 | 10 |

gif:

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

apng:

20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | pixi-apngAndGif demo 8 | 9 | 10 | 11 |

gif:

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |

apng:

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixi-apngAndGif 2 | 3 | Let Pixi.js support apng, gif images. And allow control of its operation. 4 | 5 | ## DEMO 6 | 7 | - Global [**Pixi-apngAndGif.js Use the demo**](http://jsbin.com/nodeto/edit?html,js,output) 8 | - 中国大陆 [**Pixi-apngAndGif.js Use the demo**](https://jsrun.net/yXhKp) 9 | 10 | # USE 11 | 12 | ### ES6 13 | 14 | ```bash 15 | # Support pixi4.0 16 | npm install pixi-apngandgif@1.0.0 17 | 18 | # Support pixi5.0+ 19 | npm install pixi-apngandgif 20 | ``` 21 | 22 | ```javascript 23 | import PixiApngAndGif from 'pixi-apngandgif' 24 | 25 | const app = new PIXI.Application(); 26 | const loader = PIXI.Loader.shared, 27 | loadOption = { 28 | loadType: PIXI.LoaderResource.LOAD_TYPE.XHR, 29 | xhrType: PIXI.LoaderResource.XHR_RESPONSE_TYPE.BUFFER, 30 | crossOrigin:'' 31 | }, 32 | imgs = { 33 | gif:'http://isparta.github.io/compare/image/dongtai/gif/1.gif', 34 | apng:'http://isparta.github.io/compare/image/dongtai/apng/1.png' 35 | }; 36 | 37 | loader.add(imgs.gif,loadOption); 38 | loader.add(imgs.apng,loadOption); 39 | loader.load((progress,resources)=>{ 40 | window.gif = new PixiApngAndGif(imgs.gif,resources); 41 | window.apng = new PixiApngAndGif(imgs.apng,resources); 42 | 43 | let gifSprite = window.gif.sprite, 44 | apngSprite = window.apng.sprite; 45 | 46 | gifSprite.x = 100; 47 | apngSprite.x = 450; 48 | 49 | gifSprite.y = 160; 50 | apngSprite.y = 160; 51 | 52 | app.stage.addChild(gifSprite); 53 | app.stage.addChild(apngSprite); 54 | }); 55 | 56 | document.body.appendChild(app.view); 57 | ``` 58 | 59 | 60 | ### Browser 61 | 62 | ```html 63 | 64 | 65 | ``` 66 | 67 | ### Application code 68 | 69 | ```javascript 70 | const app = new PIXI.Application(); 71 | const loader = PIXI.Loader.shared, 72 | loadOption = { 73 | loadType: PIXI.LoaderResource.LOAD_TYPE.XHR, 74 | xhrType: PIXI.LoaderResource.XHR_RESPONSE_TYPE.BUFFER, 75 | crossOrigin:'' 76 | }, 77 | imgs = { 78 | gif:'https://isparta.github.io/compare/image/dongtai/gif/1.gif', 79 | apng:'https://isparta.github.io/compare/image/dongtai/apng/1.png' 80 | }; 81 | 82 | loader.add(imgs.gif,loadOption); 83 | loader.add(imgs.apng,loadOption); 84 | loader.load((progress,resources)=>{ 85 | window.gif = new PixiApngAndGif(imgs.gif,resources); 86 | window.apng = new PixiApngAndGif(imgs.apng,resources); 87 | 88 | let gifSprite = window.gif.sprite, 89 | apngSprite = window.apng.sprite; 90 | 91 | gifSprite.x = 100; 92 | apngSprite.x = 450; 93 | 94 | gifSprite.y = 160; 95 | apngSprite.y = 160; 96 | 97 | app.stage.addChild(gifSprite); 98 | app.stage.addChild(apngSprite); 99 | }); 100 | 101 | document.body.appendChild(app.view); 102 | ``` 103 | 104 | ## API 105 | 106 | ### `.play(bout,callback)` 107 | 108 | Play animation 109 | `bout`Used to specify the number of plays 110 | `callback`Callback executed after the specified number of plays has been completed 111 | 112 | ### `.pause()` 113 | 114 | Pause animation 115 | 116 | ### `.stop()` 117 | 118 | Stop animation 119 | 120 | ### `.jumpToFrame(frame)` 121 | 122 | Jump to the specified frame 123 | 124 | ### `.getDuration()` 125 | 126 | Get the total duration of an animation single play 127 | 128 | ### `.getFramesLength()` 129 | 130 | Get the number of animation frames 131 | 132 | ### `.on(status,callback)` 133 | 134 | Used to invoke the specified method in the specified phase of the animation 135 | `status`Four states(`playing`、`played`、`pause`、`stop`) 136 | `callback`Callback, there is a parameter. The status of the current animation is recorded. 137 | -------------------------------------------------------------------------------- /src/PixiApngAndGif.es6: -------------------------------------------------------------------------------- 1 | import $getExeName from './lib/_getExeName' // 用于获取路径扩展名 2 | import $omggif from './lib/_omggif' // gif图片编解码 3 | import $upngjs from './lib/_upng' // png图片编解码 4 | 5 | class Image{ 6 | constructor(esource,resources){ 7 | const _ts = this; 8 | _ts.esource = esource; 9 | _ts.resources = resources; 10 | 11 | _ts.init(); 12 | } 13 | init(){ 14 | const _ts = this, 15 | esource = _ts.esource, 16 | resources = _ts.resources; 17 | 18 | _ts.temp = { // 临时数据 19 | //loop:0, // 保存当前需要播放的次数 20 | //tickerIsAdd:undefined // 保存轮循执行器是否添加 21 | events:{} // 用于存放事件 22 | }; 23 | 24 | // 属性 25 | _ts.__attr = { 26 | autoPlay:true, // 默认自动播放 27 | loop:0 // 默认无限次播放 28 | }; 29 | 30 | // 方法 31 | _ts.__method = { 32 | play:_ts.play // 播放方法 33 | }; 34 | 35 | // 状态 36 | _ts.__status = { 37 | status:'init', // 状态,默认初始化(init、playing、played、pause、stop) 38 | frame:0, // 当前帧数 39 | loops:0, // 连续循环播放次数,停止播放会清0 40 | time:0 41 | }; 42 | 43 | // 循环执行器 44 | _ts.ticker = new PIXI.Ticker(); 45 | _ts.ticker.stop(); 46 | 47 | // 精灵 48 | _ts.sprite = this.createSprite(esource,resources); 49 | } 50 | 51 | // 播放 52 | play(loop,callback){ 53 | const _ts = this; 54 | 55 | // 没有纹理材质时抛出错误 56 | if(!_ts.textures.length){ 57 | throw new Error('没有可用的textures'); 58 | }; 59 | 60 | // 纹理材质只有一帧时不往下执行 61 | if(_ts.textures.length === 1){ 62 | return; 63 | }; 64 | 65 | let status = _ts.__status, 66 | attr = _ts.__attr, 67 | time = 0; 68 | 69 | // 当状态是停止的时候,将播放次数清0 70 | if(status.status === 'stop'){ 71 | status.loops = 0; 72 | }; 73 | 74 | // 设置循环参数 75 | loop = typeof loop === 'number' ? loop : attr.loop; 76 | _ts.temp.loop = loop; 77 | attr.loop = loop; 78 | 79 | // 为轮循执行器添加一个操作 80 | if(!_ts.temp.tickerIsAdd){ 81 | _ts.ticker.add(deltaTime => { 82 | let elapsed = PIXI.Ticker.shared.elapsedMS; 83 | time+=elapsed; 84 | 85 | // 当帧停留时间已达到间隔帧率时播放下一帧 86 | if(time > _ts.framesDelay[status.frame]){ 87 | status.frame++; 88 | 89 | // 修改状态为执行中 90 | status.status = 'playing'; 91 | 92 | // 当一次播放完成,将播放帧归0,并记录播放次数 93 | if(status.frame > _ts.textures.length - 1){ 94 | status.frame = 0; 95 | status.loops++; 96 | 97 | // 当指定了有效的播放次数并且当前播放次数达到指定次数时,执行回调则停止播放 98 | if(_ts.temp.loop > 0 && status.loops >= _ts.temp.loop){ 99 | if(typeof callback === 'function'){ 100 | callback(status); 101 | }; 102 | // 修改状态为执行完成并停止 103 | status.status = 'played'; 104 | _ts.runEvent('played',status); 105 | _ts.stop(); 106 | }; 107 | }; 108 | 109 | // 修改精灵纹理材质与当前的帧率相匹配 110 | _ts.sprite.texture = _ts.textures[status.frame]; 111 | time = 0; 112 | 113 | _ts.runEvent('playing',status); 114 | }; 115 | }); 116 | _ts.temp.tickerIsAdd = true; 117 | }; 118 | 119 | // 让轮循执行器开始执行 120 | _ts.ticker.start(); 121 | } 122 | 123 | // 暂停 124 | pause(){ 125 | const _ts = this, 126 | status = _ts.__status; 127 | _ts.ticker.stop(); 128 | status.status = 'pause'; 129 | _ts.runEvent('pause',status); 130 | } 131 | 132 | // 停止播放并跳至第一帧 133 | stop(){ 134 | const _ts = this, 135 | status = _ts.__status; 136 | _ts.ticker.stop(); 137 | status.status = 'stop'; 138 | _ts.runEvent('stop',status); 139 | } 140 | 141 | // 跳至指定的帧数 142 | jumpToFrame(frameIndex){ 143 | const _ts = this, 144 | textures = _ts.textures; 145 | 146 | // 没有纹理材质时抛出错误 147 | if(!textures.length){ 148 | throw new Error('没有可用的textures'); 149 | }; 150 | 151 | let status = _ts.__status; 152 | 153 | frameIndex = frameIndex < 0 ? 0 : frameIndex > textures.length - 1 ? textures.length - 1 : frameIndex; 154 | 155 | if(typeof frameIndex === 'number'){ 156 | _ts.sprite.texture = textures[frameIndex]; 157 | status.frame = frameIndex; 158 | }; 159 | } 160 | 161 | // 获取总播放时长 162 | getDuration(){ 163 | const _ts = this, 164 | framesDelay = _ts.framesDelay; 165 | 166 | // 没有帧时间时抛出错误 167 | if(!framesDelay.length){ 168 | throw new Error('未找到图片帧时间'); 169 | }; 170 | 171 | let time = 0; 172 | 173 | for(let i=0,len=framesDelay.length; i{ 232 | let gifDecodeData = _ts.gifResourceToTextures(resources[imgSrc]); 233 | _ts.textures = gifDecodeData.textures; 234 | _ts.framesDelay = gifDecodeData.delayTimes; 235 | _ts.play(); 236 | 237 | // 返回精灵并将纹理材质设置为第一帧图像 238 | return new Sprite(_ts.textures[0]); 239 | }, 240 | 'png':()=>{ 241 | let pngDecodeData = _ts.apngResourceToTextures(resources[imgSrc]); 242 | _ts.textures = pngDecodeData.textures; 243 | _ts.framesDelay = pngDecodeData.delayTimes; 244 | _ts.play(); 245 | 246 | // 返回精灵并将纹理材质设置为第一帧图像 247 | return new Sprite(_ts.textures[0]); 248 | }, 249 | 'other':()=>{ 250 | _ts.textures = [resources[imgSrc].texture]; 251 | return new Sprite(resources[imgSrc].texture); 252 | } 253 | }; 254 | return funs[exeName](); 255 | } 256 | 257 | /** 258 | * 将apng缓存资源转换为纹理材质 259 | * @param {object} resource 缓存资源 260 | * @return {object} 返回一个对象,包括apng的每帧时长及解码出来材质 261 | */ 262 | apngResourceToTextures(resource){ 263 | const _ts = this; 264 | 265 | let obj = { 266 | delayTimes:[], 267 | textures:[] 268 | }, 269 | buf = new Uint8Array(resource.data), 270 | upng = $upngjs.decode(buf), 271 | rgba = $upngjs.toRGBA8(upng), 272 | pngWidth = upng.width, 273 | pngHeight = upng.height, 274 | pngFramesLen = upng.frames.length, 275 | 276 | spriteSheet, 277 | canvas, 278 | ctx, 279 | imageData; 280 | 281 | 282 | 283 | // 记录下每帧的时间 284 | upng.frames.forEach((item,index)=>{ 285 | obj.delayTimes.push(item.delay); 286 | }); 287 | 288 | for(let i=0,len=rgba.length; i, 2013. 2 | // 3 | // https://github.com/deanm/omggif 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to 7 | // deal in the Software without restriction, including without limitation the 8 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | // sell copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | // IN THE SOFTWARE. 22 | // 23 | // omggif is a JavaScript implementation of a GIF 89a encoder and decoder, 24 | // including animation and compression. It does not rely on any specific 25 | // underlying system, so should run in the browser, Node, or Plask. 26 | 27 | "use strict"; 28 | 29 | function GifReader(buf) { 30 | var p = 0; 31 | 32 | // - Header (GIF87a or GIF89a). 33 | if (buf[p++] !== 0x47 || buf[p++] !== 0x49 || buf[p++] !== 0x46 || 34 | buf[p++] !== 0x38 || (buf[p++] + 1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) { 35 | throw new Error("Invalid GIF 87a/89a header."); 36 | } 37 | 38 | // - Logical Screen Descriptor. 39 | var width = buf[p++] | buf[p++] << 8; 40 | var height = buf[p++] | buf[p++] << 8; 41 | var pf0 = buf[p++]; // . 42 | var global_palette_flag = pf0 >> 7; 43 | var num_global_colors_pow2 = pf0 & 0x7; 44 | var num_global_colors = 1 << (num_global_colors_pow2 + 1); 45 | var background = buf[p++]; 46 | buf[p++]; // Pixel aspect ratio (unused?). 47 | 48 | var global_palette_offset = null; 49 | var global_palette_size = null; 50 | 51 | if (global_palette_flag) { 52 | global_palette_offset = p; 53 | global_palette_size = num_global_colors; 54 | p += num_global_colors * 3; // Seek past palette. 55 | } 56 | 57 | var no_eof = true; 58 | 59 | var frames = []; 60 | 61 | var delay = 0; 62 | var transparent_index = null; 63 | var disposal = 0; // 0 - No disposal specified. 64 | var loop_count = null; 65 | 66 | this.width = width; 67 | this.height = height; 68 | 69 | while (no_eof && p < buf.length) { 70 | switch (buf[p++]) { 71 | case 0x21: // Graphics Control Extension Block 72 | switch (buf[p++]) { 73 | case 0xff: // Application specific block 74 | // Try if it's a Netscape block (with animation loop counter). 75 | if (buf[p] !== 0x0b || // 21 FF already read, check block size. 76 | // NETSCAPE2.0 77 | buf[p + 1] == 0x4e && buf[p + 2] == 0x45 && buf[p + 3] == 0x54 && 78 | buf[p + 4] == 0x53 && buf[p + 5] == 0x43 && buf[p + 6] == 0x41 && 79 | buf[p + 7] == 0x50 && buf[p + 8] == 0x45 && buf[p + 9] == 0x32 && 80 | buf[p + 10] == 0x2e && buf[p + 11] == 0x30 && 81 | // Sub-block 82 | buf[p + 12] == 0x03 && buf[p + 13] == 0x01 && buf[p + 16] == 0) { 83 | p += 14; 84 | loop_count = buf[p++] | buf[p++] << 8; 85 | p++; // Skip terminator. 86 | } else { // We don't know what it is, just try to get past it. 87 | p += 12; 88 | while (true) { // Seek through subblocks. 89 | var block_size = buf[p++]; 90 | // Bad block size (ex: undefined from an out of bounds read). 91 | if (!(block_size >= 0)) throw Error("Invalid block size"); 92 | if (block_size === 0) break; // 0 size is terminator 93 | p += block_size; 94 | } 95 | } 96 | break; 97 | 98 | case 0xf9: // Graphics Control Extension 99 | if (buf[p++] !== 0x4 || buf[p + 4] !== 0) 100 | throw new Error("Invalid graphics extension block."); 101 | var pf1 = buf[p++]; 102 | delay = buf[p++] | buf[p++] << 8; 103 | transparent_index = buf[p++]; 104 | if ((pf1 & 1) === 0) transparent_index = null; 105 | disposal = pf1 >> 2 & 0x7; 106 | p++; // Skip terminator. 107 | break; 108 | 109 | case 0xfe: // Comment Extension. 110 | while (true) { // Seek through subblocks. 111 | var block_size = buf[p++]; 112 | // Bad block size (ex: undefined from an out of bounds read). 113 | if (!(block_size >= 0)) throw Error("Invalid block size"); 114 | if (block_size === 0) break; // 0 size is terminator 115 | // console.log(buf.slice(p, p+block_size).toString('ascii')); 116 | p += block_size; 117 | } 118 | break; 119 | 120 | default: 121 | throw new Error( 122 | "Unknown graphic control label: 0x" + buf[p - 1].toString(16)); 123 | } 124 | break; 125 | 126 | case 0x2c: // Image Descriptor. 127 | var x = buf[p++] | buf[p++] << 8; 128 | var y = buf[p++] | buf[p++] << 8; 129 | var w = buf[p++] | buf[p++] << 8; 130 | var h = buf[p++] | buf[p++] << 8; 131 | var pf2 = buf[p++]; 132 | var local_palette_flag = pf2 >> 7; 133 | var interlace_flag = pf2 >> 6 & 1; 134 | var num_local_colors_pow2 = pf2 & 0x7; 135 | var num_local_colors = 1 << (num_local_colors_pow2 + 1); 136 | var palette_offset = global_palette_offset; 137 | var palette_size = global_palette_size; 138 | var has_local_palette = false; 139 | if (local_palette_flag) { 140 | var has_local_palette = true; 141 | palette_offset = p; // Override with local palette. 142 | palette_size = num_local_colors; 143 | p += num_local_colors * 3; // Seek past palette. 144 | } 145 | 146 | var data_offset = p; 147 | 148 | p++; // codesize 149 | while (true) { 150 | var block_size = buf[p++]; 151 | // Bad block size (ex: undefined from an out of bounds read). 152 | if (!(block_size >= 0)) throw Error("Invalid block size"); 153 | if (block_size === 0) break; // 0 size is terminator 154 | p += block_size; 155 | } 156 | 157 | frames.push({ 158 | x: x, 159 | y: y, 160 | width: w, 161 | height: h, 162 | has_local_palette: has_local_palette, 163 | palette_offset: palette_offset, 164 | palette_size: palette_size, 165 | data_offset: data_offset, 166 | data_length: p - data_offset, 167 | transparent_index: transparent_index, 168 | interlaced: !!interlace_flag, 169 | delay: delay, 170 | disposal: disposal 171 | }); 172 | break; 173 | 174 | case 0x3b: // Trailer Marker (end of file). 175 | no_eof = false; 176 | break; 177 | 178 | default: 179 | throw new Error("Unknown gif block: 0x" + buf[p - 1].toString(16)); 180 | break; 181 | } 182 | } 183 | 184 | this.numFrames = function () { 185 | return frames.length; 186 | }; 187 | 188 | this.loopCount = function () { 189 | return loop_count; 190 | }; 191 | 192 | this.frameInfo = function (frame_num) { 193 | if (frame_num < 0 || frame_num >= frames.length) 194 | throw new Error("Frame index out of range."); 195 | return frames[frame_num]; 196 | } 197 | 198 | this.decodeAndBlitFrameBGRA = function (frame_num, pixels) { 199 | var frame = this.frameInfo(frame_num); 200 | var num_pixels = frame.width * frame.height; 201 | var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices. 202 | GifReaderLZWOutputIndexStream( 203 | buf, frame.data_offset, index_stream, num_pixels); 204 | var palette_offset = frame.palette_offset; 205 | 206 | // NOTE(deanm): It seems to be much faster to compare index to 256 than 207 | // to === null. Not sure why, but CompareStub_EQ_STRICT shows up high in 208 | // the profile, not sure if it's related to using a Uint8Array. 209 | var trans = frame.transparent_index; 210 | if (trans === null) trans = 256; 211 | 212 | // We are possibly just blitting to a portion of the entire frame. 213 | // That is a subrect within the framerect, so the additional pixels 214 | // must be skipped over after we finished a scanline. 215 | var framewidth = frame.width; 216 | var framestride = width - framewidth; 217 | var xleft = framewidth; // Number of subrect pixels left in scanline. 218 | 219 | // Output indicies of the top left and bottom right corners of the subrect. 220 | var opbeg = ((frame.y * width) + frame.x) * 4; 221 | var opend = ((frame.y + frame.height) * width + frame.x) * 4; 222 | var op = opbeg; 223 | 224 | var scanstride = framestride * 4; 225 | 226 | // Use scanstride to skip past the rows when interlacing. This is skipping 227 | // 7 rows for the first two passes, then 3 then 1. 228 | if (frame.interlaced === true) { 229 | scanstride += width * 4 * 7; // Pass 1. 230 | } 231 | 232 | var interlaceskip = 8; // Tracking the row interval in the current pass. 233 | 234 | for (var i = 0, il = index_stream.length; i < il; ++i) { 235 | var index = index_stream[i]; 236 | 237 | if (xleft === 0) { // Beginning of new scan line 238 | op += scanstride; 239 | xleft = framewidth; 240 | if (op >= opend) { // Catch the wrap to switch passes when interlacing. 241 | scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); 242 | // interlaceskip / 2 * 4 is interlaceskip << 1. 243 | op = opbeg + (framewidth + framestride) * (interlaceskip << 1); 244 | interlaceskip >>= 1; 245 | } 246 | } 247 | 248 | if (index === trans) { 249 | op += 4; 250 | } else { 251 | var r = buf[palette_offset + index * 3]; 252 | var g = buf[palette_offset + index * 3 + 1]; 253 | var b = buf[palette_offset + index * 3 + 2]; 254 | pixels[op++] = b; 255 | pixels[op++] = g; 256 | pixels[op++] = r; 257 | pixels[op++] = 255; 258 | } 259 | --xleft; 260 | } 261 | }; 262 | 263 | // I will go to copy and paste hell one day... 264 | this.decodeAndBlitFrameRGBA = function (frame_num, pixels) { 265 | var frame = this.frameInfo(frame_num); 266 | var num_pixels = frame.width * frame.height; 267 | var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices. 268 | GifReaderLZWOutputIndexStream( 269 | buf, frame.data_offset, index_stream, num_pixels); 270 | var palette_offset = frame.palette_offset; 271 | 272 | // NOTE(deanm): It seems to be much faster to compare index to 256 than 273 | // to === null. Not sure why, but CompareStub_EQ_STRICT shows up high in 274 | // the profile, not sure if it's related to using a Uint8Array. 275 | var trans = frame.transparent_index; 276 | if (trans === null) trans = 256; 277 | 278 | // We are possibly just blitting to a portion of the entire frame. 279 | // That is a subrect within the framerect, so the additional pixels 280 | // must be skipped over after we finished a scanline. 281 | var framewidth = frame.width; 282 | var framestride = width - framewidth; 283 | var xleft = framewidth; // Number of subrect pixels left in scanline. 284 | 285 | // Output indicies of the top left and bottom right corners of the subrect. 286 | var opbeg = ((frame.y * width) + frame.x) * 4; 287 | var opend = ((frame.y + frame.height) * width + frame.x) * 4; 288 | var op = opbeg; 289 | 290 | var scanstride = framestride * 4; 291 | 292 | // Use scanstride to skip past the rows when interlacing. This is skipping 293 | // 7 rows for the first two passes, then 3 then 1. 294 | if (frame.interlaced === true) { 295 | scanstride += width * 4 * 7; // Pass 1. 296 | } 297 | 298 | var interlaceskip = 8; // Tracking the row interval in the current pass. 299 | 300 | for (var i = 0, il = index_stream.length; i < il; ++i) { 301 | var index = index_stream[i]; 302 | 303 | if (xleft === 0) { // Beginning of new scan line 304 | op += scanstride; 305 | xleft = framewidth; 306 | if (op >= opend) { // Catch the wrap to switch passes when interlacing. 307 | scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); 308 | // interlaceskip / 2 * 4 is interlaceskip << 1. 309 | op = opbeg + (framewidth + framestride) * (interlaceskip << 1); 310 | interlaceskip >>= 1; 311 | } 312 | } 313 | 314 | if (index === trans) { 315 | op += 4; 316 | } else { 317 | var r = buf[palette_offset + index * 3]; 318 | var g = buf[palette_offset + index * 3 + 1]; 319 | var b = buf[palette_offset + index * 3 + 2]; 320 | pixels[op++] = r; 321 | pixels[op++] = g; 322 | pixels[op++] = b; 323 | pixels[op++] = 255; 324 | } 325 | --xleft; 326 | } 327 | }; 328 | } 329 | 330 | function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) { 331 | var min_code_size = code_stream[p++]; 332 | 333 | var clear_code = 1 << min_code_size; 334 | var eoi_code = clear_code + 1; 335 | var next_code = eoi_code + 1; 336 | 337 | var cur_code_size = min_code_size + 1; // Number of bits per code. 338 | // NOTE: This shares the same name as the encoder, but has a different 339 | // meaning here. Here this masks each code coming from the code stream. 340 | var code_mask = (1 << cur_code_size) - 1; 341 | var cur_shift = 0; 342 | var cur = 0; 343 | 344 | var op = 0; // Output pointer. 345 | 346 | var subblock_size = code_stream[p++]; 347 | 348 | // TODO(deanm): Would using a TypedArray be any faster? At least it would 349 | // solve the fast mode / backing store uncertainty. 350 | // var code_table = Array(4096); 351 | var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits. 352 | 353 | var prev_code = null; // Track code-1. 354 | 355 | while (true) { 356 | // Read up to two bytes, making sure we always 12-bits for max sized code. 357 | while (cur_shift < 16) { 358 | if (subblock_size === 0) break; // No more data to be read. 359 | 360 | cur |= code_stream[p++] << cur_shift; 361 | cur_shift += 8; 362 | 363 | if (subblock_size === 1) { // Never let it get to 0 to hold logic above. 364 | subblock_size = code_stream[p++]; // Next subblock. 365 | } else { 366 | --subblock_size; 367 | } 368 | } 369 | 370 | // TODO(deanm): We should never really get here, we should have received 371 | // and EOI. 372 | if (cur_shift < cur_code_size) 373 | break; 374 | 375 | var code = cur & code_mask; 376 | cur >>= cur_code_size; 377 | cur_shift -= cur_code_size; 378 | 379 | // TODO(deanm): Maybe should check that the first code was a clear code, 380 | // at least this is what you're supposed to do. But actually our encoder 381 | // now doesn't emit a clear code first anyway. 382 | if (code === clear_code) { 383 | // We don't actually have to clear the table. This could be a good idea 384 | // for greater error checking, but we don't really do any anyway. We 385 | // will just track it with next_code and overwrite old entries. 386 | 387 | next_code = eoi_code + 1; 388 | cur_code_size = min_code_size + 1; 389 | code_mask = (1 << cur_code_size) - 1; 390 | 391 | // Don't update prev_code ? 392 | prev_code = null; 393 | continue; 394 | } else if (code === eoi_code) { 395 | break; 396 | } 397 | 398 | // We have a similar situation as the decoder, where we want to store 399 | // variable length entries (code table entries), but we want to do in a 400 | // faster manner than an array of arrays. The code below stores sort of a 401 | // linked list within the code table, and then "chases" through it to 402 | // construct the dictionary entries. When a new entry is created, just the 403 | // last byte is stored, and the rest (prefix) of the entry is only 404 | // referenced by its table entry. Then the code chases through the 405 | // prefixes until it reaches a single byte code. We have to chase twice, 406 | // first to compute the length, and then to actually copy the data to the 407 | // output (backwards, since we know the length). The alternative would be 408 | // storing something in an intermediate stack, but that doesn't make any 409 | // more sense. I implemented an approach where it also stored the length 410 | // in the code table, although it's a bit tricky because you run out of 411 | // bits (12 + 12 + 8), but I didn't measure much improvements (the table 412 | // entries are generally not the long). Even when I created benchmarks for 413 | // very long table entries the complexity did not seem worth it. 414 | // The code table stores the prefix entry in 12 bits and then the suffix 415 | // byte in 8 bits, so each entry is 20 bits. 416 | 417 | var chase_code = code < next_code ? code : prev_code; 418 | 419 | // Chase what we will output, either {CODE} or {CODE-1}. 420 | var chase_length = 0; 421 | var chase = chase_code; 422 | while (chase > clear_code) { 423 | chase = code_table[chase] >> 8; 424 | ++chase_length; 425 | } 426 | 427 | var k = chase; 428 | 429 | var op_end = op + chase_length + (chase_code !== code ? 1 : 0); 430 | if (op_end > output_length) { 431 | console.log("Warning, gif stream longer than expected."); 432 | return; 433 | } 434 | 435 | // Already have the first byte from the chase, might as well write it fast. 436 | output[op++] = k; 437 | 438 | op += chase_length; 439 | var b = op; // Track pointer, writing backwards. 440 | 441 | if (chase_code !== code) // The case of emitting {CODE-1} + k. 442 | output[op++] = k; 443 | 444 | chase = chase_code; 445 | while (chase_length--) { 446 | chase = code_table[chase]; 447 | output[--b] = chase & 0xff; // Write backwards. 448 | chase >>= 8; // Pull down to the prefix code. 449 | } 450 | 451 | if (prev_code !== null && next_code < 4096) { 452 | code_table[next_code++] = prev_code << 8 | k; 453 | // TODO(deanm): Figure out this clearing vs code growth logic better. I 454 | // have an feeling that it should just happen somewhere else, for now it 455 | // is awkward between when we grow past the max and then hit a clear code. 456 | // For now just check if we hit the max 12-bits (then a clear code should 457 | // follow, also of course encoded in 12-bits). 458 | if (next_code >= code_mask + 1 && cur_code_size < 12) { 459 | ++cur_code_size; 460 | code_mask = code_mask << 1 | 1; 461 | } 462 | } 463 | 464 | prev_code = code; 465 | } 466 | 467 | if (op !== output_length) { 468 | console.log("Warning, gif stream shorter than expected."); 469 | } 470 | 471 | return output; 472 | } 473 | 474 | export default GifReader; -------------------------------------------------------------------------------- /src/lib/_upng.es6: -------------------------------------------------------------------------------- 1 | import pako from 'pako' 2 | 3 | var UPNG = {}; 4 | 5 | if (Uint8Array && !Uint8Array.prototype.slice) { 6 | Uint8Array.prototype.slice = function (...arg) { 7 | return new Uint8Array(this).subarray(...arg); 8 | }; 9 | }; 10 | (function (UPNG, pako) { 11 | UPNG.toRGBA8 = function (out) { 12 | var w = out.width, 13 | h = out.height; 14 | if (out.tabs.acTL == null) return [UPNG.toRGBA8.decodeImage(out.data, w, h, out).buffer]; 15 | 16 | var frms = []; 17 | if (out.frames[0].data == null) out.frames[0].data = out.data; 18 | 19 | var img, empty = new Uint8Array(w * h * 4); 20 | for (var i = 0; i < out.frames.length; i++) { 21 | var frm = out.frames[i]; 22 | var fx = frm.rect.x, 23 | fy = frm.rect.y, 24 | fw = frm.rect.width, 25 | fh = frm.rect.height; 26 | var fdata = UPNG.toRGBA8.decodeImage(frm.data, fw, fh, out); 27 | 28 | if (i == 0) img = fdata; 29 | else if (frm.blend == 0) UPNG._copyTile(fdata, fw, fh, img, w, h, fx, fy, 0); 30 | else if (frm.blend == 1) UPNG._copyTile(fdata, fw, fh, img, w, h, fx, fy, 1); 31 | 32 | frms.push(img.buffer); 33 | img = img.slice(0); 34 | 35 | if (frm.dispose == 0) {} else if (frm.dispose == 1) UPNG._copyTile(empty, fw, fh, img, w, h, fx, fy, 0); 36 | else if (frm.dispose == 2) { 37 | var pi = i - 1; 38 | while (out.frames[pi].dispose == 2) pi--; 39 | img = new Uint8Array(frms[pi]).slice(0); 40 | } 41 | } 42 | return frms; 43 | } 44 | UPNG.toRGBA8.decodeImage = function (data, w, h, out) { 45 | var area = w * h, 46 | bpp = UPNG.decode._getBPP(out); 47 | var bpl = Math.ceil(w * bpp / 8); // bytes per line 48 | var bf = new Uint8Array(area * 4), 49 | bf32 = new Uint32Array(bf.buffer); 50 | var ctype = out.ctype, 51 | depth = out.depth; 52 | var rs = UPNG._bin.readUshort; 53 | 54 | //console.log(ctype, depth); 55 | if (ctype == 6) { // RGB + alpha 56 | var qarea = area << 2; 57 | if (depth == 8) 58 | for (var i = 0; i < qarea; i++) { 59 | bf[i] = data[i]; 60 | /*if((i&3)==3 && data[i]!=0) bf[i]=255;*/ 61 | } 62 | if (depth == 16) 63 | for (var i = 0; i < qarea; i++) { 64 | bf[i] = data[i << 1]; 65 | } 66 | } else if (ctype == 2) { // RGB 67 | var ts = out.tabs["tRNS"], 68 | tr = -1, 69 | tg = -1, 70 | tb = -1; 71 | if (ts) { 72 | tr = ts[0]; 73 | tg = ts[1]; 74 | tb = ts[2]; 75 | } 76 | if (depth == 8) 77 | for (var i = 0; i < area; i++) { 78 | var qi = i << 2, 79 | ti = i * 3; 80 | bf[qi] = data[ti]; 81 | bf[qi + 1] = data[ti + 1]; 82 | bf[qi + 2] = data[ti + 2]; 83 | bf[qi + 3] = 255; 84 | if (tr != -1 && data[ti] == tr && data[ti + 1] == tg && data[ti + 2] == tb) bf[qi + 3] = 0; 85 | } 86 | if (depth == 16) 87 | for (var i = 0; i < area; i++) { 88 | var qi = i << 2, 89 | ti = i * 6; 90 | bf[qi] = data[ti]; 91 | bf[qi + 1] = data[ti + 2]; 92 | bf[qi + 2] = data[ti + 4]; 93 | bf[qi + 3] = 255; 94 | if (tr != -1 && rs(data, ti) == tr && rs(data, ti + 2) == tg && rs(data, ti + 4) == tb) bf[qi + 3] = 0; 95 | } 96 | } else if (ctype == 3) { // palette 97 | var p = out.tabs["PLTE"], 98 | ap = out.tabs["tRNS"], 99 | tl = ap ? ap.length : 0; 100 | //console.log(p, ap); 101 | if (depth == 1) 102 | for (var y = 0; y < h; y++) { 103 | var s0 = y * bpl, 104 | t0 = y * w; 105 | for (var i = 0; i < w; i++) { 106 | var qi = (t0 + i) << 2, 107 | j = ((data[s0 + (i >> 3)] >> (7 - ((i & 7) << 0))) & 1), 108 | cj = 3 * j; 109 | bf[qi] = p[cj]; 110 | bf[qi + 1] = p[cj + 1]; 111 | bf[qi + 2] = p[cj + 2]; 112 | bf[qi + 3] = (j < tl) ? ap[j] : 255; 113 | } 114 | } 115 | if (depth == 2) 116 | for (var y = 0; y < h; y++) { 117 | var s0 = y * bpl, 118 | t0 = y * w; 119 | for (var i = 0; i < w; i++) { 120 | var qi = (t0 + i) << 2, 121 | j = ((data[s0 + (i >> 2)] >> (6 - ((i & 3) << 1))) & 3), 122 | cj = 3 * j; 123 | bf[qi] = p[cj]; 124 | bf[qi + 1] = p[cj + 1]; 125 | bf[qi + 2] = p[cj + 2]; 126 | bf[qi + 3] = (j < tl) ? ap[j] : 255; 127 | } 128 | } 129 | if (depth == 4) 130 | for (var y = 0; y < h; y++) { 131 | var s0 = y * bpl, 132 | t0 = y * w; 133 | for (var i = 0; i < w; i++) { 134 | var qi = (t0 + i) << 2, 135 | j = ((data[s0 + (i >> 1)] >> (4 - ((i & 1) << 2))) & 15), 136 | cj = 3 * j; 137 | bf[qi] = p[cj]; 138 | bf[qi + 1] = p[cj + 1]; 139 | bf[qi + 2] = p[cj + 2]; 140 | bf[qi + 3] = (j < tl) ? ap[j] : 255; 141 | } 142 | } 143 | if (depth == 8) 144 | for (var i = 0; i < area; i++) { 145 | var qi = i << 2, 146 | j = data[i], 147 | cj = 3 * j; 148 | bf[qi] = p[cj]; 149 | bf[qi + 1] = p[cj + 1]; 150 | bf[qi + 2] = p[cj + 2]; 151 | bf[qi + 3] = (j < tl) ? ap[j] : 255; 152 | } 153 | } else if (ctype == 4) { // gray + alpha 154 | if (depth == 8) 155 | for (var i = 0; i < area; i++) { 156 | var qi = i << 2, 157 | di = i << 1, 158 | gr = data[di]; 159 | bf[qi] = gr; 160 | bf[qi + 1] = gr; 161 | bf[qi + 2] = gr; 162 | bf[qi + 3] = data[di + 1]; 163 | } 164 | if (depth == 16) 165 | for (var i = 0; i < area; i++) { 166 | var qi = i << 2, 167 | di = i << 2, 168 | gr = data[di]; 169 | bf[qi] = gr; 170 | bf[qi + 1] = gr; 171 | bf[qi + 2] = gr; 172 | bf[qi + 3] = data[di + 2]; 173 | } 174 | } else if (ctype == 0) { // gray 175 | var tr = out.tabs["tRNS"] ? out.tabs["tRNS"] : -1; 176 | if (depth == 1) 177 | for (var i = 0; i < area; i++) { 178 | var gr = 255 * ((data[i >> 3] >> (7 - ((i & 7)))) & 1), 179 | al = (gr == tr * 255) ? 0 : 255; 180 | bf32[i] = (al << 24) | (gr << 16) | (gr << 8) | gr; 181 | } 182 | if (depth == 2) 183 | for (var i = 0; i < area; i++) { 184 | var gr = 85 * ((data[i >> 2] >> (6 - ((i & 3) << 1))) & 3), 185 | al = (gr == tr * 85) ? 0 : 255; 186 | bf32[i] = (al << 24) | (gr << 16) | (gr << 8) | gr; 187 | } 188 | if (depth == 4) 189 | for (var i = 0; i < area; i++) { 190 | var gr = 17 * ((data[i >> 1] >> (4 - ((i & 1) << 2))) & 15), 191 | al = (gr == tr * 17) ? 0 : 255; 192 | bf32[i] = (al << 24) | (gr << 16) | (gr << 8) | gr; 193 | } 194 | if (depth == 8) 195 | for (var i = 0; i < area; i++) { 196 | var gr = data[i], 197 | al = (gr == tr) ? 0 : 255; 198 | bf32[i] = (al << 24) | (gr << 16) | (gr << 8) | gr; 199 | } 200 | if (depth == 16) 201 | for (var i = 0; i < area; i++) { 202 | var gr = data[i << 1], 203 | al = (rs(data, i << 1) == tr) ? 0 : 255; 204 | bf32[i] = (al << 24) | (gr << 16) | (gr << 8) | gr; 205 | } 206 | } 207 | return bf; 208 | } 209 | 210 | UPNG.decode = function (buff) { 211 | var data = new Uint8Array(buff), 212 | offset = 8, 213 | bin = UPNG._bin, 214 | rUs = bin.readUshort, 215 | rUi = bin.readUint; 216 | var out = { 217 | tabs: {}, 218 | frames: [] 219 | }; 220 | var dd = new Uint8Array(data.length), 221 | doff = 0; // put all IDAT data into it 222 | var fd, foff = 0; // frames 223 | var mgck = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; 224 | for (var i = 0; i < 8; i++) 225 | if (data[i] != mgck[i]) throw "The input is not a PNG file!"; 226 | 227 | while (offset < data.length) { 228 | var len = bin.readUint(data, offset); 229 | offset += 4; 230 | var type = bin.readASCII(data, offset, 4); 231 | offset += 4; 232 | //console.log(type,len); 233 | if (type == "IHDR") { 234 | UPNG.decode._IHDR(data, offset, out); 235 | } else if (type == "IDAT") { 236 | for (var i = 0; i < len; i++) dd[doff + i] = data[offset + i]; 237 | doff += len; 238 | } else if (type == "acTL") { 239 | out.tabs[type] = { 240 | num_frames: rUi(data, offset), 241 | num_plays: rUi(data, offset + 4) 242 | }; 243 | fd = new Uint8Array(data.length); 244 | } else if (type == "fcTL") { 245 | if (foff != 0) { 246 | var fr = out.frames[out.frames.length - 1]; 247 | fr.data = UPNG.decode._decompress(out, fd.slice(0, foff), fr.rect.width, fr.rect.height); 248 | foff = 0; 249 | } 250 | var rct = { 251 | x: rUi(data, offset + 12), 252 | y: rUi(data, offset + 16), 253 | width: rUi(data, offset + 4), 254 | height: rUi(data, offset + 8) 255 | }; 256 | var del = rUs(data, offset + 22); 257 | del = rUs(data, offset + 20) / (del == 0 ? 100 : del); 258 | var frm = { 259 | rect: rct, 260 | delay: Math.round(del * 1000), 261 | dispose: data[offset + 24], 262 | blend: data[offset + 25] 263 | }; 264 | //console.log(frm); 265 | out.frames.push(frm); 266 | } else if (type == "fdAT") { 267 | for (var i = 0; i < len - 4; i++) fd[foff + i] = data[offset + i + 4]; 268 | foff += len - 4; 269 | } else if (type == "pHYs") { 270 | out.tabs[type] = [bin.readUint(data, offset), bin.readUint(data, offset + 4), data[offset + 8]]; 271 | } else if (type == "cHRM") { 272 | out.tabs[type] = []; 273 | for (var i = 0; i < 8; i++) out.tabs[type].push(bin.readUint(data, offset + i * 4)); 274 | } else if (type == "tEXt") { 275 | if (out.tabs[type] == null) out.tabs[type] = {}; 276 | var nz = bin.nextZero(data, offset); 277 | var keyw = bin.readASCII(data, offset, nz - offset); 278 | var text = bin.readASCII(data, nz + 1, offset + len - nz - 1); 279 | out.tabs[type][keyw] = text; 280 | } else if (type == "iTXt") { 281 | if (out.tabs[type] == null) out.tabs[type] = {}; 282 | var nz = 0, 283 | off = offset; 284 | nz = bin.nextZero(data, off); 285 | var keyw = bin.readASCII(data, off, nz - off); 286 | off = nz + 1; 287 | var cflag = data[off], 288 | cmeth = data[off + 1]; 289 | off += 2; 290 | nz = bin.nextZero(data, off); 291 | var ltag = bin.readASCII(data, off, nz - off); 292 | off = nz + 1; 293 | nz = bin.nextZero(data, off); 294 | var tkeyw = bin.readUTF8(data, off, nz - off); 295 | off = nz + 1; 296 | var text = bin.readUTF8(data, off, len - (off - offset)); 297 | out.tabs[type][keyw] = text; 298 | } else if (type == "PLTE") { 299 | out.tabs[type] = bin.readBytes(data, offset, len); 300 | } else if (type == "hIST") { 301 | var pl = out.tabs["PLTE"].length / 3; 302 | out.tabs[type] = []; 303 | for (var i = 0; i < pl; i++) out.tabs[type].push(rUs(data, offset + i * 2)); 304 | } else if (type == "tRNS") { 305 | if (out.ctype == 3) out.tabs[type] = bin.readBytes(data, offset, len); 306 | else if (out.ctype == 0) out.tabs[type] = rUs(data, offset); 307 | else if (out.ctype == 2) out.tabs[type] = [rUs(data, offset), rUs(data, offset + 2), rUs(data, offset + 4)]; 308 | //else console.log("tRNS for unsupported color type",out.ctype, len); 309 | } else if (type == "gAMA") out.tabs[type] = bin.readUint(data, offset) / 100000; 310 | else if (type == "sRGB") out.tabs[type] = data[offset]; 311 | else if (type == "bKGD") { 312 | if (out.ctype == 0 || out.ctype == 4) out.tabs[type] = [rUs(data, offset)]; 313 | else if (out.ctype == 2 || out.ctype == 6) out.tabs[type] = [rUs(data, offset), rUs(data, offset + 2), rUs(data, offset + 4)]; 314 | else if (out.ctype == 3) out.tabs[type] = data[offset]; 315 | } else if (type == "IEND") { 316 | break; 317 | } 318 | offset += len; 319 | var crc = bin.readUint(data, offset); 320 | offset += 4; 321 | } 322 | if (foff != 0) { 323 | var fr = out.frames[out.frames.length - 1]; 324 | fr.data = UPNG.decode._decompress(out, fd.slice(0, foff), fr.rect.width, fr.rect.height); 325 | foff = 0; 326 | } 327 | out.data = UPNG.decode._decompress(out, dd, out.width, out.height); 328 | 329 | delete out.compress; 330 | delete out.interlace; 331 | delete out.filter; 332 | return out; 333 | } 334 | 335 | UPNG.decode._decompress = function (out, dd, w, h) { 336 | if (out.compress == 0) dd = UPNG.decode._inflate(dd); 337 | 338 | if (out.interlace == 0) dd = UPNG.decode._filterZero(dd, out, 0, w, h); 339 | else if (out.interlace == 1) dd = UPNG.decode._readInterlace(dd, out); 340 | return dd; 341 | } 342 | 343 | UPNG.decode._inflate = function (data) { 344 | return pako["inflate"](data); 345 | } 346 | 347 | UPNG.decode._readInterlace = function (data, out) { 348 | var w = out.width, 349 | h = out.height; 350 | var bpp = UPNG.decode._getBPP(out), 351 | cbpp = bpp >> 3, 352 | bpl = Math.ceil(w * bpp / 8); 353 | var img = new Uint8Array(h * bpl); 354 | var di = 0; 355 | 356 | var starting_row = [0, 0, 4, 0, 2, 0, 1]; 357 | var starting_col = [0, 4, 0, 2, 0, 1, 0]; 358 | var row_increment = [8, 8, 8, 4, 4, 2, 2]; 359 | var col_increment = [8, 8, 4, 4, 2, 2, 1]; 360 | 361 | var pass = 0; 362 | while (pass < 7) { 363 | var ri = row_increment[pass], 364 | ci = col_increment[pass]; 365 | var sw = 0, 366 | sh = 0; 367 | var cr = starting_row[pass]; 368 | while (cr < h) { 369 | cr += ri; 370 | sh++; 371 | } 372 | var cc = starting_col[pass]; 373 | while (cc < w) { 374 | cc += ci; 375 | sw++; 376 | } 377 | var bpll = Math.ceil(sw * bpp / 8); 378 | UPNG.decode._filterZero(data, out, di, sw, sh); 379 | 380 | var y = 0, 381 | row = starting_row[pass]; 382 | while (row < h) { 383 | var col = starting_col[pass]; 384 | var cdi = (di + y * bpll) << 3; 385 | 386 | while (col < w) { 387 | if (bpp == 1) { 388 | var val = data[cdi >> 3]; 389 | val = (val >> (7 - (cdi & 7))) & 1; 390 | img[row * bpl + (col >> 3)] |= (val << (7 - ((col & 3) << 0))); 391 | } 392 | if (bpp == 2) { 393 | var val = data[cdi >> 3]; 394 | val = (val >> (6 - (cdi & 7))) & 3; 395 | img[row * bpl + (col >> 2)] |= (val << (6 - ((col & 3) << 1))); 396 | } 397 | if (bpp == 4) { 398 | var val = data[cdi >> 3]; 399 | val = (val >> (4 - (cdi & 7))) & 15; 400 | img[row * bpl + (col >> 1)] |= (val << (4 - ((col & 1) << 2))); 401 | } 402 | if (bpp >= 8) { 403 | var ii = row * bpl + col * cbpp; 404 | for (var j = 0; j < cbpp; j++) img[ii + j] = data[(cdi >> 3) + j]; 405 | } 406 | cdi += bpp; 407 | col += ci; 408 | } 409 | y++; 410 | row += ri; 411 | } 412 | if (sw * sh != 0) di += sh * (1 + bpll); 413 | pass = pass + 1; 414 | } 415 | return img; 416 | } 417 | 418 | UPNG.decode._getBPP = function (out) { 419 | var noc = [1, null, 3, 1, 2, null, 4][out.ctype]; 420 | return noc * out.depth; 421 | } 422 | 423 | UPNG.decode._filterZero = function (data, out, off, w, h) { 424 | var bpp = UPNG.decode._getBPP(out), 425 | bpl = Math.ceil(w * bpp / 8), 426 | paeth = UPNG.decode._paeth; 427 | bpp = Math.ceil(bpp / 8); 428 | 429 | for (var y = 0; y < h; y++) { 430 | var i = off + y * bpl, 431 | di = i + y + 1; 432 | var type = data[di - 1]; 433 | 434 | if (type == 0) 435 | for (var x = 0; x < bpl; x++) data[i + x] = data[di + x]; 436 | else if (type == 1) { 437 | for (var x = 0; x < bpp; x++) data[i + x] = data[di + x]; 438 | for (var x = bpp; x < bpl; x++) data[i + x] = (data[di + x] + data[i + x - bpp]) & 255; 439 | } else if (y == 0) { 440 | for (var x = 0; x < bpp; x++) data[i + x] = data[di + x]; 441 | if (type == 2) 442 | for (var x = bpp; x < bpl; x++) data[i + x] = (data[di + x]) & 255; 443 | if (type == 3) 444 | for (var x = bpp; x < bpl; x++) data[i + x] = (data[di + x] + (data[i + x - bpp] >> 1)) & 255; 445 | if (type == 4) 446 | for (var x = bpp; x < bpl; x++) data[i + x] = (data[di + x] + paeth(data[i + x - bpp], 0, 0)) & 255; 447 | } else { 448 | if (type == 2) { 449 | for (var x = 0; x < bpl; x++) data[i + x] = (data[di + x] + data[i + x - bpl]) & 255; 450 | } 451 | 452 | if (type == 3) { 453 | for (var x = 0; x < bpp; x++) data[i + x] = (data[di + x] + (data[i + x - bpl] >> 1)) & 255; 454 | for (var x = bpp; x < bpl; x++) data[i + x] = (data[di + x] + ((data[i + x - bpl] + data[i + x - bpp]) >> 1)) & 255; 455 | } 456 | 457 | if (type == 4) { 458 | for (var x = 0; x < bpp; x++) data[i + x] = (data[di + x] + paeth(0, data[i + x - bpl], 0)) & 255; 459 | for (var x = bpp; x < bpl; x++) data[i + x] = (data[di + x] + paeth(data[i + x - bpp], data[i + x - bpl], data[i + x - bpp - bpl])) & 255; 460 | } 461 | } 462 | } 463 | return data; 464 | } 465 | 466 | UPNG.decode._paeth = function (a, b, c) { 467 | var p = a + b - c, 468 | pa = Math.abs(p - a), 469 | pb = Math.abs(p - b), 470 | pc = Math.abs(p - c); 471 | if (pa <= pb && pa <= pc) return a; 472 | else if (pb <= pc) return b; 473 | return c; 474 | } 475 | 476 | UPNG.decode._IHDR = function (data, offset, out) { 477 | var bin = UPNG._bin; 478 | out.width = bin.readUint(data, offset); 479 | offset += 4; 480 | out.height = bin.readUint(data, offset); 481 | offset += 4; 482 | out.depth = data[offset]; 483 | offset++; 484 | out.ctype = data[offset]; 485 | offset++; 486 | out.compress = data[offset]; 487 | offset++; 488 | out.filter = data[offset]; 489 | offset++; 490 | out.interlace = data[offset]; 491 | offset++; 492 | } 493 | 494 | UPNG._bin = { 495 | nextZero: function (data, p) { 496 | while (data[p] != 0) p++; 497 | return p; 498 | }, 499 | readUshort: function (buff, p) { 500 | return (buff[p] << 8) | buff[p + 1]; 501 | }, 502 | writeUshort: function (buff, p, n) { 503 | buff[p] = (n >> 8) & 255; 504 | buff[p + 1] = n & 255; 505 | }, 506 | readUint: function (buff, p) { 507 | return (buff[p] * (256 * 256 * 256)) + ((buff[p + 1] << 16) | (buff[p + 2] << 8) | buff[p + 3]); 508 | }, 509 | writeUint: function (buff, p, n) { 510 | buff[p] = (n >> 24) & 255; 511 | buff[p + 1] = (n >> 16) & 255; 512 | buff[p + 2] = (n >> 8) & 255; 513 | buff[p + 3] = n & 255; 514 | }, 515 | readASCII: function (buff, p, l) { 516 | var s = ""; 517 | for (var i = 0; i < l; i++) s += String.fromCharCode(buff[p + i]); 518 | return s; 519 | }, 520 | writeASCII: function (data, p, s) { 521 | for (var i = 0; i < s.length; i++) data[p + i] = s.charCodeAt(i); 522 | }, 523 | readBytes: function (buff, p, l) { 524 | var arr = []; 525 | for (var i = 0; i < l; i++) arr.push(buff[p + i]); 526 | return arr; 527 | }, 528 | pad: function (n) { 529 | return n.length < 2 ? "0" + n : n; 530 | }, 531 | readUTF8: function (buff, p, l) { 532 | var s = "", 533 | ns; 534 | for (var i = 0; i < l; i++) s += "%" + UPNG._bin.pad(buff[p + i].toString(16)); 535 | try { 536 | ns = decodeURIComponent(s); 537 | } catch (e) { 538 | return UPNG._bin.readASCII(buff, p, l); 539 | } 540 | return ns; 541 | } 542 | } 543 | UPNG._copyTile = function (sb, sw, sh, tb, tw, th, xoff, yoff, mode) { 544 | var w = Math.min(sw, tw), 545 | h = Math.min(sh, th); 546 | var si = 0, 547 | ti = 0; 548 | for (var y = 0; y < h; y++) 549 | for (var x = 0; x < w; x++) { 550 | if (xoff >= 0 && yoff >= 0) { 551 | si = (y * sw + x) << 2; 552 | ti = ((yoff + y) * tw + xoff + x) << 2; 553 | } else { 554 | si = ((-yoff + y) * sw - xoff + x) << 2; 555 | ti = (y * tw + x) << 2; 556 | } 557 | 558 | if (mode == 0) { 559 | tb[ti] = sb[si]; 560 | tb[ti + 1] = sb[si + 1]; 561 | tb[ti + 2] = sb[si + 2]; 562 | tb[ti + 3] = sb[si + 3]; 563 | } else if (mode == 1) { 564 | var fa = sb[si + 3] * (1 / 255), 565 | fr = sb[si] * fa, 566 | fg = sb[si + 1] * fa, 567 | fb = sb[si + 2] * fa; 568 | var ba = tb[ti + 3] * (1 / 255), 569 | br = tb[ti] * ba, 570 | bg = tb[ti + 1] * ba, 571 | bb = tb[ti + 2] * ba; 572 | 573 | var ifa = 1 - fa, 574 | oa = fa + ba * ifa, 575 | ioa = (oa == 0 ? 0 : 1 / oa); 576 | tb[ti + 3] = 255 * oa; 577 | tb[ti + 0] = (fr + br * ifa) * ioa; 578 | tb[ti + 1] = (fg + bg * ifa) * ioa; 579 | tb[ti + 2] = (fb + bb * ifa) * ioa; 580 | } else if (mode == 2) { // copy only differences, otherwise zero 581 | var fa = sb[si + 3], 582 | fr = sb[si], 583 | fg = sb[si + 1], 584 | fb = sb[si + 2]; 585 | var ba = tb[ti + 3], 586 | br = tb[ti], 587 | bg = tb[ti + 1], 588 | bb = tb[ti + 2]; 589 | if (fa == ba && fr == br && fg == bg && fb == bb) { 590 | tb[ti] = 0; 591 | tb[ti + 1] = 0; 592 | tb[ti + 2] = 0; 593 | tb[ti + 3] = 0; 594 | } else { 595 | tb[ti] = fr; 596 | tb[ti + 1] = fg; 597 | tb[ti + 2] = fb; 598 | tb[ti + 3] = fa; 599 | } 600 | } else if (mode == 3) { // check if can be blended 601 | var fa = sb[si + 3], 602 | fr = sb[si], 603 | fg = sb[si + 1], 604 | fb = sb[si + 2]; 605 | var ba = tb[ti + 3], 606 | br = tb[ti], 607 | bg = tb[ti + 1], 608 | bb = tb[ti + 2]; 609 | if (fa == ba && fr == br && fg == bg && fb == bb) continue; 610 | //if(fa!=255 && ba!=0) return false; 611 | if (fa < 220 && ba > 20) return false; 612 | } 613 | } 614 | return true; 615 | } 616 | 617 | UPNG.encode = function (bufs, w, h, ps, dels, forbidPlte) { 618 | if (ps == null) ps = 0; 619 | if (forbidPlte == null) forbidPlte = false; 620 | 621 | var nimg = UPNG.encode.compress(bufs, w, h, ps, false, forbidPlte); 622 | UPNG.encode.compressPNG(nimg, -1); 623 | 624 | return UPNG.encode._main(nimg, w, h, dels); 625 | } 626 | 627 | UPNG.encodeLL = function (bufs, w, h, cc, ac, depth, dels) { 628 | var nimg = { 629 | ctype: 0 + (cc == 1 ? 0 : 2) + (ac == 0 ? 0 : 4), 630 | depth: depth, 631 | frames: [] 632 | }; 633 | 634 | var bipp = (cc + ac) * depth, 635 | bipl = bipp * w; 636 | for (var i = 0; i < bufs.length; i++) nimg.frames.push({ 637 | rect: { 638 | x: 0, 639 | y: 0, 640 | width: w, 641 | height: h 642 | }, 643 | img: new Uint8Array(bufs[i]), 644 | blend: 0, 645 | dispose: 1, 646 | bpp: Math.ceil(bipp / 8), 647 | bpl: Math.ceil(bipl / 8) 648 | }); 649 | 650 | UPNG.encode.compressPNG(nimg, 4); 651 | 652 | return UPNG.encode._main(nimg, w, h, dels); 653 | } 654 | 655 | UPNG.encode._main = function (nimg, w, h, dels) { 656 | var crc = UPNG.crc.crc, 657 | wUi = UPNG._bin.writeUint, 658 | wUs = UPNG._bin.writeUshort, 659 | wAs = UPNG._bin.writeASCII; 660 | var offset = 8, 661 | anim = nimg.frames.length > 1, 662 | pltAlpha = false; 663 | 664 | var leng = 8 + (16 + 5 + 4) + (9 + 4) + (anim ? 20 : 0); 665 | if (nimg.ctype == 3) { 666 | var dl = nimg.plte.length; 667 | for (var i = 0; i < dl; i++) 668 | if ((nimg.plte[i] >>> 24) != 255) pltAlpha = true; 669 | leng += (8 + dl * 3 + 4) + (pltAlpha ? (8 + dl * 1 + 4) : 0); 670 | } 671 | for (var j = 0; j < nimg.frames.length; j++) { 672 | var fr = nimg.frames[j]; 673 | if (anim) leng += 38; 674 | leng += fr.cimg.length + 12; 675 | if (j != 0) leng += 4; 676 | } 677 | leng += 12; 678 | 679 | var data = new Uint8Array(leng); 680 | var wr = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; 681 | for (var i = 0; i < 8; i++) data[i] = wr[i]; 682 | 683 | wUi(data, offset, 13); 684 | offset += 4; 685 | wAs(data, offset, "IHDR"); 686 | offset += 4; 687 | wUi(data, offset, w); 688 | offset += 4; 689 | wUi(data, offset, h); 690 | offset += 4; 691 | data[offset] = nimg.depth; 692 | offset++; // depth 693 | data[offset] = nimg.ctype; 694 | offset++; // ctype 695 | data[offset] = 0; 696 | offset++; // compress 697 | data[offset] = 0; 698 | offset++; // filter 699 | data[offset] = 0; 700 | offset++; // interlace 701 | wUi(data, offset, crc(data, offset - 17, 17)); 702 | offset += 4; // crc 703 | // 9 bytes to say, that it is sRGB 704 | wUi(data, offset, 1); 705 | offset += 4; 706 | wAs(data, offset, "sRGB"); 707 | offset += 4; 708 | data[offset] = 1; 709 | offset++; 710 | wUi(data, offset, crc(data, offset - 5, 5)); 711 | offset += 4; // crc 712 | if (anim) { 713 | wUi(data, offset, 8); 714 | offset += 4; 715 | wAs(data, offset, "acTL"); 716 | offset += 4; 717 | wUi(data, offset, nimg.frames.length); 718 | offset += 4; 719 | wUi(data, offset, 0); 720 | offset += 4; 721 | wUi(data, offset, crc(data, offset - 12, 12)); 722 | offset += 4; // crc 723 | } 724 | 725 | if (nimg.ctype == 3) { 726 | var dl = nimg.plte.length; 727 | wUi(data, offset, dl * 3); 728 | offset += 4; 729 | wAs(data, offset, "PLTE"); 730 | offset += 4; 731 | for (var i = 0; i < dl; i++) { 732 | var ti = i * 3, 733 | c = nimg.plte[i], 734 | r = (c) & 255, 735 | g = (c >>> 8) & 255, 736 | b = (c >>> 16) & 255; 737 | data[offset + ti + 0] = r; 738 | data[offset + ti + 1] = g; 739 | data[offset + ti + 2] = b; 740 | } 741 | offset += dl * 3; 742 | wUi(data, offset, crc(data, offset - dl * 3 - 4, dl * 3 + 4)); 743 | offset += 4; // crc 744 | if (pltAlpha) { 745 | wUi(data, offset, dl); 746 | offset += 4; 747 | wAs(data, offset, "tRNS"); 748 | offset += 4; 749 | for (var i = 0; i < dl; i++) data[offset + i] = (nimg.plte[i] >>> 24) & 255; 750 | offset += dl; 751 | wUi(data, offset, crc(data, offset - dl - 4, dl + 4)); 752 | offset += 4; // crc 753 | } 754 | } 755 | 756 | var fi = 0; 757 | for (var j = 0; j < nimg.frames.length; j++) { 758 | var fr = nimg.frames[j]; 759 | if (anim) { 760 | wUi(data, offset, 26); 761 | offset += 4; 762 | wAs(data, offset, "fcTL"); 763 | offset += 4; 764 | wUi(data, offset, fi++); 765 | offset += 4; 766 | wUi(data, offset, fr.rect.width); 767 | offset += 4; 768 | wUi(data, offset, fr.rect.height); 769 | offset += 4; 770 | wUi(data, offset, fr.rect.x); 771 | offset += 4; 772 | wUi(data, offset, fr.rect.y); 773 | offset += 4; 774 | wUs(data, offset, dels[j]); 775 | offset += 2; 776 | wUs(data, offset, 1000); 777 | offset += 2; 778 | data[offset] = fr.dispose; 779 | offset++; // dispose 780 | data[offset] = fr.blend; 781 | offset++; // blend 782 | wUi(data, offset, crc(data, offset - 30, 30)); 783 | offset += 4; // crc 784 | } 785 | 786 | var imgd = fr.cimg, 787 | dl = imgd.length; 788 | wUi(data, offset, dl + (j == 0 ? 0 : 4)); 789 | offset += 4; 790 | var ioff = offset; 791 | wAs(data, offset, (j == 0) ? "IDAT" : "fdAT"); 792 | offset += 4; 793 | if (j != 0) { 794 | wUi(data, offset, fi++); 795 | offset += 4; 796 | } 797 | for (var i = 0; i < dl; i++) data[offset + i] = imgd[i]; 798 | offset += dl; 799 | wUi(data, offset, crc(data, ioff, offset - ioff)); 800 | offset += 4; // crc 801 | } 802 | 803 | wUi(data, offset, 0); 804 | offset += 4; 805 | wAs(data, offset, "IEND"); 806 | offset += 4; 807 | wUi(data, offset, crc(data, offset - 4, 4)); 808 | offset += 4; // crc 809 | return data.buffer; 810 | } 811 | 812 | UPNG.encode.compressPNG = function (out, filter) { 813 | for (var i = 0; i < out.frames.length; i++) { 814 | var frm = out.frames[i], 815 | nw = frm.rect.width, 816 | nh = frm.rect.height; 817 | var fdata = new Uint8Array(nh * frm.bpl + nh); 818 | frm.cimg = UPNG.encode._filterZero(frm.img, nh, frm.bpp, frm.bpl, fdata, filter); 819 | } 820 | } 821 | 822 | UPNG.encode.compress = function (bufs, w, h, ps, forGIF, forbidPlte) { 823 | //var time = Date.now(); 824 | if (forbidPlte == null) forbidPlte = false; 825 | 826 | var ctype = 6, 827 | depth = 8, 828 | alphaAnd = 255 829 | 830 | for (var j = 0; j < bufs.length; j++) { // when not quantized, other frames can contain colors, that are not in an initial frame 831 | var img = new Uint8Array(bufs[j]), 832 | ilen = img.length; 833 | for (var i = 0; i < ilen; i += 4) alphaAnd &= img[i + 3]; 834 | } 835 | var gotAlpha = (alphaAnd != 255); 836 | 837 | //console.log("alpha check", Date.now()-time); time = Date.now(); 838 | var brute = gotAlpha && forGIF; // brute : frames can only be copied, not "blended" 839 | var frms = UPNG.encode.framize(bufs, w, h, forGIF, brute); 840 | //console.log("framize", Date.now()-time); time = Date.now(); 841 | var cmap = {}, 842 | plte = [], 843 | inds = []; 844 | 845 | if (ps != 0) { 846 | var nbufs = []; 847 | for (var i = 0; i < frms.length; i++) nbufs.push(frms[i].img.buffer); 848 | 849 | var abuf = UPNG.encode.concatRGBA(nbufs, forGIF), 850 | qres = UPNG.quantize(abuf, ps); 851 | var cof = 0, 852 | bb = new Uint8Array(qres.abuf); 853 | for (var i = 0; i < frms.length; i++) { 854 | var ti = frms[i].img, 855 | bln = ti.length; 856 | inds.push(new Uint8Array(qres.inds.buffer, cof >> 2, bln >> 2)); 857 | for (var j = 0; j < bln; j += 4) { 858 | ti[j] = bb[cof + j]; 859 | ti[j + 1] = bb[cof + j + 1]; 860 | ti[j + 2] = bb[cof + j + 2]; 861 | ti[j + 3] = bb[cof + j + 3]; 862 | } 863 | cof += bln; 864 | } 865 | 866 | for (var i = 0; i < qres.plte.length; i++) plte.push(qres.plte[i].est.rgba); 867 | //console.log("quantize", Date.now()-time); time = Date.now(); 868 | } else { 869 | // what if ps==0, but there are <=256 colors? we still need to detect, if the palette could be used 870 | for (var j = 0; j < frms.length; j++) { // when not quantized, other frames can contain colors, that are not in an initial frame 871 | var frm = frms[j], 872 | img32 = new Uint32Array(frm.img.buffer), 873 | nw = frm.rect.width, 874 | ilen = img32.length; 875 | var ind = new Uint8Array(ilen); 876 | inds.push(ind); 877 | for (var i = 0; i < ilen; i++) { 878 | var c = img32[i]; 879 | if (i != 0 && c == img32[i - 1]) ind[i] = ind[i - 1]; 880 | else if (i > nw && c == img32[i - nw]) ind[i] = ind[i - nw]; 881 | else { 882 | var cmc = cmap[c]; 883 | if (cmc == null) { 884 | cmap[c] = cmc = plte.length; 885 | plte.push(c); 886 | if (plte.length >= 300) break; 887 | } 888 | ind[i] = cmc; 889 | } 890 | } 891 | } 892 | //console.log("make palette", Date.now()-time); time = Date.now(); 893 | } 894 | 895 | var cc = plte.length; //console.log("colors:",cc); 896 | if (cc <= 256 && forbidPlte == false) { 897 | if (cc <= 2) depth = 1; 898 | else if (cc <= 4) depth = 2; 899 | else if (cc <= 16) depth = 4; 900 | else depth = 8; 901 | if (forGIF) depth = 8; 902 | } 903 | 904 | for (var j = 0; j < frms.length; j++) { 905 | var frm = frms[j], 906 | nx = frm.rect.x, 907 | ny = frm.rect.y, 908 | nw = frm.rect.width, 909 | nh = frm.rect.height; 910 | var cimg = frm.img, 911 | cimg32 = new Uint32Array(cimg.buffer); 912 | var bpl = 4 * nw, 913 | bpp = 4; 914 | if (cc <= 256 && forbidPlte == false) { 915 | bpl = Math.ceil(depth * nw / 8); 916 | var nimg = new Uint8Array(bpl * nh); 917 | var inj = inds[j]; 918 | for (var y = 0; y < nh; y++) { 919 | var i = y * bpl, 920 | ii = y * nw; 921 | if (depth == 8) 922 | for (var x = 0; x < nw; x++) nimg[i + (x)] = (inj[ii + x]); 923 | else if (depth == 4) 924 | for (var x = 0; x < nw; x++) nimg[i + (x >> 1)] |= (inj[ii + x] << (4 - (x & 1) * 4)); 925 | else if (depth == 2) 926 | for (var x = 0; x < nw; x++) nimg[i + (x >> 2)] |= (inj[ii + x] << (6 - (x & 3) * 2)); 927 | else if (depth == 1) 928 | for (var x = 0; x < nw; x++) nimg[i + (x >> 3)] |= (inj[ii + x] << (7 - (x & 7) * 1)); 929 | } 930 | cimg = nimg; 931 | ctype = 3; 932 | bpp = 1; 933 | } else if (gotAlpha == false && frms.length == 1) { // some next "reduced" frames may contain alpha for blending 934 | var nimg = new Uint8Array(nw * nh * 3), 935 | area = nw * nh; 936 | for (var i = 0; i < area; i++) { 937 | var ti = i * 3, 938 | qi = i * 4; 939 | nimg[ti] = cimg[qi]; 940 | nimg[ti + 1] = cimg[qi + 1]; 941 | nimg[ti + 2] = cimg[qi + 2]; 942 | } 943 | cimg = nimg; 944 | ctype = 2; 945 | bpp = 3; 946 | bpl = 3 * nw; 947 | } 948 | frm.img = cimg; 949 | frm.bpl = bpl; 950 | frm.bpp = bpp; 951 | } 952 | //console.log("colors => palette indices", Date.now()-time); time = Date.now(); 953 | return { 954 | ctype: ctype, 955 | depth: depth, 956 | plte: plte, 957 | frames: frms 958 | }; 959 | } 960 | UPNG.encode.framize = function (bufs, w, h, forGIF, brute) { 961 | var frms = []; 962 | for (var j = 0; j < bufs.length; j++) { 963 | var cimg = new Uint8Array(bufs[j]), 964 | cimg32 = new Uint32Array(cimg.buffer); 965 | 966 | var nx = 0, 967 | ny = 0, 968 | nw = w, 969 | nh = h, 970 | blend = 0; 971 | if (j != 0 && !brute) { 972 | var tlim = (forGIF || j == 1 || frms[frms.length - 2].dispose == 2) ? 1 : 2, 973 | tstp = 0, 974 | tarea = 1e9; 975 | for (var it = 0; it < tlim; it++) { 976 | var pimg = new Uint8Array(bufs[j - 1 - it]), 977 | p32 = new Uint32Array(bufs[j - 1 - it]); 978 | var mix = w, 979 | miy = h, 980 | max = -1, 981 | may = -1; 982 | for (var y = 0; y < h; y++) 983 | for (var x = 0; x < w; x++) { 984 | var i = y * w + x; 985 | if (cimg32[i] != p32[i]) { 986 | if (x < mix) mix = x; 987 | if (x > max) max = x; 988 | if (y < miy) miy = y; 989 | if (y > may) may = y; 990 | } 991 | } 992 | var sarea = (max == -1) ? 1 : (max - mix + 1) * (may - miy + 1); 993 | if (sarea < tarea) { 994 | tarea = sarea; 995 | tstp = it; 996 | if (max == -1) { 997 | nx = ny = 0; 998 | nw = nh = 1; 999 | } else { 1000 | nx = mix; 1001 | ny = miy; 1002 | nw = max - mix + 1; 1003 | nh = may - miy + 1; 1004 | } 1005 | } 1006 | } 1007 | 1008 | var pimg = new Uint8Array(bufs[j - 1 - tstp]); 1009 | if (tstp == 1) frms[frms.length - 1].dispose = 2; 1010 | 1011 | var nimg = new Uint8Array(nw * nh * 4), 1012 | nimg32 = new Uint32Array(nimg.buffer); 1013 | UPNG._copyTile(pimg, w, h, nimg, nw, nh, -nx, -ny, 0); 1014 | if (UPNG._copyTile(cimg, w, h, nimg, nw, nh, -nx, -ny, 3)) { 1015 | UPNG._copyTile(cimg, w, h, nimg, nw, nh, -nx, -ny, 2); 1016 | blend = 1; 1017 | } else { 1018 | UPNG._copyTile(cimg, w, h, nimg, nw, nh, -nx, -ny, 0); 1019 | blend = 0; 1020 | } 1021 | cimg = nimg; 1022 | } else cimg = cimg.slice(0); // img may be rewrited further ... don't rewrite input 1023 | frms.push({ 1024 | rect: { 1025 | x: nx, 1026 | y: ny, 1027 | width: nw, 1028 | height: nh 1029 | }, 1030 | img: cimg, 1031 | blend: blend, 1032 | dispose: brute ? 1 : 0 1033 | }); 1034 | } 1035 | return frms; 1036 | } 1037 | 1038 | UPNG.encode._filterZero = function (img, h, bpp, bpl, data, filter) { 1039 | if (filter != -1) { 1040 | for (var y = 0; y < h; y++) UPNG.encode._filterLine(data, img, y, bpl, bpp, filter); 1041 | return pako["deflate"](data); 1042 | } 1043 | var fls = []; 1044 | for (var t = 0; t < 5; t++) { 1045 | if (h * bpl > 500000 && (t == 2 || t == 3 || t == 4)) continue; 1046 | for (var y = 0; y < h; y++) UPNG.encode._filterLine(data, img, y, bpl, bpp, t); 1047 | fls.push(pako["deflate"](data)); 1048 | if (bpp == 1) break; 1049 | } 1050 | var ti, tsize = 1e9; 1051 | for (var i = 0; i < fls.length; i++) 1052 | if (fls[i].length < tsize) { 1053 | ti = i; 1054 | tsize = fls[i].length; 1055 | } 1056 | return fls[ti]; 1057 | } 1058 | UPNG.encode._filterLine = function (data, img, y, bpl, bpp, type) { 1059 | var i = y * bpl, 1060 | di = i + y, 1061 | paeth = UPNG.decode._paeth; 1062 | data[di] = type; 1063 | di++; 1064 | 1065 | if (type == 0) 1066 | for (var x = 0; x < bpl; x++) data[di + x] = img[i + x]; 1067 | else if (type == 1) { 1068 | for (var x = 0; x < bpp; x++) data[di + x] = img[i + x]; 1069 | for (var x = bpp; x < bpl; x++) data[di + x] = (img[i + x] - img[i + x - bpp] + 256) & 255; 1070 | } else if (y == 0) { 1071 | for (var x = 0; x < bpp; x++) data[di + x] = img[i + x]; 1072 | 1073 | if (type == 2) 1074 | for (var x = bpp; x < bpl; x++) data[di + x] = img[i + x]; 1075 | if (type == 3) 1076 | for (var x = bpp; x < bpl; x++) data[di + x] = (img[i + x] - (img[i + x - bpp] >> 1) + 256) & 255; 1077 | if (type == 4) 1078 | for (var x = bpp; x < bpl; x++) data[di + x] = (img[i + x] - paeth(img[i + x - bpp], 0, 0) + 256) & 255; 1079 | } else { 1080 | if (type == 2) { 1081 | for (var x = 0; x < bpl; x++) data[di + x] = (img[i + x] + 256 - img[i + x - bpl]) & 255; 1082 | } 1083 | if (type == 3) { 1084 | for (var x = 0; x < bpp; x++) data[di + x] = (img[i + x] + 256 - (img[i + x - bpl] >> 1)) & 255; 1085 | for (var x = bpp; x < bpl; x++) data[di + x] = (img[i + x] + 256 - ((img[i + x - bpl] + img[i + x - bpp]) >> 1)) & 255; 1086 | } 1087 | if (type == 4) { 1088 | for (var x = 0; x < bpp; x++) data[di + x] = (img[i + x] + 256 - paeth(0, img[i + x - bpl], 0)) & 255; 1089 | for (var x = bpp; x < bpl; x++) data[di + x] = (img[i + x] + 256 - paeth(img[i + x - bpp], img[i + x - bpl], img[i + x - bpp - bpl])) & 255; 1090 | } 1091 | } 1092 | } 1093 | 1094 | UPNG.crc = { 1095 | table: (function () { 1096 | var tab = new Uint32Array(256); 1097 | for (var n = 0; n < 256; n++) { 1098 | var c = n; 1099 | for (var k = 0; k < 8; k++) { 1100 | if (c & 1) c = 0xedb88320 ^ (c >>> 1); 1101 | else c = c >>> 1; 1102 | } 1103 | tab[n] = c; 1104 | } 1105 | return tab; 1106 | })(), 1107 | update: function (c, buf, off, len) { 1108 | for (var i = 0; i < len; i++) c = UPNG.crc.table[(c ^ buf[off + i]) & 0xff] ^ (c >>> 8); 1109 | return c; 1110 | }, 1111 | crc: function (b, o, l) { 1112 | return UPNG.crc.update(0xffffffff, b, o, l) ^ 0xffffffff; 1113 | } 1114 | } 1115 | 1116 | UPNG.quantize = function (abuf, ps) { 1117 | var oimg = new Uint8Array(abuf), 1118 | nimg = oimg.slice(0), 1119 | nimg32 = new Uint32Array(nimg.buffer); 1120 | 1121 | var KD = UPNG.quantize.getKDtree(nimg, ps); 1122 | var root = KD[0], 1123 | leafs = KD[1]; 1124 | 1125 | var planeDst = UPNG.quantize.planeDst; 1126 | var sb = oimg, 1127 | tb = nimg32, 1128 | len = sb.length; 1129 | 1130 | var inds = new Uint8Array(oimg.length >> 2); 1131 | for (var i = 0; i < len; i += 4) { 1132 | var r = sb[i] * (1 / 255), 1133 | g = sb[i + 1] * (1 / 255), 1134 | b = sb[i + 2] * (1 / 255), 1135 | a = sb[i + 3] * (1 / 255); 1136 | 1137 | // exact, but too slow :( 1138 | var nd = UPNG.quantize.getNearest(root, r, g, b, a); 1139 | //var nd = root; 1140 | //while(nd.left) nd = (planeDst(nd.est,r,g,b,a)<=0) ? nd.left : nd.right; 1141 | inds[i >> 2] = nd.ind; 1142 | tb[i >> 2] = nd.est.rgba; 1143 | } 1144 | return { 1145 | abuf: nimg.buffer, 1146 | inds: inds, 1147 | plte: leafs 1148 | }; 1149 | } 1150 | 1151 | UPNG.quantize.getKDtree = function (nimg, ps, err) { 1152 | if (err == null) err = 0.0001; 1153 | var nimg32 = new Uint32Array(nimg.buffer); 1154 | 1155 | var root = { 1156 | i0: 0, 1157 | i1: nimg.length, 1158 | bst: null, 1159 | est: null, 1160 | tdst: 0, 1161 | left: null, 1162 | right: null 1163 | }; // basic statistic, extra statistic 1164 | root.bst = UPNG.quantize.stats(nimg, root.i0, root.i1); 1165 | root.est = UPNG.quantize.estats(root.bst); 1166 | var leafs = [root]; 1167 | 1168 | while (leafs.length < ps) { 1169 | var maxL = 0, 1170 | mi = 0; 1171 | for (var i = 0; i < leafs.length; i++) 1172 | if (leafs[i].est.L > maxL) { 1173 | maxL = leafs[i].est.L; 1174 | mi = i; 1175 | } 1176 | if (maxL < err) break; 1177 | var node = leafs[mi]; 1178 | 1179 | var s0 = UPNG.quantize.splitPixels(nimg, nimg32, node.i0, node.i1, node.est.e, node.est.eMq255); 1180 | var s0wrong = (node.i0 >= s0 || node.i1 <= s0); 1181 | //console.log(maxL, leafs.length, mi); 1182 | if (s0wrong) { 1183 | node.est.L = 0; 1184 | continue; 1185 | } 1186 | 1187 | var ln = { 1188 | i0: node.i0, 1189 | i1: s0, 1190 | bst: null, 1191 | est: null, 1192 | tdst: 0, 1193 | left: null, 1194 | right: null 1195 | }; 1196 | ln.bst = UPNG.quantize.stats(nimg, ln.i0, ln.i1); 1197 | ln.est = UPNG.quantize.estats(ln.bst); 1198 | var rn = { 1199 | i0: s0, 1200 | i1: node.i1, 1201 | bst: null, 1202 | est: null, 1203 | tdst: 0, 1204 | left: null, 1205 | right: null 1206 | }; 1207 | rn.bst = { 1208 | R: [], 1209 | m: [], 1210 | N: node.bst.N - ln.bst.N 1211 | }; 1212 | for (var i = 0; i < 16; i++) rn.bst.R[i] = node.bst.R[i] - ln.bst.R[i]; 1213 | for (var i = 0; i < 4; i++) rn.bst.m[i] = node.bst.m[i] - ln.bst.m[i]; 1214 | rn.est = UPNG.quantize.estats(rn.bst); 1215 | 1216 | node.left = ln; 1217 | node.right = rn; 1218 | leafs[mi] = ln; 1219 | leafs.push(rn); 1220 | } 1221 | leafs.sort(function (a, b) { 1222 | return b.bst.N - a.bst.N; 1223 | }); 1224 | for (var i = 0; i < leafs.length; i++) leafs[i].ind = i; 1225 | return [root, leafs]; 1226 | } 1227 | 1228 | UPNG.quantize.getNearest = function (nd, r, g, b, a) { 1229 | if (nd.left == null) { 1230 | nd.tdst = UPNG.quantize.dist(nd.est.q, r, g, b, a); 1231 | return nd; 1232 | } 1233 | var planeDst = UPNG.quantize.planeDst(nd.est, r, g, b, a); 1234 | 1235 | var node0 = nd.left, 1236 | node1 = nd.right; 1237 | if (planeDst > 0) { 1238 | node0 = nd.right; 1239 | node1 = nd.left; 1240 | } 1241 | 1242 | var ln = UPNG.quantize.getNearest(node0, r, g, b, a); 1243 | if (ln.tdst <= planeDst * planeDst) return ln; 1244 | var rn = UPNG.quantize.getNearest(node1, r, g, b, a); 1245 | return rn.tdst < ln.tdst ? rn : ln; 1246 | } 1247 | UPNG.quantize.planeDst = function (est, r, g, b, a) { 1248 | var e = est.e; 1249 | return e[0] * r + e[1] * g + e[2] * b + e[3] * a - est.eMq; 1250 | } 1251 | UPNG.quantize.dist = function (q, r, g, b, a) { 1252 | var d0 = r - q[0], 1253 | d1 = g - q[1], 1254 | d2 = b - q[2], 1255 | d3 = a - q[3]; 1256 | return d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3; 1257 | } 1258 | 1259 | UPNG.quantize.splitPixels = function (nimg, nimg32, i0, i1, e, eMq) { 1260 | var vecDot = UPNG.quantize.vecDot; 1261 | i1 -= 4; 1262 | var shfs = 0; 1263 | while (i0 < i1) { 1264 | while (vecDot(nimg, i0, e) <= eMq) i0 += 4; 1265 | while (vecDot(nimg, i1, e) > eMq) i1 -= 4; 1266 | if (i0 >= i1) break; 1267 | 1268 | var t = nimg32[i0 >> 2]; 1269 | nimg32[i0 >> 2] = nimg32[i1 >> 2]; 1270 | nimg32[i1 >> 2] = t; 1271 | 1272 | i0 += 4; 1273 | i1 -= 4; 1274 | } 1275 | while (vecDot(nimg, i0, e) > eMq) i0 -= 4; 1276 | return i0 + 4; 1277 | } 1278 | UPNG.quantize.vecDot = function (nimg, i, e) { 1279 | return nimg[i] * e[0] + nimg[i + 1] * e[1] + nimg[i + 2] * e[2] + nimg[i + 3] * e[3]; 1280 | } 1281 | UPNG.quantize.stats = function (nimg, i0, i1) { 1282 | var R = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 1283 | var m = [0, 0, 0, 0]; 1284 | var N = (i1 - i0) >> 2; 1285 | for (var i = i0; i < i1; i += 4) { 1286 | var r = nimg[i] * (1 / 255), 1287 | g = nimg[i + 1] * (1 / 255), 1288 | b = nimg[i + 2] * (1 / 255), 1289 | a = nimg[i + 3] * (1 / 255); 1290 | //var r = nimg[i], g = nimg[i+1], b = nimg[i+2], a = nimg[i+3]; 1291 | m[0] += r; 1292 | m[1] += g; 1293 | m[2] += b; 1294 | m[3] += a; 1295 | 1296 | R[0] += r * r; 1297 | R[1] += r * g; 1298 | R[2] += r * b; 1299 | R[3] += r * a; 1300 | R[5] += g * g; 1301 | R[6] += g * b; 1302 | R[7] += g * a; 1303 | R[10] += b * b; 1304 | R[11] += b * a; 1305 | R[15] += a * a; 1306 | } 1307 | R[4] = R[1]; 1308 | R[8] = R[2]; 1309 | R[9] = R[6]; 1310 | R[12] = R[3]; 1311 | R[13] = R[7]; 1312 | R[14] = R[11]; 1313 | 1314 | return { 1315 | R: R, 1316 | m: m, 1317 | N: N 1318 | }; 1319 | } 1320 | UPNG.quantize.estats = function (stats) { 1321 | var R = stats.R, 1322 | m = stats.m, 1323 | N = stats.N; 1324 | 1325 | // when all samples are equal, but N is large (millions), the Rj can be non-zero ( 0.0003.... - precission error) 1326 | var m0 = m[0], 1327 | m1 = m[1], 1328 | m2 = m[2], 1329 | m3 = m[3], 1330 | iN = (N == 0 ? 0 : 1 / N); 1331 | var Rj = [R[0] - m0 * m0 * iN, R[1] - m0 * m1 * iN, R[2] - m0 * m2 * iN, R[3] - m0 * m3 * iN, R[4] - m1 * m0 * iN, R[5] - m1 * m1 * iN, R[6] - m1 * m2 * iN, R[7] - m1 * m3 * iN, R[8] - m2 * m0 * iN, R[9] - m2 * m1 * iN, R[10] - m2 * m2 * iN, R[11] - m2 * m3 * iN, R[12] - m3 * m0 * iN, R[13] - m3 * m1 * iN, R[14] - m3 * m2 * iN, R[15] - m3 * m3 * iN]; 1332 | 1333 | var A = Rj, 1334 | M = UPNG.M4; 1335 | var b = [0.5, 0.5, 0.5, 0.5], 1336 | mi = 0, 1337 | tmi = 0; 1338 | 1339 | if (N != 0) 1340 | for (var i = 0; i < 10; i++) { 1341 | b = M.multVec(A, b); 1342 | tmi = Math.sqrt(M.dot(b, b)); 1343 | b = M.sml(1 / tmi, b); 1344 | if (Math.abs(tmi - mi) < 1e-9) break; 1345 | mi = tmi; 1346 | } 1347 | //b = [0,0,1,0]; mi=N; 1348 | var q = [m0 * iN, m1 * iN, m2 * iN, m3 * iN]; 1349 | var eMq255 = M.dot(M.sml(255, q), b); 1350 | 1351 | return { 1352 | Cov: Rj, 1353 | q: q, 1354 | e: b, 1355 | L: mi, 1356 | eMq255: eMq255, 1357 | eMq: M.dot(b, q), 1358 | rgba: (((Math.round(255 * q[3]) << 24) | (Math.round(255 * q[2]) << 16) | (Math.round(255 * q[1]) << 8) | (Math.round(255 * q[0]) << 0)) >>> 0) 1359 | }; 1360 | } 1361 | UPNG.M4 = { 1362 | multVec: function (m, v) { 1363 | return [m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * v[3], m[4] * v[0] + m[5] * v[1] + m[6] * v[2] + m[7] * v[3], m[8] * v[0] + m[9] * v[1] + m[10] * v[2] + m[11] * v[3], m[12] * v[0] + m[13] * v[1] + m[14] * v[2] + m[15] * v[3]]; 1364 | }, 1365 | dot: function (x, y) { 1366 | return x[0] * y[0] + x[1] * y[1] + x[2] * y[2] + x[3] * y[3]; 1367 | }, 1368 | sml: function (a, y) { 1369 | return [a * y[0], a * y[1], a * y[2], a * y[3]]; 1370 | } 1371 | } 1372 | 1373 | UPNG.encode.concatRGBA = function (bufs, roundAlpha) { 1374 | var tlen = 0; 1375 | for (var i = 0; i < bufs.length; i++) tlen += bufs[i].byteLength; 1376 | var nimg = new Uint8Array(tlen), 1377 | noff = 0; 1378 | for (var i = 0; i < bufs.length; i++) { 1379 | var img = new Uint8Array(bufs[i]), 1380 | il = img.length; 1381 | for (var j = 0; j < il; j += 4) { 1382 | var r = img[j], 1383 | g = img[j + 1], 1384 | b = img[j + 2], 1385 | a = img[j + 3]; 1386 | if (roundAlpha) a = (a & 128) == 0 ? 0 : 255; 1387 | if (a == 0) r = g = b = 0; 1388 | nimg[noff + j] = r; 1389 | nimg[noff + j + 1] = g; 1390 | nimg[noff + j + 2] = b; 1391 | nimg[noff + j + 3] = a; 1392 | } 1393 | noff += il; 1394 | } 1395 | return nimg.buffer; 1396 | } 1397 | 1398 | })(UPNG, pako); 1399 | 1400 | export default UPNG; -------------------------------------------------------------------------------- /dist/PixiApngAndGif.js: -------------------------------------------------------------------------------- 1 | /*! Project:pixi-apngAndGi, Create:FWS 2018.09.28 15:29, Update:FWS 2020.03.10 09:17 */ 2 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):"function"==typeof define&&(define.cmd||define.hjs)?define(function(require,exports,e){e.exports=t()}):e.PixiApngAndGif=t()}(this,function(){"use strict";function e(e){var r=0;if(71!==e[r++]||73!==e[r++]||70!==e[r++]||56!==e[r++]||56!=(e[r++]+1&253)||97!==e[r++])throw new Error("Invalid GIF 87a/89a header.");var a=e[r++]|e[r++]<<8,n=e[r++]|e[r++]<<8,i=e[r++],s=i>>7,o=7&i,l=1<=0))throw Error("Invalid block size");if(0===g)break;r+=g}break;case 249:if(4!==e[r++]||0!==e[r+4])throw new Error("Invalid graphics extension block.");var b=e[r++];_=e[r++]|e[r++]<<8,c=e[r++],0==(1&b)&&(c=null),p=b>>2&7,r++;break;case 254:for(;;){var g=e[r++];if(!(g>=0))throw Error("Invalid block size");if(0===g)break;r+=g}break;default:throw new Error("Unknown graphic control label: 0x"+e[r-1].toString(16))}break;case 44:var w=e[r++]|e[r++]<<8,m=e[r++]|e[r++]<<8,y=e[r++]|e[r++]<<8,k=e[r++]|e[r++]<<8,x=e[r++],z=x>>7,E=x>>6&1,A=7&x,S=1<=0))throw Error("Invalid block size");if(0===g)break;r+=g}u.push({x:w,y:m,width:y,height:k,has_local_palette:B,palette_offset:I,palette_size:R,data_offset:Z,data_length:r-Z,transparent_index:c,interlaced:!!E,delay:_,disposal:p});break;case 59:d=!1;break;default:throw new Error("Unknown gif block: 0x"+e[r-1].toString(16))}this.numFrames=function(){return u.length},this.loopCount=function(){return v},this.frameInfo=function(e){if(e<0||e>=u.length)throw new Error("Frame index out of range.");return u[e]},this.decodeAndBlitFrameBGRA=function(r,n){var i=this.frameInfo(r),s=i.width*i.height,o=new Uint8Array(s);t(e,i.data_offset,o,s);var l=i.palette_offset,f=i.transparent_index;null===f&&(f=256);var h=i.width,d=a-h,u=h,_=4*(i.y*a+i.x),c=4*((i.y+i.height)*a+i.x),p=_,v=4*d;!0===i.interlaced&&(v+=4*a*7);for(var g=8,b=0,w=o.length;b=c&&(v=4*d+4*a*(g-1),p=_+(h+d)*(g<<1),g>>=1)),m===f)p+=4;else{var y=e[l+3*m],k=e[l+3*m+1],x=e[l+3*m+2];n[p++]=x,n[p++]=k,n[p++]=y,n[p++]=255}--u}},this.decodeAndBlitFrameRGBA=function(r,n){var i=this.frameInfo(r),s=i.width*i.height,o=new Uint8Array(s);t(e,i.data_offset,o,s);var l=i.palette_offset,f=i.transparent_index;null===f&&(f=256);var h=i.width,d=a-h,u=h,_=4*(i.y*a+i.x),c=4*((i.y+i.height)*a+i.x),p=_,v=4*d;!0===i.interlaced&&(v+=4*a*7);for(var g=8,b=0,w=o.length;b=c&&(v=4*d+4*a*(g-1),p=_+(h+d)*(g<<1),g>>=1)),m===f)p+=4;else{var y=e[l+3*m],k=e[l+3*m+1],x=e[l+3*m+2];n[p++]=y,n[p++]=k,n[p++]=x,n[p++]=255}--u}}}function t(e,t,r,a){for(var n=e[t++],i=1<>=l,h-=l,v!==i){if(v===s)break;for(var g=vi;)w=c[w]>>8,++b;var m=w;if(u+b+(g!==v?1:0)>a)return void console.log("Warning, gif stream longer than expected.");r[u++]=m,u+=b;var y=u;for(g!==v&&(r[u++]=m),w=g;b--;)w=c[w],r[--y]=255&w,w>>=8;null!==p&&o<4096&&(c[o++]=p<<8|m,o>=f+1&&l<12&&(++l,f=f<<1|1)),p=v}else o=s+1,l=n+1,f=(1<=0;)e[t]=0}function a(e,t,r,a,n){this.static_tree=e,this.extra_bits=t,this.extra_base=r,this.elems=a,this.max_length=n,this.has_stree=e&&e.length}function n(e,t){this.dyn_tree=e,this.max_code=0,this.stat_desc=t}function i(e){return e<256?dt[e]:dt[256+(e>>>7)]}function s(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function o(e,t,r){e.bi_valid>$e-r?(e.bi_buf|=t<>$e-e.bi_valid,e.bi_valid+=r-$e):(e.bi_buf|=t<>>=1,r<<=1}while(--t>0);return r>>>1}function h(e){16===e.bi_valid?(s(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):e.bi_valid>=8&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}function d(e,t){var r,a,n,i,s,o,l=t.dyn_tree,f=t.max_code,h=t.stat_desc.static_tree,d=t.stat_desc.has_stree,u=t.stat_desc.extra_bits,_=t.stat_desc.extra_base,c=t.stat_desc.max_length,p=0;for(i=0;i<=Qe;i++)e.bl_count[i]=0;for(l[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;rc&&(i=c,p++),l[2*a+1]=i,a>f||(e.bl_count[i]++,s=0,a>=_&&(s=u[a-_]),o=l[2*a],e.opt_len+=o*(i+s),d&&(e.static_len+=o*(h[2*a+1]+s)));if(0!==p){do{for(i=c-1;0===e.bl_count[i];)i--;e.bl_count[i]--,e.bl_count[i+1]+=2,e.bl_count[c]--,p-=2}while(p>0);for(i=c;0!==i;i--)for(a=e.bl_count[i];0!==a;)(n=e.heap[--r])>f||(l[2*n+1]!==i&&(e.opt_len+=(i-l[2*n+1])*l[2*n],l[2*n+1]=i),a--)}}function u(e,t,r){var a,n,i=new Array(Qe+1),s=0;for(a=1;a<=Qe;a++)i[a]=s=s+r[a-1]<<1;for(n=0;n<=t;n++){var o=e[2*n+1];0!==o&&(e[2*n]=f(i[o]++,o))}}function _(){var e,t,r,n,i,s=new Array(Qe+1);for(r=0,n=0;n>=7;n8?s(e,e.bi_buf):e.bi_valid>0&&(e.pending_buf[e.pending++]=e.bi_buf),e.bi_buf=0,e.bi_valid=0}function v(e,t,r,a){p(e),a&&(s(e,r),s(e,~r)),Ce.arraySet(e.pending_buf,e.window,t,r,e.pending),e.pending+=r}function g(e,t,r,a){var n=2*t,i=2*r;return e[n]>1;r>=1;r--)b(e,i,r);n=l;do{r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],b(e,i,1),a=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=a,i[2*n]=i[2*r]+i[2*a],e.depth[n]=(e.depth[r]>=e.depth[a]?e.depth[r]:e.depth[a])+1,i[2*r+1]=i[2*a+1]=n,e.heap[1]=n++,b(e,i,1)}while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],d(e,t),u(i,f,e.bl_count)}function y(e,t,r){var a,n,i=-1,s=t[1],o=0,l=7,f=4;for(0===s&&(l=138,f=3),t[2*(r+1)+1]=65535,a=0;a<=r;a++)n=s,s=t[2*(a+1)+1],++o=3&&0===e.bl_tree[2*lt[t]+1];t--);return e.opt_len+=3*(t+1)+5+5+4,t}function z(e,t,r,a){var n;for(o(e,t-257,5),o(e,r-1,5),o(e,a-4,4),n=0;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return Me;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return Pe;for(t=32;t0?(e.strm.data_type===He&&(e.strm.data_type=E(e)),m(e,e.l_desc),m(e,e.d_desc),s=x(e),n=e.opt_len+3+7>>>3,(i=e.static_len+3+7>>>3)<=n&&(n=i)):n=i=r+5,r+4<=n&&-1!==t?S(e,t,r,a):e.strategy===Fe||i===n?(o(e,(qe<<1)+(a?1:0),3),w(e,ft,ht)):(o(e,(Ge<<1)+(a?1:0),3),z(e,e.l_desc.max_code+1,e.d_desc.max_code+1,s+1),w(e,e.dyn_ltree,e.dyn_dtree)),c(e),a&&p(e)}function B(e,t,r){return e.pending_buf[e.d_buf+2*e.last_lit]=t>>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(ut[r]+Xe+1)]++,e.dyn_dtree[2*i(t)]++),e.last_lit===e.lit_bufsize-1}function Z(e,t,r,a){for(var n=65535&e|0,i=e>>>16&65535|0,s=0;0!==r;){s=r>2e3?2e3:r,r-=s;do{n=n+t[a++]|0,i=i+n|0}while(--s);n%=65521,i%=65521}return n|i<<16|0}function U(e,t,r,a){var n=Rt,i=a+r;e^=-1;for(var s=a;s>>8^n[255&(e^t[s])];return-1^e}function T(e,t){return e.msg=Lt[t],t}function N(e){return(e<<1)-(e>4?9:0)}function D(e){for(var t=e.length;--t>=0;)e[t]=0}function O(e){var t=e.state,r=t.pending;r>e.avail_out&&(r=e.avail_out),0!==r&&(Ce.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function L(e,t){Nt._tr_flush_block(e,e.block_start>=0?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,O(e.strm)}function C(e,t){e.pending_buf[e.pending++]=t}function F(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function M(e,t,r,a){var n=e.avail_in;return n>a&&(n=a),0===n?0:(e.avail_in-=n,Ce.arraySet(t,e.input,e.next_in,n,r),1===e.state.wrap?e.adler=Dt(e.adler,t,n,r):2===e.state.wrap&&(e.adler=Ot(e.adler,t,n,r)),e.next_in+=n,e.total_in+=n,n)}function P(e,t){var r,a,n=e.max_chain_length,i=e.strstart,s=e.prev_length,o=e.nice_match,l=e.strstart>e.w_size-ur?e.strstart-(e.w_size-ur):0,f=e.window,h=e.w_mask,d=e.prev,u=e.strstart+dr,_=f[i+s-1],c=f[i+s];e.prev_length>=e.good_match&&(n>>=2),o>e.lookahead&&(o=e.lookahead);do{if(r=t,f[r+s]===c&&f[r+s-1]===_&&f[r]===f[i]&&f[++r]===f[i+1]){i+=2,r++;do{}while(f[++i]===f[++r]&&f[++i]===f[++r]&&f[++i]===f[++r]&&f[++i]===f[++r]&&f[++i]===f[++r]&&f[++i]===f[++r]&&f[++i]===f[++r]&&f[++i]===f[++r]&&is){if(e.match_start=t,s=a,a>=o)break;_=f[i+s-1],c=f[i+s]}}}while((t=d[t&h])>l&&0!=--n);return s<=e.lookahead?s:e.lookahead}function H(e){var t,r,a,n,i,s=e.w_size;do{if(n=e.window_size-e.lookahead-e.strstart,e.strstart>=s+(s-ur)){Ce.arraySet(e.window,e.window,s,s,0),e.match_start-=s,e.strstart-=s,e.block_start-=s,r=e.hash_size,t=r;do{a=e.head[--t],e.head[t]=a>=s?a-s:0}while(--r);r=s,t=r;do{a=e.prev[--t],e.prev[t]=a>=s?a-s:0}while(--r);n+=s}if(0===e.strm.avail_in)break;if(r=M(e.strm,e.window,e.strstart+e.lookahead,n),e.lookahead+=r,e.lookahead+e.insert>=hr)for(i=e.strstart-e.insert,e.ins_h=e.window[i],e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(H(e),0===e.lookahead&&t===Ct)return yr;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var a=e.block_start+r;if((0===e.strstart||e.strstart>=a)&&(e.lookahead=e.strstart-a,e.strstart=a,L(e,!1),0===e.strm.avail_out))return yr;if(e.strstart-e.block_start>=e.w_size-ur&&(L(e,!1),0===e.strm.avail_out))return yr}return e.insert=0,t===Pt?(L(e,!0),0===e.strm.avail_out?xr:zr):(e.strstart>e.block_start&&(L(e,!1),e.strm.avail_out),yr)}function q(e,t){for(var r,a;;){if(e.lookahead=hr&&(e.ins_h=(e.ins_h<=hr)if(a=Nt._tr_tally(e,e.strstart-e.match_start,e.match_length-hr),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=hr){e.match_length--;do{e.strstart++,e.ins_h=(e.ins_h<=hr&&(e.ins_h=(e.ins_h<4096)&&(e.match_length=hr-1)),e.prev_length>=hr&&e.match_length<=e.prev_length){n=e.strstart+e.lookahead-hr,a=Nt._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-hr),e.lookahead-=e.prev_length-1,e.prev_length-=2;do{++e.strstart<=n&&(e.ins_h=(e.ins_h<=hr&&e.strstart>0&&(n=e.strstart-1,(a=s[n])===s[++n]&&a===s[++n]&&a===s[++n])){i=e.strstart+dr;do{}while(a===s[++n]&&a===s[++n]&&a===s[++n]&&a===s[++n]&&a===s[++n]&&a===s[++n]&&a===s[++n]&&a===s[++n]&&ne.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=hr?(r=Nt._tr_tally(e,1,e.match_length-hr),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=Nt._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(L(e,!1),0===e.strm.avail_out))return yr}return e.insert=0,t===Pt?(L(e,!0),0===e.strm.avail_out?xr:zr):e.last_lit&&(L(e,!1),0===e.strm.avail_out)?yr:kr}function X(e,t){for(var r;;){if(0===e.lookahead&&(H(e),0===e.lookahead)){if(t===Ct)return yr;break}if(e.match_length=0,r=Nt._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(L(e,!1),0===e.strm.avail_out))return yr}return e.insert=0,t===Pt?(L(e,!0),0===e.strm.avail_out?xr:zr):e.last_lit&&(L(e,!1),0===e.strm.avail_out)?yr:kr}function Y(e,t,r,a,n){this.good_length=e,this.max_lazy=t,this.nice_length=r,this.max_chain=a,this.func=n}function W(e){e.window_size=2*e.w_size,D(e.head),e.max_lazy_match=bt[e.level].max_lazy,e.good_match=bt[e.level].good_length,e.nice_match=bt[e.level].nice_length,e.max_chain_length=bt[e.level].max_chain,e.strstart=0,e.block_start=0,e.lookahead=0,e.insert=0,e.match_length=e.prev_length=hr-1,e.match_available=0,e.ins_h=0}function V(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=tr,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Ce.Buf16(2*lr),this.dyn_dtree=new Ce.Buf16(2*(2*sr+1)),this.bl_tree=new Ce.Buf16(2*(2*or+1)),D(this.dyn_ltree),D(this.dyn_dtree),D(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Ce.Buf16(fr+1),this.heap=new Ce.Buf16(2*ir+1),D(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Ce.Buf16(2*ir+1),D(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function J(e){var t;return e&&e.state?(e.total_in=e.total_out=0,e.data_type=er,t=e.state,t.pending=0,t.pending_out=0,t.wrap<0&&(t.wrap=-t.wrap),t.status=t.wrap?cr:wr,e.adler=2===t.wrap?0:1,t.last_flush=Ct,Nt._tr_init(t),jt):T(e,Gt)}function Q(e){var t=J(e);return t===jt&&W(e.state),t}function ee(e,t){return e&&e.state?2!==e.state.wrap?Gt:(e.state.gzhead=t,jt):Gt}function te(e,t,r,a,n,i){if(!e)return Gt;var s=1;if(t===Yt&&(t=6),a<0?(s=0,a=-a):a>15&&(s=2,a-=16),n<1||n>rr||r!==tr||a<8||a>15||t<0||t>9||i<0||i>Qt)return T(e,Gt);8===a&&(a=9);var o=new V;return e.state=o,o.strm=e,o.wrap=s,o.gzhead=null,o.w_bits=a,o.w_size=1<Ht||t<0)return e?T(e,Gt):Gt;if(a=e.state,!e.output||!e.input&&0!==e.avail_in||a.status===mr&&t!==Pt)return T(e,0===e.avail_out?Xt:Gt);if(a.strm=e,r=a.last_flush,a.last_flush=t,a.status===cr)if(2===a.wrap)e.adler=0,C(a,31),C(a,139),C(a,8),a.gzhead?(C(a,(a.gzhead.text?1:0)+(a.gzhead.hcrc?2:0)+(a.gzhead.extra?4:0)+(a.gzhead.name?8:0)+(a.gzhead.comment?16:0)),C(a,255&a.gzhead.time),C(a,a.gzhead.time>>8&255),C(a,a.gzhead.time>>16&255),C(a,a.gzhead.time>>24&255),C(a,9===a.level?2:a.strategy>=Vt||a.level<2?4:0),C(a,255&a.gzhead.os),a.gzhead.extra&&a.gzhead.extra.length&&(C(a,255&a.gzhead.extra.length),C(a,a.gzhead.extra.length>>8&255)),a.gzhead.hcrc&&(e.adler=Ot(e.adler,a.pending_buf,a.pending,0)),a.gzindex=0,a.status=pr):(C(a,0),C(a,0),C(a,0),C(a,0),C(a,0),C(a,9===a.level?2:a.strategy>=Vt||a.level<2?4:0),C(a,Er),a.status=wr);else{var s=tr+(a.w_bits-8<<4)<<8,o=-1;o=a.strategy>=Vt||a.level<2?0:a.level<6?1:6===a.level?2:3,s|=o<<6,0!==a.strstart&&(s|=_r),s+=31-s%31,a.status=wr,F(a,s),0!==a.strstart&&(F(a,e.adler>>>16),F(a,65535&e.adler)),e.adler=1}if(a.status===pr)if(a.gzhead.extra){for(n=a.pending;a.gzindex<(65535&a.gzhead.extra.length)&&(a.pending!==a.pending_buf_size||(a.gzhead.hcrc&&a.pending>n&&(e.adler=Ot(e.adler,a.pending_buf,a.pending-n,n)),O(e),n=a.pending,a.pending!==a.pending_buf_size));)C(a,255&a.gzhead.extra[a.gzindex]),a.gzindex++;a.gzhead.hcrc&&a.pending>n&&(e.adler=Ot(e.adler,a.pending_buf,a.pending-n,n)),a.gzindex===a.gzhead.extra.length&&(a.gzindex=0,a.status=vr)}else a.status=vr;if(a.status===vr)if(a.gzhead.name){n=a.pending;do{if(a.pending===a.pending_buf_size&&(a.gzhead.hcrc&&a.pending>n&&(e.adler=Ot(e.adler,a.pending_buf,a.pending-n,n)),O(e),n=a.pending,a.pending===a.pending_buf_size)){i=1;break}i=a.gzindexn&&(e.adler=Ot(e.adler,a.pending_buf,a.pending-n,n)),0===i&&(a.gzindex=0,a.status=gr)}else a.status=gr;if(a.status===gr)if(a.gzhead.comment){n=a.pending;do{if(a.pending===a.pending_buf_size&&(a.gzhead.hcrc&&a.pending>n&&(e.adler=Ot(e.adler,a.pending_buf,a.pending-n,n)),O(e),n=a.pending,a.pending===a.pending_buf_size)){i=1;break}i=a.gzindexn&&(e.adler=Ot(e.adler,a.pending_buf,a.pending-n,n)),0===i&&(a.status=br)}else a.status=br;if(a.status===br&&(a.gzhead.hcrc?(a.pending+2>a.pending_buf_size&&O(e),a.pending+2<=a.pending_buf_size&&(C(a,255&e.adler),C(a,e.adler>>8&255),e.adler=0,a.status=wr)):a.status=wr),0!==a.pending){if(O(e),0===e.avail_out)return a.last_flush=-1,jt}else if(0===e.avail_in&&N(t)<=N(r)&&t!==Pt)return T(e,Xt);if(a.status===mr&&0!==e.avail_in)return T(e,Xt);if(0!==e.avail_in||0!==a.lookahead||t!==Ct&&a.status!==mr){var l=a.strategy===Vt?X(a,t):a.strategy===Jt?K(a,t):bt[a.level].func(a,t);if(l!==xr&&l!==zr||(a.status=mr),l===yr||l===xr)return 0===e.avail_out&&(a.last_flush=-1),jt;if(l===kr&&(t===Ft?Nt._tr_align(a):t!==Ht&&(Nt._tr_stored_block(a,0,0,!1),t===Mt&&(D(a.head),0===a.lookahead&&(a.strstart=0,a.block_start=0,a.insert=0))),O(e),0===e.avail_out))return a.last_flush=-1,jt}return t!==Pt?jt:a.wrap<=0?qt:(2===a.wrap?(C(a,255&e.adler),C(a,e.adler>>8&255),C(a,e.adler>>16&255),C(a,e.adler>>24&255),C(a,255&e.total_in),C(a,e.total_in>>8&255),C(a,e.total_in>>16&255),C(a,e.total_in>>24&255)):(F(a,e.adler>>>16),F(a,65535&e.adler)),O(e),a.wrap>0&&(a.wrap=-a.wrap),0!==a.pending?jt:qt)}function ne(e){var t;return e&&e.state?(t=e.state.status)!==cr&&t!==pr&&t!==vr&&t!==gr&&t!==br&&t!==wr&&t!==mr?T(e,Gt):(e.state=null,t===wr?T(e,Kt):jt):Gt}function ie(e,t){var r,a,n,i,s,o,l,f,h=t.length;if(!e||!e.state)return Gt;if(r=e.state,2===(i=r.wrap)||1===i&&r.status!==cr||r.lookahead)return Gt;for(1===i&&(e.adler=Dt(e.adler,t,h,0)),r.wrap=0,h>=r.w_size&&(0===i&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),f=new Ce.Buf8(r.w_size),Ce.arraySet(f,t,h-r.w_size,r.w_size,0),t=f,h=r.w_size),s=e.avail_in,o=e.next_in,l=e.input,e.avail_in=h,e.next_in=0,e.input=t,H(r);r.lookahead>=hr;){a=r.strstart,n=r.lookahead-(hr-1);do{r.ins_h=(r.ins_h<0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Qr,this.strm.avail_out=0;var r=Vr.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(r!==ea)throw new Error(Lt[r]);if(t.header&&Vr.deflateSetHeader(this.strm,t.header),t.dictionary){var a;if(a="string"==typeof t.dictionary?Jr.string2buf(t.dictionary):"[object ArrayBuffer]"===$r.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,(r=Vr.deflateSetDictionary(this.strm,a))!==ea)throw new Error(Lt[r]);this._dict_set=!0}}function fe(e,t){var r=new le(t);if(r.push(e,!0),r.err)throw r.msg||Lt[r.err];return r.result}function he(e,t){return t=t||{},t.raw=!0,fe(e,t)}function de(e,t){return t=t||{},t.gzip=!0,fe(e,t)}function ue(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function _e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Ce.Buf16(320),this.work=new Ce.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function ce(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=Oa,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new Ce.Buf32(pn),t.distcode=t.distdyn=new Ce.Buf32(vn),t.sane=1,t.back=-1,Ia):Za}function pe(e){var t;return e&&e.state?(t=e.state,t.wsize=0,t.whave=0,t.wnext=0,ce(e)):Za}function ve(e,t){var r,a;return e&&e.state?(a=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?Za:(null!==a.window&&a.wbits!==t&&(a.window=null),a.wrap=r,a.wbits=t,pe(e))):Za}function ge(e,t){var r,a;return e?(a=new _e,e.state=a,a.window=null,r=ve(e,t),r!==Ia&&(e.state=null),r):Za}function be(e){return ge(e,gn)}function we(e){if(bn){var t;for(na=new Ce.Buf32(512),ia=new Ce.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(ya(xa,e.lens,0,288,na,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;ya(za,e.lens,0,32,ia,0,e.work,{bits:5}),bn=!1}e.lencode=na,e.lenbits=9,e.distcode=ia,e.distbits=5}function me(e,t,r,a){var n,i=e.state;return null===i.window&&(i.wsize=1<=i.wsize?(Ce.arraySet(i.window,t,r-i.wsize,i.wsize,0),i.wnext=0,i.whave=i.wsize):(n=i.wsize-i.wnext,n>a&&(n=a),Ce.arraySet(i.window,t,r-a,n,i.wnext),a-=n,a?(Ce.arraySet(i.window,t,r-a,a,0),i.wnext=a,i.whave=i.wsize):(i.wnext+=n,i.wnext===i.wsize&&(i.wnext=0),i.whave>>8&255,r.check=Ot(r.check,S,2,0),f=0,h=0,r.mode=La;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&f)<<8)+(f>>8))%31){e.msg="incorrect header check",r.mode=un;break}if((15&f)!==Da){e.msg="unknown compression method",r.mode=un;break}if(f>>>=4,h-=4,k=8+(15&f),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=un;break}r.dmax=1<>8&1),512&r.flags&&(S[0]=255&f,S[1]=f>>>8&255,r.check=Ot(r.check,S,2,0)),f=0,h=0,r.mode=Ca;case Ca:for(;h<32;){if(0===o)break e;o--,f+=a[i++]<>>8&255,S[2]=f>>>16&255,S[3]=f>>>24&255,r.check=Ot(r.check,S,4,0)),f=0,h=0,r.mode=Fa;case Fa:for(;h<16;){if(0===o)break e;o--,f+=a[i++]<>8),512&r.flags&&(S[0]=255&f,S[1]=f>>>8&255,r.check=Ot(r.check,S,2,0)),f=0,h=0,r.mode=Ma;case Ma:if(1024&r.flags){for(;h<16;){if(0===o)break e;o--,f+=a[i++]<>>8&255,r.check=Ot(r.check,S,2,0)),f=0,h=0}else r.head&&(r.head.extra=null);r.mode=Pa;case Pa:if(1024&r.flags&&(_=r.length,_>o&&(_=o),_&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),Ce.arraySet(r.head.extra,a,i,_,k)),512&r.flags&&(r.check=Ot(r.check,a,_,i)),o-=_,i+=_,r.length-=_),r.length))break e;r.length=0,r.mode=Ha;case Ha:if(2048&r.flags){if(0===o)break e;_=0;do{k=a[i+_++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k))}while(k&&_>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=Xa;break;case Ga:for(;h<32;){if(0===o)break e;o--,f+=a[i++]<>>=7&h,h-=7&h,r.mode=fn;break}for(;h<3;){if(0===o)break e;o--,f+=a[i++]<>>=1,h-=1,3&f){case 0:r.mode=Wa;break;case 1:if(we(r),r.mode=tn,t===Sa){f>>>=2,h-=2;break e}break;case 2:r.mode=Qa;break;case 3:e.msg="invalid block type",r.mode=un}f>>>=2,h-=2;break;case Wa:for(f>>>=7&h,h-=7&h;h<32;){if(0===o)break e;o--,f+=a[i++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=un;break}if(r.length=65535&f,f=0,h=0,r.mode=Va,t===Sa)break e;case Va:r.mode=Ja;case Ja:if(_=r.length){if(_>o&&(_=o),_>l&&(_=l),0===_)break e;Ce.arraySet(n,a,i,_,s),o-=_,i+=_,l-=_,s+=_,r.length-=_;break}r.mode=Xa;break;case Qa:for(;h<14;){if(0===o)break e;o--,f+=a[i++]<>>=5,h-=5,r.ndist=1+(31&f),f>>>=5,h-=5,r.ncode=4+(15&f),f>>>=4,h-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=un;break}r.have=0,r.mode=$a;case $a:for(;r.have>>=3,h-=3}for(;r.have<19;)r.lens[I[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,z={bits:r.lenbits},x=ya(ka,r.lens,0,19,r.lencode,0,r.work,z),r.lenbits=z.bits,x){e.msg="invalid code lengths set",r.mode=un;break}r.have=0,r.mode=en;case en:for(;r.have>>24,g=A>>>16&255,b=65535&A,!(v<=h);){if(0===o)break e;o--,f+=a[i++]<>>=v,h-=v,r.lens[r.have++]=b;else{if(16===b){for(E=v+2;h>>=v,h-=v,0===r.have){e.msg="invalid bit length repeat",r.mode=un;break}k=r.lens[r.have-1],_=3+(3&f),f>>>=2,h-=2}else if(17===b){for(E=v+3;h>>=v,h-=v,k=0,_=3+(7&f),f>>>=3,h-=3}else{for(E=v+7;h>>=v,h-=v,k=0,_=11+(127&f),f>>>=7,h-=7}if(r.have+_>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=un;break}for(;_--;)r.lens[r.have++]=k}}if(r.mode===un)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=un;break}if(r.lenbits=9,z={bits:r.lenbits},x=ya(xa,r.lens,0,r.nlen,r.lencode,0,r.work,z),r.lenbits=z.bits,x){e.msg="invalid literal/lengths set",r.mode=un;break}if(r.distbits=6,r.distcode=r.distdyn,z={bits:r.distbits},x=ya(za,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,z),r.distbits=z.bits,x){e.msg="invalid distances set",r.mode=un;break}if(r.mode=tn,t===Sa)break e;case tn:r.mode=rn;case rn:if(o>=6&&l>=258){e.next_out=s,e.avail_out=l,e.next_in=i,e.avail_in=o,r.hold=f,r.bits=h,ma(e,u),s=e.next_out,n=e.output,l=e.avail_out,i=e.next_in,a=e.input,o=e.avail_in,f=r.hold,h=r.bits,r.mode===Xa&&(r.back=-1);break}for(r.back=0;A=r.lencode[f&(1<>>24,g=A>>>16&255,b=65535&A,!(v<=h);){if(0===o)break e;o--,f+=a[i++]<>w)],v=A>>>24,g=A>>>16&255,b=65535&A,!(w+v<=h);){if(0===o)break e;o--,f+=a[i++]<>>=w,h-=w,r.back+=w}if(f>>>=v,h-=v,r.back+=v,r.length=b,0===g){r.mode=ln;break}if(32&g){r.back=-1,r.mode=Xa;break}if(64&g){e.msg="invalid literal/length code",r.mode=un;break}r.extra=15&g,r.mode=an;case an:if(r.extra){for(E=r.extra;h>>=r.extra,h-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=nn;case nn:for(;A=r.distcode[f&(1<>>24,g=A>>>16&255,b=65535&A,!(v<=h);){if(0===o)break e;o--,f+=a[i++]<>w)],v=A>>>24,g=A>>>16&255,b=65535&A,!(w+v<=h);){if(0===o)break e;o--,f+=a[i++]<>>=w,h-=w,r.back+=w}if(f>>>=v,h-=v,r.back+=v,64&g){e.msg="invalid distance code",r.mode=un;break}r.offset=b,r.extra=15&g,r.mode=sn;case sn:if(r.extra){for(E=r.extra;h>>=r.extra,h-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=un;break}r.mode=on;case on:if(0===l)break e;if(_=u-l,r.offset>_){if((_=r.offset-_)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=un;break}_>r.wnext?(_-=r.wnext,c=r.wsize-_):c=r.wnext-_,_>r.length&&(_=r.length),p=r.window}else p=n,c=s-r.offset,_=r.length;_>l&&(_=l),l-=_,r.length-=_;do{n[s++]=p[c++]}while(--_);0===r.length&&(r.mode=rn);break;case ln:if(0===l)break e;n[s++]=r.length,l--,r.mode=rn;break;case fn:if(r.wrap){for(;h<32;){if(0===o)break e;o--,f|=a[i++]<=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Qr,this.strm.avail_out=0;var r=li.inflateInit2(this.strm,t.windowBits);if(r!==fi.Z_OK)throw new Error(Lt[r]);if(this.header=new hi,li.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=Jr.string2buf(t.dictionary):"[object ArrayBuffer]"===di.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(r=li.inflateSetDictionary(this.strm,t.dictionary))!==fi.Z_OK))throw new Error(Lt[r])}function Se(e,t){var r=new Ae(t);if(r.push(e,!0),r.err)throw r.msg||Lt[r.err];return r.result}function Ie(e,t){return t=t||{},t.raw=!0,Se(e,t)}var Re=function(e){var t=e.split(".");return t[t.length-1]},Be=function(e,t){return t={exports:{}},e(t,t.exports),t.exports}(function(e,exports){function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;exports.assign=function(e){for(var r=Array.prototype.slice.call(arguments,1);r.length;){var a=r.shift();if(a){if("object"!=typeof a)throw new TypeError(a+"must be non-object");for(var n in a)t(a,n)&&(e[n]=a[n])}}return e},exports.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var a={arraySet:function(e,t,r,a,n){if(t.subarray&&e.subarray)return void e.set(t.subarray(r,r+a),n);for(var i=0;i>>1:e>>>1;t[r]=e}return t}(),Bt=U,Zt=Object.freeze({default:Bt,__moduleExports:Bt}),Ut={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},Tt=Object.freeze({default:Ut,__moduleExports:Ut}),Nt=At&&Et||At,Dt=It&&St||It,Ot=Zt&&Bt||Zt,Lt=Tt&&Ut||Tt,Ct=0,Ft=1,Mt=3,Pt=4,Ht=5,jt=0,qt=1,Gt=-2,Kt=-3,Xt=-5,Yt=-1,Wt=1,Vt=2,Jt=3,Qt=4,$t=0,er=2,tr=8,rr=9,ar=15,nr=8,ir=286,sr=30,or=19,lr=2*ir+1,fr=15,hr=3,dr=258,ur=dr+hr+1,_r=32,cr=42,pr=69,vr=73,gr=91,br=103,wr=113,mr=666,yr=1,kr=2,xr=3,zr=4,Er=3;bt=[new Y(0,0,0,0,j),new Y(4,4,8,4,q),new Y(4,5,16,8,q),new Y(4,6,32,32,q),new Y(4,4,16,16,G),new Y(8,16,32,32,G),new Y(8,16,128,128,G),new Y(8,32,128,256,G),new Y(32,128,258,1024,G),new Y(32,258,258,4096,G)];var Ar=re,Sr=te,Ir=Q,Rr=J,Br=ee,Zr=ae,Ur=ne,Tr=ie,Nr="pako deflate (from Nodeca project)",Dr={deflateInit:Ar,deflateInit2:Sr,deflateReset:Ir,deflateResetKeep:Rr,deflateSetHeader:Br,deflate:Zr,deflateEnd:Ur,deflateSetDictionary:Tr,deflateInfo:Nr},Or=Object.freeze({default:Dr,__moduleExports:Dr,deflateInit:Ar,deflateInit2:Sr,deflateReset:Ir,deflateResetKeep:Rr,deflateSetHeader:Br,deflate:Zr,deflateEnd:Ur,deflateSetDictionary:Tr,deflateInfo:Nr}),Lr=!0,Cr=!0;try{String.fromCharCode.apply(null,[0])}catch(zi){Lr=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(zi){Cr=!1}for(var Fr=new Ce.Buf8(256),Mr=0;Mr<256;Mr++)Fr[Mr]=Mr>=252?6:Mr>=248?5:Mr>=240?4:Mr>=224?3:Mr>=192?2:1;Fr[254]=Fr[254]=1;var Pr=function(e){var t,r,a,n,i,s=e.length,o=0;for(n=0;n>>6,t[i++]=128|63&r):r<65536?(t[i++]=224|r>>>12,t[i++]=128|r>>>6&63,t[i++]=128|63&r):(t[i++]=240|r>>>18,t[i++]=128|r>>>12&63,t[i++]=128|r>>>6&63,t[i++]=128|63&r);return t},Hr=function(e){return se(e,e.length)},jr=function(e){for(var t=new Ce.Buf8(e.length),r=0,a=t.length;r4)o[a++]=65533,r+=i-1;else{for(n&=2===i?31:3===i?15:7;i>1&&r1?o[a++]=65533:n<65536?o[a++]=n:(n-=65536,o[a++]=55296|n>>10&1023,o[a++]=56320|1023&n)}return se(o,a)},Gr=function(e,t){var r;for(t=t||e.length,t>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+Fr[e[r]]>t?r:t},Kr={string2buf:Pr,buf2binstring:Hr,binstring2buf:jr,buf2string:qr,utf8border:Gr},Xr=Object.freeze({default:Kr,__moduleExports:Kr,string2buf:Pr,buf2binstring:Hr,binstring2buf:jr,buf2string:qr,utf8border:Gr}),Yr=oe,Wr=Object.freeze({default:Yr,__moduleExports:Yr}),Vr=Or&&Dr||Or,Jr=Xr&&Kr||Xr,Qr=Wr&&Yr||Wr,$r=Object.prototype.toString,ea=0,ta=-1,ra=0,aa=8;le.prototype.push=function(e,t){var r,a,n=this.strm,i=this.options.chunkSize;if(this.ended)return!1;a=t===~~t?t:!0===t?4:0,"string"==typeof e?n.input=Jr.string2buf(e):"[object ArrayBuffer]"===$r.call(e)?n.input=new Uint8Array(e):n.input=e,n.next_in=0,n.avail_in=n.input.length;do{if(0===n.avail_out&&(n.output=new Ce.Buf8(i),n.next_out=0,n.avail_out=i),1!==(r=Vr.deflate(n,a))&&r!==ea)return this.onEnd(r),this.ended=!0,!1;0!==n.avail_out&&(0!==n.avail_in||4!==a&&2!==a)||("string"===this.options.to?this.onData(Jr.buf2binstring(Ce.shrinkBuf(n.output,n.next_out))):this.onData(Ce.shrinkBuf(n.output,n.next_out)))}while((n.avail_in>0||0===n.avail_out)&&1!==r);return 4===a?(r=Vr.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===ea):2!==a||(this.onEnd(ea),n.avail_out=0,!0)},le.prototype.onData=function(e){this.chunks.push(e)},le.prototype.onEnd=function(e){e===ea&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Ce.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var na,ia,sa=le,oa=fe,la=he,fa=de,ha={Deflate:sa,deflate:oa,deflateRaw:la,gzip:fa},da=Object.freeze({default:ha,__moduleExports:ha,Deflate:sa,deflate:oa,deflateRaw:la,gzip:fa}),ua=function(e,t){var r,a,n,i,s,o,l,f,h,d,u,_,c,p,v,g,b,w,m,y,k,x,z,E,A;r=e.state,a=e.next_in,E=e.input,n=a+(e.avail_in-5),i=e.next_out,A=e.output,s=i-(t-e.avail_out),o=i+(e.avail_out-257),l=r.dmax,f=r.wsize,h=r.whave,d=r.wnext,u=r.window,_=r.hold,c=r.bits,p=r.lencode,v=r.distcode,g=(1<>>24,_>>>=m,c-=m,0===(m=w>>>16&255))A[i++]=65535&w;else{if(!(16&m)){if(0==(64&m)){w=p[(65535&w)+(_&(1<>>=m,c-=m),c<15&&(_+=E[a++]<>>24,_>>>=m,c-=m,!(16&(m=w>>>16&255))){if(0==(64&m)){w=v[(65535&w)+(_&(1<l){e.msg="invalid distance too far back",r.mode=30;break e}if(_>>>=m,c-=m,m=i-s,k>m){if((m=k-m)>h&&r.sane){e.msg="invalid distance too far back",r.mode=30;break e}if(x=0,z=u,0===d){if(x+=f-m,m2;)A[i++]=z[x++],A[i++]=z[x++],A[i++]=z[x++],y-=3;y&&(A[i++]=z[x++],y>1&&(A[i++]=z[x++]))}else{x=i-k;do{A[i++]=A[x++],A[i++]=A[x++],A[i++]=A[x++],y-=3}while(y>2);y&&(A[i++]=A[x++],y>1&&(A[i++]=A[x++]))}break}}break}}while(a>3,a-=y,c-=y<<3,_&=(1<=1&&0===B[y];y--);if(k>y&&(k=y),0===y)return n[i++]=20971520,n[i++]=20971520,o.bits=1,0;for(m=1;m0&&(0===e||1!==y))return-1;for(Z[1]=0,b=1;b<15;b++)Z[b+1]=Z[b]+B[b];for(w=0;w852||2===e&&A>592)return 1;for(;;){c=b-z,s[w]<_?(p=0,v=s[w]):s[w]>_?(p=U[T+s[w]],v=I[R+s[w]]):(p=96,v=0),l=1<>z)+f]=c<<24|p<<16|v|0}while(0!==f);for(l=1<>=1;if(0!==l?(S&=l-1,S+=l):S=0,w++,0==--B[b]){if(b===y)break;b=t[r+s[w]]}if(b>k&&(S&d)!==h){for(0===z&&(z=k),u+=m,x=b-z,E=1<852||2===e&&A>592)return 1;h=S&d,n[h]=k<<24|x<<16|u-i|0}}return 0!==S&&(n[u+S]=b-z<<24|64<<16|0),o.bits=k,0},wa=Object.freeze({default:ba,__moduleExports:ba}),ma=_a&&ua||_a,ya=wa&&ba||wa,ka=0,xa=1,za=2,Ea=4,Aa=5,Sa=6,Ia=0,Ra=1,Ba=2,Za=-2,Ua=-3,Ta=-4,Na=-5,Da=8,Oa=1,La=2,Ca=3,Fa=4,Ma=5,Pa=6,Ha=7,ja=8,qa=9,Ga=10,Ka=11,Xa=12,Ya=13,Wa=14,Va=15,Ja=16,Qa=17,$a=18,en=19,tn=20,rn=21,an=22,nn=23,sn=24,on=25,ln=26,fn=27,hn=28,dn=29,un=30,_n=31,cn=32,pn=852,vn=592,gn=15,bn=!0,wn=pe,mn=ve,yn=ce,kn=be,xn=ge,zn=ye,En=ke,An=xe,Sn=ze,In="pako inflate (from Nodeca project)",Rn={inflateReset:wn,inflateReset2:mn,inflateResetKeep:yn,inflateInit:kn,inflateInit2:xn,inflate:zn,inflateEnd:En,inflateGetHeader:An,inflateSetDictionary:Sn,inflateInfo:In},Bn=Object.freeze({default:Rn,__moduleExports:Rn,inflateReset:wn,inflateReset2:mn,inflateResetKeep:yn,inflateInit:kn,inflateInit2:xn,inflate:zn,inflateEnd:En,inflateGetHeader:An,inflateSetDictionary:Sn,inflateInfo:In}),Zn={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8},Un=Zn.Z_NO_FLUSH,Tn=Zn.Z_PARTIAL_FLUSH,Nn=Zn.Z_SYNC_FLUSH,Dn=Zn.Z_FULL_FLUSH,On=Zn.Z_FINISH,Ln=Zn.Z_BLOCK,Cn=Zn.Z_TREES,Fn=Zn.Z_OK,Mn=Zn.Z_STREAM_END,Pn=Zn.Z_NEED_DICT,Hn=Zn.Z_ERRNO,jn=Zn.Z_STREAM_ERROR,qn=Zn.Z_DATA_ERROR,Gn=Zn.Z_BUF_ERROR,Kn=Zn.Z_NO_COMPRESSION,Xn=Zn.Z_BEST_SPEED,Yn=Zn.Z_BEST_COMPRESSION,Wn=Zn.Z_DEFAULT_COMPRESSION,Vn=Zn.Z_FILTERED,Jn=Zn.Z_HUFFMAN_ONLY,Qn=Zn.Z_RLE,$n=Zn.Z_FIXED,ei=Zn.Z_DEFAULT_STRATEGY,ti=Zn.Z_BINARY,ri=Zn.Z_TEXT,ai=Zn.Z_UNKNOWN,ni=Zn.Z_DEFLATED,ii=Object.freeze({default:Zn,__moduleExports:Zn,Z_NO_FLUSH:Un,Z_PARTIAL_FLUSH:Tn,Z_SYNC_FLUSH:Nn,Z_FULL_FLUSH:Dn,Z_FINISH:On,Z_BLOCK:Ln,Z_TREES:Cn,Z_OK:Fn,Z_STREAM_END:Mn,Z_NEED_DICT:Pn,Z_ERRNO:Hn,Z_STREAM_ERROR:jn,Z_DATA_ERROR:qn,Z_BUF_ERROR:Gn,Z_NO_COMPRESSION:Kn,Z_BEST_SPEED:Xn,Z_BEST_COMPRESSION:Yn,Z_DEFAULT_COMPRESSION:Wn,Z_FILTERED:Vn,Z_HUFFMAN_ONLY:Jn,Z_RLE:Qn,Z_FIXED:$n,Z_DEFAULT_STRATEGY:ei,Z_BINARY:ti,Z_TEXT:ri,Z_UNKNOWN:ai,Z_DEFLATED:ni}),si=Ee,oi=Object.freeze({default:si,__moduleExports:si}),li=Bn&&Rn||Bn,fi=ii&&Zn||ii,hi=oi&&si||oi,di=Object.prototype.toString;Ae.prototype.push=function(e,t){var r,a,n,i,s,o=this.strm,l=this.options.chunkSize,f=this.options.dictionary,h=!1;if(this.ended)return!1;a=t===~~t?t:!0===t?fi.Z_FINISH:fi.Z_NO_FLUSH,"string"==typeof e?o.input=Jr.binstring2buf(e):"[object ArrayBuffer]"===di.call(e)?o.input=new Uint8Array(e):o.input=e,o.next_in=0,o.avail_in=o.input.length;do{if(0===o.avail_out&&(o.output=new Ce.Buf8(l),o.next_out=0,o.avail_out=l),r=li.inflate(o,fi.Z_NO_FLUSH),r===fi.Z_NEED_DICT&&f&&(r=li.inflateSetDictionary(this.strm,f)),r===fi.Z_BUF_ERROR&&!0===h&&(r=fi.Z_OK,h=!1),r!==fi.Z_STREAM_END&&r!==fi.Z_OK)return this.onEnd(r),this.ended=!0,!1;o.next_out&&(0!==o.avail_out&&r!==fi.Z_STREAM_END&&(0!==o.avail_in||a!==fi.Z_FINISH&&a!==fi.Z_SYNC_FLUSH)||("string"===this.options.to?(n=Jr.utf8border(o.output,o.next_out),i=o.next_out-n,s=Jr.buf2string(o.output,n),o.next_out=i,o.avail_out=l-i,i&&Ce.arraySet(o.output,o.output,n,i,0),this.onData(s)):this.onData(Ce.shrinkBuf(o.output,o.next_out)))),0===o.avail_in&&0===o.avail_out&&(h=!0)}while((o.avail_in>0||0===o.avail_out)&&r!==fi.Z_STREAM_END);return r===fi.Z_STREAM_END&&(a=fi.Z_FINISH),a===fi.Z_FINISH?(r=li.inflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===fi.Z_OK):a!==fi.Z_SYNC_FLUSH||(this.onEnd(fi.Z_OK),o.avail_out=0,!0)},Ae.prototype.onData=function(e){this.chunks.push(e)},Ae.prototype.onEnd=function(e){e===fi.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Ce.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg};var ui=Ae,_i=Se,ci=Ie,pi=Se,vi={Inflate:ui,inflate:_i,inflateRaw:ci,ungzip:pi},gi=Object.freeze({default:vi,__moduleExports:vi,Inflate:ui,inflate:_i,inflateRaw:ci,ungzip:pi}),bi=da&&ha||da,wi=gi&&vi||gi,mi=Ce.assign,yi={};mi(yi,bi,wi,fi);var ki=yi,xi={};return Uint8Array&&!Uint8Array.prototype.slice&&(Uint8Array.prototype.slice=function(){for(var e=[],t=0;t>3)]>>7-((7&c)<<0)&1,I=3*S;l[w]=y[I],l[w+1]=y[I+1],l[w+2]=y[I+2],l[w+3]=S>2)]>>6-((3&c)<<1)&3,I=3*S;l[w]=y[I],l[w+1]=y[I+1],l[w+2]=y[I+2],l[w+3]=S>1)]>>4-((1&c)<<2)&15,I=3*S;l[w]=y[I],l[w+1]=y[I+1],l[w+2]=y[I+2],l[w+3]=S>3]>>7-(7&c)&1),Z=B==255*v?0:255;f[c]=Z<<24|B<<16|B<<8|B}if(2==d)for(var c=0;c>2]>>6-((3&c)<<1)&3),Z=B==85*v?0:255;f[c]=Z<<24|B<<16|B<<8|B}if(4==d)for(var c=0;c>1]>>4-((1&c)<<2)&15),Z=B==17*v?0:255;f[c]=Z<<24|B<<16|B<<8|B}if(8==d)for(var c=0;c>3,o=Math.ceil(a*i/8),l=new Uint8Array(n*o),f=0,h=[0,0,4,0,2,0,1],d=[0,4,0,2,0,1,0],u=[8,8,8,4,4,2,2],_=[8,8,4,4,2,2,1],c=0;c<7;){for(var p=u[c],v=_[c],g=0,b=0,w=h[c];w>3];A=A>>7-(7&E)&1,l[x*o+(z>>3)]|=A<<7-((3&z)<<0)}if(2==i){var A=t[E>>3];A=A>>6-(7&E)&3,l[x*o+(z>>2)]|=A<<6-((3&z)<<1)}if(4==i){var A=t[E>>3];A=A>>4-(7&E)&15,l[x*o+(z>>1)]|=A<<4-((1&z)<<2)}if(i>=8)for(var S=x*o+z*s,I=0;I>3)+I];E+=i,z+=v}k++,x+=p}g*b!=0&&(f+=b*(1+y)),c+=1}return l},e.decode._getBPP=function(e){return[1,null,3,1,2,null,4][e.ctype]*e.depth},e.decode._filterZero=function(t,r,a,n,i){var s=e.decode._getBPP(r),o=Math.ceil(n*s/8),l=e.decode._paeth;s=Math.ceil(s/8);for(var f=0;f>1)&255;if(4==u)for(var _=s;_>1)&255;for(var _=s;_>1)&255}if(4==u){for(var _=0;_>8&255,e[t+1]=255&r},readUint:function(e,t){return 16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3])},writeUint:function(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r},readASCII:function(e,t,r){for(var a="",n=0;n=0&&o>=0?(d=_*t+c<<2,u=(o+_)*n+s+c<<2):(d=(-o+_)*t-s+c<<2,u=_*n+c<<2),0==l)a[u]=e[d],a[u+1]=e[d+1],a[u+2]=e[d+2],a[u+3]=e[d+3];else if(1==l){var p=e[d+3]*(1/255),v=e[d]*p,g=e[d+1]*p,b=e[d+2]*p,w=a[u+3]*(1/255),m=a[u]*w,y=a[u+1]*w,k=a[u+2]*w,x=1-p,z=p+w*x,E=0==z?0:1/z;a[u+3]=255*z,a[u+0]=(v+m*x)*E,a[u+1]=(g+y*x)*E,a[u+2]=(b+k*x)*E}else if(2==l){var p=e[d+3],v=e[d],g=e[d+1],b=e[d+2],w=a[u+3],m=a[u],y=a[u+1],k=a[u+2];p==w&&v==m&&g==y&&b==k?(a[u]=0,a[u+1]=0,a[u+2]=0,a[u+3]=0):(a[u]=v,a[u+1]=g,a[u+2]=b,a[u+3]=p)}else if(3==l){var p=e[d+3],v=e[d],g=e[d+1],b=e[d+2],w=a[u+3],m=a[u],y=a[u+1],k=a[u+2];if(p==w&&v==m&&g==y&&b==k)continue;if(p<220&&w>20)return!1}return!0},e.encode=function(t,r,a,n,i,s){null==n&&(n=0),null==s&&(s=!1);var o=e.encode.compress(t,r,a,n,!1,s);return e.encode.compressPNG(o,-1),e.encode._main(o,r,a,i)},e.encodeLL=function(t,r,a,n,i,s,o){for(var l={ctype:0+(1==n?0:2)+(0==i?0:4),depth:s,frames:[]},f=(n+i)*s,h=f*r,d=0;d1,d=!1,u=46+(h?20:0);if(3==t.ctype){for(var _=t.plte.length,c=0;c<_;c++)t.plte[c]>>>24!=255&&(d=!0);u+=8+3*_+4+(d?8+1*_+4:0)}for(var p=0;p>>8&255,x=m>>>16&255;g[f+w+0]=y,g[f+w+1]=k,g[f+w+2]=x}if(f+=3*_,s(g,f,i(g,f-3*_-4,3*_+4)),f+=4,d){s(g,f,_),f+=4,l(g,f,"tRNS"),f+=4;for(var c=0;c<_;c++)g[f+c]=t.plte[c]>>>24&255;f+=_,s(g,f,i(g,f-_-4,_+4)),f+=4}}for(var z=0,p=0;p>2,A>>2));for(var h=0;hR&&Z==I[_-R])B[_]=B[_-R];else{var U=g[Z];if(null==U&&(g[Z]=U=b.length,b.push(Z),b.length>=300))break;B[_]=U}}}var T=b.length;T<=256&&0==s&&(l=T<=2?1:T<=4?2:T<=16?4:8,i&&(l=8));for(var h=0;h>1)]|=F[P+H]<<4-4*(1&H);else if(2==l)for(var H=0;H>2)]|=F[P+H]<<6-2*(3&H);else if(1==l)for(var H=0;H>3)]|=F[P+H]<<7-1*(7&H)}D=C,o=3,L=1}else if(0==c&&1==v.length){for(var C=new Uint8Array(R*N*3),j=R*N,_=0;_x&&(x=A),Ez&&(z=E))}var I=-1==x?1:(x-y+1)*(z-k+1);I5e5)||2!=h&&3!=h&&4!=h){for(var l=0;l>1)+256&255;if(4==s)for(var h=i;h>1)&255;for(var h=i;h>1)&255}if(4==s){for(var h=0;h>>1:r>>>=1;e[t]=r}return e}(),update:function(t,r,a,n){for(var i=0;i>>8;return t},crc:function(t,r,a){return 4294967295^e.crc.update(4294967295,t,r,a)}},e.quantize=function(t,r){for(var a=new Uint8Array(t),n=a.slice(0),i=new Uint32Array(n.buffer),s=e.quantize.getKDtree(n,r),o=s[0],l=s[1],f=(e.quantize.planeDst,a),h=i,d=f.length,u=new Uint8Array(a.length>>2),_=0;_>2]=b.ind,h[_>>2]=b.est.rgba}return{abuf:n.buffer,inds:u,plte:l}},e.quantize.getKDtree=function(t,r,a){null==a&&(a=1e-4);var n=new Uint32Array(t.buffer),i={i0:0,i1:t.length,bst:null,est:null,tdst:0,left:null,right:null};i.bst=e.quantize.stats(t,i.i0,i.i1),i.est=e.quantize.estats(i.bst);for(var s=[i];s.lengtho&&(o=s[f].est.L,l=f);if(o=d||h.i1<=d)h.est.L=0;else{var u={i0:h.i0,i1:d,bst:null,est:null,tdst:0,left:null,right:null};u.bst=e.quantize.stats(t,u.i0,u.i1),u.est=e.quantize.estats(u.bst);var _={i0:d,i1:h.i1,bst:null,est:null,tdst:0,left:null,right:null};_.bst={R:[],m:[],N:h.bst.N-u.bst.N};for(var f=0;f<16;f++)_.bst.R[f]=h.bst.R[f]-u.bst.R[f];for(var f=0;f<4;f++)_.bst.m[f]=h.bst.m[f]-u.bst.m[f];_.est=e.quantize.estats(_.bst),h.left=u,h.right=_,s[l]=u,s.push(_)}}s.sort(function(e,t){return t.bst.N-e.bst.N});for(var f=0;f0&&(o=t.right,l=t.left);var f=e.quantize.getNearest(o,r,a,n,i);if(f.tdst<=s*s)return f;var h=e.quantize.getNearest(l,r,a,n,i);return h.tdsts;)n-=4;if(a>=n)break;var l=r[a>>2];r[a>>2]=r[n>>2],r[n>>2]=l,a+=4,n-=4}for(;o(t,a,i)>s;)a-=4;return a+4},e.quantize.vecDot=function(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]},e.quantize.stats=function(e,t,r){for(var a=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],n=[0,0,0,0],i=r-t>>2,s=t;s>>0}},e.M4={multVec:function(e,t){return[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]]},dot:function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]},sml:function(e,t){return[e*t[0],e*t[1],e*t[2],e*t[3]]}},e.encode.concatRGBA=function(e,t){for(var r=0,a=0;ar.framesDelay[a.frame]&&(a.frame++,a.status="playing",a.frame>r.textures.length-1&&(a.frame=0,a.loops++,r.temp.loop>0&&a.loops>=r.temp.loop&&("function"==typeof t&&t(a),a.status="played",r.runEvent("played",a),r.stop())),r.sprite.texture=r.textures[a.frame],i=0,r.runEvent("playing",a))}),r.temp.tickerIsAdd=!0),r.ticker.start()}},t.prototype.pause=function(){var e=this,t=e.__status;e.ticker.stop(),t.status="pause",e.runEvent("pause",t)},t.prototype.stop=function(){var e=this,t=e.__status;e.ticker.stop(),t.status="stop",e.runEvent("stop",t)},t.prototype.jumpToFrame=function(e){var t=this,r=t.textures;if(!r.length)throw new Error("没有可用的textures");var a=t.__status;"number"==typeof(e=e<0?0:e>r.length-1?r.length-1:e)&&(t.sprite.texture=r[e],a.frame=e)},t.prototype.getDuration=function(){var e=this,t=e.framesDelay;if(!t.length)throw new Error("未找到图片帧时间");for(var r=0,a=0,n=t.length;a