KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > iv > flash > api > CXForm


1 /*
2  * $Id: CXForm.java,v 1.3 2002/08/12 21:18:28 skavish Exp $
3  *
4  * ==========================================================================
5  *
6  * The JGenerator Software License, Version 1.0
7  *
8  * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if
22  * any, must include the following acknowlegement:
23  * "This product includes software developed by Dmitry Skavish
24  * (skavish@usa.net, http://www.flashgap.com/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The name "The JGenerator" must not be used to endorse or promote
29  * products derived from this software without prior written permission.
30  * For written permission, please contact skavish@usa.net.
31  *
32  * 5. Products derived from this software may not be called "The JGenerator"
33  * nor may "The JGenerator" appear in their names without prior written
34  * permission of Dmitry Skavish.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
40  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  *
49  */

50
51 package org.openlaszlo.iv.flash.api;
52
53 import java.io.*;
54 import org.openlaszlo.iv.flash.parser.*;
55 import org.openlaszlo.iv.flash.util.*;
56
57 /**
58  * Class defines a simple transform that can be applied to the color space of a graphic object.<BR>
59  * There are two types of transform possible:
60  * <P>
61  * 1. Multiplication Transforms<BR>
62  * 2. Addition Transforms<BR>
63  * <P>
64  * Multiplication transforms multiply the red, green, and blue components by an 8.8 fixed-point multiplication term.
65  * The fixed-point representation of 1.0 is 0x100 or 256 decimal.
66  * Therefore, the result of a multiplication operation should be divided by 256.<BR>
67  * <P>
68  * For any color (R,G,B,A) the transformed color (R', G', B', A') is calculated as follows:
69  * <P>
70  * R' = (R * RedMultTerm) / 256<BR>
71  * G' = (G * GreenMultTerm) / 256<BR>
72  * B' = (B * BlueMultTerm) / 256<BR>
73  * A' = (A * AlphaMultTerm) / 256<br>
74  * <P>
75  * Addition transforms simply add an addition term (positive or negative) to the red, green and blue components of
76  * the object being displayed. If the result is greater than 255, the result is clamped to 255.
77  * If the result is less than zero, the result is clamped to zero.
78  * <P>
79  * For any color (R,G,B,A) the transformed color (R', G', B', A') is calculated as follows:
80  * <P>
81  * R' = max(0, min(R + RedAddTerm, 255))<BR>
82  * G' = max(0, min(G + GreenAddTerm, 255))<BR>
83  * B' = max(0, min(B + BlueAddTerm, 255))<BR>
84  * A' = max(0, min(A + AlphaAddTerm, 255))<br>
85  * <P>
86  * Addition and Multiplication transforms can be combined as below.
87  * The multiplication operation is performed first.
88  * <P>
89  * R' = max(0, min(((R * RedMultTerm) / 256) + RedAddTerm, 255))<BR>
90  * G' = max(0, min(((G * GreenMultTerm) / 256) + GreenAddTerm, 255))<BR>
91  * B' = max(0, min(((B * BlueMultTerm) / 256) + BlueAddTerm, 255))<BR>
92  * A' = max(0, min(((A * AlphaMultTerm) / 256) + AlphaAddTerm, 255))<br>
93  *
94  * @author Dmitry Skavish
95  */

96 public final class CXForm extends FlashItem {
97
98     private int rAdd;
99     private int gAdd;
100     private int bAdd;
101     private int aAdd;
102     private int rMul;
103     private int gMul;
104     private int bMul;
105     private int aMul;
106     private boolean withAlpha;
107
108     public CXForm() {}
109
110     /**
111      * Creates color transformation
112      *
113      * @param withAlpha if true creates transformation with alpha
114      */

115     public CXForm( boolean withAlpha ) {
116         this.withAlpha = withAlpha;
117     }
118
119     public int getRedAdd() {
120         return rAdd;
121     }
122     public int getGreenAdd() {
123         return gAdd;
124     }
125     public int getBlueAdd() {
126         return bAdd;
127     }
128     public int getAlphaAdd() {
129         return aAdd;
130     }
131
132     public int getRedMul() {
133         return rMul;
134     }
135     public int getGreenMul() {
136         return gMul;
137     }
138     public int getBlueMul() {
139         return bMul;
140     }
141     public int getAlphaMul() {
142         return aMul;
143     }
144
145     public void setRedAdd( int v ) {
146         rAdd = v;
147     }
148     public void setGreenAdd( int v ) {
149         gAdd = v;
150     }
151     public void setBlueAdd( int v ) {
152         bAdd = v;
153     }
154     public void setAlphaAdd( int v ) {
155         aAdd = v;
156     }
157
158     public void setRedMul( int v ) {
159         rMul = v;
160     }
161     public void setGreenMul( int v ) {
162         gMul = v;
163     }
164     public void setBlueMul( int v ) {
165         bMul = v;
166     }
167     public void setAlphaMul( int v ) {
168         aMul = v;
169     }
170
171     public void setWithAlpha( boolean withAlpha ) {
172         this.withAlpha = withAlpha;
173     }
174
175     private boolean hasAdd() {
176         return rAdd != 0 || gAdd != 0 || bAdd != 0 || aAdd != 0;
177     }
178
179     private boolean hasMul() {
180         return rMul != 256 || gMul != 256 || bMul != 256 || aMul != 256;
181     }
182
183     /**
184      * Creates transformation which being applied to colors reduces or increases brightness
185      *
186      * @param f value between -1.0 and 1.0<br>
187      * from -1 to 0 - reduce brightness<br>
188      * from 0 to 1 - increase brightness
189      * @param withAlpha if true this transformation will be with alpha
190      * @return new transformation
191      */

192     public static CXForm newBrightness( double f, boolean withAlpha ) {
193         CXForm cx = newIdentity(withAlpha);
194         if( f < 0.0 ) {
195             int ff = (int) ((1.0+f)*256.0);
196             cx.setRedMul(ff);
197             cx.setGreenMul(ff);
198             cx.setBlueMul(ff);
199         } else {
200             int ff = (int) (f*256.0);
201             cx.setRedAdd(ff);
202             cx.setGreenAdd(ff);
203             cx.setBlueAdd(ff);
204             ff = 256-ff;
205             cx.setRedMul(ff);
206             cx.setGreenMul(ff);
207             cx.setBlueMul(ff);
208         }
209         return cx;
210     }
211
212     /**
213      * Creates identity transformation (no tranformation at all)
214      *
215      * @param withAlpha if true then create transformation with alpha
216      * @return default transformation
217      */

218     public static CXForm newIdentity( boolean withAlpha ) {
219         CXForm cx = new CXForm( withAlpha );
220         cx.initDefault();
221         return cx;
222     }
223
224     /**
225      * Creates transformation which being to applied to colors sets their alpha to specified value
226      *
227      * @param alpha alpha in range 0..256
228      * @return transformation with specified alpha
229      */

230     public static CXForm newAlpha( int alpha ) {
231         CXForm cx = new CXForm(true);
232         cx.initDefault();
233         cx.aMul = alpha;
234         return cx;
235     }
236
237     private void initDefault() {
238         rMul = gMul = bMul = aMul = 256;
239         rAdd = gAdd = bAdd = aAdd = 0;
240     }
241
242     /**
243      * Creates linear interpolation of the two specified transformation
244      *
245      * @param t coefficient of the interpolation [0..1]
246      * @param c1 first matrix
247      * @param c2 second matrix
248      * @return interpolation of two specified matrixes
249      */

250     public static CXForm interLinear( double t, CXForm c1, CXForm c2 ) {
251         double t1 = 1.0-t;
252         CXForm n = new CXForm();
253         n.withAlpha = c1.withAlpha||c2.withAlpha;
254         n.rAdd = (int) (c1.rAdd*t1+c2.rAdd*t);
255         n.gAdd = (int) (c1.gAdd*t1+c2.gAdd*t);
256         n.bAdd = (int) (c1.bAdd*t1+c2.bAdd*t);
257         n.aAdd = (int) (c1.aAdd*t1+c2.aAdd*t);
258         n.rMul = (int) (c1.rMul*t1+c2.rMul*t);
259         n.gMul = (int) (c1.gMul*t1+c2.gMul*t);
260         n.bMul = (int) (c1.bMul*t1+c2.bMul*t);
261         n.aMul = (int) (c1.aMul*t1+c2.aMul*t);
262         return n;
263
264     }
265     /**
266      * Transforms specified color
267      *
268      * @param color specified color to be transformed
269      * @return new transformed color
270      */

271     public AlphaColor transform( AlphaColor color ) {
272         int r = Math.max(0, Math.min(((color.getRed()*rMul)/256)+rAdd, 255));
273         int g = Math.max(0, Math.min(((color.getGreen()*gMul)/256)+gAdd, 255));
274         int b = Math.max(0, Math.min(((color.getBlue()*bMul)/256)+bAdd, 255));
275         int a = Math.max(0, Math.min(((color.getAlpha()*aMul)/256)+aAdd, 255));
276
277         return new AlphaColor(r, g, b, a);
278     }
279
280     /**
281      * Transforms specified color
282      *
283      * @param color specified color to be transformed
284      * @return new transformed color
285      */

286     public Color transform( Color color ) {
287         if( color instanceof AlphaColor ) return transform((AlphaColor) color);
288
289         int r = Math.max(0, Math.min(((color.getRed()*rMul)/256)+rAdd, 255));
290         int g = Math.max(0, Math.min(((color.getGreen()*gMul)/256)+gAdd, 255));
291         int b = Math.max(0, Math.min(((color.getBlue()*bMul)/256)+bAdd, 255));
292
293         return new Color(r, g, b);
294     }
295
296     public static CXForm parse( Parser p, boolean withAlpha ) {
297         p.initBits();
298         CXForm f = new CXForm();
299         f.withAlpha = withAlpha;
300         boolean hasAdd = p.getBool();
301         boolean hasMul = p.getBool();
302         int nBits = p.getBits(4);
303         if( hasMul ) {
304             f.rMul = p.getSBits(nBits);
305             f.gMul = p.getSBits(nBits);
306             f.bMul = p.getSBits(nBits);
307             if( withAlpha ) f.aMul = p.getSBits(nBits);
308             else f.aMul = 256;
309         } else {
310             f.rMul = f.gMul = f.bMul = f.aMul = 256;
311         }
312         if( hasAdd ) {
313             f.rAdd = p.getSBits(nBits);
314             f.gAdd = p.getSBits(nBits);
315             f.bAdd = p.getSBits(nBits);
316             if( withAlpha ) f.aAdd = p.getSBits(nBits);
317             else f.aAdd = 0;
318         } else {
319             f.rAdd = f.gAdd = f.bAdd = f.aAdd = 0;
320         }
321         return f;
322     }
323
324     public void write( FlashOutput fob ) {
325         fob.initBits();
326         if( withAlpha ) writeWithAlpha( fob );
327         else writeNoAlpha( fob );
328         fob.flushBits();
329     }
330
331     protected final void writeWithAlpha( FlashOutput fob ) {
332         int nBits;
333         boolean hasAdd = hasAdd();
334         boolean hasMul = hasMul();
335         if( hasAdd && hasMul ) {
336             int max1 = Util.getMax(rAdd, gAdd, bAdd, aAdd);
337             int max2 = Util.getMax(rMul, gMul, bMul, aMul);
338             nBits = Util.getMinBitsS( Util.getMax(max1, max2) );
339             fob.writeBits(0x3, 2);
340         } else if( hasAdd ) {
341             nBits = Util.getMinBitsS( Util.getMax(rAdd, gAdd, bAdd, aAdd) );
342             fob.writeBits(0x2, 2);
343         } else if( hasMul ) {
344             nBits = Util.getMinBitsS( Util.getMax(rMul, gMul, bMul, aMul) );
345             fob.writeBits(0x1, 2);
346         } else {
347             nBits = 0;
348             fob.writeBits(0x0, 2);
349         }
350         fob.writeBits(nBits, 4);
351         if( hasMul ) {
352             fob.writeBits(rMul, nBits);
353             fob.writeBits(gMul, nBits);
354             fob.writeBits(bMul, nBits);
355             fob.writeBits(aMul, nBits);
356         }
357         if( hasAdd ) {
358             fob.writeBits(rAdd, nBits);
359             fob.writeBits(gAdd, nBits);
360             fob.writeBits(bAdd, nBits);
361             fob.writeBits(aAdd, nBits);
362         }
363     }
364
365     protected final void writeNoAlpha( FlashOutput fob ) {
366         int nBits;
367         boolean hasAdd = hasAdd();
368         boolean hasMul = hasMul();
369         if( hasAdd && hasMul ) {
370             int max1 = Util.getMax(rAdd, gAdd, bAdd);
371             int max2 = Util.getMax(rMul, gMul, bMul);
372             nBits = Util.getMinBitsS( Util.getMax(max1, max2) );
373             fob.writeBits(0x3, 2);
374         } else if( hasAdd ) {
375             nBits = Util.getMinBitsS( Util.getMax(rAdd, gAdd, bAdd) );
376             fob.writeBits(0x2, 2);
377         } else if( hasMul ) {
378             nBits = Util.getMinBitsS( Util.getMax(rMul, gMul, bMul) );
379             fob.writeBits(0x1, 2);
380         } else {
381             nBits = 0;
382             fob.writeBits(0x0, 2);
383         }
384         fob.writeBits(nBits, 4);
385         if( hasMul ) {
386             fob.writeBits(rMul, nBits);
387             fob.writeBits(gMul, nBits);
388             fob.writeBits(bMul, nBits);
389         }
390         if( hasAdd ) {
391             fob.writeBits(rAdd, nBits);
392             fob.writeBits(gAdd, nBits);
393             fob.writeBits(bAdd, nBits);
394         }
395     }
396
397     public void printContent( PrintStream out, String JavaDoc indent ) {
398         out.println( indent+"CXForm: withAlpha="+withAlpha );
399         out.println( indent+" Add: |0x"+Util.b2h(rAdd)+",0x"+Util.b2h(gAdd)+",0x"+Util.b2h(bAdd)+",0x"+Util.b2h(aAdd)+"|" );
400         out.println( indent+" Mul: |0x"+Util.w2h(rMul)+",0x"+Util.w2h(gMul)+",0x"+Util.w2h(bMul)+",0x"+Util.w2h(aMul)+"|" );
401     }
402
403     protected FlashItem copyInto( FlashItem item, ScriptCopier copier ) {
404         super.copyInto( item, copier );
405         ((CXForm)item).rAdd = rAdd;
406         ((CXForm)item).gAdd = gAdd;
407         ((CXForm)item).bAdd = bAdd;
408         ((CXForm)item).aAdd = aAdd;
409         ((CXForm)item).rMul = rMul;
410         ((CXForm)item).gMul = gMul;
411         ((CXForm)item).bMul = bMul;
412         ((CXForm)item).aMul = aMul;
413         ((CXForm)item).withAlpha = withAlpha;
414         return item;
415     }
416
417     public FlashItem getCopy( ScriptCopier copier ) {
418         return copyInto( new CXForm(), copier );
419     }
420 }
421
422
Popular Tags