5 #include <exec/types.h>
6 #include <graphics/gels.h>
7 #include <graphics/rastport.h>
8 #include <graphics/scale.h>
9 #include <cybergraphx/cybergraphics.h>
10 #include <scalos/scalosgfx.h>
14 #include <proto/dos.h>
15 #include <proto/exec.h>
16 #include <proto/graphics.h>
17 #include <proto/utility.h>
18 #include <proto/cybergraphics.h>
19 #include <proto/scalos.h>
20 #include <proto/layers.h>
22 #include <clib/alib_protos.h>
31 #include "scalosgfx.h"
33 //-----------------------------------------------------------------------
35 //-----------------------------------------------------------------------
37 static ULONG
FindBestPen(const ULONG
*ColorTable
, ULONG NumColors
, ULONG Red
, ULONG Green
, LONG Blue
);
38 static long GetColorDistance(const ULONG
*ColorTableEntry
, ULONG Red
, ULONG Green
, ULONG Blue
);
40 //-----------------------------------------------------------------------
42 void ARGBSetAlpha(struct ARGB
*argb
, ULONG Width
, ULONG Height
, UBYTE Alpha
)
46 d1(KPrintF("%s/%ld: argb=%08lx Width=%lu Height=%lu Alpha=%lu\n", \
47 __FUNC__
, __LINE__
, argb
, Width
, Height
, Alpha
));
49 for (y
= 0; y
< Height
; y
++)
53 for (x
= 0; x
< Width
; x
++)
61 //-----------------------------------------------------------------------
63 void ARGBSetAlphaFromMask(struct ARGBHeader
*argbh
, PLANEPTR MaskPlane
)
66 ULONG MaskBytesPerRow
= ((argbh
->argb_Width
+ 15) & ~0x0f) / 8;
67 struct ARGB
*pargb
= argbh
->argb_ImageData
;
69 for (y
= 0; y
< argbh
->argb_Height
; y
++)
73 UWORD BitMask
= 0x0080;
74 const UBYTE
*MaskPtr2
= MaskPlane
;
76 for (x
= 0; x
< argbh
->argb_Width
; x
++, pargb
++)
78 if (*MaskPtr2
& BitMask
)
91 MaskPlane
+= MaskBytesPerRow
;
95 //-----------------------------------------------------------------------
97 struct ARGB
*CreateARGBFromBitMap(struct BitMap
*bm
,
98 ULONG Width
, ULONG Height
,
99 ULONG NumberOfColors
, const ULONG
*ColorTable
, PLANEPTR MaskPlane
,
100 struct ScalosGfxBase
*ScalosGfxBase
)
103 UBYTE
*LineArray
= NULL
;
104 struct BitMap
*TempBM
= NULL
;
109 ULONG MaskBytesPerRow
= ((Width
+ 15) & ~0x0f) / 8;
111 d1(KPrintF("%s/%ld: MaskPlane=%08lx MaskBytesPerRow=%lu\n", __FUNC__
, __LINE__
, MaskPlane
, MaskBytesPerRow
));
113 argb
= AllocARGB(Width
, Height
, ScalosGfxBase
);
117 Depth
= GetBitMapAttr(bm
, BMA_DEPTH
);
122 if (Depth
<= 8 || (NULL
== CyberGfxBase
))
124 struct RastPort TempRp
;
126 struct ARGB
*pargb
= argb
;
127 size_t ArraySize
= (((Width
+ 15) >> 4) << 4);
129 LineArray
= ScalosGfxAllocVecPooled(ScalosGfxBase
, ArraySize
);
130 if (NULL
== LineArray
)
133 InitRastPort(&TempRp
);
136 TempRp
.BitMap
= TempBM
= AllocBitMap(TEMPRP_WIDTH(Width
), 1, 8, 0, NULL
);
140 for (y
= 0; y
< Height
; y
++)
143 UBYTE
*pLine
= LineArray
;
153 UWORD BitMask
= 0x0080;
154 const UBYTE
*MaskPtr2
= MaskPlane
;
156 for (x
= 0; x
< Width
; x
++, pargb
++)
158 UBYTE col
= *pLine
++;
159 const ULONG
*ColorReg
= ColorTable
+ 3 * col
;
161 pargb
->Red
= ColorReg
[0] >> 24;
162 pargb
->Green
= ColorReg
[1] >> 24;
163 pargb
->Blue
= ColorReg
[2] >> 24;
165 if (*MaskPtr2
& BitMask
)
178 MaskPlane
+= MaskBytesPerRow
;
182 for (x
= 0; x
< Width
; x
++, pargb
++)
184 UBYTE col
= *pLine
++;
185 const ULONG
*ColorReg
= ColorTable
+ 3 * col
;
188 pargb
->Red
= ColorReg
[0] >> 24;
189 pargb
->Green
= ColorReg
[1] >> 24;
190 pargb
->Blue
= ColorReg
[2] >> 24;
197 ReadPixelArray(argb
, 0, 0,
198 Width
* sizeof(struct ARGB
),
204 struct ARGBHeader argbh
;
206 argbh
.argb_Width
= Width
;
207 argbh
.argb_Height
= Height
;
208 argbh
.argb_ImageData
= argb
;
210 d1(KPrintF("%s/%ld: MaskPlane=%08lx\n", __FUNC__
, __LINE__
, MaskPlane
));
212 ARGBSetAlphaFromMask(&argbh
, MaskPlane
);
216 ARGBSetAlpha(argb
, Width
, Height
, (UBYTE
) ~0);
224 ScalosGfxFreeVecPooled(ScalosGfxBase
, LineArray
);
229 //-----------------------------------------------------------------------
231 void WriteARGBToBitMap(struct ARGB
*argb
, struct BitMap
*bm
,
232 ULONG Width
, ULONG Height
,
233 ULONG NumberOfColors
, const ULONG
*ColorTable
,
234 struct ScalosGfxBase
*ScalosGfxBase
)
238 UBYTE
*LineArray
= NULL
;
239 struct BitMap
*TempBM
= NULL
;
245 Depth
= GetBitMapAttr(bm
, BMA_DEPTH
);
247 d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%ld\n", __FUNC__
, __LINE__
, Width
, Height
));
249 if ((NULL
== CyberGfxBase
) || (Depth
<= 8) || !GetCyberMapAttr(bm
, CYBRMATTR_ISCYBERGFX
))
251 struct RastPort TempRp
;
253 struct ARGB
*pargb
= argb
;
254 size_t ArraySize
= (((Width
+ 15) >> 4) << 4);
256 d1(KPrintF("%s/%ld: DestWidth=%lu DestHeight=%ld\n", __FUNC__
, __LINE__
, Width
, Height
));
258 LineArray
= ScalosGfxAllocVecPooled(ScalosGfxBase
, ArraySize
);
259 if (NULL
== LineArray
)
262 InitRastPort(&TempRp
);
265 TempRp
.BitMap
= TempBM
= AllocBitMap(TEMPRP_WIDTH(Width
), 1, 8, 0, NULL
);
269 for (y
= 0; y
< Height
; y
++)
272 UBYTE
*pLine
= LineArray
;
274 for (x
= 0; x
< Width
; x
++)
276 *pLine
++ = FindBestPen(ColorTable
, NumberOfColors
,
292 WritePixelArray(argb
, 0, 0,
293 Width
* sizeof(struct ARGB
),
303 ScalosGfxFreeVecPooled(ScalosGfxBase
, LineArray
);
306 //-----------------------------------------------------------------------
308 void FreeARGB(struct ARGB
**argb
, struct ScalosGfxBase
*ScalosGfxBase
)
313 d1(KPrintF("%s/%ld: argb=%08lx\n", __FUNC__
, __LINE__
, *argb
));
314 ScalosGfxFreeVecPooled(ScalosGfxBase
, *argb
);
319 //-----------------------------------------------------------------------
321 struct ARGB
*AllocARGB(ULONG Width
, ULONG Height
, struct ScalosGfxBase
*ScalosGfxBase
)
325 if (0 == Width
|| 0 == Height
)
328 argb
= ScalosGfxAllocVecPooled(ScalosGfxBase
, Width
* Height
* sizeof(struct ARGB
));
329 d1(KPrintF("%s/%ld: ARGB=%08lx Width=%lu Height=%ld\n", __FUNC__
, __LINE__
, argb
, Width
, Height
));
334 //-----------------------------------------------------------------------
336 void FillARGBFromBitMap(struct ARGBHeader
*argbh
, struct BitMap
*srcBM
,
346 if ((NULL
== CyberGfxBase
) || !GetCyberMapAttr(srcBM
, CYBRMATTR_ISCYBERGFX
))
349 d1(KPrintF("%s/%ld: Width=%ld Height=%ld\n", __FUNC__
, __LINE__
, argbh
->argb_Width
, argbh
->argb_Height
));
351 handle
= LockBitMapTags(srcBM
,
352 LBMI_PIXFMT
, (ULONG
) &PixFmt
,
353 LBMI_BASEADDRESS
, (ULONG
) &src
,
354 LBMI_BYTESPERROW
, (ULONG
) &BytesPerRow
,
355 LBMI_BYTESPERPIX
, (ULONG
) &BytesPerPixel
,
358 d1(KPrintF(__FILE__
"/%s/%ld: handle=%08lx\n", __FUNC__
, __LINE__
, handle
));
363 d1(KPrintF("%s/%ld: src=%08lx\n", __FUNC__
, __LINE__
, src
));
364 d1(KPrintF("%s/%ld: PixFmt=%ld BytesPerRow=%ld\n", __FUNC__
, __LINE__
, PixFmt
, BytesPerRow
));
366 dest
= argbh
->argb_ImageData
;
371 for (y
= 0; y
< argbh
->argb_Height
; y
++)
374 const UBYTE
*srcPtr
= src
;
376 for (x
= 0; x
< argbh
->argb_Width
; x
++)
378 dest
->Blue
= srcPtr
[0];
379 dest
->Green
= srcPtr
[1];
380 dest
->Red
= srcPtr
[2];
381 dest
->Alpha
= (UBYTE
) ~0;
384 srcPtr
+= BytesPerPixel
;
391 for (y
= 0; y
< argbh
->argb_Height
; y
++)
394 const UBYTE
*srcPtr
= src
;
396 for (x
= 0; x
< argbh
->argb_Width
; x
++)
398 dest
->Blue
= srcPtr
[0];
399 dest
->Green
= srcPtr
[1];
400 dest
->Red
= srcPtr
[2];
401 dest
->Alpha
= srcPtr
[3];
404 srcPtr
+= BytesPerPixel
;
412 for (y
= 0; y
< argbh
->argb_Height
; y
++)
415 const UBYTE
*srcPtr
= src
;
417 for (x
= 0; x
< argbh
->argb_Width
; x
++)
419 dest
->Red
= srcPtr
[0];
420 dest
->Green
= srcPtr
[1];
421 dest
->Blue
= srcPtr
[2];
422 dest
->Alpha
= (UBYTE
) ~0;
425 srcPtr
+= BytesPerPixel
;
432 for (y
= 0; y
< argbh
->argb_Height
; y
++)
435 const UBYTE
*srcPtr
= src
;
437 for (x
= 0; x
< argbh
->argb_Width
; x
++)
439 dest
->Red
= srcPtr
[0];
440 dest
->Green
= srcPtr
[1];
441 dest
->Blue
= srcPtr
[2];
442 dest
->Alpha
= srcPtr
[3];
445 srcPtr
+= BytesPerPixel
;
453 for (y
= 0; y
< argbh
->argb_Height
; y
++)
456 const UBYTE
*srcPtr
= src
;
458 for (x
= 0; x
< argbh
->argb_Width
; x
++)
460 dest
->Red
= srcPtr
[1];
461 dest
->Green
= srcPtr
[2];
462 dest
->Blue
= srcPtr
[3];
463 dest
->Alpha
= srcPtr
[0];
466 srcPtr
+= BytesPerPixel
;
474 for (y
= 0; y
< argbh
->argb_Height
; y
++)
477 const UWORD
*srcPtr
= (UWORD
*) src
;
479 for (x
= 0; x
< argbh
->argb_Width
; x
++)
481 dest
->Red
= GET_RED_RGB16(srcPtr
);
482 dest
->Green
= GET_GREEN_RGB16(srcPtr
);
483 dest
->Blue
= GET_BLUE_RGB16(srcPtr
);
484 dest
->Alpha
= (UBYTE
) ~0;
495 for (y
= 0; y
< argbh
->argb_Height
; y
++)
498 const UWORD
*srcPtr
= (UWORD
*) src
;
500 for (x
= 0; x
< argbh
->argb_Width
; x
++)
502 dest
->Red
= GET_RED_BGR16(srcPtr
);
503 dest
->Green
= GET_GREEN_BGR16(srcPtr
);
504 dest
->Blue
= GET_BLUE_BGR16(srcPtr
);
505 dest
->Alpha
= (UBYTE
) ~0;
515 for (y
= 0; y
< argbh
->argb_Height
; y
++)
518 const UWORD
*srcPtr
= (UWORD
*) src
;
520 for (x
= 0; x
< argbh
->argb_Width
; x
++)
522 dest
->Red
= GET_RED_RGB15(srcPtr
);
523 dest
->Green
= GET_GREEN_RGB15(srcPtr
);
524 dest
->Blue
= GET_BLUE_RGB15(srcPtr
);
525 dest
->Alpha
= (UBYTE
) ~0;
535 for (y
= 0; y
< argbh
->argb_Height
; y
++)
538 const UWORD
*srcPtr
= (UWORD
*) src
;
540 for (x
= 0; x
< argbh
->argb_Width
; x
++)
542 dest
->Red
= GET_RED_BGR15(srcPtr
);
543 dest
->Green
= GET_GREEN_BGR15(srcPtr
);
544 dest
->Blue
= GET_BLUE_BGR15(srcPtr
);
545 dest
->Alpha
= (UBYTE
) ~0;
555 for (y
= 0; y
< argbh
->argb_Height
; y
++)
558 const UWORD
*srcPtr
= (UWORD
*) src
;
560 for (x
= 0; x
< argbh
->argb_Width
; x
++)
562 dest
->Red
= GET_RED_RGB16PC(srcPtr
);
563 dest
->Green
= GET_GREEN_RGB16PC(srcPtr
);
564 dest
->Blue
= GET_BLUE_RGB16PC(srcPtr
);
565 dest
->Alpha
= (UBYTE
) ~0;
575 for (y
= 0; y
< argbh
->argb_Height
; y
++)
578 const UWORD
*srcPtr
= (UWORD
*) src
;
580 for (x
= 0; x
< argbh
->argb_Width
; x
++)
582 dest
->Red
= GET_RED_BGR16PC(srcPtr
);
583 dest
->Green
= GET_GREEN_BGR16PC(srcPtr
);
584 dest
->Blue
= GET_BLUE_BGR16PC(srcPtr
);
585 dest
->Alpha
= (UBYTE
) ~0;
595 for (y
= 0; y
< argbh
->argb_Height
; y
++)
598 const UWORD
*srcPtr
= (UWORD
*) src
;
600 for (x
= 0; x
< argbh
->argb_Width
; x
++)
602 dest
->Red
= GET_RED_RGB15PC(srcPtr
);
603 dest
->Green
= GET_GREEN_RGB15PC(srcPtr
);
604 dest
->Blue
= GET_BLUE_RGB15PC(srcPtr
);
605 dest
->Alpha
= (UBYTE
) ~0;
615 d1(KPrintF("%s/%ld: src=%08lx\n", __FUNC__
, __LINE__
, src
));
617 dest
= argbh
->argb_ImageData
;
619 for (y
= 0; y
< argbh
->argb_Height
; y
++)
622 const UWORD
*srcPtr
= (UWORD
*) src
;
624 for (x
= 0; x
< argbh
->argb_Width
; x
++)
626 dest
->Red
= GET_RED_BGR15PC(srcPtr
);
627 dest
->Green
= GET_GREEN_BGR15PC(srcPtr
);
628 dest
->Blue
= GET_BLUE_BGR15PC(srcPtr
);
629 dest
->Alpha
= (UBYTE
) ~0;
642 UnLockBitMap(handle
);
644 ARGBSetAlphaFromMask(argbh
, MaskPlane
);
648 kprintf(__FILE__
"/%s/%ld: Can't lock bitmap\n", __FUNC__
, __LINE__
);
652 //-----------------------------------------------------------------------
654 static ULONG
FindBestPen(const ULONG
*ColorTable
, ULONG NumColors
, ULONG Red
, ULONG Green
, LONG Blue
)
657 long BestDistance
= LONG_MAX
;
660 for (n
= 0; n
< NumColors
; n
++)
662 long ColorDistance
= GetColorDistance(ColorTable
, Red
, Green
, Blue
);
664 d1(KPrintF("%s/%ld: R=%08lx G=%08lx b=%08lx Best=%ld Dist=%ld\n", \
665 __LINE__
, ColorTable
[0], ColorTable
[1], ColorTable
[2], BestDistance
, ColorDistance
));
667 if (ColorDistance
< BestDistance
)
669 BestDistance
= ColorDistance
;
676 d1(KPrintF("%s/%ld: R=%08lx G=%08lx B=%08lx NumColors=%lu BestPen=%lu\n", \
677 __LINE__
, Red
, Green
, Blue
, NumColors
, BestPen
));
682 //-----------------------------------------------------------------------
684 static long GetColorDistance(const ULONG
*ColorTableEntry
, ULONG Red
, ULONG Green
, ULONG Blue
)
686 LONG dRed
,dGreen
,dBlue
;
688 dRed
= (LONG
) (Red
>> 24) - (LONG
) (ColorTableEntry
[0] >> 24);
689 dGreen
= (LONG
) (Green
>> 24) - (LONG
) (ColorTableEntry
[1] >> 24);
690 dBlue
= (LONG
) (Blue
>> 24) - (LONG
) (ColorTableEntry
[2] >> 24);
692 return dRed
* dRed
+ dGreen
* dGreen
+dBlue
* dBlue
;
695 //-----------------------------------------------------------------------
697 struct ScalosBitMapAndColor
*AllocEmptySAC(struct ScalosGfxBase
*ScalosGfxBase
)
699 struct ScalosBitMapAndColor
*sac
;
701 sac
= ScalosGfxAllocVecPooled(ScalosGfxBase
, sizeof(struct ScalosBitMapAndColor
));
703 memset(sac
, 0, sizeof(struct ScalosBitMapAndColor
));
705 d1(KPrintF(__FILE__
"/%s/%ld: END sac=%08lx\n", __FUNC__
, __LINE__
, sac
));
710 //-----------------------------------------------------------------------
712 struct ScalosBitMapAndColor
*AllocSAC(ULONG Width
, ULONG Height
, ULONG Depth
,
713 struct BitMap
*FriendBM
, struct TagItem
*TagList
,
714 struct ScalosGfxBase
*ScalosGfxBase
)
716 struct ScalosBitMapAndColor
*sac
= NULL
;
717 BOOL Success
= FALSE
;
721 d1(KPrintF(__FILE__
"/%s/%ld: START Width=%lu Heioght=%lu Depth=%lu FriendBM=%08lx\n", \
722 __FUNC__
, __LINE__
, Width
, Height
, Depth
, FriendBM
));
725 if (Depth
< 1 || Depth
> 8)
727 if (Width
< 1 || Height
< 1)
730 sac
= AllocEmptySAC(ScalosGfxBase
);
734 sac
->sac_Width
= Width
;
735 sac
->sac_Height
= Height
;
736 sac
->sac_Depth
= Depth
;
738 sac
->sac_BitMap
= AllocBitMap(Width
, Height
, 8, BMF_CLEAR
, FriendBM
);
739 d1(KPrintF(__FILE__
"/%s/%ld: sac_BitMap=%08lx\n", __FUNC__
, __LINE__
, sac
->sac_BitMap
));
740 if (NULL
== sac
->sac_BitMap
)
743 sac
->sac_NumColors
= 1 << Depth
;
745 sac
->sac_ColorTable
= ScalosGfxAllocVecPooled(ScalosGfxBase
, SAC_COLORTABLESIZE(sac
));
746 d1(KPrintF(__FILE__
"/%s/%ld: sac_ColorTable=%08lx\n", __FUNC__
, __LINE__
, sac
->sac_ColorTable
));
747 if (NULL
== sac
->sac_ColorTable
)
755 FreeSAC(sac
, ScalosGfxBase
);
759 d1(KPrintF(__FILE__
"/%s/%ld: END sac=%08lx\n", __FUNC__
, __LINE__
, sac
));
763 //-----------------------------------------------------------------------
765 void FreeSAC(struct ScalosBitMapAndColor
*sac
, struct ScalosGfxBase
*ScalosGfxBase
)
767 d1(KPrintF(__FILE__
"/%s/%ld: START sac=%08lx\n", __FUNC__
, __LINE__
, sac
));
770 d1(KPrintF(__FILE__
"/%s/%ld: sac_ColorTable=%08lx\n", __FUNC__
, __LINE__
, sac
->sac_ColorTable
));
771 if (sac
->sac_ColorTable
)
773 if (!(sac
->sac_Flags
& SACFLAGF_NO_FREE_COLORTABLE
))
774 ScalosGfxFreeVecPooled(ScalosGfxBase
, sac
->sac_ColorTable
);
775 sac
->sac_ColorTable
= NULL
;
777 d1(KPrintF(__FILE__
"/%s/%ld: sac_Flags=%08lx sac_BitMap=%08lx\n", __FUNC__
, __LINE__
, sac
->sac_Flags
, sac
->sac_BitMap
));
780 if (!(sac
->sac_Flags
& SACFLAGF_NO_FREE_BITMAP
))
781 FreeBitMap(sac
->sac_BitMap
);
782 sac
->sac_BitMap
= NULL
;
784 ScalosGfxFreeVecPooled(ScalosGfxBase
, sac
);
786 d1(KPrintF(__FILE__
"/%s/%ld: END\n", __FUNC__
, __LINE__
));
789 //-----------------------------------------------------------------------
791 void BlitARGB(struct ARGBHeader
*DestARGB
, const struct ARGBHeader
*SrcARGB
,
792 LONG DestLeft
, LONG DestTop
, LONG SrcLeft
, LONG SrcTop
,
793 LONG Width
, LONG Height
)
795 struct ARGB
*dest
= DestARGB
->argb_ImageData
+ DestTop
* DestARGB
->argb_Width
;
796 const struct ARGB
*src
= SrcARGB
->argb_ImageData
+ SrcTop
* SrcARGB
->argb_Width
;
799 for (y
= 0; y
< Height
; y
++)
801 memcpy(dest
+ DestLeft
, src
+ SrcLeft
, Width
* sizeof(struct ARGB
));
802 dest
+= DestARGB
->argb_Width
;
803 src
+= SrcARGB
->argb_Width
;
807 //-----------------------------------------------------------------------
809 void FillARGB(struct ARGBHeader
*DestARGB
, const struct ARGB
*fillARGB
,
810 LONG left
, LONG top
, LONG width
, LONG height
)
812 struct ARGB
*dest
= DestARGB
->argb_ImageData
+ top
* DestARGB
->argb_Width
;
815 for (y
= 0; y
< height
; y
++)
818 struct ARGB
*destRow
= dest
+ left
;
820 for (x
= 0; x
< width
; x
++)
821 *destRow
++ = *fillARGB
;
823 dest
+= DestARGB
->argb_Width
;
827 //-----------------------------------------------------------------------
829 void SetARGB(struct ARGBHeader
*DestARGB
, const struct ARGB
*fillARGB
)
831 struct ARGB
*dest
= DestARGB
->argb_ImageData
;
832 size_t Length
= DestARGB
->argb_Width
* DestARGB
->argb_Height
;
838 //-----------------------------------------------------------------------
840 BOOL
SetNewSacColorMap(struct ScalosBitMapAndColor
*sac
, const ULONG
*colorMap
,
841 ULONG colorEntries
, struct ScalosGfxBase
*ScalosGfxBase
)
843 BOOL Success
= FALSE
;
849 if (sac
->sac_ColorTable
)
851 if (!(sac
->sac_Flags
& SACFLAGF_NO_FREE_COLORTABLE
))
852 ScalosGfxFreeVecPooled(ScalosGfxBase
, sac
->sac_ColorTable
);
853 sac
->sac_ColorTable
= NULL
;
856 sac
->sac_NumColors
= colorEntries
;
857 sac
->sac_Flags
&= ~SACFLAGF_NO_FREE_COLORTABLE
;
859 sac
->sac_ColorTable
= ScalosGfxAllocVecPooled(ScalosGfxBase
, SAC_COLORTABLESIZE(sac
));
860 if (NULL
== sac
->sac_ColorTable
)
863 memcpy(sac
->sac_ColorTable
, colorMap
, SAC_COLORTABLESIZE(sac
));
871 //-----------------------------------------------------------------------