1 /*
2 * The 3D Studio File Format Library
3 * Copyright (C) 1996-2007 by Jan Eric Kyprianidis <www.kyprianidis.com>
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: background.c,v 1.12 2007/06/20 17:04:08 jeh Exp $
21 */
22 #include <lib3ds/background.h>
23 #include <lib3ds/chunk.h>
24 #include <lib3ds/io.h>
25 #include <string.h>
26 #include <math.h>
27
28
29 /*!
30 * \defgroup background Background Settings
31 */
32
33
34 static Lib3dsBool
solid_bgnd_read(Lib3dsBackground * background,Lib3dsIo * io)35 solid_bgnd_read(Lib3dsBackground *background, Lib3dsIo *io)
36 {
37 Lib3dsChunk c;
38 Lib3dsWord chunk;
39 Lib3dsBool have_lin=LIB3DS_FALSE;
40
41 if (!lib3ds_chunk_read_start(&c, LIB3DS_SOLID_BGND, io)) {
42 return(LIB3DS_FALSE);
43 }
44
45 while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
46 switch (chunk) {
47 case LIB3DS_LIN_COLOR_F:
48 lib3ds_io_read_rgb(io, background->solid.col);
49 have_lin=LIB3DS_TRUE;
50 break;
51 case LIB3DS_COLOR_F:
52 lib3ds_io_read_rgb(io, background->solid.col);
53 break;
54 default:
55 lib3ds_chunk_unknown(chunk);
56 }
57 }
58
59 lib3ds_chunk_read_end(&c, io);
60 return(LIB3DS_TRUE);
61 }
62
63
64 static Lib3dsBool
v_gradient_read(Lib3dsBackground * background,Lib3dsIo * io)65 v_gradient_read(Lib3dsBackground *background, Lib3dsIo *io)
66 {
67 Lib3dsChunk c;
68 Lib3dsWord chunk;
69 int index[2];
70 Lib3dsRgb col[2][3];
71 int have_lin=0;
72
73
74 if (!lib3ds_chunk_read_start(&c, LIB3DS_V_GRADIENT, io)) {
75 return(LIB3DS_FALSE);
76 }
77 background->gradient.percent=lib3ds_io_read_float(io);
78 lib3ds_chunk_read_tell(&c, io);
79
80 index[0]=index[1]=0;
81 while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
82 switch (chunk) {
83 case LIB3DS_COLOR_F:
84 lib3ds_io_read_rgb(io, col[0][index[0]]);
85 index[0]++;
86 break;
87 case LIB3DS_LIN_COLOR_F:
88 lib3ds_io_read_rgb(io, col[1][index[1]]);
89 index[1]++;
90 have_lin=1;
91 break;
92 default:
93 lib3ds_chunk_unknown(chunk);
94 }
95 }
96 {
97 int i;
98 for (i=0; i<3; ++i) {
99 background->gradient.top[i]=col[have_lin][0][i];
100 background->gradient.middle[i]=col[have_lin][1][i];
101 background->gradient.bottom[i]=col[have_lin][2][i];
102 }
103 }
104 lib3ds_chunk_read_end(&c, io);
105 return(LIB3DS_TRUE);
106 }
107
108
109 /*!
110 * \ingroup background
111 */
112 Lib3dsBool
lib3ds_background_read(Lib3dsBackground * background,Lib3dsIo * io)113 lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io)
114 {
115 Lib3dsChunk c;
116
117 if (!lib3ds_chunk_read(&c, io)) {
118 return(LIB3DS_FALSE);
119 }
120
121 switch (c.chunk) {
122 case LIB3DS_BIT_MAP:
123 {
124 if (!lib3ds_io_read_string(io, background->bitmap.name, 64)) {
125 return(LIB3DS_FALSE);
126 }
127 }
128 break;
129 case LIB3DS_SOLID_BGND:
130 {
131 lib3ds_chunk_read_reset(&c, io);
132 if (!solid_bgnd_read(background, io)) {
133 return(LIB3DS_FALSE);
134 }
135 }
136 break;
137 case LIB3DS_V_GRADIENT:
138 {
139 lib3ds_chunk_read_reset(&c, io);
140 if (!v_gradient_read(background, io)) {
141 return(LIB3DS_FALSE);
142 }
143 }
144 break;
145 case LIB3DS_USE_BIT_MAP:
146 {
147 background->bitmap.use=LIB3DS_TRUE;
148 }
149 break;
150 case LIB3DS_USE_SOLID_BGND:
151 {
152 background->solid.use=LIB3DS_TRUE;
153 }
154 break;
155 case LIB3DS_USE_V_GRADIENT:
156 {
157 background->gradient.use=LIB3DS_TRUE;
158 }
159 break;
160 }
161
162 return(LIB3DS_TRUE);
163 }
164
165
166 static Lib3dsBool
colorf_write(Lib3dsRgba rgb,Lib3dsIo * io)167 colorf_write(Lib3dsRgba rgb, Lib3dsIo *io)
168 {
169 Lib3dsChunk c;
170
171 c.chunk=LIB3DS_COLOR_F;
172 c.size=18;
173 lib3ds_chunk_write(&c,io);
174 lib3ds_io_write_rgb(io, rgb);
175
176 c.chunk=LIB3DS_LIN_COLOR_F;
177 c.size=18;
178 lib3ds_chunk_write(&c,io);
179 lib3ds_io_write_rgb(io, rgb);
180 return(LIB3DS_TRUE);
181 }
182
183
184 static Lib3dsBool
colorf_defined(Lib3dsRgba rgb)185 colorf_defined(Lib3dsRgba rgb)
186 {
187 int i;
188 for (i=0; i<3; ++i) {
189 if (fabs(rgb[i])>LIB3DS_EPSILON) {
190 break;
191 }
192 }
193 return(i<3);
194 }
195
196
197 /*!
198 * \ingroup background
199 */
200 Lib3dsBool
lib3ds_background_write(Lib3dsBackground * background,Lib3dsIo * io)201 lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io)
202 {
203 if (strlen(background->bitmap.name)) { /*---- LIB3DS_BIT_MAP ----*/
204 Lib3dsChunk c;
205 c.chunk=LIB3DS_BIT_MAP;
206 c.size=6+1+(Lib3dsDword)strlen(background->bitmap.name);
207 lib3ds_chunk_write(&c,io);
208 lib3ds_io_write_string(io, background->bitmap.name);
209 }
210
211 if (colorf_defined(background->solid.col)) { /*---- LIB3DS_SOLID_BGND ----*/
212 Lib3dsChunk c;
213 c.chunk=LIB3DS_SOLID_BGND;
214 c.size=42;
215 lib3ds_chunk_write(&c,io);
216 colorf_write(background->solid.col, io);
217 }
218
219 if (colorf_defined(background->gradient.top) ||
220 colorf_defined(background->gradient.middle) ||
221 colorf_defined(background->gradient.bottom)) { /*---- LIB3DS_V_GRADIENT ----*/
222 Lib3dsChunk c;
223 c.chunk=LIB3DS_V_GRADIENT;
224 c.size=118;
225 lib3ds_chunk_write(&c,io);
226 lib3ds_io_write_float(io, background->gradient.percent);
227 colorf_write(background->gradient.top,io);
228 colorf_write(background->gradient.middle,io);
229 colorf_write(background->gradient.bottom,io);
230 }
231
232 if (background->bitmap.use) { /*---- LIB3DS_USE_BIT_MAP ----*/
233 Lib3dsChunk c;
234 c.chunk=LIB3DS_USE_BIT_MAP;
235 c.size=6;
236 lib3ds_chunk_write(&c,io);
237 }
238
239 if (background->solid.use) { /*---- LIB3DS_USE_SOLID_BGND ----*/
240 Lib3dsChunk c;
241 c.chunk=LIB3DS_USE_SOLID_BGND;
242 c.size=6;
243 lib3ds_chunk_write(&c,io);
244 }
245
246 if (background->gradient.use) { /*---- LIB3DS_USE_V_GRADIENT ----*/
247 Lib3dsChunk c;
248 c.chunk=LIB3DS_USE_V_GRADIENT;
249 c.size=6;
250 lib3ds_chunk_write(&c,io);
251 }
252
253 return(LIB3DS_TRUE);
254 }
255
256