ReconstructionRenderOutput.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   ReconstructionRenderOutput.cpp
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @author Matthew Jacobs (jacobs.mh@gmail.com)
00005    @date   Fall 2008
00006    
00007    @brief
00008       Records point samples from a renderer and attempts to reconstruct the 
00009    underlying image by filtering samples with a reconstruction filter
00010    <!-------------------------------------------------------------------->**/
00011 
00012 #include "ReconstructionRenderOutput.h"
00013 #include "PointSample.h"
00014 #include <SpectralSampleSet.h>
00015 
00016 #include <filters.h>
00017 #include <QtCore>
00018 
00019 ReconstructionRenderOutput::ReconstructionRenderOutput(Image *output, 
00020                                                        KernelFilter *f) 
00021    : RenderOutput(), m_output(output), 
00022      m_filter(f), m_progressiveValues(NULL)
00023 {
00024    if (output) {
00025       const unsigned width  = output->getWidth();
00026       const unsigned height = output->getHeight();
00027       
00028       m_viewport.setSize(width, height);
00029    }
00030 }
00031 
00032 ReconstructionRenderOutput::~ReconstructionRenderOutput() {
00033    safeDelete(m_filter);
00034    safeDeleteArray(m_progressiveValues);
00035 }
00036 
00037 void ReconstructionRenderOutput::addSample(const PointSample &sample) {
00038    ASSERT(m_output && m_filter);
00039    
00040    const SpectralSampleSet &value = sample.value.getValue<SpectralSampleSet>();
00041    const unsigned width   = m_output->getWidth();
00042    const unsigned height  = m_output->getHeight();
00043    const unsigned half    = (m_filter->getWidth() >> 1);
00044    unsigned col, row;
00045    
00046    m_viewport.getBin(sample.position, col, row);
00047    
00048    ASSERT(row < width);
00049    ASSERT(col < height);
00050    QMutexLocker lock(&m_mutex);
00051    
00052    // progressive, normalized filter
00053    for(unsigned y = MAX(0, (signed)row - half); y <= MIN(height - 1, row + half); ++y) {
00054       for(unsigned x = MAX(0, (signed)col - half); x <= MIN(width - 1, col + half); ++x) {
00055          const real_t weight = m_filter->evaluate(
00056             Vector2(x - sample.position[0] + 0.5, y - sample.position[1] + 0.5));
00057          
00058          if (weight > 0) {
00059             unsigned offset = y * width + x;
00060             m_progressiveValues[offset].addSample(value, weight);
00061             
00062             const SpectralSampleSet &updated = m_progressiveValues[offset].getValue();
00063             m_output->setPixel(y, x, updated);
00064          }
00065       }
00066    }
00067    
00068    _addSample(sample);
00069 }
00070 
00071 void ReconstructionRenderOutput::init() {
00072    RenderOutput::init();
00073    ASSERT(m_output);
00074    
00075    safeDeleteArray(m_progressiveValues);
00076    m_progressiveValues = new ProgressiveFilterValue<SpectralSampleSet>
00077       [m_output->getWidth() * m_output->getHeight()];
00078    
00079    if (NULL == m_filter) {
00080       const std::string &filter = 
00081          getValue<std::string>("filter", "lanczosSinc");
00082       
00083       m_filter = KernelFilter::create(filter, *this);
00084    }
00085    
00086    ASSERT(m_filter);
00087    m_filter->init();
00088 }
00089 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6