1 /* wvWare
2  * Copyright (C) Caolan McNamara, Dom Lachowicz, and others
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "wv.h"
28 #include "wvinternal.h"
29 
30 void
wvCopyBlip(Blip * dest,Blip * src)31 wvCopyBlip (Blip * dest, Blip * src)
32 {
33     int i;
34     wvCopyFBSE (&dest->fbse, &src->fbse);
35     dest->type = src->type;
36 
37     if (src->name)
38       {
39 	  dest->name = (U16 *) wvMalloc (src->fbse.cbName * sizeof (U16));
40 	  for (i = 0; i < src->fbse.cbName; i++)
41 	      dest->name[i] = src->name[i];
42       }
43     else
44 	dest->name = NULL;
45     switch (dest->type)
46       {
47       case msoblipWMF:
48       case msoblipEMF:
49       case msoblipPICT:
50 	  wvCopyMetafile (&dest->blip.metafile, &(src->blip.metafile));
51 	  break;
52       case msoblipJPEG:
53       case msoblipPNG:
54       case msoblipDIB:
55 	  wvCopyBitmap (&dest->blip.bitmap, &(src->blip.bitmap));
56 	  break;
57       }
58 }
59 
60 void
wvReleaseBlip(Blip * blip)61 wvReleaseBlip (Blip * blip)
62 {
63     wvFree (blip->name);
64 }
65 
66 U32
wvGetBlip(Blip * blip,wvStream * fd,wvStream * delay)67 wvGetBlip (Blip * blip, wvStream * fd, wvStream * delay)
68 {
69     U32 i, count, count2;
70     MSOFBH amsofbh;
71     long pos = 0;
72     count = wvGetFBSE (&blip->fbse, fd);
73     wvTrace (("count is %d\n", count));
74     if (blip->fbse.cbName == 0)
75 	blip->name = NULL;
76     else
77 	blip->name = (U16 *) wvMalloc (sizeof (U16) * blip->fbse.cbName);
78     for (i = 0; i < blip->fbse.cbName; i++)
79 	blip->name[i] = read_16ubit (fd);
80     count += blip->fbse.cbName * 2;
81     wvTrace (("count is %d\n", count));
82     wvTrace (("offset %x\n", blip->fbse.foDelay));
83 
84     if (delay)
85       {
86 	  pos = wvStream_tell (delay);
87 	  if(blip->fbse.foDelay!=-1)
88 		wvStream_goto (delay, blip->fbse.foDelay);
89 	  wvTrace (("offset %x\n", blip->fbse.foDelay));
90 	  fd = delay;
91       }
92 
93     count2 = wvGetMSOFBH (&amsofbh, fd);
94     wvTrace (("count is %d\n", count2));
95     wvTrace (
96 	     ("HERE is %x %x (%d)\n", wvStream_tell (fd), amsofbh.fbt,
97 	      amsofbh.fbt - msofbtBlipFirst));
98     wvTrace (("type is %x\n", amsofbh.fbt));
99     switch (amsofbh.fbt - msofbtBlipFirst)
100       {
101       case msoblipWMF:
102       case msoblipEMF:
103       case msoblipPICT:
104 	  count2 += wvGetMetafile (&blip->blip.metafile, &amsofbh, fd);
105 	  break;
106       case msoblipJPEG:
107       case msoblipPNG:
108       case msoblipDIB:
109 	  count2 += wvGetBitmap (&blip->blip.bitmap, &amsofbh, fd);
110 	  break;
111       }
112     wvTrace (("count is %d\n", count2));
113     blip->type = amsofbh.fbt - msofbtBlipFirst;
114 
115     if (delay)
116       {
117 	  wvStream_goto (delay, pos);
118 	  return (count);
119       }
120 
121     return (count + count2);
122 }
123 
124 U32
wvGetFBSE(FBSE * afbse,wvStream * fd)125 wvGetFBSE (FBSE * afbse, wvStream * fd)
126 {
127     int i;
128     afbse->btWin32 = read_8ubit (fd);
129     afbse->btMacOS = read_8ubit (fd);
130     for (i = 0; i < 16; i++)
131 	afbse->rgbUid[i] = read_8ubit (fd);
132     afbse->tag = read_16ubit (fd);
133     afbse->size = read_32ubit (fd);
134     afbse->cRef = read_32ubit (fd);
135     afbse->foDelay = read_32ubit (fd);
136     wvTrace (("location is %x, size is %d\n", afbse->foDelay, afbse->size));
137     afbse->usage = read_8ubit (fd);
138     afbse->cbName = read_8ubit (fd);
139     wvTrace (("name len is %d\n", afbse->cbName));
140     afbse->unused2 = read_8ubit (fd);
141     afbse->unused3 = read_8ubit (fd);
142     return (36);
143 }
144 
145 void
wvCopyFBSE(FBSE * dest,FBSE * src)146 wvCopyFBSE (FBSE * dest, FBSE * src)
147 {
148     memcpy (dest, src, sizeof (FBSE));
149 }
150 
151 
152 U32
wvGetBitmap(BitmapBlip * abm,MSOFBH * amsofbh,wvStream * fd)153 wvGetBitmap (BitmapBlip * abm, MSOFBH * amsofbh, wvStream * fd)
154 {
155     U32 i, count;
156     char extra = 0;
157     wvStream * stm = NULL;
158     wvTrace (("starting bitmap at %x\n", wvStream_tell (fd)));
159     for (i = 0; i < 16; i++)
160 	abm->m_rgbUid[i] = read_8ubit (fd);
161     count = 16;
162 
163     abm->m_rgbUidPrimary[0] = 0;
164 
165     switch (amsofbh->fbt - msofbtBlipFirst)
166       {
167       case msoblipPNG:
168 	  wvTrace (("msoblipPNG\n"));
169 	  /*  sprintf(buffer,"%s-wv-%d.png",aimage,no++); */
170 	  if (amsofbh->inst ^ msobiPNG)
171 	      extra = 1;
172 	  break;
173       case msoblipJPEG:
174 	  wvTrace (("msoblipJPEG\n"));
175 	  /*  sprintf(buffer,"%s-wv-%d.jpg",aimage,no++); */
176 	  if (amsofbh->inst ^ msobiJFIF)
177 	      extra = 1;
178 	  break;
179       case msoblipDIB:
180 	  wvTrace (("msoblipDIB\n"));
181 	  /*  sprintf(buffer,"%s-wv-%d.dib",aimage,no++); */
182 	  if (amsofbh->inst ^ msobiDIB)
183 	      extra = 1;
184 	  break;
185       }
186 
187     if (extra)
188       {
189 	  for (i = 0; i < 16; i++)
190 	      abm->m_rgbUidPrimary[i] = read_8ubit (fd);
191 	  count += 16;
192       }
193 
194     abm->m_bTag = read_8ubit (fd);
195     abm->m_pvBits = NULL;
196 
197     count++;
198     stm = wvStream_TMP_create (amsofbh->cbLength);
199 
200     if (!stm) {
201       abm->m_pvBits = NULL;
202       return 0;
203     }
204 
205     char *tmp = wvMalloc( amsofbh->cbLength - count);
206     if (!tmp) {
207       abm->m_pvBits = NULL;
208       return 0;
209     }
210     wvStream_read(tmp,1,amsofbh->cbLength - count,fd);
211     wvStream_write(tmp,1,amsofbh->cbLength - count,stm);
212     wvFree(tmp);
213 
214     wvStream_rewind (stm);
215 
216     abm->m_pvBits = stm;
217 
218     count += i;
219     return count;
220 }
221 
222 void
wvCopyBitmap(BitmapBlip * dest,BitmapBlip * src)223 wvCopyBitmap (BitmapBlip * dest, BitmapBlip * src)
224 {
225     U8 i;
226     for (i = 0; i < 16; i++)
227       {
228 	  dest->m_rgbUid[i] = src->m_rgbUid[i];
229 	  dest->m_rgbUidPrimary[i] = src->m_rgbUidPrimary[i];
230       }
231 
232     dest->m_bTag = src->m_bTag;
233     dest->m_pvBits = src->m_pvBits;
234 }
235 
236 
237 U32
wvGetMetafile(MetaFileBlip * amf,MSOFBH * amsofbh,wvStream * fd)238 wvGetMetafile (MetaFileBlip * amf, MSOFBH * amsofbh, wvStream * fd)
239 {
240     char extra = 0;
241     U32 i, count;
242     wvStream * stm = 0;
243     char *buf, *p;
244 
245     for (i = 0; i < 16; i++)
246 	amf->m_rgbUid[i] = read_8ubit (fd);
247     count = 16;
248 
249     amf->m_rgbUidPrimary[0] = 0;
250 
251     switch (amsofbh->fbt - msofbtBlipFirst)
252       {
253       case msoblipEMF:
254 	  wvTrace (("msoblipEMF\n"));
255 	  /*
256 	     sprintf(buffer,"%s-wv-%d.emf",aimage,no++);
257 	   */
258 	  if (amsofbh->inst ^ msobiEMF)
259 	      extra = 1;
260 	  break;
261       case msoblipWMF:
262 	  wvTrace (("msoblipWMF\n"));
263 	  /*
264 	     sprintf(buffer,"%s-wv-%d.wmf",aimage,no++);
265 	   */
266 	  if (amsofbh->inst ^ msobiWMF)
267 	      extra = 1;
268 	  break;
269       case msoblipPICT:
270 	  wvTrace (("msoblipPICT\n"));
271 	  /*
272 	     sprintf(buffer,"%s-wv-%d.pict",aimage,no++);
273 	   */
274 	  if (amsofbh->inst ^ msobiPICT)
275 	      extra = 1;
276 	  break;
277       }
278 
279     if (extra)
280       {
281 	  for (i = 0; i < 16; i++)
282 	      amf->m_rgbUidPrimary[i] = read_8ubit (fd);
283 	  count += 16;
284       }
285 
286 
287     amf->m_cb = read_32ubit (fd);
288     amf->m_rcBounds.bottom = read_32ubit (fd);
289     amf->m_rcBounds.top = read_32ubit (fd);
290     amf->m_rcBounds.right = read_32ubit (fd);
291     amf->m_rcBounds.left = read_32ubit (fd);
292     amf->m_ptSize.y = read_32ubit (fd);
293     amf->m_ptSize.x = read_32ubit (fd);
294     amf->m_cbSave = read_32ubit (fd);
295     amf->m_fCompression = read_8ubit (fd);
296     amf->m_fFilter = read_8ubit (fd);
297     amf->m_pvBits = NULL;
298     count += 34;
299 
300     buf = wvMalloc(amsofbh->cbLength);
301     p = buf;
302 
303     for (i = count; i < amsofbh->cbLength; i++)
304 	*p++ = read_8ubit (fd);
305     count += i;
306 
307     wvStream_memory_create (&stm, buf, amsofbh->cbLength);
308 
309     amf->m_pvBits = stm;
310 
311     return (count);
312 }
313 
314 
wvCopyMetafile(MetaFileBlip * dest,MetaFileBlip * src)315 void wvCopyMetafile (MetaFileBlip * dest,
316 		     MetaFileBlip * src)
317 {
318   U8 i; for (i = 0; i < 16; i++)
319     {
320       dest->m_rgbUid[i] = src->m_rgbUid[i];
321       dest->m_rgbUidPrimary[i] = src->m_rgbUidPrimary[i];}
322   dest->m_cb = src->m_cb;
323   dest->m_rcBounds.bottom = src->m_rcBounds.bottom;
324   dest->m_rcBounds.top = src->m_rcBounds.top;
325   dest->m_rcBounds.right = src->m_rcBounds.right;
326   dest->m_rcBounds.left = src->m_rcBounds.left;
327   dest->m_ptSize.y = src->m_ptSize.y;
328   dest->m_ptSize.x = src->m_ptSize.x;
329   dest->m_cbSave = src->m_cbSave;
330   dest->m_fCompression = src->m_fCompression;
331   dest->m_fFilter = src->m_fFilter;
332   dest->m_pvBits = src->m_pvBits;
333 }
334 
335 /* TODO: code wvPutBlip(), wvPutMetafile() */
336 
337 void
wvPutFBSE(FBSE * item,wvStream * fd)338 wvPutFBSE (FBSE * item, wvStream * fd)
339 {
340     int i;
341 
342     write_8ubit (fd, item->btWin32);
343     write_8ubit (fd, item->btMacOS);
344 
345     for (i = 0; i < 16; i++)
346 	write_8ubit (fd, item->rgbUid[i]);
347 
348     write_16ubit (fd, item->tag);
349     write_32ubit (fd, item->size);
350     write_32ubit (fd, item->cRef);
351     write_32ubit (fd, item->foDelay);
352     write_8ubit (fd, item->usage);
353     write_8ubit (fd, item->cbName);
354     write_8ubit (fd, item->unused2);
355     write_8ubit (fd, item->unused3);
356 }
357