00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "highcontrast.h"
00025 #include "stats.h"
00026
00027 using namespace lux;
00028
00029
00030 void HighContrastOp::Map(const float *y, int xRes, int yRes,
00031 float maxDisplayY, float *scale) const {
00032
00033 float minY = y[0], maxY = y[0];
00034 for (int i = 0; i < xRes * yRes; ++i) {
00035 minY = min(minY, y[i]);
00036 maxY = max(maxY, y[i]);
00037 }
00038 float CYmin = C(minY), CYmax = C(maxY);
00039
00040 MIPMapImpl<float,float> pyramid(MIPMAP_EWA, xRes, yRes,
00041 y, 4.f, TEXTURE_CLAMP);
00042
00043 ProgressReporter progress(xRes*yRes, "Tone Mapping");
00044 for (int y = 0; y < yRes; ++y) {
00045 float yc = (float(y) + .5f) / float(yRes);
00046 for (int x = 0; x < xRes; ++x) {
00047 float xc = (float(x) + .5f) / float(xRes);
00048
00049 float dwidth = 1.f / float(max(xRes, yRes));
00050 float maxWidth = 32.f / float(max(xRes, yRes));
00051 float width = dwidth, prevWidth = 0.f;
00052 float Yadapt;
00053 float prevlc = 0.f;
00054 const float maxLocalContrast = .5f;
00055 while (1) {
00056
00057 float b0 = pyramid.Lookup(xc, yc, width,
00058 0.f, 0.f, width);
00059 float b1 = pyramid.Lookup(xc, yc, 2.f*width,
00060 0.f, 0.f, 2.f*width);
00061 float lc = fabsf((b0 - b1) / b0);
00062
00063 if (lc > maxLocalContrast) {
00064 float t = (maxLocalContrast - prevlc) / (lc - prevlc);
00065 float w = Lerp(t, prevWidth, width);
00066 Yadapt = pyramid.Lookup(xc, yc, w,
00067 0.f, 0.f, w);
00068 break;
00069 }
00070
00071 prevlc = lc;
00072 prevWidth = width;
00073 width += dwidth;
00074 if (width >= maxWidth) {
00075 Yadapt = pyramid.Lookup(xc, yc, maxWidth,
00076 0.f, 0.f, maxWidth);
00077 break;
00078 }
00079 }
00080
00081 scale[x + y*xRes] = T(Yadapt, CYmin, CYmax, maxDisplayY) /
00082 Yadapt;
00083 }
00084 progress.Update(xRes);
00085 }
00086 progress.Done();
00087 }
00088 ToneMap * HighContrastOp::CreateToneMap(const ParamSet &ps) {
00089 return new HighContrastOp;
00090 }