diff options
Diffstat (limited to 'xorg-server/render/miindex.c')
-rw-r--r-- | xorg-server/render/miindex.c | 716 |
1 files changed, 358 insertions, 358 deletions
diff --git a/xorg-server/render/miindex.c b/xorg-server/render/miindex.c index 4e0cf0084..75f941477 100644 --- a/xorg-server/render/miindex.c +++ b/xorg-server/render/miindex.c @@ -1,358 +1,358 @@ -/* - * - * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#ifndef _MIINDEX_H_ -#define _MIINDEX_H_ - -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "mi.h" -#include "picturestr.h" -#include "mipict.h" -#include "colormapst.h" - -#define NUM_CUBE_LEVELS 4 -#define NUM_GRAY_LEVELS 13 - -static Bool -miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump) -{ - int r, g, b; - unsigned short red, green, blue; - Pixel pixel; - Bool used[MI_MAX_INDEXED]; - int needed; - int policy; - int cube, gray; - int i, n; - - if (pColormap->mid != pColormap->pScreen->defColormap) - { - policy = PictureCmapPolicyAll; - } - else - { - int avail = pColormap->pVisual->ColormapEntries; - policy = PictureCmapPolicy; - if (policy == PictureCmapPolicyDefault) - { - if (avail >= 256 && (pColormap->pVisual->class|DynamicClass) == PseudoColor) - policy = PictureCmapPolicyColor; - else if (avail >= 64) - policy = PictureCmapPolicyGray; - else - policy = PictureCmapPolicyMono; - } - } - /* - * Make sure enough cells are free for the chosen policy - */ - for (;;) - { - switch (policy) { - case PictureCmapPolicyAll: - needed = 0; - break; - case PictureCmapPolicyColor: - needed = 71; - break; - case PictureCmapPolicyGray: - needed = 11; - break; - case PictureCmapPolicyMono: - default: - needed = 0; - break; - } - if (needed <= pColormap->freeRed) - break; - policy--; - } - - /* - * Compute size of cube and gray ramps - */ - cube = gray = 0; - switch (policy) { - case PictureCmapPolicyAll: - /* - * Allocate as big a cube as possible - */ - if ((pColormap->pVisual->class|DynamicClass) == PseudoColor) - { - for (cube = 1; cube * cube * cube < pColormap->pVisual->ColormapEntries; cube++) - ; - cube--; - if (cube == 1) - cube = 0; - } - else - cube = 0; - /* - * Figure out how many gray levels to use so that they - * line up neatly with the cube - */ - if (cube) - { - needed = pColormap->pVisual->ColormapEntries - (cube*cube*cube); - /* levels to fill in with */ - gray = needed / (cube - 1); - /* total levels */ - gray = (gray + 1) * (cube - 1) + 1; - } - else - gray = pColormap->pVisual->ColormapEntries; - break; - - case PictureCmapPolicyColor: - cube = NUM_CUBE_LEVELS; - /* fall through ... */ - case PictureCmapPolicyGray: - gray = NUM_GRAY_LEVELS; - break; - case PictureCmapPolicyMono: - default: - gray = 2; - break; - } - - memset (used, '\0', pColormap->pVisual->ColormapEntries * sizeof (Bool)); - for (r = 0; r < cube; r++) - for (g = 0; g < cube; g++) - for (b = 0; b < cube; b++) - { - pixel = 0; - red = (r * 65535 + (cube-1)/2) / (cube - 1); - green = (g * 65535 + (cube-1)/2) / (cube - 1); - blue = (b * 65535 + (cube-1)/2) / (cube - 1); - if (AllocColor (pColormap, &red, &green, - &blue, &pixel, 0) != Success) - return FALSE; - used[pixel] = TRUE; - } - for (g = 0; g < gray; g++) - { - pixel = 0; - red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1); - if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success) - return FALSE; - used[pixel] = TRUE; - } - n = 0; - for (i = 0; i < pColormap->pVisual->ColormapEntries; i++) - if (used[i]) - pixels[n++] = i; - - *nump = n; - - return TRUE; -} - -/* 0 <= red, green, blue < 32 */ -static Pixel -FindBestColor (miIndexedPtr pIndexed, Pixel *pixels, int num, - int red, int green, int blue) -{ - Pixel best = pixels[0]; - int bestDist = 1 << 30; - int dist; - int dr, dg, db; - while (num--) - { - Pixel pixel = *pixels++; - CARD32 v = pIndexed->rgba[pixel]; - - dr = ((v >> 19) & 0x1f); - dg = ((v >> 11) & 0x1f); - db = ((v >> 3) & 0x1f); - dr = dr - red; - dg = dg - green; - db = db - blue; - dist = dr * dr + dg * dg + db * db; - if (dist < bestDist) - { - bestDist = dist; - best = pixel; - } - } - return best; -} - -/* 0 <= gray < 32768 */ -static Pixel -FindBestGray (miIndexedPtr pIndexed, Pixel *pixels, int num, int gray) -{ - Pixel best = pixels[0]; - int bestDist = 1 << 30; - int dist; - int dr; - int r; - - while (num--) - { - Pixel pixel = *pixels++; - CARD32 v = pIndexed->rgba[pixel]; - - r = v & 0xff; - r = r | (r << 8); - dr = gray - (r >> 1); - dist = dr * dr; - if (dist < bestDist) - { - bestDist = dist; - best = pixel; - } - } - return best; -} - -Bool -miInitIndexed (ScreenPtr pScreen, - PictFormatPtr pFormat) -{ - ColormapPtr pColormap = pFormat->index.pColormap; - VisualPtr pVisual = pColormap->pVisual; - miIndexedPtr pIndexed; - Pixel pixels[MI_MAX_INDEXED]; - xrgb rgb[MI_MAX_INDEXED]; - int num; - int i; - Pixel p, r, g, b; - - if (pVisual->ColormapEntries > MI_MAX_INDEXED) - return FALSE; - - if (pVisual->class & DynamicClass) - { - if (!miBuildRenderColormap (pColormap, pixels, &num)) - return FALSE; - } - else - { - num = pVisual->ColormapEntries; - for (p = 0; p < num; p++) - pixels[p] = p; - } - - pIndexed = xalloc (sizeof (miIndexedRec)); - if (!pIndexed) - return FALSE; - - pFormat->index.nvalues = num; - pFormat->index.pValues = xalloc (num * sizeof (xIndexValue)); - if (!pFormat->index.pValues) - { - xfree (pIndexed); - return FALSE; - } - - - /* - * Build mapping from pixel value to ARGB - */ - QueryColors (pColormap, num, pixels, rgb); - for (i = 0; i < num; i++) - { - p = pixels[i]; - pFormat->index.pValues[i].pixel = p; - pFormat->index.pValues[i].red = rgb[i].red; - pFormat->index.pValues[i].green = rgb[i].green; - pFormat->index.pValues[i].blue = rgb[i].blue; - pFormat->index.pValues[i].alpha = 0xffff; - pIndexed->rgba[p] = (0xff000000 | - ((rgb[i].red & 0xff00) << 8) | - ((rgb[i].green & 0xff00) ) | - ((rgb[i].blue & 0xff00) >> 8)); - } - - /* - * Build mapping from RGB to pixel value. This could probably be - * done a bit quicker... - */ - switch (pVisual->class | DynamicClass) { - case GrayScale: - pIndexed->color = FALSE; - for (r = 0; r < 32768; r++) - pIndexed->ent[r] = FindBestGray (pIndexed, pixels, num, r); - break; - case PseudoColor: - pIndexed->color = TRUE; - p = 0; - for (r = 0; r < 32; r++) - for (g = 0; g < 32; g++) - for (b = 0; b < 32; b++) - { - pIndexed->ent[p] = FindBestColor (pIndexed, pixels, num, - r, g, b); - p++; - } - break; - } - pFormat->index.devPrivate = pIndexed; - return TRUE; -} - -void -miCloseIndexed (ScreenPtr pScreen, - PictFormatPtr pFormat) -{ - if (pFormat->index.devPrivate) - { - xfree (pFormat->index.devPrivate); - pFormat->index.devPrivate = 0; - } - if (pFormat->index.pValues) - { - xfree (pFormat->index.pValues); - pFormat->index.pValues = 0; - } -} - -void -miUpdateIndexed (ScreenPtr pScreen, - PictFormatPtr pFormat, - int ndef, - xColorItem *pdef) -{ - miIndexedPtr pIndexed = pFormat->index.devPrivate; - - if (pIndexed) - { - while (ndef--) - { - pIndexed->rgba[pdef->pixel] = (0xff000000 | - ((pdef->red & 0xff00) << 8) | - ((pdef->green & 0xff00) ) | - ((pdef->blue & 0xff00) >> 8)); - pdef++; - } - } -} - -#endif /* _MIINDEX_H_ */ +/*
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _MIINDEX_H_
+#define _MIINDEX_H_
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+#include "colormapst.h"
+
+#define NUM_CUBE_LEVELS 4
+#define NUM_GRAY_LEVELS 13
+
+static Bool
+miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump)
+{
+ int r, g, b;
+ unsigned short red, green, blue;
+ Pixel pixel;
+ Bool used[MI_MAX_INDEXED];
+ int needed;
+ int policy;
+ int cube, gray;
+ int i, n;
+
+ if (pColormap->mid != pColormap->pScreen->defColormap)
+ {
+ policy = PictureCmapPolicyAll;
+ }
+ else
+ {
+ int avail = pColormap->pVisual->ColormapEntries;
+ policy = PictureCmapPolicy;
+ if (policy == PictureCmapPolicyDefault)
+ {
+ if (avail >= 256 && (pColormap->pVisual->class|DynamicClass) == PseudoColor)
+ policy = PictureCmapPolicyColor;
+ else if (avail >= 64)
+ policy = PictureCmapPolicyGray;
+ else
+ policy = PictureCmapPolicyMono;
+ }
+ }
+ /*
+ * Make sure enough cells are free for the chosen policy
+ */
+ for (;;)
+ {
+ switch (policy) {
+ case PictureCmapPolicyAll:
+ needed = 0;
+ break;
+ case PictureCmapPolicyColor:
+ needed = 71;
+ break;
+ case PictureCmapPolicyGray:
+ needed = 11;
+ break;
+ case PictureCmapPolicyMono:
+ default:
+ needed = 0;
+ break;
+ }
+ if (needed <= pColormap->freeRed)
+ break;
+ policy--;
+ }
+
+ /*
+ * Compute size of cube and gray ramps
+ */
+ cube = gray = 0;
+ switch (policy) {
+ case PictureCmapPolicyAll:
+ /*
+ * Allocate as big a cube as possible
+ */
+ if ((pColormap->pVisual->class|DynamicClass) == PseudoColor)
+ {
+ for (cube = 1; cube * cube * cube < pColormap->pVisual->ColormapEntries; cube++)
+ ;
+ cube--;
+ if (cube == 1)
+ cube = 0;
+ }
+ else
+ cube = 0;
+ /*
+ * Figure out how many gray levels to use so that they
+ * line up neatly with the cube
+ */
+ if (cube)
+ {
+ needed = pColormap->pVisual->ColormapEntries - (cube*cube*cube);
+ /* levels to fill in with */
+ gray = needed / (cube - 1);
+ /* total levels */
+ gray = (gray + 1) * (cube - 1) + 1;
+ }
+ else
+ gray = pColormap->pVisual->ColormapEntries;
+ break;
+
+ case PictureCmapPolicyColor:
+ cube = NUM_CUBE_LEVELS;
+ /* fall through ... */
+ case PictureCmapPolicyGray:
+ gray = NUM_GRAY_LEVELS;
+ break;
+ case PictureCmapPolicyMono:
+ default:
+ gray = 2;
+ break;
+ }
+
+ memset (used, '\0', pColormap->pVisual->ColormapEntries * sizeof (Bool));
+ for (r = 0; r < cube; r++)
+ for (g = 0; g < cube; g++)
+ for (b = 0; b < cube; b++)
+ {
+ pixel = 0;
+ red = (r * 65535 + (cube-1)/2) / (cube - 1);
+ green = (g * 65535 + (cube-1)/2) / (cube - 1);
+ blue = (b * 65535 + (cube-1)/2) / (cube - 1);
+ if (AllocColor (pColormap, &red, &green,
+ &blue, &pixel, 0) != Success)
+ return FALSE;
+ used[pixel] = TRUE;
+ }
+ for (g = 0; g < gray; g++)
+ {
+ pixel = 0;
+ red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1);
+ if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success)
+ return FALSE;
+ used[pixel] = TRUE;
+ }
+ n = 0;
+ for (i = 0; i < pColormap->pVisual->ColormapEntries; i++)
+ if (used[i])
+ pixels[n++] = i;
+
+ *nump = n;
+
+ return TRUE;
+}
+
+/* 0 <= red, green, blue < 32 */
+static Pixel
+FindBestColor (miIndexedPtr pIndexed, Pixel *pixels, int num,
+ int red, int green, int blue)
+{
+ Pixel best = pixels[0];
+ int bestDist = 1 << 30;
+ int dist;
+ int dr, dg, db;
+ while (num--)
+ {
+ Pixel pixel = *pixels++;
+ CARD32 v = pIndexed->rgba[pixel];
+
+ dr = ((v >> 19) & 0x1f);
+ dg = ((v >> 11) & 0x1f);
+ db = ((v >> 3) & 0x1f);
+ dr = dr - red;
+ dg = dg - green;
+ db = db - blue;
+ dist = dr * dr + dg * dg + db * db;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = pixel;
+ }
+ }
+ return best;
+}
+
+/* 0 <= gray < 32768 */
+static Pixel
+FindBestGray (miIndexedPtr pIndexed, Pixel *pixels, int num, int gray)
+{
+ Pixel best = pixels[0];
+ int bestDist = 1 << 30;
+ int dist;
+ int dr;
+ int r;
+
+ while (num--)
+ {
+ Pixel pixel = *pixels++;
+ CARD32 v = pIndexed->rgba[pixel];
+
+ r = v & 0xff;
+ r = r | (r << 8);
+ dr = gray - (r >> 1);
+ dist = dr * dr;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = pixel;
+ }
+ }
+ return best;
+}
+
+Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ ColormapPtr pColormap = pFormat->index.pColormap;
+ VisualPtr pVisual = pColormap->pVisual;
+ miIndexedPtr pIndexed;
+ Pixel pixels[MI_MAX_INDEXED];
+ xrgb rgb[MI_MAX_INDEXED];
+ int num;
+ int i;
+ Pixel p, r, g, b;
+
+ if (pVisual->ColormapEntries > MI_MAX_INDEXED)
+ return FALSE;
+
+ if (pVisual->class & DynamicClass)
+ {
+ if (!miBuildRenderColormap (pColormap, pixels, &num))
+ return FALSE;
+ }
+ else
+ {
+ num = pVisual->ColormapEntries;
+ for (p = 0; p < num; p++)
+ pixels[p] = p;
+ }
+
+ pIndexed = malloc(sizeof (miIndexedRec));
+ if (!pIndexed)
+ return FALSE;
+
+ pFormat->index.nvalues = num;
+ pFormat->index.pValues = malloc(num * sizeof (xIndexValue));
+ if (!pFormat->index.pValues)
+ {
+ free(pIndexed);
+ return FALSE;
+ }
+
+
+ /*
+ * Build mapping from pixel value to ARGB
+ */
+ QueryColors (pColormap, num, pixels, rgb, serverClient);
+ for (i = 0; i < num; i++)
+ {
+ p = pixels[i];
+ pFormat->index.pValues[i].pixel = p;
+ pFormat->index.pValues[i].red = rgb[i].red;
+ pFormat->index.pValues[i].green = rgb[i].green;
+ pFormat->index.pValues[i].blue = rgb[i].blue;
+ pFormat->index.pValues[i].alpha = 0xffff;
+ pIndexed->rgba[p] = (0xff000000 |
+ ((rgb[i].red & 0xff00) << 8) |
+ ((rgb[i].green & 0xff00) ) |
+ ((rgb[i].blue & 0xff00) >> 8));
+ }
+
+ /*
+ * Build mapping from RGB to pixel value. This could probably be
+ * done a bit quicker...
+ */
+ switch (pVisual->class | DynamicClass) {
+ case GrayScale:
+ pIndexed->color = FALSE;
+ for (r = 0; r < 32768; r++)
+ pIndexed->ent[r] = FindBestGray (pIndexed, pixels, num, r);
+ break;
+ case PseudoColor:
+ pIndexed->color = TRUE;
+ p = 0;
+ for (r = 0; r < 32; r++)
+ for (g = 0; g < 32; g++)
+ for (b = 0; b < 32; b++)
+ {
+ pIndexed->ent[p] = FindBestColor (pIndexed, pixels, num,
+ r, g, b);
+ p++;
+ }
+ break;
+ }
+ pFormat->index.devPrivate = pIndexed;
+ return TRUE;
+}
+
+void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ if (pFormat->index.devPrivate)
+ {
+ free(pFormat->index.devPrivate);
+ pFormat->index.devPrivate = 0;
+ }
+ if (pFormat->index.pValues)
+ {
+ free(pFormat->index.pValues);
+ pFormat->index.pValues = 0;
+ }
+}
+
+void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef)
+{
+ miIndexedPtr pIndexed = pFormat->index.devPrivate;
+
+ if (pIndexed)
+ {
+ while (ndef--)
+ {
+ pIndexed->rgba[pdef->pixel] = (0xff000000 |
+ ((pdef->red & 0xff00) << 8) |
+ ((pdef->green & 0xff00) ) |
+ ((pdef->blue & 0xff00) >> 8));
+ pdef++;
+ }
+ }
+}
+
+#endif /* _MIINDEX_H_ */
|