Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / bodychunk.c
blob5e6b8734f4b89cf5ba71d37f4a08e90b07602c59
1 /*
2 Copyright © 2002-2006, 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, LONG bpr)
32 UBYTE *s, *d, byte;
33 UBYTE pmask, dmask = 1, notdmask = ~1;
34 WORD x, pl;
36 for(pl = 0; pl < depth; pl++)
38 pmask = 0x80;
39 s = src;
40 d = dest;
42 byte = *s++;
44 for(x = 0; x < width; x++)
46 if (byte & pmask)
48 *d++ |= dmask;
50 else
52 *d++ &= notdmask;
55 if (pmask == 0x1)
57 pmask = 0x80;
58 byte = *s++;
60 else
62 pmask >>= 1;
66 dmask <<= 1; notdmask = ~dmask;
68 src += bpr;
72 static UBYTE *unpack_byterun1(UBYTE *src, UBYTE *dest, LONG unpackedsize)
74 UBYTE r;
75 BYTE c;
77 for(;;)
79 c = (BYTE)(*src++);
80 if (c >= 0)
82 while(c-- >= 0)
84 *dest++ = *src++;
85 if (--unpackedsize <= 0) return src;
88 else if (c != -128)
90 c = -c;
91 r = *src++;
93 while(c-- >= 0)
95 *dest++ = r;
96 if (--unpackedsize <= 0) return src;
103 static BOOL make_bitmap(struct IClass *cl, Object *obj)
105 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
106 struct RastPort bmrp, temprp;
107 UBYTE *chunkyline;
108 UBYTE *bodyptr, *unpackptr;
109 LONG w16, bpr, bpl;
110 WORD x, y, totdepth;
112 if (!data->body ||
113 (data->width < 1) ||
114 (data->height < 1) ||
115 (data->depth < 1) ||
116 (data->depth > 8) ||
117 (data->compression > 1) )
119 return FALSE;
122 chunkyline = AllocVec(2 * (data->width + 16), MEMF_PUBLIC | MEMF_CLEAR);
123 if (!chunkyline) return FALSE;
125 unpackptr = chunkyline + data->width + 16;
127 data->bm = AllocBitMap(data->width, data->height, data->depth, BMF_CLEAR, NULL);
128 if (!data->bm)
130 FreeVec(chunkyline);
131 return FALSE;
134 InitRastPort(&temprp);
135 temprp.BitMap = AllocBitMap(data->width, 1, 1, 0, NULL);
137 InitRastPort(&bmrp);
138 bmrp.BitMap = data->bm;
140 bodyptr = data->body;
141 w16 = (data->width + 15) & ~15;
142 bpr = w16 / 8;
144 totdepth = data->depth + ((data->masking == 1) ? 1 : 0);
145 bpl = bpr * totdepth;
147 for(y = 0; y < data->height; y++)
149 if (data->compression)
151 bodyptr = unpack_byterun1(bodyptr, unpackptr, bpl);
152 planar2chunky(unpackptr, chunkyline, data->width, data->depth, bpr);
154 else
156 planar2chunky(bodyptr, chunkyline, data->width, data->depth, bpr);
157 bodyptr += bpl;
160 if (temprp.BitMap)
162 WritePixelLine8(&bmrp, 0, y, data->width, chunkyline, &temprp);
164 else
166 for(x = 0; x < data->width; x++)
168 SetAPen(&bmrp, chunkyline[x]);
169 WritePixel(&bmrp, x, y);
174 DeinitRastPort(&temprp);
175 DeinitRastPort(&bmrp);
177 if (temprp.BitMap)
179 WaitBlit();
180 FreeBitMap(temprp.BitMap);
183 FreeVec(chunkyline);
185 return TRUE;
188 /**************************************************************************
189 OM_NEW
190 **************************************************************************/
191 IPTR Bodychunk__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
193 struct MUI_BodychunkData *data;
194 struct TagItem *tag, *tags;
196 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
197 if (!obj) return FALSE;
199 data = INST_DATA(cl, obj);
201 /* parse initial taglist */
203 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem**)&tags)); )
205 switch (tag->ti_Tag)
207 case MUIA_Bodychunk_Body:
208 data->body = (UBYTE *)tag->ti_Data;
209 break;
211 case MUIA_Bodychunk_Compression:
212 data->compression = (UBYTE)tag->ti_Data;
213 break;
215 case MUIA_Bodychunk_Depth:
216 data->depth = (LONG)tag->ti_Data;
217 break;
219 case MUIA_Bodychunk_Masking:
220 data->masking = (UBYTE)tag->ti_Data;
221 break;
223 case MUIA_Bitmap_Width:
224 data->width = (LONG)tag->ti_Data;
225 break;
227 case MUIA_Bitmap_Height:
228 data->height = (LONG)tag->ti_Data;
229 break;
234 return (IPTR)obj;
237 /**************************************************************************
238 OM_DISPOSE
239 **************************************************************************/
240 IPTR Bodychunk__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
242 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
244 if (data->bm)
246 WaitBlit();
247 FreeBitMap(data->bm);
250 return DoSuperMethodA(cl, obj, msg);
253 /**************************************************************************
254 OM_SET
255 **************************************************************************/
256 IPTR Bodychunk__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
258 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
259 struct TagItem *tags = msg->ops_AttrList;
260 struct TagItem *tag;
262 while ((tag = NextTagItem((const struct TagItem**)&tags)) != NULL)
264 switch (tag->ti_Tag)
266 case MUIA_Bodychunk_Body:
267 data->body = (UBYTE *)tag->ti_Data;
268 break;
270 case MUIA_Bodychunk_Compression:
271 data->compression = (UBYTE)tag->ti_Data;
272 break;
274 case MUIA_Bodychunk_Depth:
275 data->depth = (LONG)tag->ti_Data;
276 break;
278 case MUIA_Bodychunk_Masking:
279 data->masking = (UBYTE)tag->ti_Data;
280 break;
282 case MUIA_Bitmap_Width:
283 data->width = (LONG)tag->ti_Data;
284 break;
286 case MUIA_Bitmap_Height:
287 data->height = (LONG)tag->ti_Data;
288 break;
293 return DoSuperMethodA(cl, obj, (Msg)msg);
296 /**************************************************************************
297 OM_GET
298 **************************************************************************/
299 IPTR Bodychunk__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
301 #define STORE *(msg->opg_Storage)
303 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
305 switch(msg->opg_AttrID)
307 case MUIA_Bodychunk_Body:
308 STORE = (IPTR)data->body;
309 return TRUE;
311 case MUIA_Bodychunk_Compression:
312 STORE = (IPTR)data->compression;
313 return TRUE;
315 case MUIA_Bodychunk_Depth:
316 STORE = (IPTR)data->depth;
317 return TRUE;
319 case MUIA_Bodychunk_Masking:
320 STORE = (IPTR)data->masking;
321 return TRUE;
325 return DoSuperMethodA(cl, obj, (Msg)msg);
326 #undef STORE
329 /**************************************************************************
330 MUIM_Setup
331 **************************************************************************/
332 IPTR Bodychunk__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
334 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
336 if (!make_bitmap(cl, obj)) return FALSE;
338 set(obj, MUIA_Bitmap_Bitmap, (IPTR)data->bm);
340 if (!DoSuperMethodA(cl, obj, (Msg)msg))
342 set(obj, MUIA_Bitmap_Bitmap, NULL);
343 WaitBlit();
344 FreeBitMap(data->bm);
345 data->bm = NULL;
347 return FALSE;
350 return TRUE;
353 /**************************************************************************
354 MUIM_Cleanup
355 **************************************************************************/
356 IPTR Bodychunk__MUIM_Cleanup(struct IClass *cl, Object *obj, struct MUIP_Cleanup *msg)
358 struct MUI_BodychunkData *data = INST_DATA(cl, obj);
359 IPTR retval;
361 retval = DoSuperMethodA(cl, obj, (Msg)msg);
362 if (data->bm)
364 set(obj, MUIA_Bitmap_Bitmap, NULL);
366 WaitBlit();
368 FreeBitMap(data->bm);
369 data->bm = NULL;
372 return retval;
376 BOOPSI_DISPATCHER(IPTR, Bodychunk_Dispatcher, cl, obj, msg)
378 switch (msg->MethodID)
380 case OM_NEW: return Bodychunk__OM_NEW(cl, obj, (struct opSet *)msg);
381 case OM_DISPOSE: return Bodychunk__OM_DISPOSE(cl, obj, msg);
382 case OM_SET: return Bodychunk__OM_SET(cl, obj, (struct opSet *)msg);
383 case OM_GET: return Bodychunk__OM_GET(cl, obj, (struct opGet *)msg);
384 case MUIM_Setup: return Bodychunk__MUIM_Setup(cl, obj, (struct MUIP_Setup *)msg);
385 case MUIM_Cleanup: return Bodychunk__MUIM_Cleanup(cl, obj, (struct MUIP_Cleanup *)msg);
388 return DoSuperMethodA(cl, obj, msg);
390 BOOPSI_DISPATCHER_END
393 * Class descriptor.
395 const struct __MUIBuiltinClass _MUI_Bodychunk_desc = {
396 MUIC_Bodychunk,
397 MUIC_Bitmap,
398 sizeof(struct MUI_BodychunkData),
399 (void*)Bodychunk_Dispatcher