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