2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphics planar bitmap class implementation.
9 /****************************************************************************************/
11 #include <proto/exec.h>
12 #include <proto/utility.h>
13 #include <proto/oop.h>
15 #include <exec/memory.h>
16 #include <utility/tagitem.h>
17 #include <graphics/gfx.h>
20 #include <hidd/graphics.h>
24 #include "graphics_intern.h"
29 #include <aros/debug.h>
31 /*****************************************************************************************
34 --background_planarbm--
37 hidd.graphics.bitmap.planarbm
40 This is a class representing a planar Amiga(tm) bitmap in AROS graphics subsystem.
42 When you create an object of this class, an associated planar bitmap will be created.
43 However, it's possible to use this class with pre-existing bitmaps, making them
44 available to the graphics HIDD subsystem.
46 *****************************************************************************************/
48 /*****************************************************************************************
51 aoHidd_PlanarBM_AllocPlanes
57 hidd.graphics.bitmap.planarbm
60 Set this attribute to FALSE if you want to create an empty bitmap object containing
61 no bitmap data. Useful if you want to create an empty object to be associated with
62 existing bitmap later.
65 This attribute is obsolete. It's equal to supplying aoHidd_PlanarBM_BitMap attribute
73 aoHidd_PlanarBM_BitMap
77 *****************************************************************************************/
79 /*****************************************************************************************
82 aoHidd_PlanarBM_BitMap
85 [ISG], struct BitMap *
88 hidd.graphics.bitmap.planarbm
91 Allows to specify or retrieve a raw planar bitmap structure associated with the object.
92 Useful for direct access to the bitmap within subclasses, as well as for associating
93 an object with already existing BitMap structure.
95 It is valid to pass this attribute with a NULL value. In this case the object becomes
96 empty and contains no actual bitmap.
99 If the object was created with own bitmap data (with no aoHidd_PlanarBM_BitMap specified
100 during creation), this data will be deallocated when you set this attribute.
102 It's up to you to deallocate own bitmaps, set using this attribute. Even if the object
103 is disposed, it won't deallocate user-supplied bitmap.
113 *****************************************************************************************/
115 OOP_Object
*PBM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
117 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
118 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
119 IPTR height
, bytesperrow
;
121 IPTR displayable
= FALSE
;
123 struct planarbm_data
*data
;
126 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
130 data
= OOP_INST_DATA(cl
, o
);
132 /* Check if we want to use existing bitmap */
134 tag
= FindTagItem(aHidd_PlanarBM_BitMap
, msg
->attrList
);
137 /* It's not our own bitmap */
138 data
->planes_alloced
= FALSE
;
139 /* Remember the bitmap. It can be NULL here. */
140 data
->bitmap
= (struct BitMap
*)tag
->ti_Data
;
142 /* That's all, we are attached to an existing BitMap */
147 /* Check obsolete attribute now */
148 data
->planes_alloced
= GetTagData(aHidd_PlanarBM_AllocPlanes
, TRUE
, msg
->attrList
);
150 if (!data
->planes_alloced
)
151 return o
; /* Late initialization */
154 /* By default we create 1-plane bitmap */
155 depth
= GetTagData(aHidd_BitMap_Depth
, 1, msg
->attrList
);
157 /* Not late initialization. Get some info on the bitmap */
158 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
159 OOP_GetAttr(o
, aHidd_BitMap_BytesPerRow
, &bytesperrow
);
160 OOP_GetAttr(o
, aHidd_BitMap_Displayable
, &displayable
);
162 data
->bitmap
= AllocMem(sizeof(struct BitMap
), MEMF_CLEAR
);
169 /* We cache some info */
170 data
->bitmap
->Rows
= height
;
171 data
->bitmap
->BytesPerRow
= bytesperrow
;
172 data
->bitmap
->Depth
= depth
;
173 data
->bitmap
->Flags
= BMF_STANDARD
|BMF_MINPLANES
; /* CHECKME */
175 data
->bitmap
->Flags
|= BMF_DISPLAYABLE
;
177 /* Allocate memory for all the planes. Use chip memory. */
178 for (i
= 0; i
< depth
; i
++)
180 data
->bitmap
->Planes
[i
] = AllocMem(height
* bytesperrow
, MEMF_CHIP
| MEMF_CLEAR
);
182 if (NULL
== data
->bitmap
->Planes
[i
])
192 OOP_MethodID dispose_mid
;
194 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
195 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
203 /****************************************************************************************/
205 static void PBM_FreeBitMap(struct planarbm_data
*data
)
207 if (data
->planes_alloced
)
209 if (NULL
!= data
->bitmap
)
213 for (i
= 0; i
< data
->bitmap
->Depth
; i
++)
215 if (data
->bitmap
->Planes
[i
])
217 FreeMem(data
->bitmap
->Planes
[i
], data
->bitmap
->Rows
* data
->bitmap
->BytesPerRow
);
220 FreeMem(data
->bitmap
, sizeof(struct BitMap
));
225 VOID
PBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
227 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
229 PBM_FreeBitMap(data
);
230 OOP_DoSuperMethod(cl
, o
, msg
);
233 /****************************************************************************************/
235 VOID
PBM__Root__Get(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Get
*msg
)
237 struct planarbm_data
*data
= OOP_INST_DATA(cl
, obj
);
239 if (msg
->attrID
== aHidd_BitMap_Depth
)
241 /* Planar bitmaps may have a variable depth. */
242 *msg
->storage
= data
->bitmap
? data
->bitmap
->Depth
: 0;
245 else if (msg
->attrID
== aHidd_PlanarBM_BitMap
)
247 *msg
->storage
= (IPTR
)data
->bitmap
;
251 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
254 /****************************************************************************************/
256 static BOOL
PBM_SetBitMap(OOP_Class
*cl
, OOP_Object
*o
, struct BitMap
*bm
)
258 struct TagItem pftags
[] =
260 { aHidd_PixFmt_Depth
, 0UL }, /* 0 */
261 { aHidd_PixFmt_BitsPerPixel
, 0UL }, /* 1 */
262 { aHidd_PixFmt_BytesPerPixel
, 1UL }, /* 2 */
263 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_Palette
}, /* 3 */
264 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Planar
}, /* 4 */
265 { aHidd_PixFmt_CLUTShift
, 0UL }, /* 5 */
266 { aHidd_PixFmt_CLUTMask
, 0x000000FF }, /* 6 */
267 { aHidd_PixFmt_RedMask
, 0x00FF0000 }, /* 7 */
268 { aHidd_PixFmt_GreenMask
, 0x0000FF00 }, /* 8 */
269 { aHidd_PixFmt_BlueMask
, 0x000000FF }, /* 9 */
270 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_Plane
},
273 struct TagItem bmtags
[] =
275 { aHidd_BitMap_Width
, 0 }, /* 0 */
276 { aHidd_BitMap_Height
, 0 }, /* 1 */
277 { aHidd_BitMap_BytesPerRow
, 0 }, /* 2 */
280 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
283 /* First we attempt to register a pixelformat */
284 pftags
[0].ti_Data
= bm
->Depth
; /* PixFmt_Depth */
285 pftags
[1].ti_Data
= bm
->Depth
; /* PixFmt_BitsPerPixel */
287 pf
= GFX__Hidd_Gfx__RegisterPixFmt(CSD(cl
)->gfxhiddclass
, pftags
);
291 /* Fail is pixelformat registration failed */
295 /* Free old bitmap, if it was ours. */
296 PBM_FreeBitMap(data
);
298 /* Set the new bitmap. It's not ours. */
300 data
->planes_alloced
= FALSE
;
302 /* Call private bitmap method to update superclass */
303 bmtags
[0].ti_Data
= bm
->BytesPerRow
* 8;
304 bmtags
[1].ti_Data
= bm
->Rows
;
305 bmtags
[2].ti_Data
= bm
->BytesPerRow
;
307 BM__Hidd_BitMap__SetBitMapTags(CSD(cl
)->bitmapclass
, o
, bmtags
);
308 BM__Hidd_BitMap__SetPixFmt(CSD(cl
)->bitmapclass
, o
, pf
);
313 VOID
PBM__Root__Set(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Set
*msg
)
315 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
316 struct TagItem
*tag
= FindTagItem(aHidd_PlanarBM_BitMap
, msg
->attrList
);
321 * TODO: We can't check for failure here. However, since we already
322 * have Depth attribute for the bitmap, may be we shouldn't register
323 * 8 pixelformats? In this case we are unable to fail.
325 PBM_SetBitMap(cl
, obj
, (struct BitMap
*)tag
->ti_Data
);
328 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
331 /****************************************************************************************/
333 VOID
PBM__Hidd_BitMap__PutPixel(OOP_Class
*cl
, OOP_Object
*o
,
334 struct pHidd_BitMap_PutPixel
*msg
)
337 struct planarbm_data
*data
;
340 UBYTE pixel
, notpixel
;
343 data
= OOP_INST_DATA(cl
, o
);
348 /* bitmap in plane-mode */
349 plane
= data
->bitmap
->Planes
;
350 offset
= msg
->x
/ 8 + msg
->y
* data
->bitmap
->BytesPerRow
;
351 pixel
= 128 >> (msg
->x
% 8);
355 for (i
= 0; i
< data
->bitmap
->Depth
; i
++, mask
<<=1, plane
++)
357 if ((*plane
!= NULL
) && (*plane
!= (UBYTE
*)-1))
359 if(msg
->pixel
& mask
)
361 *(*plane
+ offset
) = *(*plane
+ offset
) | pixel
;
365 *(*plane
+ offset
) = *(*plane
+ offset
) & notpixel
;
371 /****************************************************************************************/
373 ULONG
PBM__Hidd_BitMap__GetPixel(OOP_Class
*cl
, OOP_Object
*o
,
374 struct pHidd_BitMap_GetPixel
*msg
)
376 struct planarbm_data
*data
;
383 data
= OOP_INST_DATA(cl
, o
);
388 plane
= data
->bitmap
->Planes
;
389 offset
= msg
->x
/ 8 + msg
->y
* data
->bitmap
->BytesPerRow
;
390 pixel
= 128 >> (msg
->x
% 8);
393 for (i
= 0; i
< data
->bitmap
->Depth
; i
++, plane
++)
395 if (*plane
== (UBYTE
*)-1)
397 retval
= retval
| (1 << i
);
399 else if (*plane
!= NULL
)
401 if(*(*plane
+ offset
) & pixel
)
403 retval
= retval
| (1 << i
);
411 /****************************************************************************************/
414 * In fact these two routines are implementations of C2P algorighm. The first one takes chunky
415 * array of 8-bit values, the second one - 32-bit one.
417 static void PBM_PutImage_Native(UBYTE
*src
, ULONG modulo
, struct BitMap
*data
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
)
419 ULONG planeoffset
= starty
* data
->BytesPerRow
+ startx
/ 8;
424 for (y
= 0; y
< height
; y
++)
426 UBYTE
**plane
= data
->Planes
;
428 for (d
= 0; d
< data
->Depth
; d
++)
430 UWORD dmask
= 1L << d
;
431 UWORD pmask
= 0x80 >> startx
;
434 if (pl
== (UBYTE
*)-1) continue;
435 if (pl
== NULL
) continue;
439 for (x
= 0; x
< width
; x
++)
459 } /* for (x = 0; x < msg->width; x++) */
463 } /* for (d = 0; d < data->depth; d++) */
466 planeoffset
+= data
->BytesPerRow
;
467 } /* for (y = 0; y < msg->height; y++) */
470 static void PBM_PutImage_Native32(HIDDT_Pixel
*src
, ULONG modulo
, struct BitMap
*data
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
)
472 ULONG planeoffset
= starty
* data
->BytesPerRow
+ startx
/ 8;
477 for (y
= 0; y
< height
; y
++)
479 UBYTE
**plane
= data
->Planes
;
481 for (d
= 0; d
< data
->Depth
; d
++)
483 UWORD dmask
= 1L << d
;
484 UWORD pmask
= 0x80 >> startx
;
487 if (pl
== (UBYTE
*)-1) continue;
488 if (pl
== NULL
) continue;
492 for (x
= 0; x
< width
; x
++)
512 } /* for (x = 0; x < msg->width; x++) */
516 } /* for (d = 0; d < data->depth; d++) */
518 src
= ((APTR
)src
+ modulo
);
519 planeoffset
+= data
->BytesPerRow
;
520 } /* for (y = 0; y < msg->height; y++) */
523 VOID
PBM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
524 struct pHidd_BitMap_PutImage
*msg
)
526 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
531 if ((msg
->pixFmt
!= vHidd_StdPixFmt_Native
) &&
532 (msg
->pixFmt
!= vHidd_StdPixFmt_Native32
))
534 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
540 case vHidd_StdPixFmt_Native
:
541 PBM_PutImage_Native(msg
->pixels
, msg
->modulo
, data
->bitmap
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
544 case vHidd_StdPixFmt_Native32
:
545 PBM_PutImage_Native32((HIDDT_Pixel
*)msg
->pixels
, msg
->modulo
, data
->bitmap
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
551 /****************************************************************************************/
553 VOID
PBM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
554 struct pHidd_BitMap_PutImageLUT
*msg
)
556 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
561 /* This is the same as PutImage() with vHidd_StdPixFmt_Native format */
562 PBM_PutImage_Native(msg
->pixels
, msg
->modulo
, data
->bitmap
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
565 /****************************************************************************************/
567 VOID
PBM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
568 struct pHidd_BitMap_GetImageLUT
*msg
)
571 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
574 struct planarbm_data
*data
;
577 data
= OOP_INST_DATA(cl
, o
);
582 planeoffset
= msg
->y
* data
->bitmap
->BytesPerRow
+ msg
->x
/ 8;
585 for (d
= 0; d
< data
->bitmap
->Depth
; d
++)
587 if (data
->bitmap
->Planes
[d
] == (UBYTE
*)-1)
589 prefill
|= (1L << d
);
593 for (y
= 0; y
< msg
->height
; y
++)
595 UBYTE
*dest
= pixarray
;
597 plane
= data
->bitmap
->Planes
;
598 for(x
= 0; x
< msg
->width
; x
++)
603 for (d
= 0; d
< data
->bitmap
->Depth
; d
++)
605 UWORD dmask
= 1L << d
;
606 UWORD pmask
= 0x80 >> (msg
->x
& 7);
609 if (pl
== (UBYTE
*)-1) continue;
610 if (pl
== NULL
) continue;
614 for (x
= 0; x
< msg
->width
; x
++)
635 } /* for(x = 0; x < msg->width; x++) */
639 } /* for(d = 0; d < data->depth; d++) */
641 pixarray
+= msg
->modulo
;
642 planeoffset
+= data
->bitmap
->BytesPerRow
;
644 } /* for(y = 0; y < msg->height; y++) */
648 /****************************************************************************************/
650 BOOL
PBM__Hidd_PlanarBM__SetBitMap(OOP_Class
*cl
, OOP_Object
*o
,
651 struct pHidd_PlanarBM_SetBitMap
*msg
)
653 return PBM_SetBitMap(cl
, o
, msg
->bitMap
);
656 /****************************************************************************************/
658 BOOL
PBM__Hidd_PlanarBM__GetBitMap(OOP_Class
*cl
, OOP_Object
*o
,
659 struct pHidd_PlanarBM_GetBitMap
*msg
)
661 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
667 * Totally obsolete and deprecated.
668 * Just get aoHidd_PlanarBM_BitMap value instead.
670 CopyMem(data
->bitmap
, msg
->bitMap
, sizeof(struct BitMap
));