2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Gfx Hidd planar bitmap class implementation.
9 /****************************************************************************************/
11 #include "gfx_debug.h"
13 #include <proto/exec.h>
14 #include <proto/utility.h>
15 #include <proto/oop.h>
17 #include <exec/memory.h>
18 #include <utility/tagitem.h>
19 #include <graphics/gfx.h>
26 #include "gfx_intern.h"
28 /*****************************************************************************************
31 --background_planarbm--
34 hidd.gfx.bitmap.planarbm
37 This is a class representing a planar Amiga(tm) bitmap in AROS graphics subsystem.
39 When you create an object of this class, an associated planar bitmap will be created.
40 However, it's possible to use this class with pre-existing bitmaps, making them
41 available to the Gfx Hidd subsystem.
43 *****************************************************************************************/
45 /*****************************************************************************************
48 aoHidd_PlanarBM_AllocPlanes
54 hidd.gfx.bitmap.planarbm
57 Set this attribute to FALSE if you want to create an empty bitmap object containing
58 no bitmap data. Useful if you want to create an empty object to be associated with
59 existing bitmap later.
62 This attribute is obsolete. It's equal to supplying aoHidd_PlanarBM_BitMap attribute
70 aoHidd_PlanarBM_BitMap
74 *****************************************************************************************/
76 /*****************************************************************************************
79 aoHidd_PlanarBM_BitMap
82 [ISG], struct BitMap *
85 hidd.gfx.bitmap.planarbm
88 Allows to specify or retrieve a raw planar bitmap structure associated with the object.
89 Useful for direct access to the bitmap within subclasses, as well as for associating
90 an object with already existing BitMap structure.
92 It is valid to pass this attribute with a NULL value. In this case the object becomes
93 empty and contains no actual bitmap.
96 If the object was created with own bitmap data (with no aoHidd_PlanarBM_BitMap specified
97 during creation), this data will be deallocated when you set this attribute.
99 It's up to you to deallocate own bitmaps, set using this attribute. Even if the object
100 is disposed, it won't deallocate user-supplied bitmap.
110 *****************************************************************************************/
112 OOP_Object
*PBM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
114 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
115 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
116 IPTR height
, bytesperrow
;
118 IPTR displayable
= FALSE
;
120 struct planarbm_data
*data
;
123 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
127 data
= OOP_INST_DATA(cl
, o
);
129 /* Check if we want to use existing bitmap */
131 tag
= FindTagItem(aHidd_PlanarBM_BitMap
, msg
->attrList
);
134 /* It's not our own bitmap */
135 data
->planes_alloced
= FALSE
;
136 /* Remember the bitmap. It can be NULL here. */
137 data
->bitmap
= (struct BitMap
*)tag
->ti_Data
;
139 /* That's all, we are attached to an existing BitMap */
144 /* Check obsolete attribute now */
145 data
->planes_alloced
= GetTagData(aHidd_PlanarBM_AllocPlanes
, TRUE
, msg
->attrList
);
147 if (!data
->planes_alloced
)
148 return o
; /* Late initialization */
151 /* By default we create 1-plane bitmap */
152 depth
= GetTagData(aHidd_BitMap_Depth
, 1, msg
->attrList
);
154 /* Not late initialization. Get some info on the bitmap */
155 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
156 OOP_GetAttr(o
, aHidd_BitMap_BytesPerRow
, &bytesperrow
);
157 OOP_GetAttr(o
, aHidd_BitMap_Displayable
, &displayable
);
159 data
->bitmap
= AllocMem(sizeof(struct BitMap
), MEMF_CLEAR
);
166 /* We cache some info */
167 data
->bitmap
->Rows
= height
;
168 data
->bitmap
->BytesPerRow
= bytesperrow
;
169 data
->bitmap
->Depth
= depth
;
170 data
->bitmap
->Flags
= BMF_STANDARD
|BMF_MINPLANES
; /* CHECKME */
172 data
->bitmap
->Flags
|= BMF_DISPLAYABLE
;
174 /* Allocate memory for all the planes. Use chip memory. */
175 for (i
= 0; i
< depth
; i
++)
177 data
->bitmap
->Planes
[i
] = AllocMem(height
* bytesperrow
, MEMF_CHIP
| MEMF_CLEAR
);
179 if (NULL
== data
->bitmap
->Planes
[i
])
189 OOP_MethodID dispose_mid
;
191 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
192 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
200 /****************************************************************************************/
202 static void PBM_FreeBitMap(struct planarbm_data
*data
)
204 if (data
->planes_alloced
)
206 if (NULL
!= data
->bitmap
)
210 for (i
= 0; i
< data
->bitmap
->Depth
; i
++)
212 if (data
->bitmap
->Planes
[i
])
214 FreeMem(data
->bitmap
->Planes
[i
], data
->bitmap
->Rows
* data
->bitmap
->BytesPerRow
);
217 FreeMem(data
->bitmap
, sizeof(struct BitMap
));
222 VOID
PBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
224 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
226 PBM_FreeBitMap(data
);
227 OOP_DoSuperMethod(cl
, o
, msg
);
230 /****************************************************************************************/
232 VOID
PBM__Root__Get(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Get
*msg
)
234 struct planarbm_data
*data
= OOP_INST_DATA(cl
, obj
);
236 if (msg
->attrID
== aHidd_BitMap_Depth
)
238 /* Planar bitmaps may have a variable depth. */
239 *msg
->storage
= data
->bitmap
? data
->bitmap
->Depth
: 0;
242 else if (msg
->attrID
== aHidd_PlanarBM_BitMap
)
244 *msg
->storage
= (IPTR
)data
->bitmap
;
248 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
251 /****************************************************************************************/
253 static BOOL
PBM_SetBitMap(OOP_Class
*cl
, OOP_Object
*o
, struct BitMap
*bm
)
255 struct TagItem pftags
[] =
257 { aHidd_PixFmt_Depth
, 0UL }, /* 0 */
258 { aHidd_PixFmt_BitsPerPixel
, 0UL }, /* 1 */
259 { aHidd_PixFmt_BytesPerPixel
, 1UL }, /* 2 */
260 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_Palette
}, /* 3 */
261 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Planar
}, /* 4 */
262 { aHidd_PixFmt_CLUTShift
, 0UL }, /* 5 */
263 { aHidd_PixFmt_CLUTMask
, 0x000000FF }, /* 6 */
264 { aHidd_PixFmt_RedMask
, 0x00FF0000 }, /* 7 */
265 { aHidd_PixFmt_GreenMask
, 0x0000FF00 }, /* 8 */
266 { aHidd_PixFmt_BlueMask
, 0x000000FF }, /* 9 */
267 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_Plane
},
270 struct TagItem bmtags
[] =
272 { aHidd_BitMap_Width
, 0 }, /* 0 */
273 { aHidd_BitMap_Height
, 0 }, /* 1 */
274 { aHidd_BitMap_BytesPerRow
, 0 }, /* 2 */
277 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
280 /* First we attempt to register a pixelformat */
281 pftags
[0].ti_Data
= bm
->Depth
; /* PixFmt_Depth */
282 pftags
[1].ti_Data
= bm
->Depth
; /* PixFmt_BitsPerPixel */
284 pf
= GFXHIDD__Hidd_Gfx__RegisterPixFmt(CSD(cl
)->gfxhiddclass
, pftags
);
288 /* Fail is pixelformat registration failed */
292 /* Free old bitmap, if it was ours. */
293 PBM_FreeBitMap(data
);
295 /* Set the new bitmap. It's not ours. */
297 data
->planes_alloced
= FALSE
;
299 /* Call private bitmap method to update superclass */
300 bmtags
[0].ti_Data
= bm
->BytesPerRow
* 8;
301 bmtags
[1].ti_Data
= bm
->Rows
;
302 bmtags
[2].ti_Data
= bm
->BytesPerRow
;
304 BM__Hidd_BitMap__SetBitMapTags(CSD(cl
)->bitmapclass
, o
, bmtags
);
305 BM__Hidd_BitMap__SetPixFmt(CSD(cl
)->bitmapclass
, o
, pf
);
310 VOID
PBM__Root__Set(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Set
*msg
)
312 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
313 struct TagItem
*tag
= FindTagItem(aHidd_PlanarBM_BitMap
, msg
->attrList
);
318 * TODO: We can't check for failure here. However, since we already
319 * have Depth attribute for the bitmap, may be we shouldn't register
320 * 8 pixelformats? In this case we are unable to fail.
322 PBM_SetBitMap(cl
, obj
, (struct BitMap
*)tag
->ti_Data
);
325 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
328 /****************************************************************************************/
330 VOID
PBM__Hidd_BitMap__PutPixel(OOP_Class
*cl
, OOP_Object
*o
,
331 struct pHidd_BitMap_PutPixel
*msg
)
334 struct planarbm_data
*data
;
337 UBYTE pixel
, notpixel
;
340 data
= OOP_INST_DATA(cl
, o
);
345 /* bitmap in plane-mode */
346 plane
= data
->bitmap
->Planes
;
347 offset
= msg
->x
/ 8 + msg
->y
* data
->bitmap
->BytesPerRow
;
348 pixel
= 128 >> (msg
->x
% 8);
352 for (i
= 0; i
< data
->bitmap
->Depth
; i
++, mask
<<=1, plane
++)
354 if ((*plane
!= NULL
) && (*plane
!= (UBYTE
*)-1))
356 if(msg
->pixel
& mask
)
358 *(*plane
+ offset
) = *(*plane
+ offset
) | pixel
;
362 *(*plane
+ offset
) = *(*plane
+ offset
) & notpixel
;
368 /****************************************************************************************/
370 ULONG
PBM__Hidd_BitMap__GetPixel(OOP_Class
*cl
, OOP_Object
*o
,
371 struct pHidd_BitMap_GetPixel
*msg
)
373 struct planarbm_data
*data
;
380 data
= OOP_INST_DATA(cl
, o
);
385 plane
= data
->bitmap
->Planes
;
386 offset
= msg
->x
/ 8 + msg
->y
* data
->bitmap
->BytesPerRow
;
387 pixel
= 128 >> (msg
->x
% 8);
390 for (i
= 0; i
< data
->bitmap
->Depth
; i
++, plane
++)
392 if (*plane
== (UBYTE
*)-1)
394 retval
= retval
| (1 << i
);
396 else if (*plane
!= NULL
)
398 if(*(*plane
+ offset
) & pixel
)
400 retval
= retval
| (1 << i
);
408 /****************************************************************************************/
411 * In fact these two routines are implementations of C2P algorighm. The first one takes chunky
412 * array of 8-bit values, the second one - 32-bit one.
414 static void PBM_PutImage_Native(UBYTE
*src
, ULONG modulo
, struct BitMap
*data
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
)
416 ULONG planeoffset
= starty
* data
->BytesPerRow
+ startx
/ 8;
421 for (y
= 0; y
< height
; y
++)
423 UBYTE
**plane
= data
->Planes
;
425 for (d
= 0; d
< data
->Depth
; d
++)
427 UWORD dmask
= 1L << d
;
428 UWORD pmask
= 0x80 >> startx
;
431 if (pl
== (UBYTE
*)-1) continue;
432 if (pl
== NULL
) continue;
436 for (x
= 0; x
< width
; x
++)
456 } /* for (x = 0; x < msg->width; x++) */
460 } /* for (d = 0; d < data->depth; d++) */
463 planeoffset
+= data
->BytesPerRow
;
464 } /* for (y = 0; y < msg->height; y++) */
467 static void PBM_PutImage_Native32(HIDDT_Pixel
*src
, ULONG modulo
, struct BitMap
*data
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
)
469 ULONG planeoffset
= starty
* data
->BytesPerRow
+ startx
/ 8;
474 for (y
= 0; y
< height
; y
++)
476 UBYTE
**plane
= data
->Planes
;
478 for (d
= 0; d
< data
->Depth
; d
++)
480 UWORD dmask
= 1L << d
;
481 UWORD pmask
= 0x80 >> startx
;
484 if (pl
== (UBYTE
*)-1) continue;
485 if (pl
== NULL
) continue;
489 for (x
= 0; x
< width
; x
++)
509 } /* for (x = 0; x < msg->width; x++) */
513 } /* for (d = 0; d < data->depth; d++) */
515 src
= ((APTR
)src
+ modulo
);
516 planeoffset
+= data
->BytesPerRow
;
517 } /* for (y = 0; y < msg->height; y++) */
520 VOID
PBM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
521 struct pHidd_BitMap_PutImage
*msg
)
523 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
528 if ((msg
->pixFmt
!= vHidd_StdPixFmt_Native
) &&
529 (msg
->pixFmt
!= vHidd_StdPixFmt_Native32
))
531 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
537 case vHidd_StdPixFmt_Native
:
538 PBM_PutImage_Native(msg
->pixels
, msg
->modulo
, data
->bitmap
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
541 case vHidd_StdPixFmt_Native32
:
542 PBM_PutImage_Native32((HIDDT_Pixel
*)msg
->pixels
, msg
->modulo
, data
->bitmap
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
548 /****************************************************************************************/
550 VOID
PBM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
551 struct pHidd_BitMap_PutImageLUT
*msg
)
553 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
558 /* This is the same as PutImage() with vHidd_StdPixFmt_Native format */
559 PBM_PutImage_Native(msg
->pixels
, msg
->modulo
, data
->bitmap
, msg
->x
, msg
->y
, msg
->width
, msg
->height
);
562 /****************************************************************************************/
564 VOID
PBM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
565 struct pHidd_BitMap_GetImageLUT
*msg
)
568 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
571 struct planarbm_data
*data
;
574 data
= OOP_INST_DATA(cl
, o
);
579 planeoffset
= msg
->y
* data
->bitmap
->BytesPerRow
+ msg
->x
/ 8;
582 for (d
= 0; d
< data
->bitmap
->Depth
; d
++)
584 if (data
->bitmap
->Planes
[d
] == (UBYTE
*)-1)
586 prefill
|= (1L << d
);
590 for (y
= 0; y
< msg
->height
; y
++)
592 UBYTE
*dest
= pixarray
;
594 plane
= data
->bitmap
->Planes
;
595 for(x
= 0; x
< msg
->width
; x
++)
600 for (d
= 0; d
< data
->bitmap
->Depth
; d
++)
602 UWORD dmask
= 1L << d
;
603 UWORD pmask
= 0x80 >> (msg
->x
& 7);
606 if (pl
== (UBYTE
*)-1) continue;
607 if (pl
== NULL
) continue;
611 for (x
= 0; x
< msg
->width
; x
++)
632 } /* for(x = 0; x < msg->width; x++) */
636 } /* for(d = 0; d < data->depth; d++) */
638 pixarray
+= msg
->modulo
;
639 planeoffset
+= data
->bitmap
->BytesPerRow
;
641 } /* for(y = 0; y < msg->height; y++) */
645 /****************************************************************************************/
647 BOOL
PBM__Hidd_PlanarBM__SetBitMap(OOP_Class
*cl
, OOP_Object
*o
,
648 struct pHidd_PlanarBM_SetBitMap
*msg
)
650 return PBM_SetBitMap(cl
, o
, msg
->bitMap
);
653 /****************************************************************************************/
655 BOOL
PBM__Hidd_PlanarBM__GetBitMap(OOP_Class
*cl
, OOP_Object
*o
,
656 struct pHidd_PlanarBM_GetBitMap
*msg
)
658 struct planarbm_data
*data
= OOP_INST_DATA(cl
, o
);
664 * Totally obsolete and deprecated.
665 * Just get aoHidd_PlanarBM_BitMap value instead.
667 CopyMem(data
->bitmap
, msg
->bitMap
, sizeof(struct BitMap
));