00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "PreCompiled.h"
00020 #ifndef _PreComp_
00021 # include <cmath>
00022 # include <QMessageBox>
00023 #endif
00024
00025 #if defined(__MINGW32__)
00026 # include <GL/gl.h>
00027 # include <GL/glext.h>
00028 #endif
00029
00030 #include "GLImageBox.h"
00031
00032 using namespace ImageGui;
00033
00034 #if defined(Q_CC_MSVC)
00035 #pragma warning(disable:4305) // init: truncation from const double to float
00036 #endif
00037
00038
00039
00040
00041 GLImageBox::GLImageBox(QWidget * parent, const QGLWidget * shareWidget, Qt::WFlags f)
00042 : QGLWidget(parent, shareWidget, f)
00043 {
00044
00045
00046
00047
00048 setMouseTracking(true);
00049
00050
00051 _x0 = 0;
00052 _y0 = 0;
00053 _zoomFactor = 1.0;
00054 _base_x0 = 0;
00055 _base_y0 = 0;
00056 _pColorMap = 0;
00057 _numMapEntries = 0;
00058 }
00059
00060
00061
00062 GLImageBox::~GLImageBox()
00063 {
00064 try
00065 {
00066 delete [] _pColorMap;
00067 }
00068 catch(...) {}
00069 }
00070
00071
00072 void GLImageBox::initializeGL()
00073 {
00074 qglClearColor( Qt::black );
00075 }
00076
00077
00078
00079 void GLImageBox::resizeGL( int w, int h )
00080 {
00081 glViewport( 0, 0, (GLint)w, (GLint)h );
00082 glMatrixMode( GL_PROJECTION );
00083 glLoadIdentity();
00084 gluOrtho2D(0, width() - 1, height() - 1, 0);
00085 glMatrixMode(GL_MODELVIEW);
00086 }
00087
00088
00089 void GLImageBox::redraw()
00090 {
00091 glDraw();
00092 }
00093
00094
00095
00096 void GLImageBox::paintGL()
00097 {
00098
00099 glDrawBuffer(GL_BACK);
00100 glClear(GL_COLOR_BUFFER_BIT);
00101
00102
00103 drawImage();
00104
00105
00106 if (_image.hasValidData() == true)
00107 drawGraphics();
00108
00109
00110 glFinish();
00111
00112
00113
00114
00115
00116 }
00117
00118
00119 void GLImageBox::drawImage()
00120 {
00121 if (_image.hasValidData() == false)
00122 return;
00123
00124
00125
00126 int dx, dy;
00127 getDisplayedImageAreaSize(dx, dy);
00128
00129
00130 if ((dx > 0) && (dy > 0))
00131 {
00132
00133 int tlx = std::max<int>(0, _x0);
00134 int tly = std::max<int>(0, _y0);
00135
00136
00137 unsigned char* pPix = (unsigned char *)(_image.getPixelDataPtr());
00138 pPix += (unsigned long)(_image.getNumBytesPerPixel()) * (tly * _image.getWidth() + tlx);
00139
00140
00141 glDrawBuffer(GL_BACK);
00142 glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.getWidth());
00143 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00144 glPixelZoom(_zoomFactor, -_zoomFactor);
00145
00146
00147
00148
00149 int xx = (int)floor(ICToWC_X(tlx - 0.5) + 0.5);
00150 int yy = (int)floor(ICToWC_Y(tly - 0.5) + 0.5);
00151 glRasterPos2f(xx, yy);
00152
00153
00154
00155 double scale = (pow(2.0, _image.getNumBitsPerSample()) - 1.0) / (pow(2.0, _image.getNumSigBitsPerSample()) - 1.0);
00156 glPixelTransferf(GL_RED_SCALE, (float)scale);
00157 glPixelTransferf(GL_GREEN_SCALE, (float)scale);
00158 glPixelTransferf(GL_BLUE_SCALE, (float)scale);
00159
00160
00161 if (_pColorMap != 0)
00162 {
00163 glPixelTransferf(GL_MAP_COLOR, 1.0);
00164 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, _numMapEntries, _pColorMap);
00165 glPixelMapfv(GL_PIXEL_MAP_G_TO_G, _numMapEntries, _pColorMap + _numMapEntries);
00166 glPixelMapfv(GL_PIXEL_MAP_B_TO_B, _numMapEntries, _pColorMap + _numMapEntries * 2);
00167 glPixelMapfv(GL_PIXEL_MAP_A_TO_A, _numMapEntries, _pColorMap + _numMapEntries * 3);
00168 }
00169 else
00170 {
00171 glPixelTransferf(GL_MAP_COLOR, 0.0);
00172 float zero = 0.0;
00173 float one = 1.0;
00174 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 1, &zero);
00175 glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 1, &zero);
00176 glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 1, &zero);
00177 glPixelMapfv(GL_PIXEL_MAP_A_TO_A, 1, &one);
00178 }
00179
00180
00181 GLenum pixFormat;
00182 GLenum pixType;
00183 getPixFormat(pixFormat, pixType);
00184
00185
00186 glDrawPixels(dx, dy, pixFormat, pixType, (GLvoid *)pPix);
00187 glFlush();
00188 }
00189 }
00190
00191
00192
00193 void GLImageBox::getDisplayedImageAreaSize(int &dx, int &dy)
00194 {
00195 if (_image.hasValidData() == false)
00196 {
00197 dx = 0;
00198 dy = 0;
00199 }
00200 else
00201 {
00202
00203 limitCurrPos();
00204 limitZoomFactor();
00205
00206
00207
00208 int brx = (int)ceil(WCToIC_X(width() - 1));
00209 int bry = (int)ceil(WCToIC_Y(height() - 1));
00210
00211
00212 int itlx = std::max<int>(_x0, 0);
00213 int itly = std::max<int>(_y0, 0);
00214 int ibrx = std::min<int>(brx, (int)(_image.getWidth()) - 1);
00215 int ibry = std::min<int>(bry, (int)(_image.getHeight()) - 1);
00216 if ((itlx >= (int)(_image.getWidth())) ||
00217 (itly >= (int)(_image.getHeight())) ||
00218 (ibrx < 0) ||
00219 (ibry < 0))
00220 {
00221 dx = 0;
00222 dy = 0;
00223 }
00224 dx = ibrx - itlx + 1;
00225 dy = ibry - itly + 1;
00226 }
00227 }
00228
00229
00230
00231
00232 int GLImageBox::getImageSample(int x, int y, unsigned short sampleIndex, double &value)
00233 {
00234 return (_image.getSample(x, y, sampleIndex, value));
00235 }
00236
00237
00238 unsigned short GLImageBox::getImageNumSamplesPerPix()
00239 {
00240 return (_image.getNumSamples());
00241 }
00242
00243
00244 int GLImageBox::getImageFormat()
00245 {
00246 return (_image.getFormat());
00247 }
00248
00249
00250
00251 void GLImageBox::getPixFormat(GLenum &pixFormat, GLenum &pixType)
00252 {
00253 switch(_image.getFormat())
00254 {
00255 case IB_CF_GREY8:
00256 pixFormat = GL_LUMINANCE;
00257 pixType = GL_UNSIGNED_BYTE;
00258 break;
00259 case IB_CF_GREY16:
00260 pixFormat = GL_LUMINANCE;
00261 pixType = GL_UNSIGNED_SHORT;
00262 break;
00263 case IB_CF_GREY32:
00264 pixFormat = GL_LUMINANCE;
00265 pixType = GL_UNSIGNED_INT;
00266 break;
00267 case IB_CF_RGB24:
00268 pixFormat = GL_RGB;
00269 pixType = GL_UNSIGNED_BYTE;
00270 break;
00271 #ifndef FC_OS_CYGWIN
00272 case IB_CF_BGR24:
00273 pixFormat = GL_BGR_EXT;
00274 pixType = GL_UNSIGNED_BYTE;
00275 break;
00276 case IB_CF_RGB48:
00277 pixFormat = GL_RGB;
00278 pixType = GL_UNSIGNED_SHORT;
00279 break;
00280 case IB_CF_BGR48:
00281 pixFormat = GL_BGR_EXT;
00282 pixType = GL_UNSIGNED_SHORT;
00283 break;
00284 #endif
00285 case IB_CF_RGBA32:
00286 pixFormat = GL_RGBA;
00287 pixType = GL_UNSIGNED_BYTE;
00288 break;
00289 case IB_CF_RGBA64:
00290 pixFormat = GL_RGBA;
00291 pixType = GL_UNSIGNED_SHORT;
00292 break;
00293 #ifndef FC_OS_CYGWIN
00294 case IB_CF_BGRA32:
00295 pixFormat = GL_BGRA_EXT;
00296 pixType = GL_UNSIGNED_BYTE;
00297 break;
00298 case IB_CF_BGRA64:
00299 pixFormat = GL_BGRA_EXT;
00300 pixType = GL_UNSIGNED_SHORT;
00301 break;
00302 #endif
00303 default:
00304
00305 pixFormat = GL_LUMINANCE;
00306 pixType = GL_UNSIGNED_BYTE;
00307 QMessageBox::warning((QWidget *)this, tr("Image pixel format"),
00308 tr("Undefined type of colour space for image viewing"));
00309 return;
00310 }
00311 }
00312
00313
00314
00315 void GLImageBox::limitCurrPos()
00316 {
00317 if (_image.hasValidData() == false)
00318 return;
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 }
00331
00332
00333 void GLImageBox::limitZoomFactor()
00334 {
00335 if (_zoomFactor > 64.0)
00336 _zoomFactor = 64.0;
00337 else if (_zoomFactor < (1.0 / 64.0))
00338 _zoomFactor = 1.0 / 64.0;
00339 }
00340
00341
00342
00343 void GLImageBox::setCurrPos(int x0, int y0)
00344 {
00345 _x0 = x0;
00346 _y0 = y0;
00347 limitCurrPos();
00348 }
00349
00350
00351 void GLImageBox::fixBasePosCurr()
00352 {
00353 if (_image.hasValidData() == false)
00354 {
00355 _base_x0 = 0;
00356 _base_y0 = 0;
00357 }
00358 else
00359 {
00360 _base_x0 = _x0;
00361 _base_y0 = _y0;
00362 }
00363 }
00364
00365
00366
00367
00368 void GLImageBox::setZoomFactor(double zoomFactor, bool useCentrePt, int ICx, int ICy)
00369 {
00370 if ((useCentrePt == false) || (_image.hasValidData() == false))
00371 {
00372 _zoomFactor = zoomFactor;
00373 limitZoomFactor();
00374 }
00375 else
00376 {
00377
00378 _zoomFactor = zoomFactor;
00379 limitZoomFactor();
00380
00381
00382 int ix, iy;
00383 getCentrePoint(ix, iy);
00384
00385
00386
00387 setCurrPos(_x0 - ix + ICx, _y0 - iy + ICy);
00388 }
00389 }
00390
00391
00392
00393
00394 void GLImageBox::stretchToFit()
00395 {
00396 if (_image.hasValidData() == false)
00397 return;
00398
00399 setToFit();
00400 glDraw();
00401 }
00402
00403
00404
00405
00406 void GLImageBox::setToFit()
00407 {
00408 if (_image.hasValidData() == false)
00409 return;
00410
00411
00412 double zoomX = (double)width() / (double)(_image.getWidth());
00413 double zoomY = (double)height() / (double)(_image.getHeight());
00414 if (zoomX > zoomY)
00415 _zoomFactor = zoomY;
00416 else
00417 _zoomFactor = zoomX;
00418 limitZoomFactor();
00419
00420
00421 setCurrPos(0, 0);
00422 }
00423
00424
00425
00426
00427
00428 void GLImageBox::setNormal()
00429 {
00430 if (_image.hasValidData() == false)
00431 return;
00432
00433 if (((int)(_image.getWidth()) < width()) && ((int)(_image.getHeight()) < height()))
00434 {
00435 setZoomFactor(1.0, true, _image.getWidth() / 2, _image.getHeight() / 2);
00436 }
00437 else
00438 {
00439 _zoomFactor = 1;
00440 setCurrPos(0, 0);
00441 }
00442 }
00443
00444
00445 void GLImageBox::getCentrePoint(int &ICx, int &ICy)
00446 {
00447 ICx = (int)floor(WCToIC_X((double)(width() - 1) / 2.0) + 0.5);
00448 ICy = (int)floor(WCToIC_Y((double)(height() - 1) / 2.0) + 0.5);
00449 }
00450
00451
00452
00453 void GLImageBox::relMoveWC(int WCdx, int WCdy)
00454 {
00455 double ICdx = WCdx / _zoomFactor;
00456 double ICdy = WCdy / _zoomFactor;
00457 setCurrPos(_base_x0 - (int)floor(ICdx + 0.5), _base_y0 - (int)floor(ICdy + 0.5));
00458 glDraw();
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 double GLImageBox::WCToIC_X(double WidgetX)
00471 {
00472 return ((double)_x0 - 0.5 + (WidgetX + 0.5) / _zoomFactor);
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 double GLImageBox::WCToIC_Y(double WidgetY)
00485 {
00486 return ((double)_y0 - 0.5 + (WidgetY + 0.5) / _zoomFactor);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 double GLImageBox::ICToWC_X(double ImageX)
00499 {
00500 return ((ImageX - (double)_x0 + 0.5) * _zoomFactor - 0.5);
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 double GLImageBox::ICToWC_Y(double ImageY)
00513 {
00514 return ((ImageY - (double)_y0 + 0.5) * _zoomFactor - 0.5);
00515 }
00516
00517
00518
00519 void GLImageBox::clearImage()
00520 {
00521 _image.clear();
00522 resetDisplay();
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 int GLImageBox::createImageCopy(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, int displayMode)
00539 {
00540
00541 int ret = _image.createCopy(pSrcPixelData, width, height, format, numSigBitsPerSample);
00542
00543
00544 if (displayMode == IV_DISPLAY_RESET)
00545 {
00546
00547 resetDisplay();
00548 }
00549 else if (displayMode == IV_DISPLAY_FITIMAGE)
00550 {
00551
00552 setToFit();
00553 }
00554 else
00555 {
00556
00557 limitCurrPos();
00558 limitZoomFactor();
00559 }
00560 return ret;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 int GLImageBox::pointImageTo(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, bool takeOwnership, int displayMode)
00581 {
00582
00583 int ret = _image.pointTo(pSrcPixelData, width, height, format, numSigBitsPerSample, takeOwnership);
00584
00585
00586 if (displayMode == IV_DISPLAY_RESET)
00587 {
00588
00589 resetDisplay();
00590 }
00591 else if (displayMode == IV_DISPLAY_FITIMAGE)
00592 {
00593
00594 setToFit();
00595 }
00596 else
00597 {
00598
00599 limitCurrPos();
00600 limitZoomFactor();
00601 }
00602 return ret;
00603 }
00604
00605
00606 void GLImageBox::resetDisplay()
00607 {
00608 clearColorMap();
00609 setNormal();
00610 }
00611
00612
00613 void GLImageBox::clearColorMap()
00614 {
00615 delete [] _pColorMap;
00616 _pColorMap = 0;
00617 _numMapEntries = 0;
00618 }
00619
00620
00621 int GLImageBox::calcNumColorMapEntries()
00622 {
00623
00624
00625
00626 GLint maxMapEntries;
00627 glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &maxMapEntries);
00628 int NumEntries = maxMapEntries;
00629 if (_image.hasValidData() == true)
00630 NumEntries = (int)std::min<double>(pow(2.0, (double)(_image.getNumSigBitsPerSample())), (double)maxMapEntries);
00631 return NumEntries;
00632 }
00633
00634
00635
00636
00637
00638 int GLImageBox::createColorMap(int numEntriesReq, bool Initialise)
00639 {
00640
00641 int maxNumEntries = calcNumColorMapEntries();
00642 int numEntries;
00643 if (numEntriesReq <= 0)
00644 numEntries = maxNumEntries;
00645 else
00646 numEntries = std::min<int>(numEntriesReq, maxNumEntries);
00647
00648
00649 if (numEntries != _numMapEntries)
00650 {
00651 clearColorMap();
00652 _numMapEntries = numEntries;
00653
00654
00655 try
00656 {
00657 _pColorMap = new float[4 * _numMapEntries];
00658 }
00659 catch(...)
00660 {
00661 clearColorMap();
00662 return -1;
00663 }
00664 }
00665
00666
00667
00668 if (Initialise == true)
00669 {
00670
00671 int arrayIndex = 0;
00672 for (int chan = 0; chan < 3; chan++)
00673 {
00674 for (int in = 0; in < _numMapEntries; in++)
00675 {
00676 _pColorMap[arrayIndex] = (float)in / (float)(_numMapEntries - 1);
00677 arrayIndex++;
00678 }
00679 }
00680
00681 for (int in = 0; in < _numMapEntries; in++)
00682 {
00683 _pColorMap[arrayIndex] = 1.0;
00684 arrayIndex++;
00685 }
00686 }
00687
00688 return 0;
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698 int GLImageBox::setColorMapRGBAValue(int index, float red, float green, float blue, float alpha)
00699 {
00700 if ((index < 0) || (index >= _numMapEntries) ||
00701 (red < 0.0) || (red > 1.0) ||
00702 (green < 0.0) || (green > 1.0) ||
00703 (blue < 0.0) || (blue > 1.0) ||
00704 (alpha < 0.0) || (alpha > 1.0))
00705 return -1;
00706
00707 _pColorMap[index] = red;
00708 _pColorMap[_numMapEntries + index] = green;
00709 _pColorMap[_numMapEntries * 2 + index] = blue;
00710 _pColorMap[_numMapEntries * 3 + index] = alpha;
00711 return 0;
00712 }
00713
00714
00715
00716
00717
00718 int GLImageBox::setColorMapRedValue(int index, float value)
00719 {
00720 if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
00721 return -1;
00722
00723 _pColorMap[index] = value;
00724 return 0;
00725 }
00726
00727
00728
00729
00730
00731 int GLImageBox::setColorMapGreenValue(int index, float value)
00732 {
00733 if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
00734 return -1;
00735
00736 _pColorMap[_numMapEntries + index] = value;
00737 return 0;
00738 }
00739
00740
00741
00742
00743
00744 int GLImageBox::setColorMapBlueValue(int index, float value)
00745 {
00746 if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
00747 return -1;
00748
00749 _pColorMap[_numMapEntries * 2 + index] = value;
00750 return 0;
00751 }
00752
00753
00754
00755
00756
00757 int GLImageBox::setColorMapAlphaValue(int index, float value)
00758 {
00759 if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
00760 return -1;
00761
00762 _pColorMap[_numMapEntries * 3 + index] = value;
00763 return 0;
00764 }
00765
00766
00767 unsigned int GLImageBox::pixValToMapIndex(double PixVal)
00768 {
00769 if (_pColorMap != NULL)
00770 {
00771 double MaxVal = pow(2.0, _image.getNumBitsPerSample()) - 1.0;
00772 double Scale = (pow(2.0, _image.getNumBitsPerSample()) - 1.0) / (pow(2.0, _image.getNumSigBitsPerSample()) - 1.0);
00773 double PixVal01 = Scale * PixVal / MaxVal;
00774 int numMapEntries = getNumColorMapEntries();
00775 unsigned int MapIndex = (unsigned int)floor(0.5 + PixVal01 * (double)(numMapEntries - 1));
00776 return MapIndex;
00777 }
00778 else
00779 {
00780 return 0;
00781 }
00782 }
00783
00784
00785 #include "moc_GLImageBox.cpp"