/* Tonemap operator, tonemaps the hdr image and stores the * tonemapped image in result. Use the value key as the * key of the photograph. This function should: * 1) Calculate the log-average luminance, Lavg * 2) Calculate the tonemapped image using the equation * L(x,y) = L_w(x,y) * key / Lavg; * C_tm(x,y) = L(x,y) / (1 + L(x,y)); * 3) Store those tonemapped values to the result image, * scaling appropriately. */ void tonemap(STHDRImage* hdr, float key, STImage* result) { float logAverageLuminance = 0; float delta = 0.001; for (int i=0;i<hdr->GetWidth();i++) { for (int j=0;j<hdr->GetHeight();j++) { STColor3f currentPixel = hdr->GetPixel(i, j); logAverageLuminance += logf(currentPixel.r*0.299 + currentPixel.g*0.587 +currentPixel.b*0.114 + delta); } } logAverageLuminance /= (hdr->GetWidth()*hdr->GetHeight()); logAverageLuminance = expf(logAverageLuminance); for (int i=0;i<hdr->GetWidth();i++) { for (int j=0;j<hdr->GetHeight();j++) { STColor3f currentPixel = hdr->GetPixel(i, j); STColor3f currentPixelScaled = currentPixel * (key/logAverageLuminance); STColor3f compressedCurrentPixelScaled = currentPixelScaled / (STColor3f(1) + currentPixelScaled); STColor4ub resultPixel(compressedCurrentPixelScaled); result->SetPixel(i, j, resultPixel); } } }
void KisConvolutionPainterTest::testAsymmConvolutionImp(QBitArray channelFlags) { qreal offset = 0.0; qreal factor = 1.0; Eigen::Matrix<qreal, 3, 3> filter = initAsymmFilter(offset, factor); QRect imageRect; int pixelSize = -1; QByteArray initialData; KisPaintDeviceSP dev = initAsymTestDevice(imageRect, pixelSize, initialData); KisConvolutionKernelSP kernel = KisConvolutionKernel::fromMatrix(filter, offset, factor); KisConvolutionPainter gc(dev); gc.beginTransaction(); gc.setChannelFlags(channelFlags); QRect filterRect = imageRect.adjusted(1,1,-1,-1); gc.applyMatrix(kernel, dev, filterRect.topLeft(), filterRect.topLeft(), filterRect.size()); gc.deleteTransaction(); QByteArray resultData(initialData.size(), 0); dev->readBytes((quint8*)resultData.data(), imageRect); QRect filteredRect = imageRect.adjusted(1, 1, -1, -1); quint8 *srcPtr = (quint8*) initialData.data(); quint8 *resPtr = (quint8*) resultData.data(); for(int row = 0; row < imageRect.height(); row++) { for(int col = 0; col < imageRect.width(); col++) { bool isFiltered = filteredRect.contains(col, row); int pixelValue = 8 + row * imageRect.width() + col; KoColor filteredPixel(QColor(pixelValue, pixelValue, pixelValue, 255), dev->colorSpace()); KoColor resultPixel(dev->colorSpace()); for(int j = 0; j < pixelSize; j++) { resultPixel.data()[j] = isFiltered && channelFlags[j] ? filteredPixel.data()[j] : srcPtr[j]; } if(memcmp(resPtr, resultPixel.data(), pixelSize)) { printPixel("Actual: ", pixelSize, resPtr); printPixel("Expected:", pixelSize, resultPixel.data()); QFAIL("Failed to filter area"); } srcPtr += pixelSize; resPtr += pixelSize; } } }