Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / bodychunk.c
blob338cdf2832b6882056411d1598143a9394bc215f
1 /*
2 Copyright © 2002-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <graphics/gfx.h>
7 #include <graphics/view.h>
8 #include <clib/alib_protos.h>
9 #include <proto/exec.h>
10 #include <proto/graphics.h>
11 #include <proto/utility.h>
12 #include <proto/intuition.h>
13 #include <proto/muimaster.h>
15 #include "mui.h"
16 #include "muimaster_intern.h"
17 #include "support.h"
19 extern struct Library *MUIMasterBase;
21 struct MUI_BodychunkData
23 struct BitMap *bm;
24 UBYTE *body;
25 LONG width, height, depth;
26 UBYTE compression;
27 UBYTE masking;
30 static void planar2chunky(UBYTE *src, UBYTE *dest, WORD width, WORD depth,
31 LONG bpr)
33 UBYTE *s, *d, byte;
34 UBYTE pmask, dmask = 1, notdmask = ~1;
35 WORD x, pl;
37 for (pl = 0; pl < depth; pl++)
39 pmask = 0x80;
40 s = src;
41 d = dest;
43 byte = *s++;
45 for (x = 0; x < width; x++)
47 if (byte & pmask)
49 *d++ |= dmask;
51 else
53 *d++ &= notdmask;
56 if (pmask == 0x1)
58 pmask = 0x80;
59 byte = *s++;
61 else
63 pmask >>= 1;
67 dmask <<= 1;
68 notdmask = ~dmask;
70 src += bpr;
74 static UBYTE *unpack_byterun1(UBYTE *src, UBYTE *dest, LONG unpackedsize)
76 UBYTE r;
77 BYTE c;
79 for (;;)
81 c = (BYTE) (*src++);
82 if (c >= 0)
84 while (c-- >= 0)
86 *dest++ = *src++;
87 if (--unpackedsize <= 0)
88 return src;
91 else if (c != -128)
93 c = -c;
94 r = *src++;
96 while (c-- >= 0)
98 *dest++ = r;
99 if (--unpackedsize <= 0)
100 return src;
107 static BOOL make_bitmap(struct IClass *cl, Object *obj)
109 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
110 struct RastPort bmrp, temprp;
111 UBYTE *chunkyline;
112 UBYTE *bodyptr, *unpackptr;
113 LONG w16, bpr, bpl;
114 WORD x, y, totdepth;
116 if (!data->body ||
117 (data->width < 1) ||
118 (data->height < 1) ||
119 (data->depth < 1) || (data->depth > 8) || (data->compression > 1))
121 return FALSE;
124 chunkyline = AllocVec(2 * (data->width + 16), MEMF_PUBLIC | MEMF_CLEAR);
125 if (!chunkyline)
126 return FALSE;
128 unpackptr = chunkyline + data->width + 16;
130 data->bm =
131 AllocBitMap(data->width, data->height, data->depth, BMF_CLEAR,
132 NULL);
133 if (!data->bm)
135 FreeVec(chunkyline);
136 return FALSE;
139 InitRastPort(&temprp);
140 temprp.BitMap = AllocBitMap(data->width, 1, 1, 0, NULL);
142 InitRastPort(&bmrp);
143 bmrp.BitMap = data->bm;
145 bodyptr = data->body;
146 w16 = (data->width + 15) & ~15;
147 bpr = w16 / 8;
149 totdepth = data->depth + ((data->masking == 1) ? 1 : 0);
150 bpl = bpr * totdepth;
152 for (y = 0; y < data->height; y++)
154 if (data->compression)
156 bodyptr = unpack_byterun1(bodyptr, unpackptr, bpl);
157 planar2chunky(unpackptr, chunkyline, data->width, data->depth,
158 bpr);
160 else
162 planar2chunky(bodyptr, chunkyline, data->width, data->depth,
163 bpr);
164 bodyptr += bpl;
167 if (temprp.BitMap)
169 WritePixelLine8(&bmrp, 0, y, data->width, chunkyline, &temprp);
171 else
173 for (x = 0; x < data->width; x++)
175 SetAPen(&bmrp, chunkyline[x]);
176 WritePixel(&bmrp, x, y);
181 if (temprp.BitMap)
183 WaitBlit();
184 FreeBitMap(temprp.BitMap);
187 FreeVec(chunkyline);
189 return TRUE;
192 /**************************************************************************
193 OM_NEW
194 **************************************************************************/
195 IPTR Bodychunk__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
197 struct MUI_BodychunkData *data;
198 struct TagItem *tag, *tags;
200 obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg);
201 if (!obj)
202 return FALSE;
204 data = INST_DATA(cl, obj);
206 /* parse initial taglist */
208 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
210 switch (tag->ti_Tag)
212 case MUIA_Bodychunk_Body:
213 data->body = (UBYTE *) tag->ti_Data;
214 break;
216 case MUIA_Bodychunk_Compression:
217 data->compression = (UBYTE) tag->ti_Data;
218 break;
220 case MUIA_Bodychunk_Depth:
221 data->depth = (LONG) tag->ti_Data;
222 break;
224 case MUIA_Bodychunk_Masking:
225 data->masking = (UBYTE) tag->ti_Data;
226 break;
228 case MUIA_Bitmap_Width:
229 data->width = (LONG) tag->ti_Data;
230 break;
232 case MUIA_Bitmap_Height:
233 data->height = (LONG) tag->ti_Data;
234 break;
239 return (IPTR) obj;
242 /**************************************************************************
243 OM_DISPOSE
244 **************************************************************************/
245 IPTR Bodychunk__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
247 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
249 if (data->bm)
251 WaitBlit();
252 FreeBitMap(data->bm);
255 return DoSuperMethodA(cl, obj, msg);
258 /**************************************************************************
259 OM_SET
260 **************************************************************************/
261 IPTR Bodychunk__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
263 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
264 struct TagItem *tags = msg->ops_AttrList;
265 struct TagItem *tag;
267 while ((tag = NextTagItem(&tags)) != NULL)
269 switch (tag->ti_Tag)
271 case MUIA_Bodychunk_Body:
272 data->body = (UBYTE *) tag->ti_Data;
273 break;
275 case MUIA_Bodychunk_Compression:
276 data->compression = (UBYTE) tag->ti_Data;
277 break;
279 case MUIA_Bodychunk_Depth:
280 data->depth = (LONG) tag->ti_Data;
281 break;
283 case MUIA_Bodychunk_Masking:
284 data->masking = (UBYTE) tag->ti_Data;
285 break;
287 case MUIA_Bitmap_Width:
288 data->width = (LONG) tag->ti_Data;
289 break;
291 case MUIA_Bitmap_Height:
292 data->height = (LONG) tag->ti_Data;
293 break;
298 return DoSuperMethodA(cl, obj, (Msg) msg);
301 /**************************************************************************
302 OM_GET
303 **************************************************************************/
304 IPTR Bodychunk__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
306 #define STORE *(msg->opg_Storage)
308 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
310 switch (msg->opg_AttrID)
312 case MUIA_Bodychunk_Body:
313 STORE = (IPTR) data->body;
314 return TRUE;
316 case MUIA_Bodychunk_Compression:
317 STORE = (IPTR) data->compression;
318 return TRUE;
320 case MUIA_Bodychunk_Depth:
321 STORE = (IPTR) data->depth;
322 return TRUE;
324 case MUIA_Bodychunk_Masking:
325 STORE = (IPTR) data->masking;
326 return TRUE;
330 return DoSuperMethodA(cl, obj, (Msg) msg);
331 #undef STORE
334 /**************************************************************************
335 MUIM_Setup
336 **************************************************************************/
337 IPTR Bodychunk__MUIM_Setup(struct IClass *cl, Object *obj,
338 struct MUIP_Setup *msg)
340 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
342 if (!make_bitmap(cl, obj))
343 return FALSE;
345 set(obj, MUIA_Bitmap_Bitmap, (IPTR) data->bm);
347 if (!DoSuperMethodA(cl, obj, (Msg) msg))
349 set(obj, MUIA_Bitmap_Bitmap, NULL);
350 WaitBlit();
351 FreeBitMap(data->bm);
352 data->bm = NULL;
354 return FALSE;
357 return TRUE;
360 /**************************************************************************
361 MUIM_Cleanup
362 **************************************************************************/
363 IPTR Bodychunk__MUIM_Cleanup(struct IClass *cl, Object *obj,
364 struct MUIP_Cleanup *msg)
366 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
367 IPTR retval;
369 retval = DoSuperMethodA(cl, obj, (Msg) msg);
370 if (data->bm)
372 set(obj, MUIA_Bitmap_Bitmap, NULL);
374 WaitBlit();
376 FreeBitMap(data->bm);
377 data->bm = NULL;
380 return retval;
384 BOOPSI_DISPATCHER(IPTR, Bodychunk_Dispatcher, cl, obj, msg)
386 switch (msg->MethodID)
388 case OM_NEW:
389 return Bodychunk__OM_NEW(cl, obj, (struct opSet *)msg);
390 case OM_DISPOSE:
391 return Bodychunk__OM_DISPOSE(cl, obj, msg);
392 case OM_SET:
393 return Bodychunk__OM_SET(cl, obj, (struct opSet *)msg);
394 case OM_GET:
395 return Bodychunk__OM_GET(cl, obj, (struct opGet *)msg);
396 case MUIM_Setup:
397 return Bodychunk__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
398 case MUIM_Cleanup:
399 return Bodychunk__MUIM_Cleanup(cl, obj, (struct MUIP_Cleanup *)msg);
402 return DoSuperMethodA(cl, obj, msg);
405 BOOPSI_DISPATCHER_END
407 * Class descriptor.
409 const struct __MUIBuiltinClass _MUI_Bodychunk_desc =
411 MUIC_Bodychunk,
412 MUIC_Bitmap,
413 sizeof(struct MUI_BodychunkData),
414 (void *) Bodychunk_Dispatcher