diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-01-23 23:42:46 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-01-23 23:42:46 +0000 |
| commit | f2e005f4d99c069431f27a102cef2ee26991ca97 (patch) | |
| tree | c92797fa7057f880ff12d9c0332ba0f239224784 /otk/imagecontrol.cc | |
| parent | 104c1a164b1e4e881e141d14263895401779d453 (diff) | |
remove the old blackbox bullshit
Diffstat (limited to 'otk/imagecontrol.cc')
| -rw-r--r-- | otk/imagecontrol.cc | 556 |
1 files changed, 0 insertions, 556 deletions
diff --git a/otk/imagecontrol.cc b/otk/imagecontrol.cc deleted file mode 100644 index ab8f5c50..00000000 --- a/otk/imagecontrol.cc +++ /dev/null @@ -1,556 +0,0 @@ -// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif // HAVE_CONFIG_H - -extern "C" { -#ifdef HAVE_STDIO_H -# include <stdio.h> -#endif // HAVE_STDIO_H - -#ifdef HAVE_CTYPE_H -# include <ctype.h> -#endif // HAVE_CTYPE_H - -#include <X11/Xlib.h> -} - -#include <algorithm> - -#include "display.hh" -#include "color.hh" -#include "image.hh" -#include "texture.hh" - -namespace otk { - -static unsigned long bsqrt(unsigned long x) { - if (x <= 0) return 0; - if (x == 1) return 1; - - unsigned long r = x >> 1; - unsigned long q; - - while (1) { - q = x / r; - if (q >= r) return r; - r = (r + q) >> 1; - } -} - -ImageControl *ctrl = 0; - -ImageControl::ImageControl(const ScreenInfo *scrn, - bool _dither, int _cpc, - unsigned long cache_timeout, - unsigned long cmax) { - if (! ctrl) ctrl = this; - - screeninfo = scrn; - setDither(_dither); - setColorsPerChannel(_cpc); - - cache_max = cmax; - if (cache_timeout) - timer = new Timer(cache_timeout, (Timer::TimeoutHandler)timeout, this); - else - timer = (Timer *) 0; - - colors = (XColor *) 0; - ncolors = 0; - - grad_xbuffer = grad_ybuffer = (unsigned int *) 0; - grad_buffer_width = grad_buffer_height = 0; - - sqrt_table = (unsigned long *) 0; - - screen_depth = screeninfo->depth(); - window = screeninfo->rootWindow(); - screen_number = screeninfo->screen(); - colormap = screeninfo->colormap(); - - int count; - XPixmapFormatValues *pmv = XListPixmapFormats(**display, - &count); - if (pmv) { - bits_per_pixel = 0; - for (int i = 0; i < count; i++) - if (pmv[i].depth == screen_depth) { - bits_per_pixel = pmv[i].bits_per_pixel; - break; - } - - XFree(pmv); - } - - if (bits_per_pixel == 0) bits_per_pixel = screen_depth; - if (bits_per_pixel >= 24) setDither(False); - - red_offset = green_offset = blue_offset = 0; - - switch (getVisual()->c_class) { - case TrueColor: { - int i; - - // compute color tables - unsigned long red_mask = getVisual()->red_mask, - green_mask = getVisual()->green_mask, - blue_mask = getVisual()->blue_mask; - - while (! (red_mask & 1)) { red_offset++; red_mask >>= 1; } - while (! (green_mask & 1)) { green_offset++; green_mask >>= 1; } - while (! (blue_mask & 1)) { blue_offset++; blue_mask >>= 1; } - - red_bits = 255 / red_mask; - green_bits = 255 / green_mask; - blue_bits = 255 / blue_mask; - - for (i = 0; i < 256; i++) { - red_color_table[i] = i / red_bits; - green_color_table[i] = i / green_bits; - blue_color_table[i] = i / blue_bits; - } - break; - } - - case PseudoColor: - case StaticColor: { - ncolors = colors_per_channel * colors_per_channel * colors_per_channel; - - if (ncolors > (1 << screen_depth)) { - colors_per_channel = (1 << screen_depth) / 3; - ncolors = colors_per_channel * colors_per_channel * colors_per_channel; - } - - if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) { - fprintf(stderr, - "ImageControl::ImageControl: invalid colormap size %d " - "(%d/%d/%d) - reducing", - ncolors, colors_per_channel, colors_per_channel, - colors_per_channel); - - colors_per_channel = (1 << screen_depth) / 3; - } - - colors = new XColor[ncolors]; - if (! colors) { - fprintf(stderr, "ImageControl::ImageControl: error allocating " - "colormap\n"); - exit(1); - } - - int i = 0, ii, p, r, g, b, - -#ifdef ORDEREDPSEUDO - bits = 256 / colors_per_channel; -#else // !ORDEREDPSEUDO - bits = 255 / (colors_per_channel - 1); -#endif // ORDEREDPSEUDO - - red_bits = green_bits = blue_bits = bits; - - for (i = 0; i < 256; i++) - red_color_table[i] = green_color_table[i] = blue_color_table[i] = - i / bits; - - for (r = 0, i = 0; r < colors_per_channel; r++) - for (g = 0; g < colors_per_channel; g++) - for (b = 0; b < colors_per_channel; b++, i++) { - colors[i].red = (r * 0xffff) / (colors_per_channel - 1); - colors[i].green = (g * 0xffff) / (colors_per_channel - 1); - colors[i].blue = (b * 0xffff) / (colors_per_channel - 1);; - colors[i].flags = DoRed|DoGreen|DoBlue; - } - - for (i = 0; i < ncolors; i++) { - if (! XAllocColor(**display, colormap, &colors[i])) { - fprintf(stderr, "couldn't alloc color %i %i %i\n", - colors[i].red, colors[i].green, colors[i].blue); - colors[i].flags = 0; - } else { - colors[i].flags = DoRed|DoGreen|DoBlue; - } - } - - XColor icolors[256]; - int incolors = (((1 << screen_depth) > 256) ? 256 : (1 << screen_depth)); - - for (i = 0; i < incolors; i++) - icolors[i].pixel = i; - - XQueryColors(**display, colormap, icolors, incolors); - for (i = 0; i < ncolors; i++) { - if (! colors[i].flags) { - unsigned long chk = 0xffffffff, pixel, close = 0; - - p = 2; - while (p--) { - for (ii = 0; ii < incolors; ii++) { - r = (colors[i].red - icolors[i].red) >> 8; - g = (colors[i].green - icolors[i].green) >> 8; - b = (colors[i].blue - icolors[i].blue) >> 8; - pixel = (r * r) + (g * g) + (b * b); - - if (pixel < chk) { - chk = pixel; - close = ii; - } - - colors[i].red = icolors[close].red; - colors[i].green = icolors[close].green; - colors[i].blue = icolors[close].blue; - - if (XAllocColor(**display, colormap, - &colors[i])) { - colors[i].flags = DoRed|DoGreen|DoBlue; - break; - } - } - } - } - } - - break; - } - - case GrayScale: - case StaticGray: { - if (getVisual()->c_class == StaticGray) { - ncolors = 1 << screen_depth; - } else { - ncolors = colors_per_channel * colors_per_channel * colors_per_channel; - - if (ncolors > (1 << screen_depth)) { - colors_per_channel = (1 << screen_depth) / 3; - ncolors = - colors_per_channel * colors_per_channel * colors_per_channel; - } - } - - if (colors_per_channel < 2 || ncolors > (1 << screen_depth)) { - fprintf(stderr, - "ImageControl::ImageControl: invalid colormap size %d " - "(%d/%d/%d) - reducing", - ncolors, colors_per_channel, colors_per_channel, - colors_per_channel); - - colors_per_channel = (1 << screen_depth) / 3; - } - - colors = new XColor[ncolors]; - if (! colors) { - fprintf(stderr, - "ImageControl::ImageControl: error allocating colormap\n"); - exit(1); - } - - int i = 0, ii, p, bits = 255 / (colors_per_channel - 1); - red_bits = green_bits = blue_bits = bits; - - for (i = 0; i < 256; i++) - red_color_table[i] = green_color_table[i] = blue_color_table[i] = - i / bits; - - for (i = 0; i < ncolors; i++) { - colors[i].red = (i * 0xffff) / (colors_per_channel - 1); - colors[i].green = (i * 0xffff) / (colors_per_channel - 1); - colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);; - colors[i].flags = DoRed|DoGreen|DoBlue; - - if (! XAllocColor(**display, colormap, - &colors[i])) { - fprintf(stderr, "couldn't alloc color %i %i %i\n", - colors[i].red, colors[i].green, colors[i].blue); - colors[i].flags = 0; - } else { - colors[i].flags = DoRed|DoGreen|DoBlue; - } - } - - XColor icolors[256]; - int incolors = (((1 << screen_depth) > 256) ? 256 : - (1 << screen_depth)); - - for (i = 0; i < incolors; i++) - icolors[i].pixel = i; - - XQueryColors(**display, colormap, icolors, incolors); - for (i = 0; i < ncolors; i++) { - if (! colors[i].flags) { - unsigned long chk = 0xffffffff, pixel, close = 0; - - p = 2; - while (p--) { - for (ii = 0; ii < incolors; ii++) { - int r = (colors[i].red - icolors[i].red) >> 8; - int g = (colors[i].green - icolors[i].green) >> 8; - int b = (colors[i].blue - icolors[i].blue) >> 8; - pixel = (r * r) + (g * g) + (b * b); - - if (pixel < chk) { - chk = pixel; - close = ii; - } - - colors[i].red = icolors[close].red; - colors[i].green = icolors[close].green; - colors[i].blue = icolors[close].blue; - - if (XAllocColor(**display, colormap, - &colors[i])) { - colors[i].flags = DoRed|DoGreen|DoBlue; - break; - } - } - } - } - } - - break; - } - - default: - fprintf(stderr, "ImageControl::ImageControl: unsupported visual %d\n", - getVisual()->c_class); - exit(1); - } -} - - -ImageControl::~ImageControl(void) { - delete [] sqrt_table; - - delete [] grad_xbuffer; - - delete [] grad_ybuffer; - - if (colors) { - unsigned long *pixels = new unsigned long [ncolors]; - - for (int i = 0; i < ncolors; i++) - *(pixels + i) = (*(colors + i)).pixel; - - XFreeColors(**display, colormap, pixels, ncolors, 0); - - delete [] colors; - } - - if (! cache.empty()) { - //#ifdef DEBUG - fprintf(stderr, "ImageContol::~ImageControl: pixmap cache - " - "releasing %d pixmaps\n", cache.size()); - //#endif - CacheContainer::iterator it = cache.begin(); - const CacheContainer::iterator end = cache.end(); - for (; it != end; ++it) - XFreePixmap(**display, it->pixmap); - } - if (timer) - delete timer; -} - - -Pixmap ImageControl::searchCache(const unsigned int width, - const unsigned int height, - const unsigned long texture, - const Color &c1, const Color &c2) { - if (cache.empty()) - return None; - - CacheContainer::iterator it = cache.begin(); - const CacheContainer::iterator end = cache.end(); - for (; it != end; ++it) { - CachedImage& tmp = *it; - if (tmp.width == width && tmp.height == height && - tmp.texture == texture && tmp.pixel1 == c1.pixel()) - if (texture & Texture::Gradient) { - if (tmp.pixel2 == c2.pixel()) { - tmp.count++; - return tmp.pixmap; - } - } else { - tmp.count++; - return tmp.pixmap; - } - } - return None; -} - - -Pixmap ImageControl::renderImage(unsigned int width, unsigned int height, - const Texture &texture) { - if (texture.texture() & Texture::Parent_Relative) return ParentRelative; - - Pixmap pixmap = searchCache(width, height, texture.texture(), - texture.color(), texture.colorTo()); - if (pixmap) return pixmap; - - Image image(this, width, height); - pixmap = image.render(texture); - - if (! pixmap) - return None; - - CachedImage tmp; - - tmp.pixmap = pixmap; - tmp.width = width; - tmp.height = height; - tmp.count = 1; - tmp.texture = texture.texture(); - tmp.pixel1 = texture.color().pixel(); - - if (texture.texture() & Texture::Gradient) - tmp.pixel2 = texture.colorTo().pixel(); - else - tmp.pixel2 = 0l; - - cache.push_back(tmp); - - if (cache.size() > cache_max) { -#ifdef DEBUG - fprintf(stderr, "ImageControl::renderImage: cache is large, " - "forcing cleanout\n"); -#endif // DEBUG - - timeout(this); - } - - return pixmap; -} - - -void ImageControl::removeImage(Pixmap pixmap) { - if (! pixmap) - return; - - CacheContainer::iterator it = cache.begin(); - const CacheContainer::iterator end = cache.end(); - for (; it != end; ++it) { - CachedImage &tmp = *it; - if (tmp.pixmap == pixmap && tmp.count > 0) - tmp.count--; - } - - if (! timer) - timeout(this); -} - - -void ImageControl::getColorTables(unsigned char **rmt, unsigned char **gmt, - unsigned char **bmt, - int *roff, int *goff, int *boff, - int *rbit, int *gbit, int *bbit) { - if (rmt) *rmt = red_color_table; - if (gmt) *gmt = green_color_table; - if (bmt) *bmt = blue_color_table; - - if (roff) *roff = red_offset; - if (goff) *goff = green_offset; - if (boff) *boff = blue_offset; - - if (rbit) *rbit = red_bits; - if (gbit) *gbit = green_bits; - if (bbit) *bbit = blue_bits; -} - - -void ImageControl::getXColorTable(XColor **c, int *n) { - if (c) *c = colors; - if (n) *n = ncolors; -} - - -void ImageControl::getGradientBuffers(unsigned int w, - unsigned int h, - unsigned int **xbuf, - unsigned int **ybuf) -{ - if (w > grad_buffer_width) { - if (grad_xbuffer) - delete [] grad_xbuffer; - - grad_buffer_width = w; - - grad_xbuffer = new unsigned int[grad_buffer_width * 3]; - } - - if (h > grad_buffer_height) { - if (grad_ybuffer) - delete [] grad_ybuffer; - - grad_buffer_height = h; - - grad_ybuffer = new unsigned int[grad_buffer_height * 3]; - } - - *xbuf = grad_xbuffer; - *ybuf = grad_ybuffer; -} - - -void ImageControl::installRootColormap(void) { - int ncmap = 0; - Colormap *cmaps = - XListInstalledColormaps(**display, window, &ncmap); - - if (cmaps) { - bool install = True; - for (int i = 0; i < ncmap; i++) - if (*(cmaps + i) == colormap) - install = False; - - if (install) - XInstallColormap(**display, colormap); - - XFree(cmaps); - } -} - - -void ImageControl::setColorsPerChannel(int cpc) { - if (cpc < 2) cpc = 2; - if (cpc > 6) cpc = 6; - - colors_per_channel = cpc; -} - - -unsigned long ImageControl::getSqrt(unsigned int x) { - if (! sqrt_table) { - // build sqrt table for use with elliptic gradient - - sqrt_table = new unsigned long[(256 * 256 * 2) + 1]; - - for (int i = 0; i < (256 * 256 * 2); i++) - *(sqrt_table + i) = bsqrt(i); - } - - return (*(sqrt_table + x)); -} - - -struct ZeroRefCheck { - inline bool operator()(const ImageControl::CachedImage &image) const { - return (image.count == 0); - } -}; - -struct CacheCleaner { - ZeroRefCheck ref_check; - CacheCleaner() {} - inline void operator()(const ImageControl::CachedImage& image) const { - if (ref_check(image)) - XFreePixmap(**display, image.pixmap); - } -}; - - -void ImageControl::timeout(ImageControl *t) { - CacheCleaner cleaner; - std::for_each(t->cache.begin(), t->cache.end(), cleaner); - t->cache.remove_if(cleaner.ref_check); -} - -} |
