View Javadoc

1   // Copyright 2002-2007, FreeHEP.
2   package org.freehep.graphicsio.emf.gdi;
3   
4   import java.awt.Color;
5   import java.awt.Rectangle;
6   import java.awt.image.RenderedImage;
7   import java.awt.image.BufferedImage;
8   import java.io.IOException;
9   
10  import org.freehep.graphicsio.ImageGraphics2D;
11  import org.freehep.graphicsio.ImageConstants;
12  import org.freehep.graphicsio.emf.EMFConstants;
13  import org.freehep.graphicsio.emf.EMFInputStream;
14  import org.freehep.graphicsio.emf.EMFOutputStream;
15  import org.freehep.graphicsio.emf.EMFTag;
16  import org.freehep.graphicsio.emf.EMFImageLoader;
17  import org.freehep.graphicsio.emf.EMFRenderer;
18  import org.freehep.util.io.NoCloseOutputStream;
19  
20  /**
21   * StretchDIBits TAG. Encoded as plain RGB rather than the not-yet-working PNG
22   * format. The BI_code for BI_PNG and BI_JPG seems to be missing from the
23   * WINGDI.H file of visual C++.
24   * 
25   * @author Mark Donszelmann
26   * @version $Id: StretchDIBits.java 10510 2007-01-30 23:58:16Z duns $
27   */
28  public class StretchDIBits extends EMFTag implements EMFConstants {
29  
30      public final static int size = 80;
31  
32      private Rectangle bounds;
33  
34      private int x, y, width, height;
35  
36      private int xSrc, ySrc, widthSrc, heightSrc;
37  
38      private int usage, dwROP;
39  
40      private Color bkg;
41  
42      private BitmapInfo bmi;
43  
44      private BufferedImage image;
45  
46      public StretchDIBits() {
47          super(81, 1);
48      }
49  
50      public StretchDIBits(Rectangle bounds, int x, int y, int width, int height,
51              BufferedImage image, Color bkg) {
52          this();
53          this.bounds = bounds;
54          this.x = x;
55          this.y = y;
56          this.width = width;
57          this.height = height;
58          this.xSrc = 0;
59          this.ySrc = 0;
60          this.widthSrc = image.getWidth();
61          this.heightSrc = image.getHeight();
62          this.usage = DIB_RGB_COLORS;
63          this.dwROP = SRCCOPY;
64  
65          this.bkg = bkg;
66          this.image = image;
67          this.bmi = null;
68      }
69  
70      public EMFTag read(int tagID, EMFInputStream emf, int len)
71              throws IOException {
72  
73          StretchDIBits tag = new StretchDIBits();
74          tag.bounds = emf.readRECTL(); // 16
75          tag.x = emf.readLONG(); // 20
76          tag.y = emf.readLONG(); // 24
77          tag.xSrc = emf.readLONG(); // 28
78          tag.ySrc = emf.readLONG(); // 32
79          tag.width = emf.readLONG(); // 36
80          tag.height = emf.readLONG(); // 40
81          // ignored
82          emf.readDWORD(); // 44
83          emf.readDWORD(); // 48
84          emf.readDWORD(); // 52
85          emf.readDWORD(); // 56
86  
87          tag.usage = emf.readDWORD(); // 60
88          tag.dwROP = emf.readDWORD(); // 64
89          tag.widthSrc = emf.readLONG(); // 68
90          tag.heightSrc = emf.readLONG(); // 72
91  
92          // FIXME: this size can differ and can be placed somewhere else
93          tag.bmi = new BitmapInfo(emf);
94  
95          tag.image = EMFImageLoader.readImage(
96              tag.bmi.getHeader(),
97              tag.width,
98              tag.height,
99              emf,
100             len - 72 - BitmapInfoHeader.size, null);
101 
102         return tag;
103     }
104 
105     public void write(int tagID, EMFOutputStream emf) throws IOException {
106         emf.writeRECTL(bounds);
107         emf.writeLONG(x);
108         emf.writeLONG(y);
109         emf.writeLONG(xSrc);
110         emf.writeLONG(ySrc);
111         emf.writeLONG(widthSrc);
112         emf.writeLONG(heightSrc);
113         emf.writeDWORD(size); // bmi follows this record immediately
114         emf.writeDWORD(BitmapInfoHeader.size);
115         emf.writeDWORD(size + BitmapInfoHeader.size); // bitmap follows bmi
116 
117         // write image and calculate size
118         emf.pushBuffer();
119         int encode;
120         // plain
121         encode = BI_RGB;
122 
123         ImageGraphics2D.writeImage(
124             (RenderedImage) image,
125             ImageConstants.RAW.toLowerCase(),
126             ImageGraphics2D.getRAWProperties(bkg, "BGR"),
127             new NoCloseOutputStream(emf));
128         // emf.writeImage(image, bkg, "BGR", 1);
129         // png
130         // encode = BI_PNG;
131         // ImageGraphics2D.writeImage(image, "png", new Properties(), new
132         // NoCloseOutputStream(emf));
133         // jpg
134         // encode = BI_JPEG;
135         // ImageGraphics2D.writeImage(image, "jpg", new Properties(), new
136         // NoCloseOutputStream(emf));
137         int length = emf.popBuffer();
138 
139         emf.writeDWORD(length);
140         emf.writeDWORD(usage);
141         emf.writeDWORD(dwROP);
142         emf.writeLONG(width);
143         emf.writeLONG(height);
144 
145         BitmapInfoHeader header = new BitmapInfoHeader(widthSrc, heightSrc, 24,
146                 encode, length, 0, 0, 0, 0);
147         bmi = new BitmapInfo(header);
148         bmi.write(emf);
149 
150         emf.append();
151     }
152 
153     public String toString() {
154         return super.toString() +
155             "\n  bounds: " + bounds +
156             "\n  x, y, w, h: " + x + " " + y + " " + width + " " + height +
157             "\n  xSrc, ySrc, widthSrc, heightSrc: " + xSrc + " "
158                 + ySrc + " " + widthSrc + " " + heightSrc +
159             "\n  usage: " + usage +
160             "\n  dwROP: " + dwROP +
161             "\n  bkg: " + bkg +
162             "\n" + bmi.toString();
163     }
164 
165     /**
166      * displays the tag using the renderer
167      *
168      * @param renderer EMFRenderer storing the drawing session data
169      */
170     public void render(EMFRenderer renderer) {
171         // The StretchDIBits function copies the color data for a rectangle of pixels in a
172         // DIB to the specified destination rectangle. If the destination rectangle is larger
173         // than the source rectangle, this function stretches the rows and columns of color
174         // data to fit the destination rectangle. If the destination rectangle is smaller
175         // than the source rectangle, this function compresses the rows and columns by using
176         // the specified raster operation.
177         if (image != null) {
178             renderer.drawImage(image, x, y, widthSrc, heightSrc);
179         }
180     }
181 }