[Motiftools-xmt-cvs] CVS: xmt/Xmt Pixmap.c,1.9,1.10
Brought to you by:
motiftools
From: Grant M. <grm...@us...> - 2003-10-27 20:24:40
|
Update of /cvsroot/motiftools/xmt/Xmt In directory sc8-pr-cvs1:/tmp/cvs-serv9129 Modified Files: Pixmap.c Log Message: Major performance rework for XmtRecolorPixmap Index: Pixmap.c =================================================================== RCS file: /cvsroot/motiftools/xmt/Xmt/Pixmap.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** Pixmap.c 13 May 2003 02:16:44 -0000 1.9 --- Pixmap.c 27 Oct 2003 20:19:59 -0000 1.10 *************** *** 10,13 **** --- 10,16 ---- * * $Log$ + * Revision 1.10 2003/10/27 20:19:59 grmcdorman + * Major performance rework for XmtRecolorPixmap + * * Revision 1.9 2003/05/13 02:16:44 grmcdorman * Performance improvement for XmtRecolorPixmap. *************** *** 729,732 **** --- 732,745 ---- XGCValues values; unsigned int width, height, depth; + Visual *visual; + XColor pseudo_map[256]; + int use_map = 0; + int use_masks = 0; + int red_shift; + int green_shift; + int blue_shift; + int red_mask; + int green_mask; + int blue_mask; width = height = 0; *************** *** 750,802 **** width, height, depth); if (image != NULL && computed != None) { ! /* Convert by batching blocks of color queries, for maximum efficiency. */ int x, y; ! int ipx; ! static XColor color_list[256]; ! static int x_list[256]; ! static int y_list[256]; ! ipx = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { ! x_list[ipx] = x; ! y_list[ipx] = y; ! color_list[ipx++].pixel = XGetPixel(image, x, y); ! if (ipx == XtNumber(color_list)) { ! XQueryColors(w->core.screen->display, w->core.colormap, color_list, ipx); ! while (ipx > 0) { ! --ipx; ! intensity = (color_list[ipx].red + color_list[ipx].blue + color_list[ipx].green) / 3; ! /* find the closest of the two colours */ ! delta1 = abs(intensity - intensity1); ! delta2 = abs(intensity - intensity2); ! if (delta1 < delta2) { ! color_list[ipx].pixel = colour1; ! } else { ! color_list[ipx].pixel = colour2; ! } ! ! XPutPixel(image, x_list[ipx], y_list[ipx], color_list[ipx].pixel); ! } ! ipx = 0; } ! } ! } ! if (ipx > 0) { ! /* finish up */ ! XQueryColors(w->core.screen->display, w->core.colormap, color_list, ipx); ! while (ipx > 0) { ! --ipx; ! intensity = (color_list[ipx].red + color_list[ipx].blue + color_list[ipx].green) / 3; ! /* find the closest of the two colours */ delta1 = abs(intensity - intensity1); delta2 = abs(intensity - intensity2); if (delta1 < delta2) { ! color_list[ipx].pixel = colour1; } else { ! color_list[ipx].pixel = colour2; } ! XPutPixel(image, x_list[ipx], y_list[ipx], color_list[ipx].pixel); } } --- 763,856 ---- width, height, depth); + /* + * Simply calling XQueryColor for each pixel in the image gets expensive + * VERY quickly. + * + * On depth-8 PseudoColour screens, we can get the entire colourmap and avoid a bunch of + * XQueryColor calls. + * + * On TrueColour screens, we can do the Pixel->RGB conversion ourselves, and again avoid + * the XQueryColor calls. + */ + visual = XmtGetVisual(w); + if (visual->class == TrueColor || visual->class == DirectColor) { + int i; + int shift; + int mask; + + use_masks = 1; + + shift = 0; + mask = red_mask = visual->red_mask; + while ( mask != 0 && (mask & 1) != 0) { + mask >>= 1; + shift++; + } + red_shift = shift; + + shift = 0; + mask = green_mask = visual->green_mask; + while ( mask != 0 && (mask & 1) != 0) { + mask >>= 1; + shift++; + } + green_shift = shift; + + shift = 0; + mask = blue_mask = visual->blue_mask; + while ( mask != 0 && (mask & 1) != 0) { + mask >>= 1; + shift++; + } + blue_shift = shift; + + } else if (visual->class == PseudoColor && depth <= 8) { + int i; + for (i = 0; i < (1<<depth); i++) { + pseudo_map[i].pixel = i; + } + XQueryColors(w->core.screen->display, w->core.colormap, pseudo_map, (1<<depth)); + use_map = 1; + } if (image != NULL && computed != None) { ! Pixel pix; int x, y; ! Pixel red, green, blue; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { ! pix = XGetPixel(image, x, y); ! if (use_map) { ! /* Pixels are 16 bit; shift off the lower insignificant bits. */ ! pix >>= (16 - depth); ! red = pseudo_map[pix].red; ! green = pseudo_map[pix].green; ! blue = pseudo_map[pix].blue; ! } else if (use_masks) { ! red = (pix & red_mask) >> red_shift; ! green = (pix & green_mask) >> green_shift; ! blue = (pix & blue_mask) >> blue_shift; ! } else { ! /* Some wierd visual. Drop back to slow but safe XQueryColor. ! * We could convert these in batches (say 256) but this should be ! * so rare that it probably isn't worth the bloat. ! */ ! XColor color; ! color.pixel = pix; ! XQueryColor(w->core.screen->display, w->core.colormap, &color); ! red = color.red; ! green = color.green; ! blue = color.blue; ! } ! intensity = (red + blue + green) / 3; delta1 = abs(intensity - intensity1); delta2 = abs(intensity - intensity2); if (delta1 < delta2) { ! pix= colour1; } else { ! pix = colour1; } ! XPutPixel(image, x, y, pix); } } |