2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Gfx chunky 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>
23 #include "gfx_intern.h"
27 /****************************************************************************************/
29 OOP_Object
*CBM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
31 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
32 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
33 struct chunkybm_data
*data
;
35 IPTR bytesperrow
, bytesperpixel
;
37 OOP_MethodID dispose_mid
;
39 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
43 /* Initialize the instance data to 0 */
44 data
= OOP_INST_DATA(cl
, o
);
45 memset(data
, 0, sizeof (*data
));
47 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&pf
);
48 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (APTR
)&data
->gfxhidd
);
49 /* Get some dimensions of the bitmap */
50 OOP_GetAttr(o
, aHidd_BitMap_BytesPerRow
, &bytesperrow
);
51 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
53 data
->bytesperpixel
= bytesperpixel
;
54 data
->bytesperrow
= bytesperrow
;
56 tag
= FindTagItem(aHidd_ChunkyBM_Buffer
, msg
->attrList
);
60 * NULL user-supplied buffer is valid.
61 * In this case we create a bitmap with no buffer. We can attach it later.
63 data
->own_buffer
= FALSE
;
64 data
->buffer
= (APTR
)tag
->ti_Data
;
72 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
74 data
->own_buffer
= TRUE
;
75 data
->buffer
= AllocVec(height
* bytesperrow
, MEMF_ANY
| MEMF_CLEAR
);
81 /* free all on error */
82 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
84 OOP_CoerceMethod(cl
, o
, (OOP_Msg
)&dispose_mid
);
88 /****************************************************************************************/
90 void CBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
92 struct chunkybm_data
*data
;
94 data
= OOP_INST_DATA(cl
, o
);
97 FreeVec(data
->buffer
);
99 OOP_DoSuperMethod(cl
, o
, msg
);
104 /****************************************************************************************/
106 VOID
CBM__Hidd_BitMap__PutPixel(OOP_Class
*cl
, OOP_Object
*o
,
107 struct pHidd_BitMap_PutPixel
*msg
)
111 struct chunkybm_data
*data
;
113 data
= OOP_INST_DATA(cl
, o
);
115 /* bitmap in chunky-mode */
116 dest
= data
->buffer
+ msg
->x
* data
->bytesperpixel
+ msg
->y
* data
->bytesperrow
;
118 switch(data
->bytesperpixel
)
121 *((UBYTE
*) dest
) = (UBYTE
) msg
->pixel
;
125 *((UWORD
*) dest
) = (UWORD
) msg
->pixel
;
130 dest
[0] = (UBYTE
)(msg
->pixel
>> 16) & 0x000000FF;
131 dest
[1] = (UBYTE
)(msg
->pixel
>> 8) & 0x000000FF;
132 dest
[2] = (UBYTE
)msg
->pixel
& 0x000000FF;
134 dest
[0] = (UBYTE
)msg
->pixel
& 0x000000FF;
135 dest
[1] = (UBYTE
)(msg
->pixel
>> 8) & 0x000000FF;
136 dest
[2] = (UBYTE
)(msg
->pixel
>> 16) & 0x000000FF;
140 /* if (1 == ( ((IPTR)dest) & 1) )
142 *((UBYTE *) dest++) = (UBYTE) msg->pixel >> 16;
143 *((UWORD *) dest ) = (UWORD) msg->pixel;
147 *((UWORD *) dest++) = (UWORD) msg->pixel >> 8;
148 *((UBYTE *) dest ) = (UBYTE) msg->pixel;
153 *((ULONG
*) dest
) = (ULONG
) msg
->pixel
;
159 /****************************************************************************************/
161 ULONG
CBM__Hidd_BitMap__GetPixel(OOP_Class
*cl
, OOP_Object
*o
,
162 struct pHidd_BitMap_GetPixel
*msg
)
164 HIDDT_Pixel retval
= 0;
166 struct chunkybm_data
*data
;
168 data
= OOP_INST_DATA(cl
, o
);
170 src
= data
->buffer
+ msg
->x
* data
->bytesperpixel
+ msg
->y
* data
->bytesperrow
;
172 switch(data
->bytesperpixel
)
175 retval
= (HIDDT_Pixel
) *((UBYTE
*) src
);
179 retval
= (HIDDT_Pixel
) *((UWORD
*) src
);
184 retval
= (HIDDT_Pixel
) (src
[0] << 16) + (src
[1] << 8) + src
[2];
186 retval
= (HIDDT_Pixel
) (src
[2] << 16) + (src
[1] << 8) + src
[0];
190 //(*((UBYTE *) src++) << 16) | *((UWORD *) src));
194 retval
= ((ULONG
) *((ULONG
*) src
));
201 /****************************************************************************************/
203 VOID
CBM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_DrawRect
*msg
)
205 struct chunkybm_data
*data
=OOP_INST_DATA(cl
, o
);
206 HIDDT_Pixel fg
= GC_FG(msg
->gc
);
207 HIDDT_DrawMode mode
= GC_DRMD(msg
->gc
);
210 mod
= data
->bytesperrow
;
214 case vHidd_GC_DrawMode_Copy
:
215 switch(data
->bytesperpixel
)
218 HIDD_BM_FillMemRect8(o
,
229 HIDD_BM_FillMemRect16(o
,
240 HIDD_BM_FillMemRect24(o
,
251 HIDD_BM_FillMemRect32(o
,
264 case vHidd_GC_DrawMode_Invert
:
265 HIDD_BM_InvertMemRect(o
,
267 msg
->minX
* data
->bytesperpixel
,
269 msg
->maxX
* data
->bytesperpixel
+ data
->bytesperpixel
- 1,
275 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
282 /****************************************************************************************/
284 VOID
CBM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImage
*msg
)
286 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
287 APTR dst_pixels
, src_pixels
;
292 case vHidd_StdPixFmt_Native
:
293 switch(data
->bytesperpixel
)
296 HIDD_BM_CopyMemBox8(o
,
310 HIDD_BM_CopyMemBox16(o
,
324 HIDD_BM_CopyMemBox24(o
,
338 HIDD_BM_CopyMemBox32(o
,
351 } /* switch(data->bytesperpixel) */
354 case vHidd_StdPixFmt_Native32
:
355 switch(data
->bytesperpixel
)
358 HIDD_BM_PutMem32Image8(o
,
370 HIDD_BM_PutMem32Image16(o
,
382 HIDD_BM_PutMem32Image24(o
,
394 HIDD_BM_CopyMemBox32(o
,
407 } /* switch(data->bytesperpixel) */
411 src_pixels
= msg
->pixels
;
412 dst_pixels
= data
->buffer
+ msg
->y
* data
->bytesperrow
413 + msg
->x
* data
->bytesperpixel
;
414 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
416 HIDD_BM_ConvertPixels(o
, &src_pixels
,
417 (HIDDT_PixelFormat
*)srcpf
, msg
->modulo
, &dst_pixels
,
418 BM_PIXFMT(o
), data
->bytesperrow
, msg
->width
, msg
->height
,
421 } /* switch(msg->pixFmt) */
425 /**************************************************************************/
428 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
431 return (tmp
+ (tmp
>> 8) + 0x80) >> 8;
434 VOID
CBM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
435 struct pHidd_BitMap_PutAlphaImage
*msg
)
437 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
438 HIDDT_StdPixFmt pixFmt
= BM_PIXFMT(o
)->stdpixfmt
;
439 WORD x
, y
, src_step
, dst_step
;
441 UBYTE src_red
, src_green
, src_blue
, src_alpha
;
442 UBYTE dst_red
, dst_green
, dst_blue
;
446 case vHidd_StdPixFmt_BGR032
:
449 q
= data
->buffer
+ msg
->y
* data
->bytesperrow
450 + msg
->x
* data
->bytesperpixel
;
451 src_step
= msg
->modulo
- msg
->width
* 4;
452 dst_step
= data
->bytesperrow
- data
->bytesperpixel
* msg
->width
;
454 for(y
= 0; y
< msg
->height
; y
++)
456 for(x
= 0; x
< msg
->width
; x
++)
478 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
482 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
486 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
497 case vHidd_StdPixFmt_RGB16_LE
:
500 q
= data
->buffer
+ msg
->y
* data
->bytesperrow
501 + msg
->x
* data
->bytesperpixel
;
502 src_step
= msg
->modulo
- msg
->width
* 4;
503 dst_step
= data
->bytesperrow
- data
->bytesperpixel
* msg
->width
;
505 for(y
= 0; y
< msg
->height
; y
++)
507 for(x
= 0; x
< msg
->width
; x
++)
521 *q
++ = (src_green
<< 3) & 0xe0 | src_blue
>> 3;
522 *q
++ = src_red
& 0xf8 | src_green
>> 5;
528 dst_green
= dst_red
<< 5 | dst_blue
>> 3 & 0x1c;
532 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
533 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
534 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
536 *q
++ = (dst_green
<< 3) & 0xe0 | dst_blue
>> 3;
537 *q
++ = dst_red
& 0xf8 | dst_green
>> 5;
546 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
551 /****************************************************************************************/
553 VOID
CBM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_GetImage
*msg
)
555 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
556 APTR src_pixels
, dst_pixels
;
561 case vHidd_StdPixFmt_Native
:
562 switch(data
->bytesperpixel
)
565 HIDD_BM_CopyMemBox8(o
,
579 HIDD_BM_CopyMemBox16(o
,
593 HIDD_BM_CopyMemBox24(o
,
607 HIDD_BM_CopyMemBox32(o
,
620 } /* switch(data->bytesperpix) */
623 case vHidd_StdPixFmt_Native32
:
624 switch(data
->bytesperpixel
)
627 HIDD_BM_GetMem32Image8(o
,
639 HIDD_BM_GetMem32Image16(o
,
651 HIDD_BM_GetMem32Image24(o
,
663 HIDD_BM_CopyMemBox32(o
,
676 } /* switch(data->bytesperpixel) */
680 src_pixels
= data
->buffer
+ msg
->y
* data
->bytesperrow
681 + msg
->x
* data
->bytesperpixel
;
682 dst_pixels
= msg
->pixels
;
683 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
685 HIDD_BM_ConvertPixels(o
, &src_pixels
, BM_PIXFMT(o
),
686 data
->bytesperrow
, &dst_pixels
, (HIDDT_PixelFormat
*)dstpf
,
687 msg
->modulo
, msg
->width
, msg
->height
, NULL
);
689 } /* switch(msg->pixFmt) */
693 /****************************************************************************************/
695 VOID
CBM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutImageLUT
*msg
)
697 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
699 switch(data
->bytesperpixel
)
702 HIDD_BM_CopyLUTMemBox16(o
,
717 HIDD_BM_CopyLUTMemBox24(o
,
732 HIDD_BM_CopyLUTMemBox32(o
,
747 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
749 } /* switch(data->bytesperpixel) */
753 /****************************************************************************************/
755 VOID
CBM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
757 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
759 switch(data
->bytesperpixel
)
762 HIDD_BM_PutMemTemplate8(o
,
773 msg
->inverttemplate
);
777 HIDD_BM_PutMemTemplate16(o
,
788 msg
->inverttemplate
);
792 HIDD_BM_PutMemTemplate24(o
,
803 msg
->inverttemplate
);
807 HIDD_BM_PutMemTemplate32(o
,
818 msg
->inverttemplate
);
822 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
825 } /* switch(data->bytesperpixel) */
829 /****************************************************************************************/
831 VOID
CBM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPattern
*msg
)
833 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
835 switch(data
->bytesperpixel
)
838 HIDD_BM_PutMemPattern8(o
,
859 HIDD_BM_PutMemPattern16(o
,
880 HIDD_BM_PutMemPattern24(o
,
901 HIDD_BM_PutMemPattern32(o
,
922 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
925 } /* switch(data->bytesperpixel) */
929 /****************************************************************************************/
931 BOOL
CBM__Hidd_BitMap__ObtainDirectAccess(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_ObtainDirectAccess
*msg
)
933 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
934 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
938 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
939 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
941 *msg
->addressReturn
= data
->buffer
;
942 *msg
->widthReturn
= width
;
943 *msg
->heightReturn
= height
;
944 *msg
->bankSizeReturn
= *msg
->memSizeReturn
= data
->bytesperrow
* height
;
949 /****************************************************************************************/
951 VOID
CBM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_ReleaseDirectAccess
*msg
)
955 /****************************************************************************************/
957 VOID
CBM__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
959 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
962 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
964 if (IS_CHUNKYBM_ATTR(msg
->attrID
, idx
))
968 case aoHidd_ChunkyBM_Buffer
:
969 *msg
->storage
= (IPTR
)data
->buffer
;
974 OOP_DoSuperMethod(cl
, o
, &msg
->mID
);
977 /****************************************************************************************/
979 VOID
CBM__Root__Set(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
981 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
982 struct chunkybm_data
*data
= OOP_INST_DATA(cl
, o
);
983 struct TagItem
*tag
, *tstate
;
986 tstate
= msg
->attrList
;
987 while((tag
= NextTagItem(&tstate
)))
989 if(IS_CHUNKYBM_ATTR(tag
->ti_Tag
, idx
))
993 case aoHidd_ChunkyBM_Buffer
:
994 if (data
->own_buffer
)
996 FreeVec(data
->buffer
);
997 data
->own_buffer
= FALSE
;
999 data
->buffer
= (UBYTE
*)tag
->ti_Data
;
1000 D(bug("[CBM] New buffer now 0x%p\n", data
->buffer
));
1006 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);