1 /***************************************************************************
3 NBitmap.mcc - New Bitmap MUI Custom Class
4 Copyright (C) 2006 by Daniel Allsopp
5 Copyright (C) 2007-2013 by NList Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 NList classes Support Site: http://www.sf.net/projects/nlist-classes
21 ***************************************************************************/
23 #include <proto/exec.h>
24 #include <proto/utility.h>
25 #include <mui/NBitmap_mcc.h>
28 #include "DitherImage.h"
32 #define MEMF_SHARED MEMF_ANY
35 #define RAWIDTH(w) ((((UWORD)(w))+15)>>3 & 0xFFFE)
37 APTR
DitherImageA(CONST_APTR data
, struct TagItem
*tags
)
43 const uint32
*colorMap
= NULL
;
44 const int32
*penMap
= NULL
;
46 uint8
**maskPtr
= NULL
;
50 while((tag
= NextTagItem((APTR
)&tags
)) != NULL
)
59 height
= tag
->ti_Data
;
63 format
= tag
->ti_Data
;
66 case DITHERA_ColorMap
:
67 colorMap
= (uint32
*)tag
->ti_Data
;
71 penMap
= (int32
*)tag
->ti_Data
;
74 case DITHERA_MaskPlane
:
75 maskPtr
= (uint8
**)tag
->ti_Data
;
80 if(data
!= NULL
&& colorMap
!= NULL
&& width
> 0 && height
> 0)
82 // the 8bit chunky data don't need to reside in chip memory
83 if((result
= AllocVecShared(width
* height
, MEMF_ANY
)) != NULL
)
88 uint8
*dataPtr
= (uint8
*)data
;
89 uint8
*resultPtr
= (uint8
*)result
;
91 // only ARGB raw data contain transparency data, hence we need to
92 // allocate a mask plane only for these and only if the calling
93 // function is interested in a mask at all
94 if(format
== MUIV_NBitmap_Type_ARGB32
&& maskPtr
!= NULL
)
96 // the mask MUST reside in chip memory
97 mask
= AllocVec(RAWIDTH(width
) * height
, MEMF_CLEAR
|MEMF_CHIP
);
102 for(y
= 0; y
< height
; y
++)
105 uint8 bitMask
= 0x80;
107 for(x
= 0; x
< width
; x
++)
114 // obtain the pixel's A, R, G and B values from the raw data
117 case MUIV_NBitmap_Type_CLUT8
:
118 a
= (colorMap
[dataPtr
[0]] >> 24) & 0xff;
119 r
= (colorMap
[dataPtr
[0]] >> 16) & 0xff;
120 g
= (colorMap
[dataPtr
[0]] >> 8) & 0xff;
121 b
= (colorMap
[dataPtr
[0]] >> 0) & 0xff;
125 case MUIV_NBitmap_Type_RGB24
:
133 case MUIV_NBitmap_Type_ARGB32
:
149 // now calculate the best matching color from the given color map
151 bestError
= 0xffffffffUL
;
153 for(i
= 0; i
< 256; i
++)
158 // calculate the geometric difference to the current color
159 dr
= (int32
)((colorMap
[i
] >> 16) & 0xff) - (int32
)r
;
160 dg
= (int32
)((colorMap
[i
] >> 8) & 0xff) - (int32
)g
;
161 db
= (int32
)((colorMap
[i
] >> 0) & 0xff) - (int32
)b
;
162 error
= dr
* dr
+ dg
* dg
+ db
* db
;
164 if(bestError
> error
)
166 // remember this as the best matching color so far
170 // bail out if we found an exact match
171 if(error
== 0x00000000UL
)
176 // put the calculated color number into the destination LUT8 image
177 // using an additional pen map if available
181 *resultPtr
++ = penMap
[bestIndex
];
183 *resultPtr
++ = bestIndex
;
187 // no matching color found, use color 0
188 // can this happen at all?
194 // if we have a mask and the alpha value is >= 0x80 the
195 // pixel is treated as non-transparent
197 mPtr
[x
/8] |= bitMask
;
205 // advance the mask pointer by one line
207 mPtr
+= RAWIDTH(width
);
217 APTR STDARGS VARARGS68K
DitherImage(CONST_APTR data
, Tag tag1
, ...)
219 AROS_SLOWSTACKTAGS_PRE_AS(tag1
, APTR
)
220 retval
= DitherImageA(data
, AROS_SLOWSTACKTAGS_ARG(tag1
));
221 AROS_SLOWSTACKTAGS_POST
224 #if !defined(__PPC__)
225 APTR STDARGS VARARGS68K
DitherImage(CONST_APTR data
, ...)
230 VA_START(args
, data
);
231 ret
= DitherImageA(data
, (struct TagItem
*)VA_ARG(args
, IPTR
));
239 void FreeDitheredImage(APTR image
, APTR mask
)