KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > Acme > JPM > Encoders > ImageEncoder


1 // ImageEncoder - abstract class for writing out an image
2
//
3
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions
7
// are met:
8
// 1. Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
// 2. Redistributions in binary form must reproduce the above copyright
11
// notice, this list of conditions and the following disclaimer in the
12
// documentation and/or other materials provided with the distribution.
13
//
14
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
// SUCH DAMAGE.
25
//
26
// Visit the ACME Labs Java page for up-to-date versions of this and other
27
// fine Java utilities: http://www.acme.com/java/
28

29 package Acme.JPM.Encoders;
30
31 import java.awt.*;
32 import java.awt.image.ColorModel JavaDoc;
33 import java.awt.image.ImageConsumer JavaDoc;
34 import java.awt.image.ImageProducer JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.OutputStream JavaDoc;
37 import java.util.Hashtable JavaDoc;
38
39 /// Abstract class for writing out an image.
40
// <P>
41
// A framework for classes that encode and write out an image in
42
// a particular file format.
43
// <P>
44
// This provides a simplified rendition of the ImageConsumer interface.
45
// It always delivers the pixels as ints in the RGBdefault color model.
46
// It always provides them in top-down left-right order.
47
// If you want more flexibility you can always implement ImageConsumer
48
// directly.
49
// <P>
50
// <A HREF="../../../../resources/classes/Acme/JPM/Encoders/ImageEncoder.java">Fetch the software.</A><BR>
51
// <A HREF="../../../../resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
52
// <P>
53
// @see GifEncoder
54
// @see PpmEncoder
55
// @see Acme.JPM.Decoders.ImageDecoder
56

57 public abstract class ImageEncoder implements ImageConsumer JavaDoc {
58
59     protected OutputStream JavaDoc out;
60
61     private ImageProducer JavaDoc producer;
62     private int width = -1;
63     private int height = -1;
64     private int hintflags = 0;
65     private boolean started = false;
66     private boolean encoding;
67     private IOException JavaDoc iox;
68     private static final ColorModel JavaDoc rgbModel = ColorModel.getRGBdefault();
69     private Hashtable JavaDoc props = null;
70
71     /// Constructor.
72
// @param img The image to encode.
73
// @param out The stream to write the bytes to.
74
public ImageEncoder(Image img, OutputStream JavaDoc out) throws IOException JavaDoc {
75         this(img.getSource(), out);
76     }
77
78     /// Constructor.
79
// @param producer The ImageProducer to encode.
80
// @param out The stream to write the bytes to.
81
public ImageEncoder(ImageProducer JavaDoc producer, OutputStream JavaDoc out) throws IOException JavaDoc {
82         this.producer = producer;
83         this.out = out;
84     }
85
86
87     // Methods that subclasses implement.
88

89     /// Subclasses implement this to initialize an encoding.
90
abstract void encodeStart(int w, int h) throws IOException JavaDoc;
91
92     /// Subclasses implement this to actually write out some bits. They
93
// are guaranteed to be delivered in top-down-left-right order.
94
// One int per pixel, index is row * scansize + off + col,
95
// RGBdefault (AARRGGBB) color model.
96
abstract void encodePixels(int x, int y, int w, int h, int[] rgbPixels, int off, int scansize)
97             throws IOException JavaDoc;
98
99     /// Subclasses implement this to finish an encoding.
100
abstract void encodeDone() throws IOException JavaDoc;
101
102
103     // Our own methods.
104

105     /// Call this after initialization to get things going.
106
public synchronized void encode() throws IOException JavaDoc {
107         encoding = true;
108         iox = null;
109         producer.startProduction(this);
110         while (encoding)
111             try {
112                 wait();
113             } catch (InterruptedException JavaDoc e) {}
114         if (iox != null)
115             throw iox;
116     }
117
118     private boolean accumulate = false;
119     private int[] accumulator;
120
121     private void encodePixelsWrapper(int x, int y, int w, int h, int[] rgbPixels, int off, int scansize)
122             throws IOException JavaDoc {
123         if (!started) {
124             started = true;
125             encodeStart(width, height);
126             if ((hintflags & TOPDOWNLEFTRIGHT) == 0) {
127                 accumulate = true;
128                 accumulator = new int[width * height];
129             }
130         }
131         if (accumulate)
132             for (int row = 0; row < h; ++row)
133                 System.arraycopy(rgbPixels, row * scansize + off,
134                         accumulator, (y + row) * width + x,
135                         w);
136         else
137             encodePixels(x, y, w, h, rgbPixels, off, scansize);
138     }
139
140     private void encodeFinish() throws IOException JavaDoc {
141         if (accumulate) {
142             encodePixels(0, 0, width, height, accumulator, 0, width);
143             accumulator = null;
144             accumulate = false;
145         }
146     }
147
148     private synchronized void stop() {
149         encoding = false;
150         notifyAll();
151     }
152
153
154     // Methods from ImageConsumer.
155

156     public void setDimensions(int width, int height) {
157         this.width = width;
158         this.height = height;
159     }
160
161     public void setProperties(Hashtable JavaDoc props) {
162         this.props = props;
163     }
164
165     public void setColorModel(ColorModel JavaDoc model) {
166         // Ignore.
167
}
168
169     public void setHints(int hintflags) {
170         this.hintflags = hintflags;
171     }
172
173     public void setPixels(int x, int y, int w, int h, ColorModel JavaDoc model, byte[] pixels,
174                           int off, int scansize) {
175         int[] rgbPixels = new int[w];
176         for (int row = 0; row < h; ++row) {
177             int rowOff = off + row * scansize;
178             for (int col = 0; col < w; ++col)
179                 rgbPixels[col] = model.getRGB(pixels[rowOff + col] & 0xff);
180             try {
181                 encodePixelsWrapper(x, y + row, w, 1, rgbPixels, 0, w);
182             } catch (IOException JavaDoc e) {
183                 iox = e;
184                 stop();
185                 return;
186             }
187         }
188     }
189
190     public void setPixels(int x, int y, int w, int h, ColorModel JavaDoc model, int[] pixels,
191                           int off, int scansize) {
192         if (model == rgbModel) {
193             try {
194                 encodePixelsWrapper(x, y, w, h, pixels, off, scansize);
195             } catch (IOException JavaDoc e) {
196                 iox = e;
197                 stop();
198                 return;
199             }
200         } else {
201             int[] rgbPixels = new int[w];
202             for (int row = 0; row < h; ++row) {
203                 int rowOff = off + row * scansize;
204                 for (int col = 0; col < w; ++col)
205                     rgbPixels[col] = model.getRGB(pixels[rowOff + col]);
206                 try {
207                     encodePixelsWrapper(x, y + row, w, 1, rgbPixels, 0, w);
208                 } catch (IOException JavaDoc e) {
209                     iox = e;
210                     stop();
211                     return;
212                 }
213             }
214         }
215     }
216
217     public void imageComplete(int status) {
218         producer.removeConsumer(this);
219         if (status == ImageConsumer.IMAGEABORTED)
220             iox = new IOException JavaDoc("image aborted");
221         else {
222             try {
223                 encodeFinish();
224                 encodeDone();
225             } catch (IOException JavaDoc e) {
226                 iox = e;
227             }
228         }
229         stop();
230     }
231
232 }
233
Popular Tags