New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / graphics / obtainbestpena.c
bloba2b24213e7bc8712408ed20a0249d5fbb93eb2f4
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Obtain the best pen available for a given color
6 Lang: english
7 */
8 #include "graphics_intern.h"
9 #include <proto/utility.h>
10 #include <utility/tagitem.h>
11 #include <graphics/view.h>
13 /*****************************************************************************
15 NAME */
16 #include <proto/graphics.h>
18 AROS_LH5(LONG, ObtainBestPenA,
20 /* SYNOPSIS */
21 AROS_LHA(struct ColorMap *, cm , A0),
22 AROS_LHA(ULONG , r , D1),
23 AROS_LHA(ULONG , g , D2),
24 AROS_LHA(ULONG , b , D3),
25 AROS_LHA(struct TagItem * , tags, A1),
27 /* LOCATION */
28 struct GfxBase *, GfxBase, 140, Graphics)
30 /* FUNCTION
32 INPUTS
34 RESULT
36 NOTES
38 EXAMPLE
40 BUGS
42 SEE ALSO
44 INTERNALS
46 HISTORY
48 *****************************************************************************/
50 AROS_LIBFUNC_INIT
51 AROS_LIBBASE_EXT_DECL(struct GfxBase *,GfxBase)
53 struct PaletteExtra *pe = cm->PalExtra;
54 LONG retval = -1;
55 PalExtra_AllocList_Type index;
57 if (NULL != pe)
59 struct TagItem defaults[] =
61 {OBP_Precision, PRECISION_IMAGE },
62 {OBP_FailIfBad, FALSE }
64 ULONG best_distance = (ULONG)-1;
67 /*
68 ** override the defaults if necessary
70 defaults[0].ti_Data = GetTagData(OBP_Precision,
71 defaults[0].ti_Data,
72 tags);
74 defaults[1].ti_Data = GetTagData(OBP_FailIfBad,
75 defaults[1].ti_Data,
76 tags);
78 /*
79 ** let nobody else play with the PalExtra structure
81 ObtainSemaphore(&pe->pe_Semaphore);
83 /*
84 ** Walk through the list of shared pens and search
85 ** for the closest color.
87 index = (PalExtra_AllocList_Type)pe->pe_FirstShared;
88 while ((PalExtra_AllocList_Type)-1 != index)
90 ULONG distance = color_distance(cm,r,g,b,index);
92 if (distance < best_distance)
94 best_distance = distance;
95 retval = index;
98 index = PALEXTRA_ALLOCLIST(pe, index);
101 #warning The color distance calc might be different than in AmigaOS.
104 ** If the best distance to an available color is greater than
105 ** the square of the tolerance, try to allocate a better
106 ** color, otherwise increase the shared counter for that color.
107 ** If only a little amount of colors is free for allocation in the
108 ** colormap the restrictions towards color matching should be
109 ** much looser than if the amount of free colors is close to 0.
110 ** The autodocs say that.
112 if (
113 (retval == -1) ||
114 (PRECISION_EXACT == defaults[0].ti_Data && 0 != best_distance ) ||
115 (best_distance * pe->pe_NFree >
116 (defaults[0].ti_Data * defaults[0].ti_Data) * pe->pe_SharableColors
121 ** The given tolerance could not be accomplished.
122 ** Try to allocate a pen. If that fails we
123 ** return -1 if the user specified OBP_FailIfBad = TRUE.
125 LONG tmp = ObtainPen(cm,-1,r,g,b,0);
127 if (-1 == tmp)
130 ** Return -1 if the user is strict with color matching.
131 ** In the other case retval is not changed.
133 if (TRUE == defaults[1].ti_Data)
135 retval = -1;
137 else if (retval != -1)
140 ** One more application is using this color
143 PALEXTRA_REFCNT(pe, retval)++;
146 else
147 retval = tmp;
149 else
152 ** One more application is using this color
154 PALEXTRA_REFCNT(pe, retval)++;
157 ReleaseSemaphore(&pe->pe_Semaphore);
159 } /* if (NULL != pe) */
161 return retval;
163 AROS_LIBFUNC_EXIT
165 } /* ObtainBestPenA */