|
shun-iwasawa |
1b1839 |
#include "iwa_bokeh_advancedfx.h"
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
#include "trop.h"
|
|
shun-iwasawa |
1b1839 |
#include "trasterfx.h"
|
|
shun-iwasawa |
1b1839 |
#include "trasterimage.h"
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
#include <qreadwritelock></qreadwritelock>
|
|
shun-iwasawa |
1b1839 |
#include <qmutexlocker></qmutexlocker>
|
|
shun-iwasawa |
1b1839 |
#include <qvector></qvector>
|
|
shun-iwasawa |
1b1839 |
#include <qmap></qmap>
|
|
shun-iwasawa |
1b1839 |
#include <qset></qset>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
namespace {
|
|
shun-iwasawa |
1b1839 |
QReadWriteLock lock;
|
|
shun-iwasawa |
1b1839 |
QMutex fx_mutex;
|
|
shun-iwasawa |
1b1839 |
bool isFurtherLayer(const QPair<int, double=""> val1,</int,>
|
|
shun-iwasawa |
1b1839 |
const QPair<int, double=""> val2) {</int,>
|
|
shun-iwasawa |
1b1839 |
// if the layers are at the same depth, then put the layer with smaller index
|
|
shun-iwasawa |
1b1839 |
// above
|
|
shun-iwasawa |
1b1839 |
if (val1.second == val2.second) return val1.first > val2.first;
|
|
shun-iwasawa |
1b1839 |
return val1.second > val2.second;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
template <typename t=""></typename>
|
|
shun-iwasawa |
1b1839 |
TRasterGR8P allocateRasterAndLock(T** buf, TDimensionI dim) {
|
|
shun-iwasawa |
1b1839 |
TRasterGR8P ras(dim.lx * sizeof(T), dim.ly);
|
|
shun-iwasawa |
1b1839 |
ras->lock();
|
|
shun-iwasawa |
1b1839 |
*buf = (T*)ras->getRawData();
|
|
shun-iwasawa |
1b1839 |
return ras;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// release all registered raster memories and free all fft plans
|
|
shun-iwasawa |
1b1839 |
void releaseAllRastersAndPlans(QList<trastergr8p>& rasterList,</trastergr8p>
|
|
shun-iwasawa |
1b1839 |
QList<kiss_fftnd_cfg>& planList) {</kiss_fftnd_cfg>
|
|
shun-iwasawa |
1b1839 |
for (int r = 0; r < rasterList.size(); r++) rasterList.at(r)->unlock();
|
|
shun-iwasawa |
1b1839 |
for (int p = 0; p < planList.size(); p++) kiss_fft_free(planList.at(p));
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
}; // namespace
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
//--------------------------------------------
|
|
shun-iwasawa |
1b1839 |
// sort source images
|
|
shun-iwasawa |
1b1839 |
QList<int> Iwa_BokehAdvancedFx::getSortedSourceIndices(double frame) {</int>
|
|
shun-iwasawa |
1b1839 |
QList<qpair<int, double="">> usedSourceList;</qpair<int,>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// gather connected sources
|
|
shun-iwasawa |
1b1839 |
for (int i = 0; i < LAYER_NUM; i++) {
|
|
shun-iwasawa |
1b1839 |
if (m_layerParams[i].m_source.isConnected())
|
|
shun-iwasawa |
1b1839 |
usedSourceList.push_back(
|
|
shun-iwasawa |
1b1839 |
QPair<int, double="">(i, m_layerParams[i].m_distance->getValue(frame)));</int,>
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
if (usedSourceList.empty()) return QList<int>();</int>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// sort by distance
|
|
shun-iwasawa |
1b1839 |
std::sort(usedSourceList.begin(), usedSourceList.end(), isFurtherLayer);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
QList<int> indicesList;</int>
|
|
shun-iwasawa |
1b1839 |
for (int i = 0; i < usedSourceList.size(); i++) {
|
|
shun-iwasawa |
1b1839 |
indicesList.push_back(usedSourceList.at(i).first);
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
return indicesList;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
//--------------------------------------------
|
|
shun-iwasawa |
1b1839 |
// Compute the bokeh size for each layer. The source tile will be enlarged by
|
|
shun-iwasawa |
1b1839 |
// the largest size of them.
|
|
shun-iwasawa |
1b1839 |
QMap<int, double=""> Iwa_BokehAdvancedFx::getIrisSizes(</int,>
|
|
shun-iwasawa |
1b1839 |
const double frame, const QList<int> sourceIndices,</int>
|
|
shun-iwasawa |
1b1839 |
const double bokehPixelAmount, double& maxIrisSize) {
|
|
shun-iwasawa |
1b1839 |
// create a list of available reference image ports
|
|
shun-iwasawa |
1b1839 |
QList<int> availableCtrPorts;</int>
|
|
shun-iwasawa |
1b1839 |
for (int i = 0; i < getInputPortCount(); ++i) {
|
|
shun-iwasawa |
1b1839 |
QString portName = QString::fromStdString(getInputPortName(i));
|
|
shun-iwasawa |
1b1839 |
if (portName.startsWith("Depth") && getInputPort(i)->isConnected())
|
|
shun-iwasawa |
1b1839 |
availableCtrPorts.push_back(portName.remove(0, 5).toInt());
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
double focus = m_onFocusDistance->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
double max = 0.0;
|
|
shun-iwasawa |
1b1839 |
QMap<int, double=""> irisSizes;</int,>
|
|
shun-iwasawa |
1b1839 |
for (int s = 0; s < sourceIndices.size(); s++) {
|
|
shun-iwasawa |
1b1839 |
int index = sourceIndices.at(s);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
double layer = m_layerParams[index].m_distance->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
double adjust = m_layerParams[index].m_bokehAdjustment->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
double irisSize;
|
|
shun-iwasawa |
1b1839 |
// In case there is no available reference image
|
|
shun-iwasawa |
1b1839 |
if (m_layerParams[index].m_depth_ref->getValue() == 0 ||
|
|
shun-iwasawa |
1b1839 |
!availableCtrPorts.contains(
|
|
shun-iwasawa |
1b1839 |
m_layerParams[index].m_depth_ref->getValue())) {
|
|
shun-iwasawa |
1b1839 |
irisSize = (focus - layer) * bokehPixelAmount * adjust;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
// in case using the reference image
|
|
shun-iwasawa |
1b1839 |
else {
|
|
shun-iwasawa |
1b1839 |
double refRangeHalf =
|
|
shun-iwasawa |
1b1839 |
m_layerParams[index].m_depthRange->getValue(frame) * 0.5;
|
|
shun-iwasawa |
1b1839 |
double nearToFocus = focus - layer + refRangeHalf;
|
|
shun-iwasawa |
1b1839 |
double farToFocus = focus - layer - refRangeHalf;
|
|
shun-iwasawa |
1b1839 |
// take further point from the focus distance
|
|
shun-iwasawa |
1b1839 |
if (std::abs(nearToFocus) > std::abs(farToFocus))
|
|
shun-iwasawa |
1b1839 |
irisSize = nearToFocus * bokehPixelAmount * adjust;
|
|
shun-iwasawa |
1b1839 |
else
|
|
shun-iwasawa |
1b1839 |
irisSize = farToFocus * bokehPixelAmount * adjust;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
irisSizes[index] = irisSize;
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// update the maximum
|
|
shun-iwasawa |
1b1839 |
if (max < std::abs(irisSize)) max = std::abs(irisSize);
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
maxIrisSize = max;
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
return irisSizes;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
//-----------------------------------------------------
|
|
shun-iwasawa |
1b1839 |
// return true if the control image is available and used
|
|
shun-iwasawa |
1b1839 |
bool Iwa_BokehAdvancedFx::portIsUsed(int portIndex) {
|
|
shun-iwasawa |
1b1839 |
for (int layer = 0; layer < LAYER_NUM; layer++) {
|
|
shun-iwasawa |
1b1839 |
if (m_layerParams[layer].m_source.isConnected() &&
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_depth_ref->getValue() == portIndex)
|
|
shun-iwasawa |
1b1839 |
return true;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
return false;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
//--------------------------------------------
|
|
shun-iwasawa |
1b1839 |
Iwa_BokehAdvancedFx::Iwa_BokehAdvancedFx()
|
|
shun-iwasawa |
1b1839 |
: m_hardnessPerSource(false), m_control("Depth") {
|
|
shun-iwasawa |
1b1839 |
// Bind common parameters
|
|
shun-iwasawa |
1b1839 |
bindParam(this, "on_focus_distance", m_onFocusDistance, false);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, "bokeh_amount", m_bokehAmount, false);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, "masterHardness", m_hardness, false);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, "hardnessPerSource", m_hardnessPerSource, false);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// Bind layer parameters
|
|
shun-iwasawa |
1b1839 |
for (int layer = 0; layer < LAYER_NUM; layer++) {
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_distance = TDoubleParamP(0.5);
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_bokehAdjustment = TDoubleParamP(1);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_hardness = TDoubleParamP(0.3);
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_depth_ref = TIntParamP(0);
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_depthRange = TDoubleParamP(1.0);
|
|
shun-iwasawa |
3ca3c2 |
m_layerParams[layer].m_fillGap = TBoolParamP(true);
|
|
shun-iwasawa |
3ca3c2 |
m_layerParams[layer].m_doMedian = TBoolParamP(false);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
std::string str = QString("Source%1").arg(layer + 1).toStdString();
|
|
shun-iwasawa |
1b1839 |
addInputPort(str, m_layerParams[layer].m_source);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, QString("distance%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_distance);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, QString("bokeh_adjustment%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_bokehAdjustment);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
bindParam(this, QString("hardness%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_hardness);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, QString("depth_ref%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_depth_ref);
|
|
shun-iwasawa |
1b1839 |
bindParam(this, QString("depthRange%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_depthRange);
|
|
shun-iwasawa |
3ca3c2 |
bindParam(this, QString("fillGap%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
3ca3c2 |
m_layerParams[layer].m_fillGap);
|
|
shun-iwasawa |
3ca3c2 |
bindParam(this, QString("doMedian%1").arg(layer + 1).toStdString(),
|
|
shun-iwasawa |
3ca3c2 |
m_layerParams[layer].m_doMedian);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_distance->setValueRange(0.0, 1.0);
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_bokehAdjustment->setValueRange(0.0, 2.0);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_hardness->setValueRange(0.05, 3.0);
|
|
shun-iwasawa |
1b1839 |
m_layerParams[layer].m_depthRange->setValueRange(0.0, 1.0);
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
addInputPort("Depth1", new TRasterFxPort, 0);
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
//--------------------------------------------
|
|
shun-iwasawa |
1b1839 |
void Iwa_BokehAdvancedFx::doCompute(TTile& tile, double frame,
|
|
shun-iwasawa |
1b1839 |
const TRenderSettings& settings) {
|
|
shun-iwasawa |
1b1839 |
// If the iris is not connected, then do nothing
|
|
shun-iwasawa |
1b1839 |
if (!m_iris.isConnected()) {
|
|
shun-iwasawa |
1b1839 |
tile.getRaster()->clear();
|
|
shun-iwasawa |
1b1839 |
return;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
// If none of the source ports is connected, then do nothing
|
|
shun-iwasawa |
1b1839 |
bool sourceIsConnected = false;
|
|
shun-iwasawa |
1b1839 |
for (int i = 0; i < LAYER_NUM; i++) {
|
|
shun-iwasawa |
1b1839 |
if (m_layerParams[i].m_source.isConnected()) {
|
|
shun-iwasawa |
1b1839 |
sourceIsConnected = true;
|
|
shun-iwasawa |
1b1839 |
break;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
if (!sourceIsConnected) {
|
|
shun-iwasawa |
1b1839 |
tile.getRaster()->clear();
|
|
shun-iwasawa |
1b1839 |
return;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// Sort source layers by distance
|
|
shun-iwasawa |
1b1839 |
QList<int> sourceIndices = getSortedSourceIndices(frame);</int>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// Get the pixel size of bokehAmount ( referenced ino_blur.cpp )
|
|
shun-iwasawa |
1b1839 |
double bokehPixelAmount = BokehUtils::getBokehPixelAmount(
|
|
shun-iwasawa |
1b1839 |
m_bokehAmount->getValue(frame), settings.m_affine);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// Compute the bokeh size for each layer. The source tile will be enlarged by
|
|
shun-iwasawa |
1b1839 |
// the largest size of them.
|
|
shun-iwasawa |
1b1839 |
double maxIrisSize;
|
|
shun-iwasawa |
1b1839 |
QMap<int, double=""> irisSizes =</int,>
|
|
shun-iwasawa |
1b1839 |
getIrisSizes(frame, sourceIndices, bokehPixelAmount, maxIrisSize);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
int margin = (int)std::ceil(maxIrisSize * 0.5);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
TRectD _rectOut(tile.m_pos, TDimensionD(tile.getRaster()->getLx(),
|
|
shun-iwasawa |
1b1839 |
tile.getRaster()->getLy()));
|
|
shun-iwasawa |
1b1839 |
_rectOut = _rectOut.enlarge(static_cast<double>(margin));</double>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
TDimensionI dimOut(static_cast<int>(_rectOut.getLx() + 0.5),</int>
|
|
shun-iwasawa |
1b1839 |
static_cast<int>(_rectOut.getLy() + 0.5));</int>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// Enlarge the size to the "fast size" for kissfft which has no factors other
|
|
shun-iwasawa |
1b1839 |
// than 2,3, or 5.
|
|
shun-iwasawa |
1b1839 |
if (dimOut.lx < 10000 && dimOut.ly < 10000) {
|
|
shun-iwasawa |
1b1839 |
int new_x = kiss_fft_next_fast_size(dimOut.lx);
|
|
shun-iwasawa |
1b1839 |
int new_y = kiss_fft_next_fast_size(dimOut.ly);
|
|
shun-iwasawa |
1b1839 |
// margin should be integer
|
|
shun-iwasawa |
1b1839 |
while ((new_x - dimOut.lx) % 2 != 0)
|
|
shun-iwasawa |
1b1839 |
new_x = kiss_fft_next_fast_size(new_x + 1);
|
|
shun-iwasawa |
1b1839 |
while ((new_y - dimOut.ly) % 2 != 0)
|
|
shun-iwasawa |
1b1839 |
new_y = kiss_fft_next_fast_size(new_y + 1);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
_rectOut = _rectOut.enlarge(static_cast<double>(new_x - dimOut.lx) / 2.0,</double>
|
|
shun-iwasawa |
1b1839 |
static_cast<double>(new_y - dimOut.ly) / 2.0);</double>
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
dimOut.lx = new_x;
|
|
shun-iwasawa |
1b1839 |
dimOut.ly = new_y;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// compute the input tiles
|
|
shun-iwasawa |
1b1839 |
QMap<int, ttile*=""> sourceTiles;</int,>
|
|
shun-iwasawa |
32ddcd |
TRenderSettings infoOnInput(settings);
|
|
shun-iwasawa |
32ddcd |
infoOnInput.m_bpp = 64;
|
|
shun-iwasawa |
1b1839 |
for (auto index : sourceIndices) {
|
|
shun-iwasawa |
1b1839 |
TTile* layerTile = new TTile();
|
|
shun-iwasawa |
1b1839 |
m_layerParams[index].m_source->allocateAndCompute(
|
|
shun-iwasawa |
32ddcd |
*layerTile, _rectOut.getP00(), dimOut, 0, frame, infoOnInput);
|
|
shun-iwasawa |
1b1839 |
sourceTiles[index] = layerTile;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// obtain pixel size of original iris image
|
|
shun-iwasawa |
1b1839 |
TRectD irisBBox;
|
|
shun-iwasawa |
1b1839 |
m_iris->getBBox(frame, irisBBox, settings);
|
|
shun-iwasawa |
1b1839 |
// compute the iris tile
|
|
shun-iwasawa |
1b1839 |
TTile irisTile;
|
|
shun-iwasawa |
1b1839 |
m_iris->allocateAndCompute(
|
|
shun-iwasawa |
1b1839 |
irisTile, irisBBox.getP00(),
|
|
shun-iwasawa |
1b1839 |
TDimension(static_cast<int>(irisBBox.getLx() + 0.5),</int>
|
|
shun-iwasawa |
1b1839 |
static_cast<int>(irisBBox.getLy() + 0.5)),</int>
|
|
shun-iwasawa |
1b1839 |
tile.getRaster(), frame, settings);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// compute the reference image
|
|
shun-iwasawa |
1b1839 |
std::vector<trastergr8p> ctrl_rasters; // to be stored in uchar</trastergr8p>
|
|
shun-iwasawa |
1b1839 |
QMap<int, char*="" unsigned=""></int,>
|
|
shun-iwasawa |
1b1839 |
ctrls; // container of [port number, reference image buffer in uchar]
|
|
shun-iwasawa |
1b1839 |
for (int i = 0; i < getInputPortCount(); ++i) {
|
|
shun-iwasawa |
1b1839 |
QString portName = QString::fromStdString(getInputPortName(i));
|
|
shun-iwasawa |
1b1839 |
if (portName.startsWith("Depth") && getInputPort(i)->isConnected()) {
|
|
shun-iwasawa |
1b1839 |
int portIndex = portName.remove(0, 5).toInt();
|
|
shun-iwasawa |
1b1839 |
if (portIsUsed(portIndex)) {
|
|
shun-iwasawa |
1b1839 |
TTile tmpTile;
|
|
shun-iwasawa |
1b1839 |
TRasterFxPort* tmpCtrl = dynamic_cast<trasterfxport*>(getInputPort(i));</trasterfxport*>
|
|
shun-iwasawa |
1b1839 |
(*tmpCtrl)->allocateAndCompute(tmpTile, _rectOut.getP00(), dimOut,
|
|
shun-iwasawa |
1b1839 |
tile.getRaster(), frame, settings);
|
|
shun-iwasawa |
1b1839 |
TRasterGR8P ctrlRas(dimOut.lx, dimOut.ly);
|
|
shun-iwasawa |
1b1839 |
ctrlRas->lock();
|
|
shun-iwasawa |
1b1839 |
unsigned char* ctrl_mem = (unsigned char*)ctrlRas->getRawData();
|
|
shun-iwasawa |
1b1839 |
TRaster32P ras32 = (TRaster32P)tmpTile.getRaster();
|
|
shun-iwasawa |
1b1839 |
TRaster64P ras64 = (TRaster64P)tmpTile.getRaster();
|
|
shun-iwasawa |
1b1839 |
lock.lockForRead();
|
|
shun-iwasawa |
1b1839 |
if (ras32)
|
|
shun-iwasawa |
1b1839 |
BokehUtils::setDepthRaster<traster32p, tpixel32="">(ras32, ctrl_mem,</traster32p,>
|
|
shun-iwasawa |
1b1839 |
dimOut);
|
|
shun-iwasawa |
1b1839 |
else if (ras64)
|
|
shun-iwasawa |
1b1839 |
BokehUtils::setDepthRaster<traster64p, tpixel64="">(ras64, ctrl_mem,</traster64p,>
|
|
shun-iwasawa |
1b1839 |
dimOut);
|
|
shun-iwasawa |
1b1839 |
lock.unlock();
|
|
shun-iwasawa |
1b1839 |
ctrl_rasters.push_back(ctrlRas);
|
|
shun-iwasawa |
1b1839 |
ctrls[portIndex] = ctrl_mem;
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
double masterHardness = m_hardness->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
QList<layervalue> layerValues;</layervalue>
|
|
shun-iwasawa |
1b1839 |
for (auto index : sourceIndices) {
|
|
shun-iwasawa |
1b1839 |
LayerValue layerValue;
|
|
shun-iwasawa |
1b1839 |
layerValue.sourceTile = sourceTiles[index];
|
|
shun-iwasawa |
1b1839 |
layerValue.premultiply =
|
|
shun-iwasawa |
1b1839 |
false; // assuming input images are always premultiplied
|
|
shun-iwasawa |
1b1839 |
layerValue.layerHardness =
|
|
shun-iwasawa |
1b1839 |
(m_hardnessPerSource->getValue())
|
|
shun-iwasawa |
1b1839 |
? m_layerParams[index].m_hardness->getValue(frame)
|
|
shun-iwasawa |
1b1839 |
: masterHardness;
|
|
shun-iwasawa |
1b1839 |
layerValue.depth_ref = m_layerParams[index].m_depth_ref->getValue();
|
|
shun-iwasawa |
1b1839 |
layerValue.irisSize = irisSizes.value(index);
|
|
shun-iwasawa |
1b1839 |
layerValue.distance = m_layerParams[index].m_distance->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
layerValue.bokehAdjustment =
|
|
shun-iwasawa |
1b1839 |
m_layerParams[index].m_bokehAdjustment->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
layerValue.depthRange = m_layerParams[index].m_depthRange->getValue(frame);
|
|
shun-iwasawa |
1b1839 |
layerValue.distancePrecision = 10;
|
|
shun-iwasawa |
3ca3c2 |
layerValue.fillGap = m_layerParams[index].m_fillGap->getValue();
|
|
shun-iwasawa |
3ca3c2 |
layerValue.doMedian = m_layerParams[index].m_doMedian->getValue();
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
layerValues.append(layerValue);
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
Iwa_BokehCommonFx::doFx(tile, frame, settings, bokehPixelAmount, margin,
|
|
shun-iwasawa |
1b1839 |
dimOut, irisBBox, irisTile, layerValues, ctrls);
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
// release control image buffers
|
|
shun-iwasawa |
1b1839 |
for (int r = 0; r < ctrl_rasters.size(); r++) ctrl_rasters[r]->unlock();
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
qDeleteAll(sourceTiles);
|
|
shun-iwasawa |
1b1839 |
}
|
|
shun-iwasawa |
1b1839 |
|
|
shun-iwasawa |
1b1839 |
//--------------------------------------------
|
|
shun-iwasawa |
1b1839 |
FX_PLUGIN_IDENTIFIER(Iwa_BokehAdvancedFx, "iwa_BokehAdvancedFx")
|