wip prep commit in lieu of gfx subsystem update changes.
[AROS.git] / workbench / libs / cgfx / extractcolor.c
blobf2a9bee6f477fe6105eb9632191b17fb07a2e043
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <clib/macros.h>
11 #include <hidd/gfx.h>
12 #include <proto/exec.h>
13 #include <proto/oop.h>
15 #include "cybergraphics_intern.h"
16 #include "gfxfuncsupport.h"
18 struct extcol_render_data
20 struct BitMap *destbm;
21 HIDDT_Pixel pixel;
22 struct IntCGFXBase *CyberGfxBase;
25 static ULONG extcol_render(struct extcol_render_data *ecrd, LONG x_src, LONG y_src,
26 OOP_Object *bm_obj, OOP_Object *dst_gc,
27 struct Rectangle *rect, struct GfxBase *GfxBase)
29 /* Get the info from the hidd */
30 struct IntCGFXBase *CyberGfxBase = ecrd->CyberGfxBase;
31 struct BitMap *bm = ecrd->destbm;
32 HIDDT_Pixel *pixbuf = CyberGfxBase->pixel_buf;
33 LONG x_dest = rect->MinX;
34 LONG y_dest = rect->MinY;
35 ULONG xsize = rect->MaxX - rect->MinX + 1;
36 ULONG ysize = rect->MaxY - rect->MinY + 1;
37 LONG pixels_left_to_process = xsize * ysize;
38 ULONG next_x = 0;
39 ULONG next_y = 0;
40 ULONG current_x, current_y, tocopy_w, tocopy_h;
42 LOCK_PIXBUF
44 while (pixels_left_to_process)
46 LONG srcx, srcy, dstx, dsty;
47 LONG x, y;
49 current_x = next_x;
50 current_y = next_y;
52 if (NUMPIX < xsize)
54 /* buffer can't hold a single horizontal line, and must
55 divide each line into copies */
56 tocopy_w = xsize - current_x;
57 if (tocopy_w > NUMPIX)
59 /* Not quite finished with current horizontal pixel line */
60 tocopy_w = NUMPIX;
61 next_x += NUMPIX;
63 else
64 { /* Start at a new line */
66 next_x = 0;
67 next_y ++;
69 tocopy_h = 1;
71 else
73 tocopy_h = MIN(NUMPIX / xsize, ysize - current_y);
74 tocopy_w = xsize;
76 next_x = 0;
77 next_y += tocopy_h;
80 srcx = x_src + current_x;
81 srcy = y_src + current_y;
82 dstx = x_dest + current_x;
83 dsty = y_dest + current_y;
85 /* Get some more pixels from the HIDD */
86 HIDD_BM_GetImage(bm_obj, (UBYTE *)pixbuf, tocopy_w,
87 srcx, srcy, tocopy_w, tocopy_h, vHidd_StdPixFmt_Native32);
89 /* Write pixels to the destination */
90 for (y = 0; y < tocopy_h; y ++)
92 for (x = 0; x < tocopy_w; x ++)
94 if (*pixbuf ++ == ecrd->pixel)
96 ULONG i;
98 /* Set the according bit in the bitmap */
99 for (i = 0; i < bm->Depth; i++)
101 UBYTE *plane = bm->Planes[i];
103 if (NULL != plane)
105 UBYTE mask = XCOORD_TO_MASK(x + dstx);
107 plane += COORD_TO_BYTEIDX(x + dstx, y + dsty, bm->BytesPerRow);
108 /* Set the pixel */
109 *plane |= mask;
110 } /* if (plane allocated) */
111 } /* for (plane) */
112 } /* if (color match) */
113 } /* for (x) */
114 } /* for (y) */
116 pixels_left_to_process -= (tocopy_w * tocopy_h);
119 ULOCK_PIXBUF
121 return 1;
124 /*****************************************************************************
126 NAME */
127 #include <proto/cybergraphics.h>
129 AROS_LH7(ULONG, ExtractColor,
131 /* SYNOPSIS */
132 AROS_LHA(struct RastPort *, RastPort, A0),
133 AROS_LHA(struct BitMap *, SingleMap, A1),
134 AROS_LHA(ULONG , Colour, D0),
135 AROS_LHA(ULONG , sX, D1),
136 AROS_LHA(ULONG , sY, D2),
137 AROS_LHA(ULONG , Width, D3),
138 AROS_LHA(ULONG , Height, D4),
140 /* LOCATION */
141 struct Library *, CyberGfxBase, 31, Cybergraphics)
143 /* FUNCTION
144 Create a single-plane bitmap that describes the coordinates where a
145 particular colour is present in a portion of a RastPort (i.e. a mask).
146 A one is stored in the bitmap where the requested colour is present,
147 and a zero where it is absent.
149 For true-colour RastPorts, the colour is specified in 32-bit ARGB
150 format: 1 byte per component, in the order alpha, red, green, blue
151 (the alpha byte is ignored for RastPorts without an alpha channel).
152 For paletted RastPorts, a pen number is given instead.
154 INPUTS
155 RastPort - the RastPort to analyse.
156 SingleMap - a planar bitmap to fill (its pixel dimensions must be at
157 least as big as the rectangle being analysed).
158 Colour - the colour to extract.
159 sX, sY - top-lefthand corner of portion of RastPort to analyse
160 (in pixels).
161 Width, Height - size of the area to analyse (in pixels).
163 RESULT
164 result - Boolean success indicator.
166 NOTES
167 It is safe for the bitmap being filled to have more than one bitplane.
169 EXAMPLE
171 BUGS
173 SEE ALSO
175 INTERNALS
177 HISTORY
179 *****************************************************************************/
181 AROS_LIBFUNC_INIT
183 struct Rectangle rr;
184 LONG pixread = 0;
185 struct extcol_render_data ecrd;
186 OOP_Object *pf;
187 IPTR colmod;
189 if (!IS_HIDD_BM(RastPort->BitMap))
191 D(bug("!!! CALLING ExtractColor() ON NO-HIDD BITMAP !!!\n"));
192 return FALSE;
195 rr.MinX = sX;
196 rr.MinY = sY;
197 rr.MaxX = sX + Width - 1;
198 rr.MaxY = sY + Height - 1;
200 OOP_GetAttr(HIDD_BM_OBJ(RastPort->BitMap), aHidd_BitMap_PixFmt, (IPTR *)&pf);
201 OOP_GetAttr(pf, aHidd_PixFmt_ColorModel, (IPTR *)&colmod);
203 if (vHidd_ColorModel_Palette == colmod)
205 ecrd.pixel = Colour;
207 else
209 HIDDT_Color col;
211 col.alpha = (Colour >> 16) & 0x0000FF00;
212 col.red = (Colour >> 8 ) & 0x0000FF00;
213 col.green = Colour & 0x0000FF00;
214 col.blue = (Colour << 8) & 0x0000FF00;
216 ecrd.pixel = HIDD_BM_MapColor(HIDD_BM_OBJ(RastPort->BitMap), &col);
219 ecrd.destbm = SingleMap;
220 ecrd.CyberGfxBase = (struct IntCGFXBase *)CyberGfxBase;
222 pixread = DoRenderFunc(RastPort, NULL, &rr, extcol_render, &ecrd, FALSE);
225 * In our render callback we return one if everything went ok.
226 * DoRenderFunc() sums up all return values from callback. So, if all failed,
227 * this will be zero. Otherwise it will indicate how many times the callback
228 * was called.
230 return (pixread > 0);
232 AROS_LIBFUNC_EXIT
233 } /* ExtractColor */