1
2 package org.freehep.graphicsio.swf;
3
4 import java.awt.Color;
5 import java.awt.Image;
6 import java.awt.image.BufferedImage;
7 import java.awt.image.ImageObserver;
8 import java.awt.image.RenderedImage;
9 import java.awt.image.WritableRaster;
10 import java.io.IOException;
11 import java.util.zip.InflaterInputStream;
12
13 import org.freehep.graphicsio.ImageGraphics2D;
14 import org.freehep.graphicsio.ImageConstants;
15 import org.freehep.util.images.ImageUtilities;
16 import org.freehep.util.io.ByteOrderInputStream;
17
18
19
20
21
22
23
24
25 public class DefineBitsLossless extends DefinitionTag {
26
27 protected int character;
28
29 protected RenderedImage image;
30
31 protected Color bkg;
32
33 public DefineBitsLossless(int id, Image image, Color bkg,
34 ImageObserver observer) {
35 this(id, ImageUtilities.createRenderedImage(image, observer, bkg), bkg);
36 }
37
38 public DefineBitsLossless(int id, RenderedImage image, Color bkg) {
39 this();
40 character = id;
41 this.image = image;
42 this.bkg = bkg;
43 }
44
45 public DefineBitsLossless() {
46 super(20, 2);
47 }
48
49 protected DefineBitsLossless(int tagID, int version) {
50 super(tagID, version);
51 }
52
53 public SWFTag read(int tagID, SWFInputStream swf, int len)
54 throws IOException {
55
56 DefineBitsLossless tag = new DefineBitsLossless();
57 tag.read(tagID, swf, len, false);
58 return tag;
59 }
60
61 protected void read(int tagID, SWFInputStream swf, int len, boolean hasAlpha)
62 throws IOException {
63
64 character = swf.readUnsignedShort();
65 swf.getDictionary().put(character, this);
66
67 int format = swf.readUnsignedByte();
68 int width = swf.readUnsignedShort();
69 int height = swf.readUnsignedShort();
70
71 int colorTableSize = (format == 3) ? swf.readUnsignedByte() + 1 : 0;
72
73 InflaterInputStream zip = new InflaterInputStream(swf);
74 ByteOrderInputStream bois = new ByteOrderInputStream(zip, true);
75
76 int[][] colors = new int[colorTableSize][hasAlpha ? 4 : 3];
77 for (int i = 0; i < colorTableSize; i++) {
78 colors[i][0] = zip.read();
79 colors[i][1] = zip.read();
80 colors[i][2] = zip.read();
81 if (hasAlpha) {
82 colors[i][3] = zip.read();
83 }
84 }
85
86 BufferedImage bi = new BufferedImage(width, height,
87 (hasAlpha) ? BufferedImage.TYPE_INT_ARGB
88 : BufferedImage.TYPE_INT_RGB);
89 WritableRaster raster = bi.getRaster();
90 int[] rgba = new int[hasAlpha ? 4 : 3];
91 for (int y = 0; y < height; y++) {
92 for (int x = 0; x < width; x++) {
93 switch (format) {
94 default:
95 System.out
96 .println("ERROR: unknown format in LossLess image: "
97 + format);
98 return;
99 case 3:
100 raster.setPixel(x, y, colors[bois.readUnsignedByte()]);
101 break;
102 case 4:
103 if (hasAlpha) {
104 System.out
105 .println("ERROR: unknown format in LossLess2 image: 4");
106 return;
107 }
108 bois.readUBits(1);
109 rgba[0] = (int) bois.readUBits(5);
110 rgba[1] = (int) bois.readUBits(5);
111 rgba[2] = (int) bois.readUBits(5);
112 raster.setPixel(x, y, rgba);
113 break;
114 case 5:
115 if (hasAlpha) {
116 rgba[3] = bois.readUnsignedByte();
117 } else {
118 bois.readUnsignedByte();
119 }
120 rgba[0] = bois.readUnsignedByte();
121 rgba[1] = bois.readUnsignedByte();
122 rgba[2] = bois.readUnsignedByte();
123 raster.setPixel(x, y, rgba);
124 break;
125 }
126
127 }
128 }
129
130 image = bi;
131 }
132
133 public void write(int tagID, SWFOutputStream swf) throws IOException {
134
135 write(tagID, swf, false);
136 }
137
138 protected void write(int tagID, SWFOutputStream swf, boolean hasAlpha)
139 throws IOException {
140
141 swf.writeUnsignedShort(character);
142 swf.writeUnsignedByte(5);
143 swf.writeUnsignedShort(image.getWidth());
144 swf.writeUnsignedShort(image.getHeight());
145
146 swf.write(getImageBytes());
147 }
148
149 public int getLength() throws IOException {
150 return getImageBytes().length + 7;
151 }
152
153 private byte[] imageBytes;
154
155 private byte[] getImageBytes() throws IOException {
156 if (imageBytes == null) {
157
158 imageBytes = ImageGraphics2D.toByteArray(
159 image,
160 ImageConstants.RAW,
161 ImageConstants.ENCODING_FLATE,
162 ImageGraphics2D.getRAWProperties(bkg, ImageConstants.COLOR_MODEL_ARGB));
163 }
164 return imageBytes;
165 }
166
167 public String toString() {
168 StringBuffer s = new StringBuffer();
169 s.append(super.toString() + "\n");
170 s.append(" character: " + character);
171 s.append(" image: " + image);
172 return s.toString();
173 }
174 }