diff --git a/src/MagicScaler/Magic/InvertTransform.cs b/src/MagicScaler/Magic/InvertTransform.cs new file mode 100644 index 0000000..4ae065d --- /dev/null +++ b/src/MagicScaler/Magic/InvertTransform.cs @@ -0,0 +1,25 @@ +// Copyright © Clinton Ingram and Contributors +// SPDX-License-Identifier: MIT + +using PhotoSauce.MagicScaler.Converters; + +namespace PhotoSauce.MagicScaler.Transforms; + +internal sealed class InvertTransform(PixelSource source) : ChainedPixelSource(source) +{ + protected override unsafe void CopyPixelsInternal(in PixelArea prc, int cbStride, int cbBufferSize, byte* pbBuffer) + { + Profiler.PauseTiming(); + PrevSource.CopyPixels(prc, cbStride, cbBufferSize, pbBuffer); + Profiler.ResumeTiming(); + + nint cb = prc.Width * PrevSource.Format.BytesPerPixel; + for (int y = 0; y < prc.Height; y++) + { + InvertConverter.InvertLine(pbBuffer, cb); + pbBuffer += cbStride; + } + } + + public override string ToString() => nameof(InvertTransform); +} diff --git a/src/MagicScaler/Magic/MagicTransforms.cs b/src/MagicScaler/Magic/MagicTransforms.cs index bfc9b78..a70d34d 100644 --- a/src/MagicScaler/Magic/MagicTransforms.cs +++ b/src/MagicScaler/Magic/MagicTransforms.cs @@ -421,6 +421,27 @@ public static void AddCropper(PipelineContext ctx) return; } + // Workaround for WIC JPEG decoder bug https://github.com/saucecontrol/wic-jpeg-bug + var src = ctx.Source; + if (src is WicFramePixelSource && src.Format == PixelFormat.Cmyk32 && src.Width != crop.Width) + { + using var buff = BufferPool.RentLocal(src.Width * src.Format.BytesPerPixel); + unsafe + { + fixed (byte* pBuff = buff) + { + src.CopyPixels(src.Area.Slice(crop.Y, 1), buff.Length, buff.Length, pBuff); + uint rpix = *((uint*)pBuff + crop.X); + + src.CopyPixels(crop.Slice(0, 1), buff.Length, buff.Length, pBuff); + uint cpix = *(uint*)pBuff; + + if (cpix == ~rpix) + ctx.Source = ctx.AddProfiler(new InvertTransform(src)); + } + } + } + ctx.Source = ctx.AddProfiler(new CropTransform(ctx.Source, crop)); }