Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / pixmap.c
blob940057dba6fbeb2f5528144798d80a176147b9f6
1 /*
2 Copyright © 2011, Thore Böckelmann. All rights reserved.
3 Copyright © 2012, The AROS Development Team. All rights reserved.
4 $Id$
5 */
7 #include <proto/exec.h>
8 #include <proto/muimaster.h>
9 #include <proto/intuition.h>
10 #include <proto/graphics.h>
11 #include <proto/cybergraphics.h>
12 #include <proto/utility.h>
13 #include <proto/alib.h>
15 #include <libraries/mui.h>
16 #include <cybergraphx/cybergraphics.h>
18 #include <strings.h>
19 #include <bzlib.h>
21 #include "pixmap.h"
22 #include "pixmap_private.h"
24 #include <aros/debug.h>
26 #ifndef MEMF_SHARED
27 #define MEMF_SHARED MEMF_ANY
28 #endif
30 #ifndef MIN
31 #define MIN(a,b) ((a)<(b)?(a):(b))
32 #endif
34 // workaround for missing Zune functionality
35 static BOOL _isfloating(Object *obj)
37 return FALSE;
40 static BOOL _isdisabled(Object *obj)
42 return FALSE;
45 static void MUIP_DrawDisablePattern(struct MUI_RenderInfo *mri, LONG left,
46 LONG top, LONG width, LONG height)
51 // libbz2_nostdio needs this
52 void free(void *memory)
54 FreeVec(memory);
57 void *malloc(size_t size)
59 return AllocVec(size, MEMF_ANY);
62 void bz_internal_error(int errcode)
64 bug("[Pixmap.mui/bz_internal_error] errcode %d\n", errcode);
67 /* ------------------------------------------------------------------------- */
69 /// default color map
70 const ULONG defaultColorMap[256] = {
71 0x00000000, 0x00000055, 0x000000aa, 0x000000ff,
72 0x00002400, 0x00002455, 0x000024aa, 0x000024ff,
73 0x00004900, 0x00004955, 0x000049aa, 0x000049ff,
74 0x00006d00, 0x00006d55, 0x00006daa, 0x00006dff,
75 0x00009200, 0x00009255, 0x000092aa, 0x000092ff,
76 0x0000b600, 0x0000b655, 0x0000b6aa, 0x0000b6ff,
77 0x0000db00, 0x0000db55, 0x0000dbaa, 0x0000dbff,
78 0x0000ff00, 0x0000ff55, 0x0000ffaa, 0x0000ffff,
79 0x00240000, 0x00240055, 0x002400aa, 0x002400ff,
80 0x00242400, 0x00242455, 0x002424aa, 0x002424ff,
81 0x00244900, 0x00244955, 0x002449aa, 0x002449ff,
82 0x00246d00, 0x00246d55, 0x00246daa, 0x00246dff,
83 0x00249200, 0x00249255, 0x002492aa, 0x002492ff,
84 0x0024b600, 0x0024b655, 0x0024b6aa, 0x0024b6ff,
85 0x0024db00, 0x0024db55, 0x0024dbaa, 0x0024dbff,
86 0x0024ff00, 0x0024ff55, 0x0024ffaa, 0x0024ffff,
87 0x00490000, 0x00490055, 0x004900aa, 0x004900ff,
88 0x00492400, 0x00492455, 0x004924aa, 0x004924ff,
89 0x00494900, 0x00494955, 0x004949aa, 0x004949ff,
90 0x00496d00, 0x00496d55, 0x00496daa, 0x00496dff,
91 0x00499200, 0x00499255, 0x004992aa, 0x004992ff,
92 0x0049b600, 0x0049b655, 0x0049b6aa, 0x0049b6ff,
93 0x0049db00, 0x0049db55, 0x0049dbaa, 0x0049dbff,
94 0x0049ff00, 0x0049ff55, 0x0049ffaa, 0x0049ffff,
95 0x006d0000, 0x006d0055, 0x006d00aa, 0x006d00ff,
96 0x006d2400, 0x006d2455, 0x006d24aa, 0x006d24ff,
97 0x006d4900, 0x006d4955, 0x006d49aa, 0x006d49ff,
98 0x006d6d00, 0x006d6d55, 0x006d6daa, 0x006d6dff,
99 0x006d9200, 0x006d9255, 0x006d92aa, 0x006d92ff,
100 0x006db600, 0x006db655, 0x006db6aa, 0x006db6ff,
101 0x006ddb00, 0x006ddb55, 0x006ddbaa, 0x006ddbff,
102 0x006dff00, 0x006dff55, 0x006dffaa, 0x006dffff,
103 0x00920000, 0x00920055, 0x009200aa, 0x009200ff,
104 0x00922400, 0x00922455, 0x009224aa, 0x009224ff,
105 0x00924900, 0x00924955, 0x009249aa, 0x009249ff,
106 0x00926d00, 0x00926d55, 0x00926daa, 0x00926dff,
107 0x00929200, 0x00929255, 0x009292aa, 0x009292ff,
108 0x0092b600, 0x0092b655, 0x0092b6aa, 0x0092b6ff,
109 0x0092db00, 0x0092db55, 0x0092dbaa, 0x0092dbff,
110 0x0092ff00, 0x0092ff55, 0x0092ffaa, 0x0092ffff,
111 0x00b60000, 0x00b60055, 0x00b600aa, 0x00b600ff,
112 0x00b62400, 0x00b62455, 0x00b624aa, 0x00b624ff,
113 0x00b64900, 0x00b64955, 0x00b649aa, 0x00b649ff,
114 0x00b66d00, 0x00b66d55, 0x00b66daa, 0x00b66dff,
115 0x00b69200, 0x00b69255, 0x00b692aa, 0x00b692ff,
116 0x00b6b600, 0x00b6b655, 0x00b6b6aa, 0x00b6b6ff,
117 0x00b6db00, 0x00b6db55, 0x00b6dbaa, 0x00b6dbff,
118 0x00b6ff00, 0x00b6ff55, 0x00b6ffaa, 0x00b6ffff,
119 0x00db0000, 0x00db0055, 0x00db00aa, 0x00db00ff,
120 0x00db2400, 0x00db2455, 0x00db24aa, 0x00db24ff,
121 0x00db4900, 0x00db4955, 0x00db49aa, 0x00db49ff,
122 0x00db6d00, 0x00db6d55, 0x00db6daa, 0x00db6dff,
123 0x00db9200, 0x00db9255, 0x00db92aa, 0x00db92ff,
124 0x00dbb600, 0x00dbb655, 0x00dbb6aa, 0x00dbb6ff,
125 0x00dbdb00, 0x00dbdb55, 0x00dbdbaa, 0x00dbdbff,
126 0x00dbff00, 0x00dbff55, 0x00dbffaa, 0x00dbffff,
127 0x00ff0000, 0x00ff0055, 0x00ff00aa, 0x00ff00ff,
128 0x00ff2400, 0x00ff2455, 0x00ff24aa, 0x00ff24ff,
129 0x00ff4900, 0x00ff4955, 0x00ff49aa, 0x00ff49ff,
130 0x00ff6d00, 0x00ff6d55, 0x00ff6daa, 0x00ff6dff,
131 0x00ff9200, 0x00ff9255, 0x00ff92aa, 0x00ff92ff,
132 0x00ffb600, 0x00ffb655, 0x00ffb6aa, 0x00ffb6ff,
133 0x00ffdb00, 0x00ffdb55, 0x00ffdbaa, 0x00ffdbff,
134 0x00ffff00, 0x00ffff55, 0x00ffffaa, 0x00ffffff
139 IPTR Pixmap__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
141 struct TagItem *tag, *tags;
143 if ((obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg)) != NULL)
145 struct Pixmap_DATA *data = INST_DATA(cl, obj);
147 data->format = MUIV_Pixmap_Format_ARGB32;
148 data->alpha = 0xffffffffUL;
149 data->compression = MUIV_Pixmap_Compression_None;
151 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
153 switch (tag->ti_Tag)
155 case MUIA_LeftEdge:
156 data->leftOffset = tag->ti_Data;
157 break;
158 case MUIA_TopEdge:
159 data->topOffset = tag->ti_Data;
160 break;
161 case MUIA_Pixmap_Data:
162 data->data = (APTR) tag->ti_Data;
163 break;
164 case MUIA_Pixmap_Format:
165 data->format = tag->ti_Data;
166 break;
167 case MUIA_Pixmap_Width:
168 data->width = tag->ti_Data;
169 break;
170 case MUIA_Pixmap_Height:
171 data->height = tag->ti_Data;
172 break;
173 case MUIA_Pixmap_CLUT:
174 data->clut = (APTR) tag->ti_Data;
175 break;
176 case MUIA_Pixmap_Alpha:
177 data->alpha = tag->ti_Data;
178 break;
179 case MUIA_Pixmap_Compression:
180 data->compression = tag->ti_Data;
181 break;
182 case MUIA_Pixmap_CompressedSize:
183 data->compressedSize = tag->ti_Data;
184 break;
189 return (IPTR) obj;
193 static void FreeImage(struct IClass *cl, Object *obj)
195 struct Pixmap_DATA *data = INST_DATA(cl, obj);
197 if (data->uncompressedData != NULL
198 && data->uncompressedData != data->data)
200 FreeVec(data->uncompressedData);
201 data->uncompressedData = NULL;
205 IPTR Pixmap__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
207 FreeImage(cl, obj);
208 return DoSuperMethodA(cl, obj, msg);
212 #define RAWIDTH(w) ((((UWORD)(w))+15)>>3 & 0xFFFE)
214 static void DitherImage(struct IClass *cl, Object *obj)
216 struct Pixmap_DATA *data = INST_DATA(cl, obj);
218 if ((data->ditheredData =
219 AllocVec(data->width * data->height, MEMF_SHARED)) != NULL)
221 UBYTE *mask = NULL;
222 UBYTE *mPtr = NULL;
223 LONG y;
224 UBYTE *dataPtr = (UBYTE *) data->uncompressedData;
225 UBYTE *ditheredPtr = (UBYTE *) data->ditheredData;
226 const ULONG *colorMap =
227 (data->clut != NULL) ? data->clut : defaultColorMap;
229 // only ARGB raw data contain transparency data, hence we need to
230 // allocate a mask plane only for these
231 if (data->format == MUIV_Pixmap_Format_ARGB32)
233 mask =
234 AllocVec(RAWIDTH(data->width) * data->height,
235 MEMF_SHARED | MEMF_CLEAR | MEMF_CHIP);
236 data->ditheredMask = mask;
237 mPtr = mask;
239 else
241 data->ditheredMask = NULL;
244 for (y = 0; y < data->height; y++)
246 LONG x;
247 UBYTE bitMask = 0x80;
249 for (x = 0; x < data->width; x++)
251 UBYTE a, r, g, b;
252 ULONG i;
253 ULONG bestIndex;
254 ULONG bestError;
256 // obtain the pixel's A, R, G and B values from the raw data
257 switch (data->format)
259 case MUIV_Pixmap_Format_CLUT8:
260 a = (colorMap[dataPtr[0]] >> 24) & 0xff;
261 r = (colorMap[dataPtr[0]] >> 16) & 0xff;
262 g = (colorMap[dataPtr[0]] >> 8) & 0xff;
263 b = (colorMap[dataPtr[0]] >> 0) & 0xff;
264 dataPtr += 1;
265 break;
267 case MUIV_Pixmap_Format_RGB24:
268 a = 0xff;
269 r = dataPtr[0];
270 g = dataPtr[1];
271 b = dataPtr[2];
272 dataPtr += 3;
273 break;
275 case MUIV_Pixmap_Format_ARGB32:
276 a = dataPtr[0];
277 r = dataPtr[1];
278 g = dataPtr[2];
279 b = dataPtr[3];
280 dataPtr += 4;
281 break;
283 default:
284 a = 0x00;
285 r = 0x00;
286 g = 0x00;
287 b = 0x00;
288 break;
291 // now calculate the best matching color from the given
292 // color map
293 bestIndex = 0;
294 bestError = 0xffffffffUL;
296 for (i = 0; i < 256; i++)
298 LONG dr, dg, db;
299 ULONG error;
301 // calculate the geometric difference to the current color
302 dr = (LONG) ((colorMap[i] >> 16) & 0xff) - (LONG) r;
303 dg = (LONG) ((colorMap[i] >> 8) & 0xff) - (LONG) g;
304 db = (LONG) ((colorMap[i] >> 0) & 0xff) - (LONG) b;
305 error = dr * dr + dg * dg + db * db;
307 if (bestError > error)
309 // remember this as the best matching color so far
310 bestError = error;
311 bestIndex = i;
313 // bail out if we found an exact match
314 if (error == 0x00000000)
315 break;
319 // put the calculated color number into the destination LUT8
320 // image using the additional pen map
321 *ditheredPtr++ = data->ditheredPenMap[bestIndex];
323 if (mPtr != NULL)
325 // if we have a mask and the alpha value is >= 0x80 the
326 // pixel is treated as non-transparent
327 if (a >= 0x80)
328 mPtr[x / 8] |= bitMask;
330 bitMask >>= 1;
331 if (bitMask == 0x00)
332 bitMask = 0x80;
336 // advance the mask pointer by one line
337 if (mPtr != NULL)
338 mPtr += RAWIDTH(data->width);
341 // CyberGraphics cannot blit raw data through a mask, therefore we
342 // have to take this ugly workaround and take the detour using a
343 // bitmap.
344 if ((data->ditheredBitmap =
345 AllocBitMap(data->width, data->height, 8, BMF_MINPLANES,
346 NULL)) != NULL)
348 struct RastPort tempRP;
350 InitRastPort(&tempRP);
351 tempRP.BitMap = data->ditheredBitmap;
353 WritePixelArray(data->ditheredData, 0, 0, data->width, &tempRP,
354 0, 0, data->width, data->height, RECTFMT_LUT8);
360 static BOOL DecompressRLE(struct IClass *cl, Object *obj,
361 ULONG uncompressedSize)
363 struct Pixmap_DATA *data = INST_DATA(cl, obj);
364 BOOL success = FALSE;
366 if ((data->uncompressedData =
367 AllocVec(uncompressedSize, MEMF_SHARED)) != NULL)
369 LONG rleLen = (LONG) data->compressedSize;
370 unsigned char *rleData = (unsigned char *)data->data;
371 unsigned char *dest = (unsigned char *)data->uncompressedData;
373 while (rleLen != 0)
375 unsigned char c;
377 c = *rleData++;
378 rleLen--;
380 if (c & 0x80)
382 LONG n = (c & 0x7f) + 2;
384 c = *rleData++;
385 rleLen--;
387 memset(dest, c, n);
388 dest += n;
390 else
392 c++;
393 memcpy(dest, rleData, c);
394 rleLen -= c;
395 rleData += c;
396 dest += c;
400 success = TRUE;
403 return success;
407 static BOOL DecompressBZip2(struct IClass *cl, Object *obj,
408 ULONG uncompressedSize)
410 BOOL success = FALSE;
413 APTR uncompressedData;
415 if ((uncompressedData =
416 AllocVec(uncompressedSize, MEMF_SHARED)) != NULL)
418 bz_stream bzip2_stream;
420 memset(&bzip2_stream, 0, sizeof(bzip2_stream));
421 if (BZ2_bzDecompressInit(&bzip2_stream, 0, 1) == BZ_OK)
423 struct Pixmap_DATA *data = INST_DATA(cl, obj);
424 int err;
426 bzip2_stream.next_in = data->data;
427 bzip2_stream.avail_in = data->compressedSize;
428 bzip2_stream.next_out = uncompressedData;
429 bzip2_stream.avail_out = uncompressedSize;
431 err = BZ2_bzDecompress(&bzip2_stream);
432 if ((err != BZ_OK && err != BZ_STREAM_END)
433 || bzip2_stream.total_out_lo32 != uncompressedSize)
435 FreeVec(uncompressedData);
436 uncompressedData = NULL;
438 else
440 data->uncompressedData = uncompressedData;
441 success = TRUE;
444 BZ2_bzDecompressEnd(&bzip2_stream);
449 return success;
453 static BOOL DecompressImage(struct IClass *cl, Object *obj)
455 struct Pixmap_DATA *data = INST_DATA(cl, obj);
456 BOOL success = FALSE;
458 if (data->uncompressedData != NULL)
460 // the image has been uncompressed before, return immediate success
461 success = TRUE;
463 else if (data->compression != MUIV_Pixmap_Compression_None
464 && data->data != NULL && data->compressedSize != 0)
466 ULONG uncompressedSize;
468 switch (data->format)
470 case MUIV_Pixmap_Format_CLUT8:
471 uncompressedSize = data->width * data->height;
472 break;
474 case MUIV_Pixmap_Format_RGB24:
475 uncompressedSize = data->width * data->height * 3;
476 break;
478 case MUIV_Pixmap_Format_ARGB32:
479 uncompressedSize = data->width * data->height * 4;
480 break;
482 default:
483 uncompressedSize = 0;
484 break;
487 // uncompress the image data
488 switch (data->compression)
490 case MUIV_Pixmap_Compression_RLE:
492 success = DecompressRLE(cl, obj, uncompressedSize);
494 break;
496 case MUIV_Pixmap_Compression_BZip2:
498 success = DecompressBZip2(cl, obj, uncompressedSize);
500 break;
502 default:
504 success = FALSE;
506 break;
509 else if (data->data != NULL)
511 // nothing to do, return success
512 data->uncompressedData = data->data;
513 success = TRUE;
516 return success;
520 IPTR Pixmap__MUIM_Setup(struct IClass *cl, Object *obj,
521 struct MUIP_Setup *msg)
523 struct Pixmap_DATA *data = INST_DATA(cl, obj);
525 // just try to decompress the image, but don't fail
526 DecompressImage(cl, obj);
528 if (!DoSuperMethodA(cl, obj, (Msg) msg))
529 return FALSE;
531 // in case we are to be displayed on a colormapped screen we have to create
532 // dithered copies of the images
533 if (data->uncompressedData != NULL
534 && (data->screenDepth =
535 GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH)) <= 8)
537 ULONG i;
538 const ULONG *colorMap;
539 struct TagItem obpTags[] = {
540 {OBP_Precision, PRECISION_IMAGE},
541 {TAG_DONE, 0}
544 // use a user definable colormap or the default color map
545 if (data->clut != NULL)
546 colorMap = data->clut;
547 else
548 colorMap = defaultColorMap;
550 // allocate all pens
551 for (i = 0; i < 256; i++)
552 data->ditheredPenMap[i] =
553 ObtainBestPenA(_screen(obj)->ViewPort.ColorMap,
554 ((colorMap[i] >> 16) & 0xff) * 0x01010101UL,
555 ((colorMap[i] >> 8) & 0xff) * 0x01010101UL,
556 ((colorMap[i] >> 0) & 0xff) * 0x01010101UL, obpTags);
558 // create a dithered copy of the raw image
559 DitherImage(cl, obj);
561 else
563 data->ditheredData = NULL;
566 if (!_isfloating(obj))
568 // if there is a chance that anything of the parent's imagery may
569 // be visible below ourselves then we must make sure that our
570 // background is drawn accordingly before we draw ourselves.
571 // The background is visible if we either:
572 // - have an own alphachannel
573 // - are drawn with an additional transparency
574 // - have a transparent mask
575 if (data->format == MUIV_Pixmap_Format_ARGB32
576 || data->alpha != 0xffffffffUL || data->ditheredMask != NULL)
577 SetSuperAttrs(cl, obj, MUIA_DoubleBuffer, TRUE, MUIA_FillArea,
578 TRUE, TAG_DONE);
579 else
580 SetSuperAttrs(cl, obj, MUIA_DoubleBuffer, FALSE, MUIA_FillArea,
581 FALSE, TAG_DONE);
584 return TRUE;
588 IPTR Pixmap__MUIM_Cleanup(struct IClass *cl, Object *obj, Msg msg)
590 struct Pixmap_DATA *data = INST_DATA(cl, obj);
592 // free the possibly dithered image copy
593 if (data->ditheredData != NULL)
595 FreeVec(data->ditheredData);
596 data->ditheredData = NULL;
598 if (data->ditheredMask != NULL)
600 FreeVec(data->ditheredMask);
601 data->ditheredMask = NULL;
603 if (data->ditheredBitmap != NULL)
605 FreeBitMap(data->ditheredBitmap);
606 data->ditheredBitmap = NULL;
609 // release all allocated pens
610 if (data->screenDepth <= 8)
612 ULONG i;
614 for (i = 0; i < 256; i++)
616 if (data->ditheredPenMap[i] != -1)
617 ReleasePen(_screen(obj)->ViewPort.ColorMap,
618 data->ditheredPenMap[i]);
622 return DoSuperMethodA(cl, obj, msg);
626 IPTR Pixmap__MUIM_AskMinMax(struct IClass *cl, Object *obj,
627 struct MUIP_AskMinMax *msg)
629 struct Pixmap_DATA *data = INST_DATA(cl, obj);
631 DoSuperMethodA(cl, obj, (Msg) msg);
633 msg->MinMaxInfo->MinWidth += data->width;
634 msg->MinMaxInfo->MinHeight += data->height;
635 msg->MinMaxInfo->DefWidth += data->width;
636 msg->MinMaxInfo->DefHeight += data->height;
637 msg->MinMaxInfo->MaxWidth += data->width;
638 msg->MinMaxInfo->MaxHeight += data->height;
640 return 0;
644 static void DrawPixmapSection(struct IClass *cl, Object *obj, LONG sx,
645 LONG sy, LONG sw, LONG sh, struct MUI_RenderInfo *mri, LONG dx, LONG dy)
647 struct Pixmap_DATA *data = INST_DATA(cl, obj);
648 struct RastPort *rp = mri->mri_RastPort;
650 if (data->screenDepth <= 8 && data->ditheredBitmap != NULL)
652 // CyberGraphics cannot blit raw data through a mask, therefore we
653 // have to take this ugly workaround and take the detour using a
654 // bitmap.
655 if (data->ditheredMask != NULL)
657 BltMaskBitMapRastPort(data->ditheredBitmap, sx, sy, rp, dx, dy,
658 sw, sh, (ABC | ABNC | ANBC), data->ditheredMask);
660 else
662 BltBitMapRastPort(data->ditheredBitmap, sx, sy, rp, dx, dy, sw,
663 sh, (ABC | ABNC));
666 else if (data->uncompressedData != NULL)
668 switch (data->format)
670 case MUIV_Pixmap_Format_CLUT8:
671 WriteLUTPixelArray(data->uncompressedData, sx, sy, data->width,
672 rp, data->clut, dx, dy, sw, sh, CTABFMT_XRGB8);
673 break;
675 case MUIV_Pixmap_Format_RGB24:
676 WritePixelArray(data->uncompressedData, sx, sy, data->width * 3,
677 rp, dx, dy, sw, sh, RECTFMT_RGB);
678 break;
680 case MUIV_Pixmap_Format_ARGB32:
681 WritePixelArrayAlpha(data->uncompressedData, sx, sy,
682 data->width * 4, rp, dx, dy, sw, sh, data->alpha);
683 break;
686 else
688 // just draw a black cross in case we got no valid pixmap
689 SetAPen(rp, _pens(obj)[MPEN_TEXT]);
690 Move(rp, _mleft(obj), _mtop(obj));
691 Draw(rp, _mright(obj), _mbottom(obj));
692 Move(rp, _mleft(obj), _mbottom(obj));
693 Draw(rp, _mright(obj), _mtop(obj));
697 IPTR Pixmap__MUIM_Draw(struct IClass *cl, Object *obj,
698 struct MUIP_Draw *msg)
700 struct Pixmap_DATA *data = INST_DATA(cl, obj);
702 DoSuperMethodA(cl, obj, (Msg) msg);
704 if (msg->flags & MADF_DRAWOBJECT)
706 if (data->data != NULL)
708 int w = MIN(_mwidth(obj), data->width);
709 int h = MIN(_mheight(obj), data->height);
711 if (w > 0 && h > 0)
712 DrawPixmapSection(cl, obj, 0, 0, w, h, muiRenderInfo(obj),
713 _mleft(obj), _mtop(obj));
716 if (_isdisabled(obj))
717 MUIP_DrawDisablePattern(muiRenderInfo(obj), _left(obj),
718 _top(obj), _width(obj), _height(obj));
721 return 0;
725 IPTR Pixmap__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
727 struct Pixmap_DATA *data = INST_DATA(cl, obj);
728 BOOL decompress = FALSE;
729 BOOL refresh = FALSE;
730 struct TagItem *tag, *tags;
732 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
734 switch (tag->ti_Tag)
736 case MUIA_Pixmap_Data:
737 data->data = (APTR) tag->ti_Data;
738 refresh = TRUE;
739 decompress = TRUE;
740 break;
741 case MUIA_Pixmap_Format:
742 data->format = tag->ti_Data;
743 refresh = TRUE;
744 break;
745 case MUIA_Pixmap_Width:
746 data->width = tag->ti_Data;
747 refresh = TRUE;
748 break;
749 case MUIA_Pixmap_Height:
750 data->height = tag->ti_Data;
751 refresh = TRUE;
752 break;
753 case MUIA_Pixmap_CLUT:
754 data->clut = (APTR) tag->ti_Data;
755 refresh = TRUE;
756 break;
757 case MUIA_Pixmap_Alpha:
758 data->alpha = tag->ti_Data;
759 refresh = TRUE;
760 break;
761 case MUIA_Pixmap_Compression:
762 data->compression = tag->ti_Data;
763 refresh = TRUE;
764 decompress = TRUE;
765 break;
766 case MUIA_Pixmap_CompressedSize:
767 data->compressedSize = tag->ti_Data;
768 refresh = TRUE;
769 decompress = TRUE;
770 break;
774 if (decompress == TRUE)
776 // obtain the new image data
777 FreeImage(cl, obj);
778 if (DecompressImage(cl, obj) == FALSE)
779 return FALSE;
782 if (refresh == TRUE)
784 MUI_Redraw(obj, MADF_DRAWOBJECT);
787 DoSuperMethodA(cl, obj, (Msg) msg);
789 // signal success, this is checked by Rawimage.mcc
790 return TRUE;
794 IPTR Pixmap__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
796 struct Pixmap_DATA *data = INST_DATA(cl, obj);
797 IPTR *store = msg->opg_Storage;
799 switch (((struct opGet *)msg)->opg_AttrID)
801 case MUIA_Pixmap_Data:
802 *store = (IPTR) data->data;
803 return TRUE;
805 case MUIA_Pixmap_Format:
806 *store = data->format;
807 return TRUE;
809 case MUIA_Pixmap_Width:
810 *store = (IPTR) data->width;
811 return TRUE;
813 case MUIA_Pixmap_Height:
814 *store = (IPTR) data->height;
815 return TRUE;
817 case MUIA_Pixmap_CLUT:
818 *store = (IPTR) data->clut;
819 return TRUE;
821 case MUIA_Pixmap_Alpha:
822 *store = data->alpha;
823 return TRUE;
825 case MUIA_Pixmap_Compression:
826 *store = data->compression;
827 return TRUE;
829 case MUIA_Pixmap_CompressedSize:
830 *store = data->compressedSize;
831 return TRUE;
833 case MUIA_Pixmap_UncompressedData:
834 DecompressImage(cl, obj);
835 *store = (IPTR) data->uncompressedData;
836 return TRUE;
839 return DoSuperMethodA(cl, obj, (Msg) msg);
843 IPTR Pixmap__MUIM_Layout(struct IClass *cl, Object *obj, Msg msg)
845 struct Pixmap_DATA *data = INST_DATA(cl, obj);
846 ULONG rc = DoSuperMethodA(cl, obj, (Msg) msg);
848 if (data->leftOffset < 0)
849 _left(obj) =
850 _right(_parent(obj)) - _width(obj) + 1 + 1 + data->leftOffset;
851 else
852 _left(obj) += data->leftOffset;
854 if (data->topOffset < 0)
855 _top(obj) =
856 _bottom(_parent(obj)) - _height(obj) + 1 + 1 + data->topOffset;
857 else
858 _top(obj) += data->topOffset;
860 return rc;
864 IPTR Pixmap__MUIM_Pixmap_DrawSection(struct IClass *cl, Object *obj,
865 struct MUIP_Pixmap_DrawSection *msg)
867 BOOL success;
869 if ((success = DecompressImage(cl, obj)) == TRUE)
871 DrawPixmapSection(cl, obj, msg->sx, msg->sy, msg->sw, msg->sh,
872 msg->mri, msg->dx, msg->dy);
875 return 0;
879 #if ZUNE_BUILTIN_PIXMAP
880 BOOPSI_DISPATCHER(IPTR, Pixmap_Dispatcher, cl, obj, msg)
882 switch (msg->MethodID)
884 case OM_NEW:
885 return Pixmap__OM_NEW(cl, obj, (APTR) msg));
886 case OM_DISPOSE:
887 return Pixmap__OM_DISPOSE(cl, obj, (APTR) msg));
888 case OM_SET:
889 return Pixmap__OM_SET(cl, obj, (APTR) msg));
890 case OM_GET:
891 return Pixmap__OM_GET(cl, obj, (APTR) msg));
892 case MUIM_Draw:
893 return Pixmap__MUIM_Draw(cl, obj, (APTR) msg));
894 case MUIM_Setup:
895 return Pixmap__MUIM_Setup(cl, obj, (APTR) msg));
896 case MUIM_Cleanup:
897 return Pixmap__MUIM_Cleanup(cl, obj, (APTR) msg));
898 case MUIM_AskMinMax:
899 return Pixmap__MUIM_AskMinMax(cl, obj, (APTR) msg));
900 case MUIM_Layout:
901 return Pixmap__MUIM_Layout(cl, obj, (APTR) msg));
902 case MUIM_Pixmap_DrawSection:
903 return Pixmap__MUIM_Pixmap_DrawSection(cl, obj, (APTR) msg));
906 return DoSuperMethodA(cl, obj, (APTR) msg);
908 BOOPSI_DISPATCHER_END
910 const struct __MUIBuiltinClass _MUI_Pixmap_desc =
912 MUIC_Pixmap,
913 MUIC_Area,
914 sizeof(struct MUI_Pixmap_DATA),
915 (void *)Pixmap_Dispatcher
917 #endif