1 /*
2     Ming, an SWF output library
3     Copyright (C) 2002  Opaque Industries - http://www.opaque.net/
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 /* $Id$ */
21 
22 #include <stdlib.h>
23 #include <math.h>
24 
25 #include "libming.h"
26 #include "cxform.h"
27 #include "error.h"
28 
29 
30 struct SWFCXform_s
31 {
32 	int rMult;
33 	int gMult;
34 	int bMult;
35 	int aMult;
36 	int rAdd;
37 	int gAdd;
38 	int bAdd;
39 	int aAdd;
40 };
41 
42 /*
43  * creates a new color transform with the given parameters
44  */
45 SWFCXform
newSWFCXform(int rAdd,int gAdd,int bAdd,int aAdd,float rMult,float gMult,float bMult,float aMult)46 newSWFCXform(int rAdd, int gAdd, int bAdd, int aAdd,
47 						 float rMult, float gMult, float bMult, float aMult)
48 {
49 	SWFCXform cXform = (SWFCXform) malloc(sizeof(struct SWFCXform_s));
50 
51 	cXform->rMult = (int)floor(256*rMult);
52 	cXform->gMult = (int)floor(256*gMult);
53 	cXform->bMult = (int)floor(256*bMult);
54 	cXform->aMult = (int)floor(256*aMult);
55 
56 	cXform->rAdd = rAdd;
57 	cXform->gAdd = gAdd;
58 	cXform->bAdd = bAdd;
59 	cXform->aAdd = aAdd;
60 
61 	return cXform;
62 }
63 
64 /*
65  * creates a new color transform with the given additive parameters and
66    default multiplicative
67  */
68 SWFCXform
newSWFAddCXform(int rAdd,int gAdd,int bAdd,int aAdd)69 newSWFAddCXform(int rAdd, int gAdd, int bAdd, int aAdd)
70 {
71 	return newSWFCXform(rAdd, gAdd, bAdd, aAdd, 1.0, 1.0, 1.0, 1.0);
72 }
73 
74 /*
75  * creates a new color transform with the given multiplicative parameters
76    and default additive
77  */
78 SWFCXform
newSWFMultCXform(float rMult,float gMult,float bMult,float aMult)79 newSWFMultCXform(float rMult, float gMult, float bMult, float aMult)
80 {
81 	return newSWFCXform(0, 0, 0, 0, rMult, gMult, bMult, aMult);
82 }
83 
84 /*
85  * set the additive part of the color transform to the given parameters
86  */
87 void
SWFCXform_setColorAdd(SWFCXform cXform,int rAdd,int gAdd,int bAdd,int aAdd)88 SWFCXform_setColorAdd(SWFCXform cXform, int rAdd, int gAdd, int bAdd, int aAdd)
89 {
90 	cXform->rAdd = rAdd;
91 	cXform->gAdd = gAdd;
92 	cXform->bAdd = bAdd;
93 	cXform->aAdd = aAdd;
94 }
95 
96 /*
97  * set the multiplicative part of the color transform to the given
98    parameters
99  */
100 void
SWFCXform_setColorMult(SWFCXform cXform,float rMult,float gMult,float bMult,float aMult)101 SWFCXform_setColorMult(SWFCXform cXform,
102 											 float rMult, float gMult, float bMult, float aMult)
103 {
104 	cXform->rMult = (int)floor(256*rMult);
105 	cXform->gMult = (int)floor(256*gMult);
106 	cXform->bMult = (int)floor(256*bMult);
107 	cXform->aMult = (int)floor(256*aMult);
108 }
109 
110 /*
111  * destroys a SWFCXform instance
112  */
113 void
destroySWFCXform(SWFCXform cXform)114 destroySWFCXform(SWFCXform cXform)
115 {
116 	free(cXform);
117 }
118 
119 
120 void
SWFOutput_writeCXform(SWFOutput out,SWFCXform cXform,SWFBlocktype type)121 SWFOutput_writeCXform(SWFOutput out, SWFCXform cXform, SWFBlocktype type)
122 {
123 	int nBits = 0;
124 	int hasAdd, hasMult;
125 
126 	SWFOutput_byteAlign(out);
127 
128 	hasAdd = ( cXform->rAdd != 0 || cXform->gAdd != 0 ||
129 						 cXform->bAdd != 0 || cXform->aAdd != 0 );
130 
131 	hasMult = ( cXform->rMult != 256 || cXform->gMult != 256 ||
132 							cXform->bMult != 256 || cXform->aMult != 256 );
133 
134 	SWFOutput_writeBits(out, hasAdd ? 1 : 0, 1);
135 	SWFOutput_writeBits(out, hasMult ? 1 : 0, 1);
136 
137 	if ( hasAdd )
138 	{
139 		nBits = max(nBits, SWFOutput_numSBits(cXform->rAdd));
140 		nBits = max(nBits, SWFOutput_numSBits(cXform->gAdd));
141 		nBits = max(nBits, SWFOutput_numSBits(cXform->bAdd));
142 
143 		if ( type == SWF_PLACEOBJECT2 )
144 			nBits = max(nBits, SWFOutput_numSBits(cXform->aAdd));
145 	}
146 
147 	if ( hasMult )
148 	{
149 		nBits = max(nBits, SWFOutput_numSBits(cXform->rMult));
150 		nBits = max(nBits, SWFOutput_numSBits(cXform->gMult));
151 		nBits = max(nBits, SWFOutput_numSBits(cXform->bMult));
152 
153 		if ( type == SWF_PLACEOBJECT2 )
154 			nBits = max(nBits, SWFOutput_numSBits(cXform->aMult));
155 	}
156 
157 	if ( nBits>=16 )
158 		SWF_error("color transform data out of scale");
159 
160 	SWFOutput_writeBits(out, nBits, 4);
161 
162 	if ( hasMult )
163 	{
164 		SWFOutput_writeSBits(out, cXform->rMult, nBits);
165 		SWFOutput_writeSBits(out, cXform->gMult, nBits);
166 		SWFOutput_writeSBits(out, cXform->bMult, nBits);
167 
168 		if ( type == SWF_PLACEOBJECT2 )
169 			SWFOutput_writeSBits(out, cXform->aMult, nBits);
170 	}
171 
172 	if ( hasAdd )
173 	{
174 		SWFOutput_writeSBits(out, cXform->rAdd, nBits);
175 		SWFOutput_writeSBits(out, cXform->gAdd, nBits);
176 		SWFOutput_writeSBits(out, cXform->bAdd, nBits);
177 
178 		if ( type == SWF_PLACEOBJECT2 )
179 			SWFOutput_writeSBits(out, cXform->aAdd, nBits);
180 	}
181 }
182 
183 
184 /*
185  * Local variables:
186  * tab-width: 2
187  * c-basic-offset: 2
188  * End:
189  */
190