private void applyUserModif(ref ushort[] image, iPoint2D dim, iPoint2D offset, ushort colorDepth) { ImageEffect effect = new ImageEffect(); //get all the value Task t = Task.Run(async() => { await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { effect.exposure = exposureSlider.Value; effect.temperature = colorTempSlider.Value - 1; effect.tint = colorTintSlider.Value - 1; effect.contrast = contrastSlider.Value / 10; /* * effect.gamma = gammaSlider.Value; * effect.brightness = (1 << colorDepth) * (brightnessSlider.Value / 100); * effect.shadow = ShadowSlider.Value; * effect.hightlight = HighLightSlider.Value;*/ effect.saturation = 1 + saturationSlider.Value / 100; }); }); t.Wait(); effect.mul = raw.metadata.wbCoeffs; effect.cameraWB = cameraWB; effect.exposure = Math.Pow(2, effect.exposure); effect.camCurve = raw.curve; effect.applyModification(image, dim, offset, colorDepth); }
Camera(Camera* camera, UInt32 alias_num) { if (alias_num >= camera.aliases.size()) ThrowCME("Camera: Internal error, alias number out of range specified."); make = camera.make; model = camera.aliases[alias_num]; canonical_make = camera.canonical_make; canonical_model = camera.canonical_model; canonical_alias = camera.canonical_aliases[alias_num]; canonical_id = camera.canonical_id; mode = camera.mode; cfa = camera.cfa; supported = camera.supported; cropSize = camera.cropSize; cropPos = camera.cropPos; decoderVersion = camera.decoderVersion; for (UInt32 i = 0; i<camera.blackAreas.size(); i++) { blackAreas.push_back(camera.blackAreas[i]); } for (UInt32 i = 0; i<camera.sensorInfo.size(); i++) { sensorInfo.push_back(camera.sensorInfo[i]); } map<string, string>::const_iterator mi = camera.hints.begin(); for (; mi != camera.hints.end(); ++mi) { hints.insert(make_pair((* mi).first, (* mi).second)); } }
public void applyModification(ushort[] image, iPoint2D dim, iPoint2D offset, int colorDepth) { maxValue = (uint)(1 << colorDepth); if (!cameraWB) { mul = new float[4]; //Balance.calculateRGB((int)temperature, out mul[0], out mul[1], out mul[2]); mul[0] = (float)(255 / temperature); mul[1] = (float)(255 / tint); mul[2] = 1; } //generate the curve double[] xCurve = new double[5], yCurve = new double[5]; //mid point xCurve[2] = maxValue / 2; yCurve[2] = maxValue / 2; //shadow xCurve[0] = 0; yCurve[0] = shadow * (maxValue / (400)); //hightlight xCurve[4] = maxValue; yCurve[4] = maxValue - (hightlight * (maxValue / 400)); //contrast xCurve[1] = maxValue / 4; yCurve[1] = ((yCurve[0] + yCurve[2]) / 2) - (maxValue / 200); xCurve[3] = maxValue * 3 / 4; yCurve[3] = ((yCurve[2] + yCurve[4]) / 2) + (maxValue / 200); maxValue--; //interpolate with spline //double[] contrastCurve = Balance.contrast_curve(shadow, hightlight, 1 << colorDepth); double[] contrastCurve = Curve.cubicSpline(xCurve, yCurve); //Change the gamma/No more gammaneeded here, the raw should be transformed to neutral gamma before demos //double[] gammaCurve = Balance.gamma_curve(0.45, 4.5, 2, 8192 << 3); //gammacurve from camera //double[] gammaCurve = Balance.gamma_curve(camCurve[0] / 100, camCurve[1] / 10, 2, 8192 << 3); Parallel.For(offset.y, dim.y, y => { int realY = y * dim.x * 3; for (int x = offset.x; x < dim.x; x++) { int realPix = realY + (3 * x); //get the RGB value double red = image[realPix], green = image[realPix + 1], blue = image[realPix + 2]; //convert to linear rgb (not needed, the raw should be in linear already) /*Balance.sRGBToRGB(ref red, maxValue - 1); * Balance.sRGBToRGB(ref green, maxValue - 1); * Balance.sRGBToRGB(ref blue, maxValue - 1);*/ //scale according to the white balance //Balance.scaleColor(ref red, ref green, ref blue, mul); red *= mul[0]; green *= mul[1]; blue *= mul[2]; //clip Luminance.Clip(ref red, ref green, ref blue, maxValue); double h = 0, s = 0, l = 0; //transform to HSL value Color.rgbToHsl(red, green, blue, maxValue, ref h, ref s, ref l); //change brightness from curve //add saturation l = contrastCurve[(uint)(l * maxValue)] / maxValue; s *= saturation; s += vibrance; l *= exposure; l += brightness / 100; //change back to RGB Color.hslToRgb(h, s, l, maxValue, ref red, ref green, ref blue); //Luminance.Exposure(ref red, ref green, ref blue, exposure); //Luminance.Brightness(ref red, ref green, ref blue, brightness); //Balance.scaleGamma(ref red, ref green, ref blue, gamma, maxValue); Luminance.Contraste(ref red, ref green, ref blue, maxValue, contrast); //clip Luminance.Clip(ref red, ref green, ref blue, maxValue); image[realPix] = (byte)red; image[realPix + 1] = (byte)green; image[realPix + 2] = (byte)blue; //change gamma from curve /* * image[i * 3] = (ushort)gammaCurve[(int)red]; * image[(i * 3) + 1] = (ushort)gammaCurve[(int)green]; * image[(i * 3) + 2] = (ushort)gammaCurve[(int)blue];*/ } }); }
public unsafe int[] applyModification(ushort[] image, iPoint2D dim, iPoint2D offset, int colorDepth, ref SoftwareBitmap bitmap) { int[] value = new int[256]; using (BitmapBuffer buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Write)) { using (var reference = buffer.CreateReference()) { BitmapPlaneDescription bufferLayout = buffer.GetPlaneDescription(0); ((IMemoryBufferByteAccess)reference).GetBuffer(out var temp, out uint capacity); maxValue = (uint)(1 << colorDepth); int shift = colorDepth - 8; if (!cameraWB) { mul = new float[4]; //Balance.calculateRGB((int)temperature, out mul[0], out mul[1], out mul[2]); mul[2] = (float)(255 / temperature); mul[0] = (float)(255.0 / tint); mul[1] = 1; } //generate the curve double[] xCurve = new double[5], yCurve = new double[5]; //mid point xCurve[2] = maxValue / 2; yCurve[2] = maxValue / 2; //shadow xCurve[0] = 0; yCurve[0] = shadow * (maxValue / (400)); //hightlight xCurve[4] = maxValue; yCurve[4] = maxValue - (hightlight * (maxValue / 400)); //contrast xCurve[1] = maxValue / 4; yCurve[1] = ((yCurve[0] + yCurve[2]) / 2) - (maxValue / 200); xCurve[3] = maxValue * 3 / 4; yCurve[3] = ((yCurve[2] + yCurve[4]) / 2) + (maxValue / 200); maxValue--; //interpolate with spline //double[] contrastCurve = Balance.contrast_curve(shadow, hightlight, 1 << colorDepth); double[] contrastCurve = Curve.cubicSpline(xCurve, yCurve); //Change the gamma/No more gammaneeded here, the raw should be transformed to neutral gamma before demos //double[] gammaCurve = Balance.gamma_curve(0.45, 4.5, 2, 8192 << 3); //gammacurve from camera //double[] gammaCurve = Balance.gamma_curve(camCurve[0] / 100, camCurve[1] / 10, 2, 8192 << 3); Parallel.For(offset.y, dim.y + offset.y, y => { int realY = y * dim.x * 3; int bufferY = y * dim.x * 4 + +bufferLayout.StartIndex; for (int x = offset.x; x < dim.x + offset.x; x++) { int realPix = realY + (3 * x); int bufferPix = bufferY + (4 * x); //get the RGB value double red = image[realPix], green = image[realPix + 1], blue = image[realPix + 2]; //convert to linear rgb (not needed, the raw should be in linear already) /*Balance.sRGBToRGB(ref red, maxValue - 1); * Balance.sRGBToRGB(ref green, maxValue - 1); * Balance.sRGBToRGB(ref blue, maxValue - 1);*/ //scale according to the white balance red *= mul[0]; green *= mul[1]; blue *= mul[2]; //clip Luminance.Clip(ref red, ref green, ref blue, maxValue); double h = 0, s = 0, l = 0; //transform to HSL value Color.rgbToHsl(red, green, blue, maxValue, ref h, ref s, ref l); //change brightness from curve //add saturation l = contrastCurve[(uint)(l * maxValue)] / maxValue; s *= saturation; s += vibrance; l *= exposure; l += brightness / 100; //change back to RGB Color.hslToRgb(h, s, l, maxValue, ref red, ref green, ref blue); //Luminance.Exposure(ref red, ref green, ref blue, exposure); //Luminance.Brightness(ref red, ref green, ref blue, brightness); //Balance.scaleGamma(ref red, ref green, ref blue, gamma, maxValue); Luminance.Contraste(ref red, ref green, ref blue, maxValue, contrast); //clip Luminance.Clip(ref red, ref green, ref blue, maxValue); temp[bufferPix] = (byte)((int)blue >> shift); temp[bufferPix + 1] = (byte)((int)green >> shift); temp[bufferPix + 2] = (byte)((int)red >> shift); Interlocked.Increment(ref value[(((int)red >> shift) + ((int)green >> shift) + ((int)blue >> shift)) / 3]); //set transparency to 255 else image will be blank temp[bufferPix + 3] = 255; //change gamma from curve /* * image[i * 3] = (ushort)gammaCurve[(int)red]; * image[(i * 3) + 1] = (ushort)gammaCurve[(int)green]; * image[(i * 3) + 2] = (ushort)gammaCurve[(int)blue];*/ } }); } } return(value); }
// FC macro from dcraw outputs, given the filters definition, the dcraw color // number for that given position in the CFA pattern void FC(int filters, int row, int col) { ((filters) >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) }; ColorFilterArray(UInt32 filters) { size = new iPoint2D(8, 2); cfa = null; setSize(size); for (int x = 0; x < 8; x++) { for (int y = 0; y < 2; y++) { CFAColor c = toRawspeedColor(FC(filters, y, x)); setColorAt(iPoint2D(x, y), c); } } } ColorFilterArray& operator=(ColorFilterArray& other) { setSize(other.size); if (cfa) { memcpy(cfa, other.cfa, size.area() * sizeof(CFAColor)); } return(*this); } void setSize(iPoint2D _size) { size = _size; if (cfa) { delete[] cfa; } cfa = null; if (size.area() > 100) { ThrowRDE("ColorFilterArray:setSize if your CFA pattern is really %d pixels in area we may as well give up now", size.area()); } if (size.area() <= 0) { return; } cfa = new CFAColor[size.area()]; if (!cfa) { ThrowRDE("ColorFilterArray:setSize Unable to allocate memory"); } memset(cfa, CFA_UNKNOWN, size.area() * sizeof(CFAColor)); } CFAColor getColorAt(UInt32 x, UInt32 y) { if (!cfa) { ThrowRDE("ColorFilterArray:getColorAt: No CFA size set"); } if (x >= (UInt32)size.x || y >= (UInt32)size.y) { x = x % size.x; y = y % size.y; } return(cfa[x + y * size.x]); } void setCFA(iPoint2D in_size, ...) { if (in_size != size) { setSize(in_size); } va_list arguments; va_start(arguments, in_size); for (UInt32 i = 0; i < size.area(); i++) { cfa[i] = (CFAColor)va_arg(arguments, int); } va_end(arguments); } void shiftLeft(int n) { if (!size.x) { ThrowRDE("ColorFilterArray:shiftLeft: No CFA size set (or set to zero)"); } writeLog(DEBUG_PRIO_EXTRA, "Shift left:%d\n", n); int shift = n % size.x; if (0 == shift) { return; } CFAColor *tmp = new CFAColor[size.x]; for (int y = 0; y < size.y; y++) { CFAColor *old = &cfa[y * size.x]; memcpy(tmp, &old[shift], (size.x - shift) * sizeof(CFAColor)); memcpy(&tmp[size.x - shift], old, shift * sizeof(CFAColor)); memcpy(old, tmp, size.x * sizeof(CFAColor)); } delete[] tmp; } void shiftDown(int n) { if (!size.y) { ThrowRDE("ColorFilterArray:shiftDown: No CFA size set (or set to zero)"); } writeLog(DEBUG_PRIO_EXTRA, "Shift down:%d\n", n); int shift = n % size.y; if (0 == shift) { return; } CFAColor *tmp = new CFAColor[size.y]; for (int x = 0; x < size.x; x++) { CFAColor *old = &cfa[x]; for (int y = 0; y < size.y; y++) { tmp[y] = old[((y + shift) % size.y) * size.x]; } for (int y = 0; y < size.y; y++) { old[y * size.x] = tmp[y]; } } delete[] tmp; } string asString() { string dst = string(""); for (int y = 0; y < size.y; y++) { for (int x = 0; x < size.x; x++) { dst += colorToString(getColorAt(x, y)); dst += (x == size.x - 1) ? "\n" : ","; } } return(dst); } string colorToString(CFAColor c) { switch (c) { case CFA_RED: return(string("RED")); case CFA_GREEN: return(string("GREEN")); case CFA_BLUE: return(string("BLUE")); case CFA_GREEN2: return(string("GREEN2")); case CFA_CYAN: return(string("CYAN")); case CFA_MAGENTA: return(string("MAGENTA")); case CFA_YELLOW: return(string("YELLOW")); case CFA_WHITE: return(string("WHITE")); case CFA_FUJI_GREEN: return(string("FUJIGREEN")); default: return(string("UNKNOWN")); } } void setColorAt(iPoint2D pos, CFAColor c) { if (pos.x >= size.x || pos.x < 0) { ThrowRDE("SetColor: position out of CFA pattern"); } if (pos.y >= size.y || pos.y < 0) { ThrowRDE("SetColor: position out of CFA pattern"); } cfa[pos.x + pos.y * size.x] = c; } UInt32 getDcrawFilter() { //dcraw magic if (size.x == 6 && size.y == 6) { return(9); } if (size.x > 8 || size.y > 2 || 0 == cfa) { return(1); } if (!isPowerOfTwo(size.x)) { return(1); } UInt32 ret = 0; for (int x = 0; x < 8; x++) { for (int y = 0; y < 2; y++) { UInt32 c = toDcrawColor(getColorAt(x, y)); int g = (x >> 1) * 8; ret |= c << ((x & 1) * 2 + y * 4 + g); } } for (int y = 0; y < size.y; y++) { for (int x = 0; x < size.x; x++) { writeLog(DEBUG_PRIO_EXTRA, "%s,", colorToString((CFAColor)toDcrawColor(getColorAt(x, y))).c_str()); } writeLog(DEBUG_PRIO_EXTRA, "\n"); } writeLog(DEBUG_PRIO_EXTRA, "DCRAW filter:%x\n", ret); return(ret); } CFAColor toRawspeedColor(UInt32 dcrawColor) { switch (dcrawColor) { case 0: return(CFA_RED); case 1: return(CFA_GREEN); case 2: return(CFA_BLUE); case 3: return(CFA_GREEN2); } return(CFA_UNKNOWN); } UInt32 toDcrawColor(CFAColor c) { switch (c) { case CFA_FUJI_GREEN: case CFA_RED: return(0); case CFA_MAGENTA: case CFA_GREEN: return(1); case CFA_CYAN: case CFA_BLUE: return(2); case CFA_YELLOW: case CFA_GREEN2: return(3); default: break; } return(0); } }; } // namespace RawSpeed
ColorFilterArray() { size = new iPoint2D(0, 0); }
ColorFilterArray(iPoint2D _size) { setSize(_size); }