private static void ProcessMiddleRows(RawBGGRMap <ushort> file, ColorMapUshort res) { // Middle Rows Parallel.For(0, (res.Height - 2) / 2, yy => { var y = yy * 2 + 1; ProcessMiddleOddRows(file.GetRow(y), res.Width, res.GetRow(y)); y++; ProcessMiddleEvenRows(file.GetRow(y), res.Width, res.GetRow(y)); }); }
// B G B G // G R G R // B G B G // G R G R public ColorMap <ushort> Process(RawBGGRMap <ushort> file) { if (file.Width % 2 != 0 || file.Height % 2 != 0) { throw new ArgumentException("Width and Height should be even"); } var res = new ColorMapUshort(file.Width, file.Height, file.MaxBits + 1); ProcessTopLine(file, res); ProcessMiddleRows(file, res); ProcessBottomLine(file, res); return(res); }
// B G B G // G R G R // B G B G // G R G R private static void ProcessBottomLine(RawBGGRMap <ushort> map, ColorMapUshort res) { var pix = res.GetPixel(); var raw = map.GetRow(res.Height - 1); // Bottom Left pixel var lastY = res.Height - 1; pix.SetAndMoveNext( (ushort)(raw.GetRel(1, 0) << 1), (ushort)(raw.Value << 1), (ushort)(raw.GetRel(0, -1) << 1)); raw.MoveNext(); // Bottom row for (var x = 1; x < res.Width - 1; x += 2) { pix.SetAndMoveNext( (ushort)(raw.Value << 1), (ushort)((raw.GetRel(-1, 0) + raw.GetRel(+1, 0) + raw.GetRel(0, -1) << 1) >> 1), (ushort)((raw.GetRel(-1, 0) + raw.GetRel(+1, 0)))); pix.SetAndMoveNext( (ushort)((raw.Value + raw.GetRel(+2, 0))), (ushort)(raw.GetRel(+1, 0) << 1), (ushort)(raw.GetRel(+1, 0 - 1) << 1)); raw.MoveNext(); raw.MoveNext(); } // Bottom right pixel pix.SetAndMoveNext( (ushort)(raw.GetRel(-1, 0) << 1), (ushort)((raw.GetRel(-1, -1) + raw.GetRel(-2, 0))), (ushort)(raw.GetRel(-2, -1) << 1)); raw.MoveNext(); }
private static void ProcessTopLine(RawBGGRMap <ushort> map, VectorMap res) { float maxValue = map.MaxValue; var pix = res.GetPixel(); var raw = map.GetRow(0); // Top Left pixel pix.SetAndMoveNext( (raw.GetRel(1, 1) / maxValue), (raw.GetRel(1, 0) + raw.GetRel(0, 1)), raw.Value << 1); raw.MoveNext(); // Top row for (var x = 1; x < res.Width - 1; x += 2) { pix.SetAndMoveNext( raw.GetRel(0, 1) << 1, raw.Value << 1, (raw.GetRel(-1, 0) + raw.GetRel(+1, 0))); pix.SetAndMoveNext( (raw.GetRel(0, 1) + raw.GetRel(+2, 1)), (raw.Value + raw.GetRel(+2, 0) + (raw.GetRel(+1, 1) << 1)) >> 1, raw.GetRel(+1, 0) << 1); raw.MoveNext(); raw.MoveNext(); } // Top right pixel pix.SetAndMoveNext( (ushort)(raw.GetRel(res.Width - 1, 1) << 1), (ushort)(raw.GetRel(res.Width - 1, 0) << 1), (ushort)(raw.GetRel(res.Width - 2, 0) << 1)); raw.MoveNext(); }
private static IColorMap ApplyRawBGGRToColorMapFilter(RawBGGRMap<ushort> map, IRawToColorMap16Filter<RawBGGRMap<ushort>, ushort> filter) { return filter.Process(map); }
private static RawImageFile <ushort> DecodeImagePart(Stream stream, PanasonicExif exif) { int row, col, i, j, sh = 0; int[] pred = new int[2], nonz = new int[2]; var resultHeight = exif.ImageHeight; var resultWidth = exif.CropRight; var map = new RawBGGRMap <ushort>(resultWidth, resultHeight, 12); var raw = map.GetPixel(); int value; var bits = new PanasonicBitStream(stream); for (row = 0; row < exif.ImageHeight; row++) { for (col = 0; col < exif.ImageWidth; col++) { unchecked { i = col % 14; if (i == 0) { pred[0] = pred[1] = nonz[0] = nonz[1] = 0; } if (i % 3 == 2) { sh = 4 >> (3 - bits.Read(2)); } if (nonz[i & 1] != 0) { j = bits.Read(8); if (j != 0) { pred[i & 1] -= 0x80 << sh; if (pred[i & 1] < 0 || sh == 4) { pred[i & 1] &= ~(-1 << sh); } pred[i & 1] += j << sh; } } else { nonz[i & 1] = bits.Read(8); if (nonz[i & 1] != 0 || i > 11) { pred[i & 1] = nonz[i & 1] << 4 | bits.Read(4); } } if (col >= resultWidth) { continue; } value = pred[col & 1]; if (value > 4098) { throw new Exception("Decoding error"); } raw.SetAndMoveNext((ushort)Math.Min(4095, value)); } } } var result = new RawImageFile <ushort>(map) { Exif = exif, }; return(result); }
private static IColorMap ApplyRawBGGRToColorMapFilter(RawBGGRMap <ushort> map, IRawToColorMap16Filter <RawBGGRMap <ushort>, ushort> filter) { return(filter.Process(map)); }