summaryrefslogtreecommitdiff
path: root/src/imagecontrol.cc
diff options
context:
space:
mode:
authorMarius Nita <marius@cs.pdx.edu>2002-11-01 03:30:18 +0000
committerMarius Nita <marius@cs.pdx.edu>2002-11-01 03:30:18 +0000
commit110a1eeed9b5d0deb127a02364cf6c6fe29a9de8 (patch)
tree93f4bbe6f757ec830988e1aa7de80a4447b99962 /src/imagecontrol.cc
parent9247a7a616809e45bd26774d5aed7d24c618e6f2 (diff)
moved files into otk
Diffstat (limited to 'src/imagecontrol.cc')
-rw-r--r--src/imagecontrol.cc561
1 files changed, 0 insertions, 561 deletions
diff --git a/src/imagecontrol.cc b/src/imagecontrol.cc
deleted file mode 100644
index 7d091bb8..00000000
--- a/src/imagecontrol.cc
+++ /dev/null
@@ -1,561 +0,0 @@
-// -*- mode: C++; indent-tabs-mode: nil; -*-
-
-#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 "blackbox.hh"
-#include "basedisplay.hh"
-#include "color.hh"
-#include "image.hh"
-#include "texture.hh"
-
-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;
- }
-}
-
-BImageControl *ctrl = 0;
-
-BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn,
- bool _dither, int _cpc,
- unsigned long cache_timeout,
- unsigned long cmax) {
- if (! ctrl) ctrl = this;
-
- basedisplay = dpy;
- screeninfo = scrn;
- setDither(_dither);
- setColorsPerChannel(_cpc);
-
- cache_max = cmax;
- if (cache_timeout) {
- timer = new BTimer(basedisplay, this);
- timer->setTimeout(cache_timeout);
- timer->start();
- } else {
- timer = (BTimer *) 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->getDepth();
- window = screeninfo->getRootWindow();
- screen_number = screeninfo->getScreenNumber();
- colormap = screeninfo->getColormap();
-
- int count;
- XPixmapFormatValues *pmv = XListPixmapFormats(basedisplay->getXDisplay(),
- &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,
- "BImageControl::BImageControl: 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, "BImageControl::BImageControl: 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), 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,
- "BImageControl::BImageControl: 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,
- "BImageControl::BImageControl: 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), 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(basedisplay->getXDisplay(), colormap,
- &colors[i])) {
- colors[i].flags = DoRed|DoGreen|DoBlue;
- break;
- }
- }
- }
- }
- }
-
- break;
- }
-
- default:
- fprintf(stderr, "BImageControl::BImageControl: unsupported visual %d\n",
- getVisual()->c_class);
- exit(1);
- }
-}
-
-
-BImageControl::~BImageControl(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(basedisplay->getXDisplay(), colormap, pixels, ncolors, 0);
-
- delete [] colors;
- }
-
- if (! cache.empty()) {
- //#ifdef DEBUG
- fprintf(stderr, "BImageContol::~BImageControl: 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(basedisplay->getXDisplay(), it->pixmap);
- }
- if (timer) {
- timer->stop();
- delete timer;
- }
-}
-
-
-Pixmap BImageControl::searchCache(const unsigned int width,
- const unsigned int height,
- const unsigned long texture,
- const BColor &c1, const BColor &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 & BTexture::Gradient) {
- if (tmp.pixel2 == c2.pixel()) {
- tmp.count++;
- return tmp.pixmap;
- }
- } else {
- tmp.count++;
- return tmp.pixmap;
- }
- }
- return None;
-}
-
-
-Pixmap BImageControl::renderImage(unsigned int width, unsigned int height,
- const BTexture &texture) {
- if (texture.texture() & BTexture::Parent_Relative) return ParentRelative;
-
- Pixmap pixmap = searchCache(width, height, texture.texture(),
- texture.color(), texture.colorTo());
- if (pixmap) return pixmap;
-
- BImage 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() & BTexture::Gradient)
- tmp.pixel2 = texture.colorTo().pixel();
- else
- tmp.pixel2 = 0l;
-
- cache.push_back(tmp);
-
- if (cache.size() > cache_max) {
-#ifdef DEBUG
- fprintf(stderr, "BImageControl::renderImage: cache is large, "
- "forcing cleanout\n");
-#endif // DEBUG
-
- timeout();
- }
-
- return pixmap;
-}
-
-
-void BImageControl::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();
-}
-
-
-void BImageControl::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 BImageControl::getXColorTable(XColor **c, int *n) {
- if (c) *c = colors;
- if (n) *n = ncolors;
-}
-
-
-void BImageControl::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 BImageControl::installRootColormap(void) {
- int ncmap = 0;
- Colormap *cmaps =
- XListInstalledColormaps(basedisplay->getXDisplay(), window, &ncmap);
-
- if (cmaps) {
- bool install = True;
- for (int i = 0; i < ncmap; i++)
- if (*(cmaps + i) == colormap)
- install = False;
-
- if (install)
- XInstallColormap(basedisplay->getXDisplay(), colormap);
-
- XFree(cmaps);
- }
-}
-
-
-void BImageControl::setColorsPerChannel(int cpc) {
- if (cpc < 2) cpc = 2;
- if (cpc > 6) cpc = 6;
-
- colors_per_channel = cpc;
-}
-
-
-unsigned long BImageControl::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 BImageControl::CachedImage &image) const {
- return (image.count == 0);
- }
-};
-
-struct CacheCleaner {
- Display *display;
- ZeroRefCheck ref_check;
- CacheCleaner(Display *d): display(d) {}
- inline void operator()(const BImageControl::CachedImage& image) const {
- if (ref_check(image))
- XFreePixmap(display, image.pixmap);
- }
-};
-
-
-void BImageControl::timeout(void) {
- CacheCleaner cleaner(basedisplay->getXDisplay());
- std::for_each(cache.begin(), cache.end(), cleaner);
- cache.remove_if(cleaner.ref_check);
-}
-