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 <math.h>
23 #include <stdlib.h>
24 
25 #include "block.h"
26 #include "method.h"
27 #include "libming.h"
28 
29 
30 void
SWFBlock_setDefined(SWFBlock block)31 SWFBlock_setDefined(SWFBlock block)
32 {
33 	block->isDefined = TRUE;
34 }
35 
36 
37 byte
SWFBlock_isDefined(SWFBlock block)38 SWFBlock_isDefined(SWFBlock block)
39 {
40 	return block->isDefined;
41 }
42 
43 
44 int
SWFBlock_getLength(SWFBlock block)45 SWFBlock_getLength(SWFBlock block)
46 {
47 	return block->length;
48 }
49 
50 
51 void
destroySWFBlock(SWFBlock block)52 destroySWFBlock(SWFBlock block)
53 {
54 	if ( block->dtor )
55 		block->dtor(block);
56 	else
57 		free(block);
58 }
59 
60 
61 int
completeSWFBlock(SWFBlock block)62 completeSWFBlock(SWFBlock block)
63 {
64 	switch(block->type)
65 	{
66 	case SWF_UNUSEDBLOCK:
67 	case SWF_MINGFONT:
68 		return 0;
69 	default:
70 		break;
71 	}
72 
73 	if ( !block->completed )
74 	{
75 		if ( block->complete )
76 			block->length = block->complete(block);
77 
78 		block->completed = TRUE;
79 	}
80 
81 	if (block->type == SWF_PREBUILT)
82 		return block->length;
83 	if ( block->length > 62 ||
84 			 block->type == SWF_DEFINELOSSLESS ||
85 			 block->type == SWF_DEFINELOSSLESS2 )
86 	{
87 		return block->length + 6;
88 	}
89 	else
90 		return block->length + 2;
91 }
92 
93 
94 int
writeSWFBlockToMethod(SWFBlock block,SWFByteOutputMethod method,void * data)95 writeSWFBlockToMethod(SWFBlock block, SWFByteOutputMethod method, void *data)
96 {
97 	SWFBlocktype type = block->type;
98 	unsigned int length;
99 
100 	switch(block->type)
101 	{
102 	case SWF_UNUSEDBLOCK:
103 	case SWF_MINGFONT:
104 		return 0;
105 	default:
106 		break;
107 	}
108 
109 	if ( !block->completed )
110 		completeSWFBlock(block);
111 
112 	length = block->length;
113 
114 	/* write header */
115 
116 	if(type == SWF_PREBUILTCLIP)
117 		type = SWF_DEFINESPRITE;
118 	if ( type == SWF_PREBUILT )
119 		;
120 	else if ( length > 62 ||
121 			 type == SWF_DEFINELOSSLESS ||
122 			 type == SWF_DEFINELOSSLESS2 )
123 	{
124 		/* yep, a definebitslossless block has to be long form, even if it's
125 			 under 63 bytes.. */
126 		method((unsigned char)(((type&0x03)<<6) + 0x3f), data);
127 		method((unsigned char)((type>>2) & 0xff), data);
128 		methodWriteUInt32(length, method, data);
129 		length += 6;
130 	}
131 	else
132 	{	methodWriteUInt16(length + ((type)<<6), method, data);
133 		length += 2;
134 	}
135 
136 	if ( block->writeBlock )
137 		block->writeBlock(block, method, data);
138 
139 	return length;
140 }
141 
142 
143 void
SWFBlockInit(SWFBlock block)144 SWFBlockInit(SWFBlock block)
145 {
146 	block->type = SWF_END; // XXX - ???
147 	block->writeBlock = NULL;
148 	block->complete = NULL;
149 	block->dtor = NULL;
150 
151 	block->length = 0;
152 	block->isDefined = FALSE;
153 	block->completed = FALSE;
154 
155 	block->swfVersion = 0;
156 }
157 
158 
159 SWFBlock
newEmptySWFBlock(SWFBlocktype type)160 newEmptySWFBlock(SWFBlocktype type)
161 {
162 	SWFBlock block = (SWFBlock) malloc(sizeof(struct SWFBlock_s));
163 	SWFBlockInit(block);
164 	block->type = type;
165 
166 	return block;
167 }
168 
169 
170 SWFBlock
newSWFShowFrameBlock()171 newSWFShowFrameBlock()
172 {
173 	return newEmptySWFBlock(SWF_SHOWFRAME);
174 }
175 
176 
177 SWFBlock
newSWFEndBlock()178 newSWFEndBlock()
179 {
180 	return newEmptySWFBlock(SWF_END);
181 }
182 
183 
184 SWFBlocktype
SWFBlock_getType(SWFBlock block)185 SWFBlock_getType(SWFBlock block)
186 {
187 	return block->type;
188 }
189 
190 
191 /*
192  * Local variables:
193  * tab-width: 2
194  * c-basic-offset: 2
195  * End:
196  */
197