Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/anotherbigidea/flash/writers/SWFWriter.java


1   /****************************************************************
2    * Copyright (c) 2001, David N. Main, All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or
5    * without modification, are permitted provided that the 
6    * following conditions are met:
7    *
8    * 1. Redistributions of source code must retain the above 
9    * copyright notice, this list of conditions and the following 
10   * disclaimer. 
11   * 
12   * 2. Redistributions in binary form must reproduce the above 
13   * copyright notice, this list of conditions and the following 
14   * disclaimer in the documentation and/or other materials 
15   * provided with the distribution.
16   * 
17   * 3. The name of the author may not be used to endorse or 
18   * promote products derived from this software without specific 
19   * prior written permission. 
20   * 
21   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 
22   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
23   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
24   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
25   * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
27   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
28   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
29   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
30   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
31   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
32   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   ****************************************************************/
34  package com.anotherbigidea.flash.writers;
35  
36  import java.io.*;
37  import com.anotherbigidea.io.*;
38  import com.anotherbigidea.flash.*;
39  import com.anotherbigidea.flash.structs.Rect;
40  import com.anotherbigidea.flash.interfaces.*;
41  
42  /**
43   * Implements the SWFTags interface and writes a SWF file to the output stream
44   */
45  public class SWFWriter implements SWFTags, SWFFileSignature
46  {
47      protected OutStream    mOut;
48      protected OutputStream mOutputstream;
49      protected ByteArrayOutputStream mByteout;
50      protected String mSignature = null;
51      
52      //--deferred header values
53      protected int  frameCount;
54      protected int  version;
55      protected Rect frameSize;
56      protected int  height;
57      protected int  rate;
58      
59      /**
60       * Write to a file.
61       */
62      public SWFWriter( String filename ) throws IOException {
63        this( new FileOutputStream( filename ) );
64      }
65      
66      /**
67       * Write to an output stream - closing it at the end.
68       */
69      public SWFWriter( OutputStream outputstream )
70      {
71          mOutputstream = outputstream;
72          mOut = new OutStream( outputstream );
73      } 
74      
75    /**
76     * Write to an out stream - closing it at the end.
77     */
78      public SWFWriter( OutStream outstream )
79      {
80          mOut = outstream;
81      }
82      
83    /**
84     * Sets the file signature if it has not been set already.
85     * The setCompression(..) method calls this and thus prevents any further
86     * changes to the signature - overriding any signature passed down from the
87     * SWFReader.
88     * 
89     * @see SWFFileSignature#signature(String)
90     */    
91      public void signature( String sig ) {
92        if( mSignature != null ) return;
93      mSignature = sig;      
94      }
95      
96      /**
97       * Set Flash MX+ zip-compression on or off.  
98       * It sets the file signature and thus prevents any different signature
99       * from being specified.  Only the first call to this method has any effect,
100      * and only if signature(..) has not been called yet.
101      * 
102      * @param compressionOn true for compression, false for no compression.
103      */
104     public void setCompression( boolean compressionOn ) {
105     signature( compressionOn ?
106             SWFFileSignature.SIGNATURE_COMPRESSED :
107             SWFFileSignature.SIGNATURE_NORMAL );
108     }
109     
110     /**
111      * Writes the header unless the length or framecount are unknown (as
112      * signified by a negative value), in which case the header values are
113      * stored and written later, when the unknown value(s) can be determined.
114      * 
115      * @see SWFHeader#header(int, long, int, int, int, int)
116      */
117     public void header( int version, long length,
118                         int twipsWidth, int twipsHeight,
119                         int frameRate, int frameCount ) throws IOException
120     {
121         frameSize = new Rect( 0, 0, twipsWidth, twipsHeight );        
122 
123         //--Unknown values
124         if( length < 0 || frameCount < 0 )
125         {
126             //--defer the header
127             this.version    = version;
128             this.rate       = frameRate;
129             this.frameCount = 0;
130                 
131             //--set up a byte array for the output
132             if( mByteout == null )
133             {
134                 mByteout = new ByteArrayOutputStream( 20000 );
135                 mOut = new OutStream( mByteout );
136             }
137             
138       return;
139         }            
140 
141         writeHeader( version, length, frameRate, frameCount );        
142     }
143     
144     /**
145      * @see SWFTags#tag(int, boolean, byte[])
146      */
147     public void tag( int tagType, boolean longTag, 
148                      byte[] contents ) throws IOException
149     {
150         //System.out.println( "OUT Tag " + tagType + " " + longTag + " " + ( (contents==null) ? 0 : contents.length) );
151         //System.out.println();
152         
153         int length = (contents != null ) ? contents.length : 0;
154         longTag = ( length > 62 ) || longTag;
155         
156         int hdr = ( tagType << 6 ) + ( longTag ? 0x3f : length );
157 
158         mOut.writeUI16( hdr );
159         
160         if( longTag ) mOut.writeUI32( length );        
161         
162         if( contents != null ) mOut.write( contents );
163         
164         if( tagType == SWFConstants.TAG_SHOWFRAME ) frameCount++;        
165         if( tagType == SWFConstants.TAG_END       ) finish();
166     }
167     
168     protected void writeHeader( int version, long length,
169                                 int frameRate, int frameCount ) throws IOException 
170     {        
171     writeSignature();
172         mOut.writeUI8( version );
173         mOut.writeUI32( length );        
174         
175         //may be compressed from this point onwards
176         if( mSignature.equals( SWFFileSignature.SIGNATURE_COMPRESSED ) ) {
177           mOut.writeCompressed();
178         }
179         
180         frameSize.write( mOut );
181         mOut.writeUI16( frameRate << 8 );
182         mOut.writeUI16( frameCount );    
183     }
184     
185     private void writeSignature() throws IOException {
186       if( mSignature == null ) signature( SWFFileSignature.SIGNATURE_NORMAL );
187     mOut.write( mSignature.getBytes( "US-ASCII" ));
188     }
189     
190     /**
191      * Finish writing
192      */
193     protected void finish() throws IOException
194     {
195         //--Writing to a byte array - need to recalculate lengths
196         if( mByteout != null )
197         {
198             byte[] bytes = mByteout.toByteArray();
199 
200             long length = 12L + frameSize.getLength() + bytes.length;
201 
202             mOut = new OutStream( mOutputstream );
203             
204             writeHeader( version, length, rate, frameCount );
205             
206             mOut.write( bytes );
207         }
208 
209     mOut.close();
210     }
211 }