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 "dbl.h"
24 #include "block.h"
25 #include "method.h"
26 #include "error.h"
27 #include "input.h"
28 #include "libming.h"
29
30 #include "ming_config.h"
31
32 struct SWFDBLBitmap_s
33 {
34 struct SWFCharacter_s bitmap;
35
36 SWFInput input;
37 };
38
39
40 static int
completeSWFDBLBitmap(SWFBlock block)41 completeSWFDBLBitmap(SWFBlock block)
42 {
43 return SWFBlock_getLength(block);
44 }
45
46
47 static void
writeSWFDBLBitmapToMethod(SWFBlock block,SWFByteOutputMethod method,void * data)48 writeSWFDBLBitmapToMethod(SWFBlock block,
49 SWFByteOutputMethod method, void *data)
50 {
51 SWFDBLBitmap dbl = (SWFDBLBitmap)block;
52 int i;
53
54 methodWriteUInt16(CHARACTERID(dbl), method, data);
55
56 /* just dump the rest of the file */
57 for ( i=block->length-2; i>0; --i )
58 method((unsigned char)SWFInput_getChar(dbl->input), data);
59 }
60
61
62 SWFDBLBitmap
newSWFDBLBitmap_fromInput(SWFInput input)63 newSWFDBLBitmap_fromInput(SWFInput input)
64 {
65 SWFDBLBitmap dbl;
66 int version;
67 int width, height;
68
69 dbl = (SWFDBLBitmap)malloc(sizeof(struct SWFDBLBitmap_s));
70
71 /* If malloc failed, return NULL to signify this */
72 if (NULL == dbl)
73 return NULL;
74
75 SWFCharacterInit((SWFCharacter)dbl);
76
77 CHARACTERID(dbl) = ++SWF_gNumCharacters;
78
79 BLOCK(dbl)->writeBlock = writeSWFDBLBitmapToMethod;
80 BLOCK(dbl)->complete = completeSWFDBLBitmap;
81 BLOCK(dbl)->dtor = (destroySWFBlockMethod) destroySWFCharacter;
82
83 dbl->input = input;
84
85 if ( SWFInput_getChar(input) != 'D' ||
86 SWFInput_getChar(input) != 'B' )
87 {
88 SWF_error("File is not a DBL file!");
89 }
90
91 version = SWFInput_getChar(input);
92
93 if ( version != 'L' && version != 'l' )
94 SWF_error("File is not a DBL file!");
95
96 switch ( SWFInput_getChar(input) )
97 {
98 case 1:
99 BLOCK(dbl)->type = SWF_DEFINELOSSLESS;
100 break;
101 case 2:
102 BLOCK(dbl)->type = SWF_DEFINELOSSLESS2;
103 break;
104 default:
105 SWF_error("Unexpected DBL type byte!");
106 }
107
108 if ( version == 'l' )
109 {
110 BLOCK(dbl)->length = SWFInput_getUInt32_BE(input);
111 BLOCK(dbl)->length += 2; /* character id */
112 }
113 else
114 {
115 /* first version used a 2-byte file length.. brilliant, eh? */
116
117 BLOCK(dbl)->length = SWFInput_getUInt16_BE(input);
118 BLOCK(dbl)->length += 2; /* character id */
119 }
120
121 SWFInput_getChar(input); /* format */
122
123 width = SWFInput_getUInt16(input);
124 height = SWFInput_getUInt16(input);
125
126 /* roll back to beginning of dbl data */
127 SWFInput_seek(input, -5, SEEK_CUR);
128
129 CHARACTER(dbl)->bounds = newSWFRect(0, width, 0, height);
130
131 return dbl;
132 }
133
134 static void
writeSWFDBLBitmapDataToMethod(SWFBlock block,SWFByteOutputMethod method,void * data)135 writeSWFDBLBitmapDataToMethod(SWFBlock block, SWFByteOutputMethod method, void *data)
136 {
137 SWFDBLBitmapData dbl = (SWFDBLBitmapData)block;
138 int i;
139 unsigned char *ptr;
140
141 methodWriteUInt16(CHARACTERID(dbl), method, data);
142 method(dbl->format, data);
143 methodWriteUInt16(dbl->width, method, data);
144 methodWriteUInt16(dbl->height, method, data);
145 i=block->length-8;
146 if(dbl->format == 3) // palette image
147 method(dbl->format2, data);
148 else
149 i++;
150 /* just dump the rest of the file */
151 for (ptr = dbl->data; i>0; --i )
152 method(*ptr++, data);
153 }
154
155 static void
destroySWFDBLBitmapData(SWFDBLBitmapData bitmap)156 destroySWFDBLBitmapData(SWFDBLBitmapData bitmap)
157 {
158 if ( bitmap->data != NULL )
159 {
160 free(bitmap->data);
161 }
162
163 #if TRACK_ALLOCS
164 ming_gc_remove_node(bitmap->gcnode);
165 #endif
166
167 destroySWFCharacter((SWFCharacter) bitmap);
168 }
169
170 SWFDBLBitmapData
newSWFDBLBitmapData_fromData(dblData data)171 newSWFDBLBitmapData_fromData(dblData data)
172 {
173 SWFDBLBitmapData dbl;
174
175 dbl = (SWFDBLBitmapData)malloc(sizeof(struct SWFDBLBitmapData_s));
176
177 /* If malloc failed, return NULL to signify this */
178 if (NULL == dbl)
179 return NULL;
180
181 SWFCharacterInit((SWFCharacter)dbl);
182
183 CHARACTERID(dbl) = ++SWF_gNumCharacters;
184
185 BLOCK(dbl)->writeBlock = writeSWFDBLBitmapDataToMethod;
186 BLOCK(dbl)->complete = completeSWFDBLBitmap;
187 BLOCK(dbl)->dtor = (destroySWFBlockMethod) destroySWFDBLBitmapData;
188
189 dbl->width = data->width;
190 dbl->height = data->height;
191 dbl->format = data->format;
192 dbl->format2 = data->format2;
193 dbl->data = data->data;
194
195 if(data->hasalpha)
196 BLOCK(dbl)->type = SWF_DEFINELOSSLESS2;
197 else
198 BLOCK(dbl)->type = SWF_DEFINELOSSLESS;
199
200 BLOCK(dbl)->length = data->length;
201 BLOCK(dbl)->length += 7; /* character id, format, width, height */
202 if(dbl->format == 3)
203 BLOCK(dbl)->length++;
204
205 CHARACTER(dbl)->bounds = newSWFRect(0, dbl->width, 0, dbl->height);
206
207 #if TRACK_ALLOCS
208 dbl->gcnode = ming_gc_add_node(dbl, (dtorfunctype)destroySWFDBLBitmapData);
209 #endif
210
211 return dbl;
212 }
213
214 static void
destroySWFDBLBitmap_andInputs(SWFDBLBitmap bitmap)215 destroySWFDBLBitmap_andInputs(SWFDBLBitmap bitmap)
216 {
217 if ( bitmap->input != NULL )
218 destroySWFInput(bitmap->input);
219
220 // The bounds rectangle will be already freed in destroySWFCharacter
221 /*if ( CHARACTER(bitmap)->bounds != NULL )
222 destroySWFRect(CHARACTER(bitmap)->bounds);*/
223
224 destroySWFCharacter((SWFCharacter) bitmap);
225 }
226
227 SWFDBLBitmap
newSWFDBLBitmap(FILE * f)228 newSWFDBLBitmap(FILE* f)
229 {
230 SWFInput input = newSWFInput_file(f);
231 SWFDBLBitmap dbl = NULL;
232
233 /* If newSWFInput_file() failed, return NULL to signify this */
234 if (NULL == input)
235 return NULL;
236
237 dbl = newSWFDBLBitmap_fromInput(input);
238
239 /* If newSWFDBLBitmap_fromInput() failed, return NULL to signify this */
240 if (NULL == dbl)
241 return NULL;
242
243 BLOCK(dbl)->dtor = (destroySWFBlockMethod) destroySWFDBLBitmap_andInputs;
244 return dbl;
245 }
246
247 /*
248 * Local variables:
249 * tab-width: 2
250 * c-basic-offset: 2
251 * End:
252 */
253