View Javadoc

1   // Copyright 2001-2007, FreeHEP.
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   * DefineBitsLossless TAG.
20   * 
21   * @author Mark Donszelmann
22   * @author Charles Loomis
23   * @version $Id: DefineBitsLossless.java 10269 2007-01-09 00:32:55Z duns $
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                 // FIXME padding not taken into account.
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); // fixed to format 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             // calculate bytes
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 }