//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// /** * writes bitmaps into PNG format. * original author, Ely */ package { import flash.display.*; import flash.geom.*; import flash.utils.*; import flash.net.*; public class MustellaPNGEncoder { private var _png:ByteArray; // empty constructor public function MustellaPNGEncoder () { } public function encode(img:BitmapData):ByteArray { var imgWidth:uint = img.width; var imgHeight:uint = img.height; var imgData:ByteArray = img.getPixels(new Rectangle(0,0,imgWidth,imgHeight)); _png = new ByteArray(); _png.writeByte(137); _png.writeByte(80); _png.writeByte(78); _png.writeByte(71); _png.writeByte(13); _png.writeByte(10); _png.writeByte(26); _png.writeByte(10); var IHDR:ByteArray = new ByteArray(); IHDR.writeInt(imgWidth); IHDR.writeInt(imgHeight); IHDR.writeByte(8); // color depth: 8 bpp IHDR.writeByte(6); // color type: RGBA IHDR.writeByte(0); // compression: ZLIB IHDR.writeByte(0); // filter method IHDR.writeByte(0); // not interlaced; writeChunk([0x49,0x48,0x44,0x52],IHDR); var IDAT:ByteArray= new ByteArray(); for(var i:uint=0;i>16)&0xFF); IDAT.writeByte((p>> 8)&0xFF); IDAT.writeByte((p )&0xFF); IDAT.writeByte((p>>24)&0xFF); } } IDAT.compress(); writeChunk([0x49,0x44,0x41,0x54],IDAT); writeChunk([0x49,0x45,0x4E,0x44],null); return _png; } public function dump():String { _png.position = 0; var out:String =""; for(var i:uint=0;i<_png.length;i++) { var code:String = "0123456789abcdef"; var v:uint = _png.readUnsignedByte(); out += code.charAt((v & 0xF0) >> 4); out += code.charAt(v & 0xF); out += " "; } return out; } private function writeChunk(type:Array,data:ByteArray):void { var len:uint = 0; if(data != null) len = data.length; // data length _png.writeUnsignedInt(len); var p:uint = _png.position; _png.writeByte(type[0]); _png.writeByte(type[1]); _png.writeByte(type[2]); _png.writeByte(type[3]); if(data != null) _png.writeBytes(data); var endP:uint = _png.position; _png.position = p; var c:uint = crc(_png,endP-p); _png.position = endP; _png.writeUnsignedInt(c); } /* Table of CRCs of all 8-bit messages. */ private static var crc_table:Array; /* Flag: has the table been computed? Initially false. */ private static var crc_table_computed:Boolean = false; /* Make the table for a fast CRC. */ private function make_crc_table():void { var c:uint; var n:int; var k:int; crc_table = []; for (n = 0; n < 256; n++) { c = n; for (k = 0; k < 8; k++) { if (c & 1) c = uint(uint(0xedb88320) ^ uint(c >>> 1)); else c = uint(c >>> 1); } crc_table[n] = c; } crc_table_computed = true; } /* Update a running CRC with the bytes buf[0..len-1]--the CRC should be initialized to all 1's, and the transmitted value is the 1's complement of the final running CRC (see the crc() routine below)). */ private function update_crc(crc:uint, buf:ByteArray, len:uint):uint { var c:uint = crc; var n:int; var v:uint; if (!crc_table_computed) make_crc_table(); for (n = 0; n < len; n++) { v = buf.readUnsignedByte(); c = uint(crc_table[(c ^ v) & uint(0xff)] ^ uint(c >>> 8)); } return c; } /* Return the CRC of the bytes buf[0..len-1]. */ private function crc(buf:ByteArray, len:uint):uint { var cc:uint = update_crc(uint(0xffffffff), buf, len); return uint(cc ^ uint(0xffffffff)); } } }