|
|
|
@ -7,7 +7,6 @@ using System.IO; |
|
|
|
using System.Linq; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using SixLabors.ImageSharp.Common.Helpers; |
|
|
|
using SixLabors.ImageSharp.Formats.Jpeg.Components; |
|
|
|
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; |
|
|
|
@ -432,27 +431,27 @@ namespace SixLabors.ImageSharp.Formats.Jpeg |
|
|
|
prevDCY = this.WriteBlock( |
|
|
|
QuantIndex.Luminance, |
|
|
|
prevDCY, |
|
|
|
&pixelConverter.Y, |
|
|
|
&temp1, |
|
|
|
&temp2, |
|
|
|
&onStackLuminanceQuantTable, |
|
|
|
unzig.Data); |
|
|
|
ref pixelConverter.Y, |
|
|
|
ref temp1, |
|
|
|
ref temp2, |
|
|
|
ref onStackLuminanceQuantTable, |
|
|
|
ref unzig); |
|
|
|
prevDCCb = this.WriteBlock( |
|
|
|
QuantIndex.Chrominance, |
|
|
|
prevDCCb, |
|
|
|
&pixelConverter.Cb, |
|
|
|
&temp1, |
|
|
|
&temp2, |
|
|
|
&onStackChrominanceQuantTable, |
|
|
|
unzig.Data); |
|
|
|
ref pixelConverter.Cb, |
|
|
|
ref temp1, |
|
|
|
ref temp2, |
|
|
|
ref onStackChrominanceQuantTable, |
|
|
|
ref unzig); |
|
|
|
prevDCCr = this.WriteBlock( |
|
|
|
QuantIndex.Chrominance, |
|
|
|
prevDCCr, |
|
|
|
&pixelConverter.Cr, |
|
|
|
&temp1, |
|
|
|
&temp2, |
|
|
|
&onStackChrominanceQuantTable, |
|
|
|
unzig.Data); |
|
|
|
ref pixelConverter.Cr, |
|
|
|
ref temp1, |
|
|
|
ref temp2, |
|
|
|
ref onStackChrominanceQuantTable, |
|
|
|
ref unzig); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -517,25 +516,24 @@ namespace SixLabors.ImageSharp.Formats.Jpeg |
|
|
|
/// <param name="tempDest1">Temporal block to be used as FDCT Destination</param>
|
|
|
|
/// <param name="tempDest2">Temporal block 2</param>
|
|
|
|
/// <param name="quant">Quantization table</param>
|
|
|
|
/// <param name="unzigPtr">The 8x8 Unzig block pointer</param>
|
|
|
|
/// <param name="unZig">The 8x8 Unzig block.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// The <see cref="int"/>
|
|
|
|
/// </returns>
|
|
|
|
private int WriteBlock( |
|
|
|
QuantIndex index, |
|
|
|
int prevDC, |
|
|
|
Block8x8F* src, |
|
|
|
Block8x8F* tempDest1, |
|
|
|
Block8x8F* tempDest2, |
|
|
|
Block8x8F* quant, |
|
|
|
byte* unzigPtr) |
|
|
|
ref Block8x8F src, |
|
|
|
ref Block8x8F tempDest1, |
|
|
|
ref Block8x8F tempDest2, |
|
|
|
ref Block8x8F quant, |
|
|
|
ref ZigZag unZig) |
|
|
|
{ |
|
|
|
FastFloatingPointDCT.TransformFDCT(ref *src, ref *tempDest1, ref *tempDest2); |
|
|
|
FastFloatingPointDCT.TransformFDCT(ref src, ref tempDest1, ref tempDest2); |
|
|
|
|
|
|
|
Block8x8F.Quantize(tempDest1, tempDest2, quant, unzigPtr); |
|
|
|
float* unziggedDestPtr = (float*)tempDest2; |
|
|
|
Block8x8F.Quantize(ref tempDest1, ref tempDest2, ref quant, ref unZig); |
|
|
|
|
|
|
|
int dc = (int)unziggedDestPtr[0]; |
|
|
|
int dc = (int)tempDest2[0]; |
|
|
|
|
|
|
|
// Emit the DC delta.
|
|
|
|
this.EmitHuffRLE((HuffIndex)((2 * (int)index) + 0), 0, dc - prevDC); |
|
|
|
@ -546,7 +544,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg |
|
|
|
|
|
|
|
for (int zig = 1; zig < Block8x8F.Size; zig++) |
|
|
|
{ |
|
|
|
int ac = (int)unziggedDestPtr[zig]; |
|
|
|
int ac = (int)tempDest2[zig]; |
|
|
|
|
|
|
|
if (ac == 0) |
|
|
|
{ |
|
|
|
@ -982,11 +980,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg |
|
|
|
{ |
|
|
|
// TODO: Need a JpegScanEncoder<TPixel> class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.)
|
|
|
|
Block8x8F b = default; |
|
|
|
|
|
|
|
BlockQuad cb = default; |
|
|
|
BlockQuad cr = default; |
|
|
|
var cbPtr = (Block8x8F*)cb.Data; |
|
|
|
var crPtr = (Block8x8F*)cr.Data; |
|
|
|
Span<Block8x8F> cb = stackalloc Block8x8F[4]; |
|
|
|
Span<Block8x8F> cr = stackalloc Block8x8F[4]; |
|
|
|
|
|
|
|
Block8x8F temp1 = default; |
|
|
|
Block8x8F temp2 = default; |
|
|
|
@ -1018,38 +1013,38 @@ namespace SixLabors.ImageSharp.Formats.Jpeg |
|
|
|
|
|
|
|
pixelConverter.Convert(frame, x + xOff, y + yOff, currentRows); |
|
|
|
|
|
|
|
cbPtr[i] = pixelConverter.Cb; |
|
|
|
crPtr[i] = pixelConverter.Cr; |
|
|
|
cb[i] = pixelConverter.Cb; |
|
|
|
cr[i] = pixelConverter.Cr; |
|
|
|
|
|
|
|
prevDCY = this.WriteBlock( |
|
|
|
QuantIndex.Luminance, |
|
|
|
prevDCY, |
|
|
|
&pixelConverter.Y, |
|
|
|
&temp1, |
|
|
|
&temp2, |
|
|
|
&onStackLuminanceQuantTable, |
|
|
|
unzig.Data); |
|
|
|
ref pixelConverter.Y, |
|
|
|
ref temp1, |
|
|
|
ref temp2, |
|
|
|
ref onStackLuminanceQuantTable, |
|
|
|
ref unzig); |
|
|
|
} |
|
|
|
|
|
|
|
Block8x8F.Scale16X16To8X8(&b, cbPtr); |
|
|
|
Block8x8F.Scale16X16To8X8(ref b, cb); |
|
|
|
prevDCCb = this.WriteBlock( |
|
|
|
QuantIndex.Chrominance, |
|
|
|
prevDCCb, |
|
|
|
&b, |
|
|
|
&temp1, |
|
|
|
&temp2, |
|
|
|
&onStackChrominanceQuantTable, |
|
|
|
unzig.Data); |
|
|
|
ref b, |
|
|
|
ref temp1, |
|
|
|
ref temp2, |
|
|
|
ref onStackChrominanceQuantTable, |
|
|
|
ref unzig); |
|
|
|
|
|
|
|
Block8x8F.Scale16X16To8X8(&b, crPtr); |
|
|
|
Block8x8F.Scale16X16To8X8(ref b, cr); |
|
|
|
prevDCCr = this.WriteBlock( |
|
|
|
QuantIndex.Chrominance, |
|
|
|
prevDCCr, |
|
|
|
&b, |
|
|
|
&temp1, |
|
|
|
&temp2, |
|
|
|
&onStackChrominanceQuantTable, |
|
|
|
unzig.Data); |
|
|
|
ref b, |
|
|
|
ref temp1, |
|
|
|
ref temp2, |
|
|
|
ref onStackChrominanceQuantTable, |
|
|
|
ref unzig); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|