1
2 package org.freehep.graphicsio.swf;
3
4 import java.awt.Color;
5 import java.awt.Dimension;
6 import java.awt.geom.AffineTransform;
7 import java.awt.geom.Rectangle2D;
8 import java.io.IOException;
9 import java.io.OutputStream;
10
11 import org.freehep.util.io.ActionHeader;
12 import org.freehep.util.io.TagHeader;
13 import org.freehep.util.io.TaggedOutputStream;
14
15
16
17
18
19
20
21
22
23 public class SWFOutputStream extends TaggedOutputStream implements SWFConstants {
24
25 private Dimension size;
26
27 private float frameRate;
28
29 private int frameCount = 0;
30
31 private boolean compress;
32
33 private final static AffineTransform identityMatrix = new AffineTransform();
34
35 public SWFOutputStream(OutputStream os, Dimension size, float frameRate,
36 boolean compress) throws IOException {
37
38 this(os, DEFAULT_VERSION, size, frameRate, compress);
39 }
40
41 public SWFOutputStream(OutputStream os, int version, Dimension size,
42 float frameRate, boolean compress) throws IOException {
43
44 this(os, new SWFTagSet(version), new SWFActionSet(version), size,
45 frameRate, compress);
46 }
47
48 public SWFOutputStream(OutputStream os, SWFTagSet tagSet,
49 SWFActionSet actionSet, Dimension size, float frameRate,
50 boolean compress) throws IOException {
51
52
53 super(os, tagSet, actionSet, true);
54 this.size = size;
55 this.frameRate = frameRate;
56 this.compress = compress;
57
58
59 pushBuffer();
60
61
62 writeTag(new FileAttributes());
63 }
64
65 public void close() throws IOException {
66 long len = popBuffer() + SWFHeader.size();
67 SWFHeader header = new SWFHeader(getVersion(), len, size, frameRate,
68 frameCount, compress);
69 writeHeader(header);
70 append();
71
72 super.close();
73 }
74
75 public void writeTag(ShowFrame tag) throws IOException {
76
77 frameCount++;
78 super.writeTag(tag);
79 }
80
81 public void writeFixed(double d) throws IOException {
82
83 byteAlign();
84 long whole = (long) d;
85 long frac = (long) ((d - whole) * 0x10000);
86
87 long fixed = ((whole & 0xFFFF) << 16) | (frac & 0xFFFF);
88 writeUnsignedInt(fixed);
89 }
90
91 public void writeFixed8(double d) throws IOException {
92
93 byteAlign();
94 int whole = (int) d;
95 int frac = (int) ((d - whole) * 0x100);
96
97 int fixed = ((whole & 0xFF) << 8) | (frac & 0xFF);
98 writeUnsignedShort(fixed);
99 }
100
101 public void writeRect(Rectangle2D rect) throws IOException {
102
103 int nbits = 0;
104 nbits = Math.max(nbits, minBits((int) (rect.getMinX() * TWIPS), true));
105 nbits = Math.max(nbits, minBits((int) (rect.getMaxX() * TWIPS), true));
106 nbits = Math.max(nbits, minBits((int) (rect.getMinY() * TWIPS), true));
107 nbits = Math.max(nbits, minBits((int) (rect.getMaxY() * TWIPS), true));
108 writeRect(rect, nbits);
109 }
110
111 public void writeRect(Rectangle2D rect, int nbits) throws IOException {
112
113 byteAlign();
114 writeUBits(nbits, 5);
115 writeSBits((int) (rect.getMinX() * TWIPS), nbits);
116 writeSBits((int) (rect.getMaxX() * TWIPS), nbits);
117 writeSBits((int) (rect.getMinY() * TWIPS), nbits);
118 writeSBits((int) (rect.getMaxY() * TWIPS), nbits);
119 }
120
121 public void writeColor(Color color, boolean alpha) throws IOException {
122
123 byteAlign();
124 writeUnsignedByte(color.getRed());
125 writeUnsignedByte(color.getGreen());
126 writeUnsignedByte(color.getBlue());
127 if (alpha)
128 writeUnsignedByte(color.getAlpha());
129 }
130
131 public void writeMatrix(AffineTransform matrix) throws IOException {
132
133 if (matrix == null)
134 matrix = identityMatrix;
135
136 byteAlign();
137
138
139 if ((matrix.getScaleX() != 1.f) || (matrix.getScaleY() != 1.f)) {
140 writeBitFlag(true);
141 int nbits = 0;
142 nbits = Math.max(nbits, minBits((float) matrix.getScaleX()));
143 nbits = Math.max(nbits, minBits((float) matrix.getScaleY()));
144 writeUBits(nbits, 5);
145 writeFBits((float) matrix.getScaleX(), nbits);
146 writeFBits((float) matrix.getScaleY(), nbits);
147 } else {
148 writeBitFlag(false);
149 }
150
151
152 if ((matrix.getShearX() != 0.f) || (matrix.getShearY() != 0.f)) {
153 writeBitFlag(true);
154 int nbits = 0;
155 nbits = Math.max(nbits, minBits((float) matrix.getShearY()));
156 nbits = Math.max(nbits, minBits((float) matrix.getShearX()));
157 writeUBits(nbits, 5);
158 writeFBits((float) matrix.getShearY(), nbits);
159 writeFBits((float) matrix.getShearX(), nbits);
160 } else {
161 writeBitFlag(false);
162 }
163
164
165 int nbits = 0;
166 nbits = Math.max(nbits, minBits((int) (matrix.getTranslateX() * TWIPS),
167 true));
168 nbits = Math.max(nbits, minBits((int) (matrix.getTranslateY() * TWIPS),
169 true));
170 writeUBits(nbits, 5);
171 writeSBits((int) (matrix.getTranslateX() * TWIPS), nbits);
172 writeSBits((int) (matrix.getTranslateY() * TWIPS), nbits);
173 }
174
175 public void writeString(String s) throws IOException {
176 if (getVersion() >= 6) {
177 writeUTF(s);
178 writeByte(0);
179 } else {
180 writeAsciiZString(s);
181 }
182 }
183
184 public void writeLanguageCode(int code) throws IOException {
185 writeUnsignedByte(code);
186 }
187
188 protected void writeTagHeader(TagHeader tagHeader) throws IOException {
189 byteAlign();
190 int th = (tagHeader.getTag() << 6);
191 if (tagHeader.getLength() >= 0x3f) {
192 th |= 0x3f;
193 writeUnsignedShort(th);
194 writeUnsignedInt(tagHeader.getLength());
195 } else {
196 th |= tagHeader.getLength();
197 writeUnsignedShort(th);
198 }
199 }
200
201 protected void writeActionHeader(ActionHeader header) throws IOException {
202
203 int actionCode = header.getAction();
204 long length = header.getLength();
205 writeUnsignedByte(actionCode);
206
207 if ((actionCode & 0x80) > 0) {
208 writeUnsignedShort((int) length);
209 }
210 }
211
212 public void writeHeader(SWFHeader header) throws IOException {
213 header.write(this);
214 }
215
216 public int getVersion() {
217 return ((SWFTagSet) tagSet).getVersion();
218 }
219 }