1 /* MemoryImageSource.java -- Java class for providing image data
2    Copyright (C) 1999 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package java.awt.image;
40 
41 import java.awt.Image;
42 import java.util.Enumeration;
43 import java.util.Hashtable;
44 
45 public class MemoryImageSource implements ImageProducer
46 {
47     private boolean animated = false;
48     private boolean fullbuffers = false;
49     private int pixeli[], width, height, offset, scansize;
50     private byte pixelb[];
51     private ColorModel cm;
52     private Hashtable props, consumers = new Hashtable();
53 
54     /**
55        Constructs an ImageProducer from memory
56     */
MemoryImageSource(int w, int h, ColorModel cm, byte pix[], int off, int scan)57     public MemoryImageSource(int w, int h, ColorModel cm,
58 			     byte pix[], int off, int scan)
59     {
60 	this ( w, h, cm, pix, off, scan, null );
61     }
62     /**
63        Constructs an ImageProducer from memory
64     */
MemoryImageSource( int w, int h, ColorModel cm, byte pix[], int off, int scan, Hashtable props)65     public MemoryImageSource( int w, int h, ColorModel cm,
66 			      byte pix[], int off, int scan,
67 			      Hashtable props)
68     {
69 	width = w;
70 	height = h;
71 	this.cm = cm;
72 	offset = off;
73 	scansize = scan;
74 	this.props = props;
75 	int max = (( scansize > width ) ? scansize : width );
76 	pixelb = new byte[ max  * height ];
77 	System.arraycopy( pix, 0, pixelb, 0, max * height );
78     }
79     /**
80        Constructs an ImageProducer from memory
81     */
MemoryImageSource(int w, int h, ColorModel cm, int pix[], int off, int scan)82     public MemoryImageSource(int w, int h, ColorModel cm,
83 			     int pix[], int off, int scan)
84     {
85 	this ( w, h, cm, pix, off, scan, null );
86     }
87 
88     /**
89        Constructs an ImageProducer from memory
90     */
MemoryImageSource(int w, int h, ColorModel cm, int pix[], int off, int scan, Hashtable props)91     public MemoryImageSource(int w, int h, ColorModel cm,
92 			     int pix[], int off, int scan,
93 			     Hashtable props)
94     {
95 	width = w;
96 	height = h;
97 	this.cm = cm;
98 	offset = off;
99 	scansize = scan;
100 	this.props = props;
101 	int max = (( scansize > width ) ? scansize : width );
102 	pixeli = new int[ max  * height ];
103 	System.arraycopy( pix, 0, pixeli, 0, max * height );
104     }
105     /**
106        Constructs an ImageProducer from memory using the default RGB ColorModel
107     */
MemoryImageSource(int w, int h, int pix[], int off, int scan, Hashtable props)108     public MemoryImageSource(int w, int h,
109 			     int pix[], int off, int scan,
110 			     Hashtable props)
111     {
112 	this ( w, h, ColorModel.getRGBdefault(), pix, off, scan, props);
113     }
114 
115     /**
116        Constructs an ImageProducer from memory using the default RGB ColorModel
117     */
MemoryImageSource(int w, int h, int pix[], int off, int scan)118     public MemoryImageSource(int w, int h,
119 			     int pix[], int off, int scan)
120     {
121 	this ( w, h, ColorModel.getRGBdefault(), pix, off, scan, null);
122     }
123 
124     /**
125      * Used to register an <code>ImageConsumer</code> with this
126      * <code>ImageProducer</code>.
127      */
addConsumer(ImageConsumer ic)128     public synchronized void addConsumer(ImageConsumer ic) {
129 	if (consumers.containsKey(ic))
130 	    return;
131 
132 	consumers.put(ic, ic);
133     }
134 
135     /**
136      * Used to determine if the given <code>ImageConsumer</code> is
137      * already registered with this <code>ImageProducer</code>.
138      */
isConsumer(ImageConsumer ic)139     public synchronized boolean isConsumer(ImageConsumer ic) {
140 	if (consumers.containsKey(ic))
141 	    return true;
142 	return false;
143     }
144 
145     /**
146      * Used to remove an <code>ImageConsumer</code> from the list of
147      * registered consumers for this <code>ImageProducer</code>.
148      */
removeConsumer(ImageConsumer ic)149     public synchronized void removeConsumer(ImageConsumer ic) {
150 	consumers.remove(ic);
151     }
152 
153     /**
154      * Used to register an <code>ImageConsumer</code> with this
155      * <code>ImageProducer</code> and then immediately start
156      * reconstruction of the image data to be delivered to all
157      * registered consumers.
158      */
startProduction(ImageConsumer ic)159     public void startProduction(ImageConsumer ic) {
160 	if (!(consumers.containsKey(ic))) {
161 	    consumers.put(ic, ic);
162 	}
163 	Enumeration e = consumers.elements();
164 	for( ; e.hasMoreElements(); ) {
165 		ic = (ImageConsumer)e.nextElement();
166 		sendPicture( ic );
167 		ic.imageComplete( ImageConsumer.SINGLEFRAME );
168 	    }
169 
170     }
171 
172     /**
173      * Used to register an <code>ImageConsumer</code> with this
174      * <code>ImageProducer</code> and then request that this producer
175      * resend the image data in the order top-down, left-right.
176      */
requestTopDownLeftRightResend(ImageConsumer ic)177     public void requestTopDownLeftRightResend(ImageConsumer ic) {
178 	startProduction ( ic );
179     }
180 
181 
182     /**
183        Changes a flag to indicate whether this MemoryImageSource supports
184        animations.
185 
186        @param animated A flag indicating whether this class supports animations
187      */
setAnimated(boolean animated)188     public synchronized void setAnimated(boolean animated)
189     {
190 	this.animated = animated;
191     }
192 
193 
194     /**
195        A flag to indicate whether or not to send full buffer updates when
196        sending animation. If this flag is set then full buffers are sent
197        in the newPixels methods instead of just regions.
198 
199        @param fullbuffers - a flag indicating whether to send the full buffers
200      */
setFullBufferUpdates(boolean fullbuffers)201     public synchronized void setFullBufferUpdates(boolean fullbuffers)
202     {
203 	this.fullbuffers = fullbuffers;
204     }
205 
206     /**
207        Send an animation frame to the image consumers.
208      */
newPixels()209     public void newPixels()
210     {
211 	if( animated == true ) {
212 		ImageConsumer ic;
213 		Enumeration e = consumers.elements();
214 		for( ; e.hasMoreElements(); ) {
215 			ic = (ImageConsumer)e.nextElement();
216 			sendPicture( ic );
217 			ic.imageComplete( ImageConsumer.SINGLEFRAME );
218 		    }
219 	    }
220     }
221 
222 
sendPicture( ImageConsumer ic )223     private void sendPicture ( ImageConsumer ic )
224     {
225 	ic.setHints( ImageConsumer.TOPDOWNLEFTRIGHT );
226 	if( props != null ) {
227 	    ic.setProperties( props );
228 	}
229 	ic.setDimensions(width, height);
230 	if( pixeli != null ) {
231 	    ic.setPixels( 0, 0, width, height, cm, pixeli, offset, scansize );
232 	} else {
233 	    ic.setPixels( 0, 0, width, height, cm, pixelb, offset, scansize );
234 	}
235     }
236 
237     /**
238        Send an animation frame to the image consumers containing the specified
239        pixels unless setFullBufferUpdates is set.
240      */
newPixels(int x, int y, int w, int h)241     public synchronized void newPixels(int x,
242 				       int y,
243 				       int w,
244 				       int h)
245     {
246 	if( animated == true )
247 	    {
248 		if( fullbuffers ) {
249 		    newPixels();
250 		} else {
251 		    ImageConsumer ic;
252 		    Enumeration e = consumers.elements();
253 		    for( ; e.hasMoreElements(); ) {
254 			    ic = (ImageConsumer)e.nextElement();
255 			    ic.setHints( ImageConsumer.TOPDOWNLEFTRIGHT );
256 			    if( props != null ) {
257 				ic.setProperties( props );
258 			    }
259 			    if( pixeli != null ) {
260 				ic.setPixels( 0, 0, width, height, cm, pixeli, offset, scansize );
261 			    } else {
262 				ic.setPixels( 0, 0, width, height, cm, pixelb, offset, scansize );
263 			    }
264 			    ic.imageComplete( ImageConsumer.SINGLEFRAME );
265 		    }
266 		}
267 	    }
268     }
269 
270 
271 
272     /**
273        Send an animation frame to the image consumers containing the specified
274        pixels unless setFullBufferUpdates is set.
275 
276        If framenotify is set then a notification is sent when the frame
277        is sent otherwise no status is sent.
278      */
newPixels(int x, int y, int w, int h, boolean framenotify)279     public synchronized void newPixels(int x,
280 				       int y,
281 				       int w,
282 				       int h,
283 				       boolean framenotify)
284     {
285 	if( animated == true )
286 	    {
287 		if( fullbuffers ) {
288 		    newPixels();
289 		} else {
290 		    ImageConsumer ic;
291 		    Enumeration e = consumers.elements();
292 		    for( ; e.hasMoreElements(); ) {
293 			    ic = (ImageConsumer)e.nextElement();
294 			    ic.setHints( ImageConsumer.TOPDOWNLEFTRIGHT );
295 			    if( props != null ) {
296 				ic.setProperties( props );
297 			    }
298 			    if( pixeli != null ) {
299 				ic.setPixels( 0, 0, width, height, cm, pixeli, offset, scansize );
300 			    } else {
301 				ic.setPixels( 0, 0, width, height, cm, pixelb, offset, scansize );
302 			    }
303 			    if( framenotify == true )
304 				ic.imageComplete( ImageConsumer.SINGLEFRAME );
305 		    }
306 		}
307 	    }
308     }
309 
newPixels(byte newpix[], ColorModel newmodel, int offset, int scansize)310     public synchronized void newPixels(byte newpix[],
311 				       ColorModel newmodel,
312 				       int offset,
313 				       int scansize)
314 
315     {
316 	if( animated == true )
317 	    {
318 		//FIXME
319 	    }
320     }
321 
newPixels(int newpix[], ColorModel newmodel, int offset, int scansize)322     public synchronized void newPixels(int newpix[],
323 				       ColorModel newmodel,
324 				       int offset,
325 				       int scansize)
326 
327     {
328 	if( animated == true )
329 	    {
330 		//FIXME
331 	    }
332     }
333 
334 }
335