1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
28 #include <graphics/gfxbase.h>
29 #include <proto/exec.h>
30 #include <proto/graphics.h>
33 #define RGB8to32(x) ((x)*0x01010101UL)
35 static inline BOOL
PenMap_SetPen (ULONG
*pen_map
, LONG pen
) {
38 if (pen_map
[l
] & (1UL << b
)) {
41 pen_map
[l
] |= (1UL << b
);
46 void PenMap_ReleasePens (ULONG
*pen_map
, struct Screen
*screen
) {
47 struct ColorMap
*cmap
= screen
->ViewPort
.ColorMap
;
50 for (pen
= l
= 0; l
< 8; l
++) {
51 for (b
= 0; b
< 31; b
++, pen
++) {
52 if (pen_map
[l
] & (1UL << b
)) {
53 ReleasePen(cmap
, pen
);
60 BOOL
RemapRGBAImage (struct Screen
*screen
, BOOL rtg
, UBYTE
*rgba
, WORD w
, WORD h
,
61 ULONG
*pen_map
, struct BitMap
**bm_p
, PLANEPTR
*mask_p
)
63 static const struct TagItem tags
[] = {
64 { OBP_Precision
, PRECISION_IMAGE
},
67 struct ColorMap
*cmap
= screen
->ViewPort
.ColorMap
;
68 struct BitMap
*screen_bm
= screen
->RastPort
.BitMap
;
69 WORD depth
= rtg
? 8 : screen_bm
->Depth
;
70 UBYTE
*clut
= NULL
, *src
, *dst
, a
;
71 ULONG clut_bpr
, clut_mod
;
74 struct BitMap
*bm
= NULL
, *temp_bm
= NULL
, mask_bm
;
76 struct RastPort rp
, temp_rp
;
81 /* allocate space for chunky image */
82 clut_bpr
= (w
+ 15) & 0xFFF0;
83 clut
= AllocVec(clut_bpr
* h
, MEMF_ANY
);
88 /* remap image to chunky buffer */
91 clut_mod
= clut_bpr
- w
;
92 for (y
= 0; y
< h
; y
++) {
93 for (x
= 0; x
< w
; x
++) {
94 pen
= ObtainBestPenA(cmap
, RGB8to32(src
[0]), RGB8to32(src
[1]), RGB8to32(src
[2]), tags
);
95 if (!(pen
>= 0 && pen
<= 255)) {
98 if (PenMap_SetPen(pen_map
, pen
)) {
99 ReleasePen(cmap
, pen
);
107 /* allocate bitmap in same format as screen */
108 bm
= AllocBitMap(w
, h
, depth
, 0, screen_bm
);
113 if (GfxBase
->LibNode
.lib_Version
< 40) {
114 /* allocate temp bitmap and rp for WritePixelArray8 */
115 temp_bm
= AllocBitMap(w
, 1, depth
, 0, bm
);
119 InitRastPort(&temp_rp
);
120 temp_rp
.BitMap
= temp_bm
;
123 /* init rastport and copy graphics to bitmap */
126 if (GfxBase
->LibNode
.lib_Version
>= 40) {
127 WriteChunkyPixels(&rp
, 0, 0, w
-1, h
-1, clut
, clut_bpr
);
129 WritePixelArray8(&rp
, 0, 0, w
-1, h
-1, clut
, &temp_rp
);
132 /* allocate memory for mask */
133 interleaved
= !rtg
&& (bm
->Flags
& BMF_INTERLEAVED
);
134 mask_depth
= interleaved
? depth
: 1;
135 mask_bpr
= rtg
? (((w
+ 15) >> 3) & 0xFFFE) : (bm
->BytesPerRow
/ mask_depth
);
136 mask
= AllocVec(mask_bpr
* h
* mask_depth
, (rtg
? MEMF_ANY
: MEMF_CHIP
)|MEMF_CLEAR
);
141 /* init mask bitmap structure */
142 memset(&mask_bm
, 0, sizeof(mask_bm
));
143 mask_bm
.BytesPerRow
= mask_bpr
* mask_depth
;
145 mask_bm
.Flags
= interleaved
? BMF_INTERLEAVED
: 0;
146 mask_bm
.Depth
= mask_depth
;
148 for (i
= 0; i
< mask_depth
; i
++) {
149 mask_bm
.Planes
[i
] = (PLANEPTR
)src
;
153 /* draw mask into chunky buffer first */
154 pen
= (1UL << mask_depth
) - 1;
157 for (y
= 0; y
< h
; y
++) {
158 for (x
= 0; x
< w
; x
++) {
160 *dst
++ = a
>= 128 ? pen
: 0;
166 /* init rastport and copy mask to bitmap */
168 rp
.BitMap
= &mask_bm
;
169 if (GfxBase
->LibNode
.lib_Version
>= 40) {
170 WriteChunkyPixels(&rp
, 0, 0, w
-1, h
-1, clut
, clut_bpr
);
172 WritePixelArray8(&rp
, 0, 0, w
-1, h
-1, clut
, &temp_rp
);