/*************************************************************************** fitshistogram.cpp - FITS Historgram ----------------- begin : Thu Mar 4th 2004 copyright : (C) 2004 by Jasem Mutlaq email : mutlaqja@ikarustech.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitshistogram.h" #include "fitsviewer.h" #include "fitsimage.h" #include "indi/fitsrw.h" #include #include #include #include #include #include #include #include #include #include #include #include FITSHistogram::FITSHistogram(TQWidget *parent, const char * name) : histDialog(parent, name) { viewer = (FITSViewer *) parent; setModal(false); minSlider->setMinValue(0); minSlider->setMaxValue(BARS-1); minSlider->setValue(0); maxSlider->setMinValue(0); maxSlider->setMaxValue(BARS-1); maxSlider->setValue(BARS-1); type = 0; napply=0; histFrame->setCursor(TQt::CrossCursor); histFrame->setMouseTracking(true); setMouseTracking(true); connect(minSlider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(updateBoxes())); connect(minSlider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(updateIntenFreq(int ))); connect(maxSlider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(updateBoxes())); connect(maxSlider, TQT_SIGNAL(valueChanged(int)), this, TQT_SLOT(updateIntenFreq(int ))); connect(applyB, TQT_SIGNAL(clicked()), this, TQT_SLOT(applyScale())); constructHistogram(viewer->imgBuffer); updateBoxes(); } FITSHistogram::~FITSHistogram() {} void FITSHistogram::updateBoxes() { if (minSlider->value() == BARS) minOUT->setText(TQString("%1").arg((int) viewer->stats.max)); else minOUT->setText(TQString("%1").arg( (int) ( ceil (minSlider->value() * binSize) + viewer->stats.min))); if (maxSlider->value() == BARS) maxOUT->setText(TQString("%1").arg((int) viewer->stats.max)); else maxOUT->setText(TQString("%1").arg( (int) ( ceil (maxSlider->value() * binSize) + viewer->stats.min))); update(); } void FITSHistogram::applyScale() { int swap; int min = minSlider->value(); int max = maxSlider->value(); FITSHistogramCommand *histC; //kdDebug() << "Width " << viewer->image->width << endl; if (min > max) { swap = min; min = max; max = swap; } min = (int) (min * binSize + viewer->stats.min); max = (int) (max * binSize + viewer->stats.min); napply++; // Auto if (autoR->isOn()) type = 0; // Linear else if (linearR->isOn()) type = 1; // Log else if (logR->isOn()) type = 2; // Exp else if (sqrtR->isOn()) type = 3; histC = new FITSHistogramCommand(viewer, this, type, min, max); viewer->history->addCommand(histC); } void FITSHistogram::constructHistogram(float * buffer) { int maxHeight = 0; int height = histFrame->height(); int id; int index; int range = (int) (viewer->stats.max - viewer->stats.min); for (int i=0; i < BARS; i++) histArray[i] = 0; binSize = ( (double) range / (double) BARS); //kdDebug() << "#2" << endl; if (binSize == 0 || buffer == NULL) return; for (int i=0; i < viewer->stats.width * viewer->stats.height; i++) { id = (int) ((buffer[i] - viewer->stats.min) / binSize); if (id >= BARS) id = BARS - 1; histArray[id]++; } if (binSize < 1) for (int i=0; i < BARS - 1; i++) if (histArray[i] == 0) { index = (int) ceil(i * binSize); if (index == (int) (ceil ((i+1) * binSize))) histArray[i] = histArray[i+1]; } maxHeight = findMax() / height; kdDebug() << "Maximum height is " << maxHeight << " -- binsize " << binSize << endl; histogram = new TQPixmap(500, 150, 1); histogram->fill(TQt::black); TQPainter p(histogram); TQPen pen( white, 1); p.setPen(pen); for (int i=0; i < BARS; i++) p.drawLine(i, height , i, height - (int) ((double) histArray[i] / (double) maxHeight)); } void FITSHistogram::paintEvent( TQPaintEvent */*e*/) { int height = histFrame->height(); int xMin = minSlider->value(), xMax = maxSlider->value(); TQPainter p(histFrame); TQPen pen; pen.setWidth(1); bitBlt(histFrame, 0, 0, histogram); pen.setColor(blue); p.setPen(pen); p.drawLine(xMin, height - 2, xMin, height/2 -2); pen.setColor(red); p.setPen(pen); p.drawLine(xMax, 2, xMax, height/2 -2); } void FITSHistogram::mouseMoveEvent( TQMouseEvent *e) { int x = e->x(); int y = e->y(); x -= histFrame->x(); y -= histFrame->y(); if (x < 0 || x >= BARS || y < 0 || y > histFrame->height() ) return; updateIntenFreq(x); } void FITSHistogram::updateIntenFreq(int x) { int index = (int) ceil(x * binSize); intensityOUT->setText(TQString("%1").arg((int) ( index + viewer->stats.min))); frequencyOUT->setText(TQString("%1").arg(histArray[x])); } int FITSHistogram::findMax() { int max =0; for (int i=0; i < BARS; i++) if (histArray[i] > max) max = histArray[i]; return max; } FITSHistogramCommand::FITSHistogramCommand(TQWidget * parent, FITSHistogram *inHisto, int newType, int lmin, int lmax) { viewer = (FITSViewer *) parent; type = newType; histo = inHisto; oldImage = new TQImage(); // TODO apply maximum compression against this buffer buffer = (float *) malloc (viewer->image->width * viewer->image->height * sizeof(float)); //if (buffer == NULL) //return; min = lmin; max = lmax; } FITSHistogramCommand::~FITSHistogramCommand() { free(buffer); delete (oldImage); } void FITSHistogramCommand::execute() { float val, bufferVal; double coeff; FITSImage *image = viewer->image; int width = image->width; int height = image->height; memcpy(buffer, viewer->imgBuffer,image->width * image->height * sizeof(float)); *oldImage = image->displayImage->copy(); switch (type) { case FITSImage::FITSAuto: case FITSImage::FITSLinear: for (int i=0; i < height; i++) for (int j=0; j < width; j++) { bufferVal = viewer->imgBuffer[i * width + j]; if (bufferVal < min) bufferVal = min; else if (bufferVal > max) bufferVal = max; //val = (int) (255. * ((double) (bufferVal - min) / (double) (max - min))); //val = (int) (max * ((double) (bufferVal - min) / (double) (max - min))); //val = (int) (bufferVal - min) * (max - min) + min; //if (val < min) val = min; //else if (val > max) val = max; //image->reducedImgBuffer[i * width + j] = val; viewer->imgBuffer[i * width + j] = bufferVal; } break; case FITSImage::FITSLog: //coeff = 255. / log(1 + max); coeff = max / log(1 + max); for (int i=0; i < height; i++) for (int j=0; j < width; j++) { bufferVal = viewer->imgBuffer[i * width + j]; if (bufferVal < min) bufferVal = min; else if (bufferVal > max) bufferVal = max; val = (coeff * log(1 + bufferVal)); if (val < min) val = min; else if (val > max) val = max; viewer->imgBuffer[i * width + j] = val; //image->reducedImgBuffer[i * width + j] = val; //displayImage->setPixel(j, height - i - 1, val); } break; case FITSImage::FITSSqrt: //coeff = 255. / sqrt(max); coeff = max / sqrt(max); for (int i=0; i < height; i++) for (int j=0; j < width; j++) { bufferVal = (int) viewer->imgBuffer[i * width + j]; if (bufferVal < min) bufferVal = min; else if (bufferVal > max) bufferVal = max; val = (int) (coeff * sqrt(bufferVal)); //image->reducedImgBuffer[i * width + j] = val; viewer->imgBuffer[i * width + j] = val; //displayImage->setPixel(j, height - i - 1, val); } break; default: break; } //int lmin= image->reducedImgBuffer[0]; float lmin= viewer->imgBuffer[0]; float lmax= viewer->imgBuffer[0]; int totalPix = width * height; for (int i=1; i < totalPix; i++) //if ( image->reducedImgBuffer[i] < lmin) lmin = image->reducedImgBuffer[i]; if ( viewer->imgBuffer[i] < lmin) lmin = viewer->imgBuffer[i]; else if (viewer->imgBuffer[i] > lmax) lmax = viewer->imgBuffer[i]; double datadiff = 255.; double pixdiff = lmax - lmin; double offs = -lmin * datadiff / pixdiff; double scale = datadiff / pixdiff; int tdata = 0; for (int i=0; i < height; i++) for (int j=0; j < width; j++) { //bp8 = (FITS_BITPIX8) image->reducedImgBuffer[i * width + j]; //bp8 = (FITS_BITPIX8) tdata = (long) (viewer->imgBuffer[i * width + j] * scale + offs); if (tdata < 0) tdata = 0; else if (tdata > 255) tdata = 255; image->displayImage->setPixel(j, height - i - 1, tdata); } viewer->calculateStats(); //viewer->updateImgBuffer(); if (histo != NULL) { histo->constructHistogram(viewer->imgBuffer); histo->update(); histo->updateBoxes(); } viewer->image->zoomToCurrent(); viewer->fitsChange(); } void FITSHistogramCommand::unexecute() { memcpy( viewer->imgBuffer, buffer, viewer->image->width * viewer->image->height * sizeof(float)); viewer->calculateStats(); *viewer->image->displayImage = oldImage->copy(); viewer->image->zoomToCurrent(); if (histo != NULL) { histo->constructHistogram(viewer->imgBuffer); histo->update(); histo->updateBoxes(); } } TQString FITSHistogramCommand::name() const { switch (type) { case 0: return i18n("Auto Scale"); break; case 1: return i18n("Linear Scale"); break; case 2: return i18n("Logarithmic Scale"); break; case 3: return i18n("Square Root Scale"); break; default: break; } return i18n("Unknown"); } #include "fitshistogram.moc"