ImageCanvas.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   ImageCanvas.cpp
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Fall 2008
00006    <!-------------------------------------------------------------------->**/
00007 
00008 #include "ImageCanvas.h"
00009 #include "RenderThread.h"
00010 #include "Gui.h"
00011 
00012 #include <renderers/PointSample.h>
00013 #include <utils/SpectralSampleSet.h>
00014 
00015 ImageCanvas::ImageCanvas(Gui *gui, unsigned width, unsigned height)
00016    : Canvas(gui, width, height), 
00017      NaiveRenderOutput(), 
00018      m_qimage(NULL), m_image(NULL), m_renderCount(NULL)
00019 {
00020    m_qimage = new QImage(m_width, m_height, QImage::Format_RGB32);
00021    m_mainProxy = new MainSyscallProxy();
00022    
00023    _init();
00024 }
00025 
00026 ImageCanvas::ImageCanvas(Gui *gui, const QImage &background)
00027    : Canvas(gui, background.width(), background.height()), 
00028      NaiveRenderOutput(), 
00029      m_qimage(new QImage(background)), m_image(NULL), m_renderCount(NULL)
00030 {
00031    _init();
00032 }
00033 
00034 ImageCanvas::~ImageCanvas() {
00035    safeDelete(m_qimage);
00036    safeDelete(m_image);
00037    safeDeleteArray(m_renderCount);
00038 }
00039 
00040 
00041 bool ImageCanvas::save(const char *fileName) {
00042    if (m_qimage == NULL)
00043       return false;
00044    
00045    return m_qimage->save(QString(fileName), NULL, -1);
00046 }
00047 
00048 bool ImageCanvas::load(const char *fileName) {
00049    QImage *temp = new QImage;
00050    if (!temp->load(QString(fileName)))
00051       return false;
00052    
00053    if (temp->format() != QImage::Format_RGB32) {
00054       QImage *old = temp;
00055       
00056       temp = new QImage(old->convertToFormat(QImage::Format_RGB32));
00057       
00058       safeDelete(old);
00059    }
00060    
00061    setSize(temp->width(), temp->height());
00062    
00063    memcpy(getData(), temp->bits(), temp->numBytes());
00064    update();
00065    
00066    safeDelete(temp);
00067    return true;
00068 }
00069 
00070 
00071 void ImageCanvas::setPixel(unsigned x, unsigned y, const Rgba32 &color) {
00072    ASSERT(x >= 0 && x < m_width);
00073    ASSERT(y >= 0 && y < m_height);
00074    ASSERT(m_qimage);
00075    
00076    m_qimage->setPixel(x, y, qRgb(color.r, color.g, color.b));
00077 }
00078 
00079 Rgba32 ImageCanvas::getPixel(unsigned x, unsigned y) const {
00080    ASSERT(x >= 0 && x < m_width);
00081    ASSERT(y >= 0 && y < m_height);
00082    ASSERT(m_qimage);
00083    
00084    Rgba32 c;
00085    QRgb rgb = m_qimage->pixel(x, y);
00086    
00087    c.r = (unsigned char)qRed(rgb);
00088    c.g = (unsigned char)qGreen(rgb);
00089    c.b = (unsigned char)qBlue(rgb);
00090    
00091    return c;
00092 }
00093 
00094 void ImageCanvas::setData(const Rgba32 *data) {
00095    ASSERT(data);
00096    
00097    safeDelete(m_qimage);
00098    safeDelete(m_image);
00099    
00100    m_qimage = new QImage((unsigned char*) data, m_width, m_height, QImage::Format_RGB32);
00101    m_image  = new RgbaImage(*m_qimage);
00102    
00103    update();
00104 }
00105 
00106 void ImageCanvas::setData(const Rgba32 *data, 
00107                           unsigned newWidth, 
00108                           unsigned newHeight)
00109 {
00110    if (data == NULL)
00111       return;
00112    
00113    m_width  = newWidth;
00114    m_height = newHeight;
00115    
00116    if ((void*) data != (void*) m_qimage->bits()) {
00117       safeDelete(m_qimage);
00118       safeDelete(m_image);
00119       
00120       m_qimage = new QImage((unsigned char*) data, m_width, m_height, QImage::Format_RGB32);
00121       m_image  = new RgbaImage(*m_qimage);
00122    }
00123    
00124    _resizeImage(false);
00125 }
00126 
00127 
00128 void ImageCanvas::setWidth(unsigned width) {
00129    if (m_width != width) {
00130       m_width = width;
00131       
00132       _resizeImage();
00133    }
00134 }
00135 
00136 void ImageCanvas::setHeight(unsigned height) {
00137    if (m_height != height) {
00138       m_height = height;
00139       
00140       _resizeImage();
00141    }
00142 }
00143 
00144 void ImageCanvas::setSize(unsigned width, unsigned height) {
00145    if ((m_width != width || m_height != height) && width > 0 && height > 0) {
00146       m_width  = width;
00147       m_height = height;
00148       
00149       _resizeImage();
00150    }
00151 }
00152 
00153 
00154 bool ImageCanvas::supportsOpenGL() const {
00155    return false;
00156 }
00157 
00158 
00159 void ImageCanvas::render() {
00160    ASSERT(m_renderer);
00161    
00162    safeDeleteArray(m_renderCount);
00163    m_renderCount = new unsigned[m_height];
00164    memset(m_renderCount, 0, sizeof(unsigned) * m_height);
00165    
00166    m_renderer->render();
00167 }
00168 
00169 void ImageCanvas::render(unsigned x0, unsigned y0, 
00170                          unsigned width, unsigned height)
00171 {
00172    ASSERT(m_renderer);
00173    
00174    safeDeleteArray(m_renderCount);
00175    m_renderCount = new unsigned[m_height];
00176    memset(m_renderCount, 0, sizeof(unsigned) * m_height);
00177    
00178    // TODO: handle subrendering
00179    m_renderer->render();
00180 }
00181 
00182 void ImageCanvas::redraw() {
00183    update();
00184 }
00185 
00186 void ImageCanvas::update() {
00187    if (QThread::currentThread() == qApp->thread()) {
00188       QWidget::update();
00189    } else {
00190       LocalSyscallProxy(this, m_mainProxy).repaint(0, 0, m_width, m_height);
00191    }
00192 }
00193 
00194 void ImageCanvas::update(int x, int y, int width, int height) {
00195    if (QThread::currentThread() == qApp->thread()) {
00196       QWidget::update(x, y, width, height);
00197    } else {
00198       LocalSyscallProxy(this, m_mainProxy).repaint(x, y, width, height);
00199    }
00200 }
00201 
00202 
00203 void ImageCanvas::_addSample(const PointSample &sample) {
00204    NaiveRenderOutput::_addSample(sample);
00205    unsigned x, y;
00206    
00207    m_viewport.getBin(sample.position, x, y);
00208    
00209    if (NULL == m_renderCount) {
00210       m_renderCount = new unsigned[m_height];
00211       memset(m_renderCount, 0, sizeof(unsigned) * m_height);
00212    }
00213    
00214    // no need to synchronize access to m_renderCount because we're in Qt's 
00215    // GUI thread, which is already synchronized via the LocalSyscallProxy 
00216    // mechanism (there is only one accessible Qt GUI thread)
00217    if (++m_renderCount[y] % (m_width - 1) == 0) {
00218       if (y < m_height - 1)
00219          update(0, y, m_width, 1);
00220       else
00221          update(0, 0, m_width, m_height);
00222    }
00223 }
00224 
00225 
00226 void ImageCanvas::mousePressEvent(QMouseEvent *e) {
00227    mousePressed(e);
00228 }
00229 
00230 void ImageCanvas::mouseReleaseEvent(QMouseEvent *e) {
00231    mouseReleased(e);
00232 }
00233 
00234 void ImageCanvas::mouseMoveEvent(QMouseEvent *e) {
00235    mouseMoved(e);
00236 }
00237 
00238 void ImageCanvas::keyPressEvent(QKeyEvent *e) {
00239    keyPressed(e);
00240 }
00241 
00242 void ImageCanvas::keyReleaseEvent(QKeyEvent *e) {
00243    keyReleased(e);
00244 }
00245 
00246 
00247 QSize ImageCanvas::sizeHint() const {
00248    return QSize(getWidth(), getHeight());
00249 }
00250 
00251 QSize ImageCanvas::minimumSize() const {
00252    return sizeHint();
00253 }
00254 
00255 QSize ImageCanvas::maximumSize() const {
00256    return sizeHint();
00257 }
00258 
00259 
00260 void ImageCanvas::paintEvent(QPaintEvent *e) {
00261    ASSERT(m_qimage);
00262    
00263    if (NULL == m_qimage || m_qimage->isNull()) {
00264       cerr << "ImageCanvas::paintEvent invalid QImage" << endl;
00265       ASSERT(0);
00266       abort();
00267    }
00268    
00269    QPainter painter(this);
00270    /*const QRect clip(0, 0, m_width, m_height);
00271    p.setClipRect(clip);
00272    p.drawImage(clip, *m_qimage, clip);*/
00273    
00274    painter.drawImage(0, 0, *m_qimage);
00275    
00276    /* Notify all listeners of the paint event */
00277    ListenerListIter iter;
00278    painter.setRenderHint(QPainter::Antialiasing);
00279    
00280    for(iter = m_interactionListeners.begin(); iter != m_interactionListeners.end(); iter++) {
00281       (*iter)->paint(&painter);
00282    }
00283 }
00284 
00285 
00286 void ImageCanvas::_init() {
00287    m_image = new RgbaImage(*m_qimage);
00288    NaiveRenderOutput::setImage(m_image);
00289    
00290    _setupQWidget();
00291 }
00292 
00293 void ImageCanvas::_setupQWidget() {
00294    // minor optimization: tell Qt that we'll be painting our own background
00295    setAutoFillBackground(false);
00296    setAttribute(Qt::WA_NoSystemBackground);
00297    setFocusPolicy(Qt::StrongFocus);
00298    
00299    if (layout() != NULL)
00300       layout()->setSizeConstraint(QLayout::SetFixedSize);
00301    
00302    setMouseTracking(true);
00303    setFixedSize(m_width, m_height);
00304 }
00305 
00306 void ImageCanvas::_resizeImage(bool modifyImage) {
00307    if (modifyImage) {
00308       safeDelete(m_qimage);
00309       safeDelete(m_image);
00310       
00311       m_qimage = new QImage(m_width, m_height, QImage::Format_RGB32);
00312       m_image  = new RgbaImage(*m_qimage);
00313    }
00314    
00315    setFixedSize(m_width, m_height);
00316    //sizeChanged (m_width, m_height);
00317    
00318    if (modifyImage)
00319       update();
00320 }
00321 
00322 void ImageCanvas::_repaintPrivate(unsigned x, unsigned y, 
00323                                   unsigned w, unsigned h)
00324 {
00325    QWidget::repaint(x, y, w, h);
00326 }
00327 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6