root/as3/PNG/lib/as/jp/ferv/fileformats/png/PNG.as

リビジョン 3382, 9.7 kB (コミッタ: dsk, コミット時期: 2 年 前)

PNG ファーストコミット

Line 
1 /**
2  * The MIT License
3  *
4  * Copyright (c) 2010 ferv.jp
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 package jp.ferv.fileformats.png
25 {
26         import cmodule.png.CLibInit;
27         import flash.display.BitmapData;
28         import flash.events.Event;
29         import flash.events.EventDispatcher;
30         import flash.events.ProgressEvent;
31         import flash.utils.ByteArray;
32        
33         [Event(name = 'open', type = 'flash.events.Event')]
34         [Event(name = 'complete', type = 'flash.events.Event')]
35         [Event(name = 'progress', type = 'flash.events.ProgressEvent')]
36        
37         /**
38          * BitmapData から PNG フォーマットにエンコードされた ByteArray を作成するクラスです.
39          * 同期・非同期処理が可能です。
40          * libpng/zlib ライブラリの関数を呼び出す C のコードを Alchemy でコンパイルしています。
41          *
42          * @langversion ActionScript 3.0
43          * @playerversion Flash 10.0
44          *
45          * @author dsk
46          * @since 2010/01/29
47          */
48         public class PNG extends EventDispatcher
49         {
50                
51                 //--------------------------------------
52                 // CLASS CONSTANTS
53                 //--------------------------------------
54                
55                 private static const _ISO_8859_1:String = 'iso-8859-1';
56                 private static const _IHDR_TYPE:String  = 'IHDR';
57                 private static const _IDAT_TYPE:String  = 'IDAT';
58                 private static const _IEND_TYPE:String  = 'IEND';
59                
60                
61                 //--------------------------------------
62                 // PUBLIC VARIABLES
63                 //--------------------------------------
64                
65                 private static var _lib:*;
66                
67                 public var userData:Object;
68                
69                
70                 //--------------------------------------
71                 // PRIVATE VARIABLES
72                 //--------------------------------------
73                
74                 private var _data:ByteArray;
75                
76                
77                 //--------------------------------------
78                 // GETTER/SETTERS
79                 //--------------------------------------
80                
81                 /**
82                  * PNG フォーマットにエンコードされたバイト配列です.
83                  */
84                 public function get data():ByteArray { return _data; }
85                 public function set data(value:ByteArray):void
86                 {
87                         _data = value;
88                 }
89                
90                
91                 //--------------------------------------
92                 // CONSTRUCTOR
93                 //--------------------------------------
94                
95                 public function PNG(data:ByteArray = null)
96                 {
97                         if (!_lib)
98                         {
99                                 _lib = (new CLibInit()).init();
100                         }
101                        
102                         _data = (data)? data: new ByteArray();
103                 }
104                
105                
106                 //--------------------------------------
107                 // PUBLIC METHODS
108                 //--------------------------------------
109                
110                 /**
111                  * 同期処理で、 BitmapData を PNG フォーマットにエンコードされたバイト配列にします.
112                  * エンコード処理されたデータは data プロパティに書き込みます。
113                  *
114                  * @param       source                          エンコードする BitmapData です。
115                  * @param       colorType                       PNGColorType クラスに定義されてるカラータイプ値です。
116                  * @param       filterType                      PNGFilterType クラスに定義されている任意の 5 つのフィルタタイプ値 (NONE, SUB, UP, AVG, PAETH) の組み合わせである数値。
117                  * OR 論理演算子(|)を使用して、複数のフィルタタイプ値を選択肢として指定することができます。
118                  * @param       compressionLevel        zlib 圧縮レベルです。 0(高速無圧縮)~9(低速最大圧縮) で指定します。
119                  */
120                 public function encodeSync(source:BitmapData, colorType:int = 6, filterType:int = 248, compressionLevel:int = 1):void
121                 {
122                         _data.clear();
123                         _lib.encodeSync(_data, source.getPixels(source.rect), source.width, source.height, colorType, filterType, compressionLevel);
124                 }
125                
126                 /**
127                  * 非同期処理で、 BitmapData を PNG フォーマットにエンコードされたバイト配列にします.
128                  * エンコード処理されたデータは data プロパティに書き込みます。
129                  *
130                  * @param       source                          エンコードする BitmapData です。
131                  * @param       colorType                       PNGColorType クラスに定義されてるカラータイプ値です。
132                  * @param       filterType                      PNGFilterType クラスに定義されている任意の 5 つのフィルタタイプ値 (NONE, SUB, UP, AVG, PAETH) の組み合わせである数値。
133                  * OR 論理演算子(|)を使用して、複数のフィルタタイプ値を選択肢として指定することができます。
134                  * @param       compressionLevel        zlib 圧縮レベルです。 0(高速無圧縮)~9(低速最大圧縮) で指定します。
135                  * @param       rowSegments                     分割処理の単位となる行数です。FPS を犠牲にして高速に処理したい場合は大きな値を指定します。
136                  *
137                  * @eventType   flash.events.Event.OPEN                         エンコード処理が開始したときに送出されます。
138                  * @eventType   flash.events.ProgressEvent.PROGRESS     エンコード処理を実行中に rowSegments で指定された行数を処理する度に送出されます。
139                  * @eventType   flash.events.Event.COMPLETE                     エンコード処理が終了したときに送出されます。
140                  */
141                 public function encodeAsync(source:BitmapData, colorType:int = 6, filterType:int = 248, compressionLevel:int = 1, rowSegments:int = 10):void
142                 {
143                         _data.clear();
144                         _lib.encodeAsync(_handle, _open, _progress, _complete, rowSegments, _data, source.getPixels(source.rect), source.width, source.height, colorType, filterType, compressionLevel);
145                 }
146                
147                 /**
148                  * PNG フォーマットにエンコードされた ByteArray から主要なデータを XML に変換します.
149                  * signature と IHDR チャンクの内容を XML に変換します。
150                  * 各チャンクの length/type/CRC を chunk エレメントのアトリビュートに付加します。
151                  *
152                  * @return                                              PNG の構成を表す XML です。
153                  */
154                 public function toXML():XML
155                 {
156                         var pngXML:XML = <png />;
157                        
158                         _data.position = 0;
159                        
160                         // Read signature.
161                         pngXML.appendChild(<signature>
162                                 <signature0>{ _toHexString(_data.readUnsignedInt()) }</signature0>
163                                 <signature1>{ _toHexString(_data.readUnsignedInt()) }</signature1>
164                         </signature>);
165                        
166                         // Read chunks.
167                         var length:uint, type:String, data:ByteArray, crc:uint,
168                             width:uint, height:uint, colorType:int;
169                         var imageData:ByteArray = new ByteArray();
170                         var chunksXML:XML = <chunks />;
171                         var chunkXML:XML;
172                         do
173                         {
174                                 chunkXML = <chunk />;
175                                
176                                 length = _data.readUnsignedInt();
177                                 type = _data.readMultiByte(4, _ISO_8859_1);
178                                 if (length != 0)
179                                 {
180                                         data = new ByteArray();
181                                         _data.readBytes(data, 0, length);
182                                        
183                                         switch (type)
184                                         {
185                                                 case _IHDR_TYPE:
186                                                         data.position = 0;
187                                                         width = data.readUnsignedInt();
188                                                         chunkXML.appendChild(<width>{ width }</width>);
189                                                         height = data.readUnsignedInt();
190                                                         chunkXML.appendChild(<height>{ height }</height>);
191                                                         chunkXML.appendChild(<bitDepth>{ data.readByte() }</bitDepth>);
192                                                         colorType = data.readByte();
193                                                         chunkXML.appendChild(<colorType>{ colorType }</colorType>);
194                                                         chunkXML.appendChild(<compressionMethod>{ data.readByte() }</compressionMethod>);
195                                                         chunkXML.appendChild(<filterMethod>{ data.readByte() }</filterMethod>);
196                                                         chunkXML.appendChild(<interlaceMethod>{ data.readByte() }</interlaceMethod>);
197                                                         break;
198                                                 case _IDAT_TYPE:
199                                                         imageData.writeBytes(data);
200                                                         break;
201                                         }
202                                 }
203                                 crc = _data.readUnsignedInt();
204                                
205                                 chunkXML.@length = length;
206                                 chunkXML.@type = type;
207                                 chunkXML.@crc = _toHexString(crc);
208                                
209                                 chunksXML.appendChild(chunkXML);
210                         }
211                         while (type != _IEND_TYPE)
212                        
213                         pngXML.appendChild(chunksXML);
214                        
215                         // Get filter types.
216                         var rowSize:uint;
217                         switch (colorType)
218                         {
219                                 case PNGColorType.RGB: rowSize = 3 * width; break;
220                                 case PNGColorType.RGB_ALPHA: rowSize = 4 * width; break;
221                         }
222                         imageData.uncompress();
223                         var filters:Array = [false, false, false, false, false];
224                         var y:uint, filterType:int;
225                         for (y = 0; y < height; y ++)
226                         {
227                                 imageData.position = (1 + rowSize) * y;
228                                 filters[imageData.readByte()] = true;
229                         }
230                         var filterTypes:Array = [];
231                         var i:int;
232                         for (i = 0; i < 5; i ++)
233                         {
234                                 if (filters[i])
235                                 {
236                                         filterTypes.push(i);
237                                 }
238                         }
239                         pngXML.@filterTypes = filterTypes.join(',');
240                        
241                         return pngXML;
242                 }
243                
244                
245                 //--------------------------------------
246                 // PRIVATE METHODS
247                 //--------------------------------------
248                
249                 private function _handle():void
250                 {
251                        
252                 }
253                
254                 private function _open():void
255                 {
256                         dispatchEvent(new Event(Event.OPEN, false, false));
257                 }
258                
259                 private function _progress(bytesLoaded:uint, bytesTotal:uint):void
260                 {
261                         dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, bytesLoaded, bytesTotal));
262                 }
263                
264                 private function _complete():void
265                 {
266                         dispatchEvent(new Event(Event.COMPLETE, false, false));
267                 }
268                
269                 static private function _toHexString(hex:uint, digit:int = 8):String
270                 {
271                         var str:String = hex.toString(16).toUpperCase();
272                        
273                         while (str.length < digit)
274                         {
275                                 str = '0' + str;
276                         }
277                         str = '0x' + str;
278                        
279                         return str;
280                 }
281                
282                
283         }
284        
285        
286 }
287
288
289
290
291
292
293
294
295
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。