diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2019-09-25 18:49:21 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2019-09-25 18:49:21 (GMT) |
commit | 336c8740b21f24fed26559b5e5d1d347aa49a819 (patch) | |
tree | 02779a5f07f92b1a371a9594df19ce98dc041111 /tksao | |
parent | f9b8d12a4f5df44aabc2385045956e00e0eae5df (diff) | |
download | blt-336c8740b21f24fed26559b5e5d1d347aa49a819.zip blt-336c8740b21f24fed26559b5e5d1d347aa49a819.tar.gz blt-336c8740b21f24fed26559b5e5d1d347aa49a819.tar.bz2 |
backout colormapPM changes
Diffstat (limited to 'tksao')
-rw-r--r-- | tksao/frame/frame.C | 223 | ||||
-rw-r--r-- | tksao/frame/framebase.C | 15 | ||||
-rw-r--r-- | tksao/frame/framebase.h | 4 | ||||
-rw-r--r-- | tksao/frame/framergb.C | 262 |
4 files changed, 503 insertions, 1 deletions
diff --git a/tksao/frame/frame.C b/tksao/frame/frame.C index dc6a146..1225f09 100644 --- a/tksao/frame/frame.C +++ b/tksao/frame/frame.C @@ -555,7 +555,132 @@ void Frame::colormapCmd(int id, float b, float c, int i, update(BASE); } -void Frame::colormapBeginCmd() {} +#ifndef MAC_OSX_TK + +void Frame::colormapBeginCmd() +{ + // we need a colorScale before we can render + if (!validColorScale()) + return; + + // we need some fits data + // we assume the colorScale length will not change during motion calls + if (!context->cfits) + return; + + int width = options->width; + int height = options->height; + + // Create XImage + if (!(colormapXM = XGetImage(display, pixmap, 0, 0, + width, height, AllPlanes, ZPixmap))) { + internalError("Unable to Create Colormap XImage"); + return; + } + + // Create Pixmap + colormapPM = + Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, depth); + if (!colormapPM) { + internalError("Unable to Create Colormap Pixmap"); + return; + } + + // colormapGCXOR + colormapGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); + + // Create table index array + if (colormapData) + delete [] colormapData; + colormapData = new long[width*height]; + if (!colormapData) { + internalError("Unable to alloc tmp data array"); + return; + } + + // fill data array + // basics + int bytesPerPixel = colormapXM->bits_per_pixel/8; + + int length = colorScale->size() - 1; + int last = length * bytesPerPixel; + + FitsImage* sptr = context->cfits; + int mosaic = isMosaic(); + + long* dest = colormapData; + + // variable + double* mm = sptr->matrixToData(Coord::WIDGET).mm(); + FitsBound* params = sptr->getDataParams(context->secMode()); + int srcw = sptr->width(); + + double ll = sptr->low(); + double hh = sptr->high(); + double diff = hh - ll; + + // main loop + + SETSIGBUS + for (long jj=0; jj<height; jj++) { + for (long ii=0; ii<width; ii++, dest++) { + // default is bg + *dest = -2; + + if (mosaic) { + sptr = context->cfits; + + mm = sptr->matrixToData(Coord::WIDGET).mm(); + params = sptr->getDataParams(context->secMode()); + srcw = sptr->width(); + + ll = sptr->low(); + hh = sptr->high(); + diff = hh - ll; + } + + do { + double xx = ii*mm[0] + jj*mm[3] + mm[6]; + double yy = ii*mm[1] + jj*mm[4] + mm[7]; + + if (xx>=params->xmin && xx<params->xmax && + yy>=params->ymin && yy<params->ymax) { + double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); + + if (isfinite(diff) && isfinite(value)) { + if (value <= ll) + *dest = 0; + else if (value >= hh) + *dest = last; + else + *dest = (int)(((value - ll)/diff * length) + .5)*bytesPerPixel; + } + else + *dest = -1; + + break; + } + else { + if (mosaic) { + sptr = sptr->nextMosaic(); + + if (sptr) { + mm = sptr->matrixToData(Coord::WIDGET).mm(); + params = sptr->getDataParams(context->secMode()); + srcw = sptr->width(); + + ll = sptr->low(); + hh = sptr->high(); + diff = hh - ll; + } + } + } + } + while (mosaic && sptr); + } + } + CLEARSIGBUS +} void Frame::colormapMotionCmd(int id, float b, float c, int i, unsigned char* cells, int cnt) @@ -577,6 +702,100 @@ void Frame::colormapMotionCmd(int id, float b, float c, int i, updateColorCells(cells, cnt); updateColorScale(); + // if we have no data, stop now + if (!context->cfits) + return; + + // clear ximage + int& width = colormapXM->width; + int& height = colormapXM->height; + char* data = colormapXM->data; + int bytesPerPixel = colormapXM->bits_per_pixel/8; + int& bytesPerLine = colormapXM->bytes_per_line; + + const unsigned char* table = colorScale->colors(); + + long* src = colormapData; + for (long jj=0; jj<height; jj++) { + // line may be padded at end + char* dest = data + jj*bytesPerLine; + + for (long ii=0; ii<width; ii++, src++, dest+=bytesPerPixel) + switch (*src) { + case -1: + memcpy(dest, nanTrueColor_, bytesPerPixel); + break; + case -2: + memcpy(dest, bgTrueColor_, bytesPerPixel); + break; + default: + memcpy(dest, table+(*src), bytesPerPixel); + break; + } + } + + // XImage to Pixmap + TkPutImage(NULL, 0, display, colormapPM, widgetGC, colormapXM, + 0, 0, 0, 0, width, height); + + // Display Pixmap + Vector dd = Vector() * widgetToWindow; + XCopyArea(display, colormapPM, Tk_WindowId(tkwin), colormapGCXOR, 0, 0, + width, height, dd[0], dd[1]); + + // update panner + updatePanner(); +} + +void Frame::colormapEndCmd() +{ + if (colormapXM) { + XDestroyImage(colormapXM); + colormapXM = NULL; + } + + if (colormapPM) { + Tk_FreePixmap(display, colormapPM); + colormapPM = 0; + } + + if (colormapGCXOR) { + XFreeGC(display, colormapGCXOR); + colormapGCXOR = 0; + } + + if (colormapData) { + delete [] colormapData; + colormapData = NULL; + } + + update(BASE); // always update +} + +#else + +void Frame::colormapBeginCmd() {} + +void Frame::colormapMotionCmd(int id, float b, float c, int i, + unsigned char* cells, int cnt) +{ + // we need a colorScale before we can render + if (!validColorScale()) + return; + + // first check for change + if (cmapID == id && bias == b && contrast == c && invert == i && colorCells) + return; + + // we got a change + cmapID = id; + bias = b; + contrast = c; + invert = i; + + updateColorCells(cells, cnt); + updateColorScale(); + update(BASE); updatePanner(); } @@ -586,6 +805,8 @@ void Frame::colormapEndCmd() update(BASE); } +#endif + void Frame::getColorbarCmd() { ostringstream str; diff --git a/tksao/frame/framebase.C b/tksao/frame/framebase.C index dafaa60..86aa528 100644 --- a/tksao/frame/framebase.C +++ b/tksao/frame/framebase.C @@ -16,10 +16,25 @@ FrameBase::FrameBase(Tcl_Interp* i, Tk_Canvas c, Tk_Item* item) : Base(i, c, item) { +#ifndef MAC_OSX_TK + colormapXM = NULL; + colormapPM = 0; + colormapGCXOR = 0; +#endif } FrameBase::~FrameBase() { +#ifndef MAC_OSX_TK + if (colormapXM) + XDestroyImage(colormapXM); + + if (colormapPM) + Tk_FreePixmap(display, colormapPM); + + if (colormapGCXOR) + XFreeGC(display, colormapGCXOR); +#endif } void FrameBase::getInfoCmd(const Vector& vv, Coord::InternalSystem ref, diff --git a/tksao/frame/framebase.h b/tksao/frame/framebase.h index 457b5e3..70a1bd7 100644 --- a/tksao/frame/framebase.h +++ b/tksao/frame/framebase.h @@ -9,6 +9,10 @@ class FrameBase : public Base { protected: + XImage* colormapXM; // colormap dest ximage + Pixmap colormapPM; // colormap pixmap + GC colormapGCXOR; // GC for interactive colormap + Vector iisLastCursor; // iis cursor state info private: diff --git a/tksao/frame/framergb.C b/tksao/frame/framergb.C index 50ed145..7e77bb8 100644 --- a/tksao/frame/framergb.C +++ b/tksao/frame/framergb.C @@ -500,6 +500,266 @@ void FrameRGB::colormapCmd(float rb, float gb, float bb, update(BASE); } +#ifndef MAC_OSX_TK + +void FrameRGB::colormapBeginCmd() +{ + // we need a colorScale before we can render + if (!validColorScale()) + return; + + // we need some fits data + // we assume the colorScale length will not change during motion calls + if (!context[0].fits && !context[1].fits && !context[2].fits) + return; + + int width = options->width; + int height = options->height; + + // Create XImage + if (!(colormapXM = XGetImage(display, pixmap, 0, 0, + width, height, AllPlanes, ZPixmap))) { + internalError("Unable to Create Colormap XImage"); + return; + } + + // Create Pixmap + colormapPM = + Tk_GetPixmap(display, Tk_WindowId(tkwin), width, height, depth); + if (!colormapPM) { + internalError("Unable to Create Colormap Pixmap"); + return; + } + + // colormapGCXOR + colormapGCXOR = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); + + // Create table index array + for (int kk=0; kk<3; kk++) { + if (colormapData[kk]) + delete [] colormapData[kk]; + colormapData[kk] = new long[width*height]; + + if (!colormapData[kk]) { + internalError("Unable to alloc tmp data array"); + return; + } + } + + SETSIGBUS + + // fill data array + for (int kk=0; kk<3; kk++) { + if (!view[kk] || !context[kk].fits) + continue; + + // basics + int length = colorScale[kk]->size() - 1; + + FitsImage* sptr = context[kk].cfits; + int mosaic = context[kk].isMosaic(); + + // variable + double* mm = sptr->matrixToData(Coord::WIDGET).mm(); + FitsBound* params = sptr->getDataParams(context[kk].secMode()); + int srcw = sptr->width(); + + double ll = sptr->low(); + double hh = sptr->high(); + double diff = hh - ll; + + // main loop + long* dest = colormapData[kk]; + + for (long jj=0; jj<height; jj++) { + for (long ii=0; ii<width; ii++, dest++) { + *dest = -2; // bg + + if (mosaic) { + sptr = context[kk].cfits; + + mm = sptr->matrixToData(Coord::WIDGET).mm(); + params = sptr->getDataParams(context[kk].secMode()); + srcw = sptr->width(); + + ll = sptr->low(); + hh = sptr->high(); + diff = hh - ll; + } + + do { + double xx = ii*mm[0] + jj*mm[3] + mm[6]; + double yy = ii*mm[1] + jj*mm[4] + mm[7]; + + if (xx>=params->xmin && xx<params->xmax && + yy>=params->ymin && yy<params->ymax) { + double value = sptr->getValueDouble(long(yy)*srcw + long(xx)); + + if (isfinite(diff) && isfinite(value)) { + if (value <= ll) + *dest = 0; + else if (value >= hh) + *dest = length; + else + *dest = (int)(((value - ll)/diff * length) + .5); + } + else + *dest = -1; // nan + + break; + } + else { + if (mosaic) { + sptr = sptr->nextMosaic(); + + if (sptr) { + mm = sptr->matrixToData(Coord::WIDGET).mm(); + params = sptr->getDataParams(context[kk].secMode()); + srcw = sptr->width(); + + ll = sptr->low(); + hh = sptr->high(); + diff = hh - ll; + } + } + } + } + while (mosaic && sptr); + } + } + } + CLEARSIGBUS +} + +void FrameRGB::colormapMotionCmd(float rb, float gb, float bb, + float rc, float gc, float bc, int i, + unsigned char* cells, int cnt) +{ + // we need a colorScale before we can render + if (!validColorScale()) + return; + + // first check for change + if (bias[0] == rb && bias[1] == gb && bias[2] == bb && + contrast[0] == rc && contrast[1] == gc && contrast[2] == bc && + invert == i && colorCells) + return; + + // we got a change + bias[0] = rb; + bias[1] = gb; + bias[2] = bb; + contrast[0] = rc; + contrast[1] = gc; + contrast[2] = bc; + invert = i; + + updateColorCells(cells, cnt); + updateColorScale(); + + // special case + if ((!view[0] || !context[0].fits) && + (!view[1] || !context[1].fits) && + (!view[2] || !context[2].fits)) + return; + + int& width = colormapXM->width; + int& height = colormapXM->height; + + // create img + unsigned char* img = new unsigned char[width*height*3]; + memset(img, 0, width*height*3); + char* mk = new char[width*height]; + memset(mk, 0, width*height); + + for (int kk=0; kk<3; kk++) { + if (!view[kk] || !context[kk].fits) + continue; + + const unsigned char* table = colorScale[kk]->psColors(); + long* src = colormapData[kk]; + unsigned char* dest = img; + char* mptr = mk; + for (long jj=0; jj<height; jj++) + for (long ii=0; ii<width; ii++, src++, dest+=3, mptr++) + if (*src >= 0) { + memcpy(dest+kk, table+(*src), 1); + *mptr = 2; + } + else if (*src == -1 && *mptr < 2) + *mptr = 1; + } + + // set remainder to bg + { + unsigned char* dest = img; + char* mptr = mk; + for (long jj=0; jj<height; jj++) + for (long ii=0; ii<width; ii++, dest+=3, mptr++) + if (*mptr == 2) // good value + ; + else if (*mptr == 1) { // nan + *(dest ) = (unsigned char)nanColor->red; + *(dest+1) = (unsigned char)nanColor->green; + *(dest+2) = (unsigned char)nanColor->blue; + } + else { // bg + *(dest ) = (unsigned char)bgColor->red; + *(dest+1) = (unsigned char)bgColor->green; + *(dest+2) = (unsigned char)bgColor->blue; + } + } + + // build colormapXM + encodeTrueColor((unsigned char*)img, colormapXM); + + // clean up + if (img) + delete [] img; + if (mk) + delete [] mk; + + // XImage to Pixmap + TkPutImage(NULL, 0, display, colormapPM, widgetGC, colormapXM, + 0, 0, 0, 0, width, height); + + // Display Pixmap + Vector dd = Vector() * widgetToWindow; + XCopyArea(display, colormapPM, Tk_WindowId(tkwin), colormapGCXOR, 0, 0, + width, height, dd[0], dd[1]); + + // update panner + updatePanner(); +} + +void FrameRGB::colormapEndCmd() +{ + if (colormapXM) { + XDestroyImage(colormapXM); + colormapXM = NULL; + } + + if (colormapPM) { + Tk_FreePixmap(display, colormapPM); + colormapPM = 0; + } + + if (colormapGCXOR) { + XFreeGC(display, colormapGCXOR); + colormapGCXOR = 0; + } + + for (int kk=0; kk<3; kk++) + if (colormapData[kk]) { + delete [] colormapData[kk]; + colormapData[kk] = NULL; + } + + update(BASE); // always update +} + +#else + void FrameRGB::colormapBeginCmd() {} void FrameRGB::colormapMotionCmd(float rb, float gb, float bb, @@ -537,6 +797,8 @@ void FrameRGB::colormapEndCmd() update(BASE); } +#endif + void FrameRGB::getColorbarCmd() { ostringstream str; |