mirror of https://github.com/SixLabors/ImageSharp
6 changed files with 3 additions and 262 deletions
@ -1,98 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Runtime.CompilerServices; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using SixLabors.ImageSharp.Formats.Jpeg.Common; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Jpeg specific utilities and extension methods
|
|
||||
/// </summary>
|
|
||||
internal static class OrigJpegUtils |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Stack only TPixel -> Rgb24 conversion method on 8x8 blocks.
|
|
||||
/// </summary>
|
|
||||
public static void ConvertToRgbUnsafe<TPixel>(ref GenericBlock8x8<TPixel> source, ref GenericBlock8x8<Rgb24> dest) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
PixelOperations<TPixel>.Instance.ToRgb24(source.AsSpanUnsafe(), dest.AsSpanUnsafe(), 64); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Copy a region of an image into dest. De "outlier" area will be stretched out with pixels on the right and bottom of the image.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel type</typeparam>
|
|
||||
/// <param name="pixels">The input pixel acessor</param>
|
|
||||
/// <param name="dest">The destination <see cref="PixelArea{TPixel}"/></param>
|
|
||||
/// <param name="sourceY">Starting Y coord</param>
|
|
||||
/// <param name="sourceX">Starting X coord</param>
|
|
||||
public static void CopyRGBBytesStretchedTo<TPixel>( |
|
||||
this PixelAccessor<TPixel> pixels, |
|
||||
PixelArea<TPixel> dest, |
|
||||
int sourceY, |
|
||||
int sourceX) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
pixels.SafeCopyTo(dest, sourceY, sourceX); |
|
||||
int stretchFromX = pixels.Width - sourceX; |
|
||||
int stretchFromY = pixels.Height - sourceY; |
|
||||
StretchPixels(dest, stretchFromX, stretchFromY); |
|
||||
} |
|
||||
|
|
||||
// Nothing to stretch if (fromX, fromY) is outside the area, or is at (0,0)
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
private static bool IsInvalidStretchStartingPosition<TPixel>(PixelArea<TPixel> area, int fromX, int fromY) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
return fromX <= 0 || fromY <= 0 || fromX >= area.Width || fromY >= area.Height; |
|
||||
} |
|
||||
|
|
||||
private static void StretchPixels<TPixel>(PixelArea<TPixel> area, int fromX, int fromY) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
if (IsInvalidStretchStartingPosition(area, fromX, fromY)) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
for (int y = 0; y < fromY; y++) |
|
||||
{ |
|
||||
ref RGB24 ptrBase = ref GetRowStart(area, y); |
|
||||
|
|
||||
for (int x = fromX; x < area.Width; x++) |
|
||||
{ |
|
||||
// Copy the left neighbour pixel to the current one
|
|
||||
Unsafe.Add(ref ptrBase, x) = Unsafe.Add(ref ptrBase, x - 1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
for (int y = fromY; y < area.Height; y++) |
|
||||
{ |
|
||||
ref RGB24 currBase = ref GetRowStart(area, y); |
|
||||
ref RGB24 prevBase = ref GetRowStart(area, y - 1); |
|
||||
|
|
||||
for (int x = 0; x < area.Width; x++) |
|
||||
{ |
|
||||
// Copy the top neighbour pixel to the current one
|
|
||||
Unsafe.Add(ref currBase, x) = Unsafe.Add(ref prevBase, x); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
private static ref RGB24 GetRowStart<TPixel>(PixelArea<TPixel> area, int y) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
return ref Unsafe.As<byte, RGB24>(ref area.GetRowSpan(y).DangerousGetPinnableReference()); |
|
||||
} |
|
||||
|
|
||||
[StructLayout(LayoutKind.Sequential, Size = 3)] |
|
||||
private struct RGB24 |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,102 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Numerics; |
|
||||
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using Xunit; |
|
||||
|
|
||||
// ReSharper disable InconsistentNaming
|
|
||||
namespace SixLabors.ImageSharp.Tests.Formats.Jpg |
|
||||
{ |
|
||||
public class JpegUtilsTests |
|
||||
{ |
|
||||
public static Image<TPixel> CreateTestImage<TPixel>() |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
var image = new Image<TPixel>(10, 10); |
|
||||
using (PixelAccessor<TPixel> pixels = image.Lock()) |
|
||||
{ |
|
||||
for (int i = 0; i < 10; i++) |
|
||||
{ |
|
||||
for (int j = 0; j < 10; j++) |
|
||||
{ |
|
||||
var v = new Vector4(i / 10f, j / 10f, 0, 1); |
|
||||
|
|
||||
var color = default(TPixel); |
|
||||
color.PackFromVector4(v); |
|
||||
|
|
||||
pixels[i, j] = color; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return image; |
|
||||
} |
|
||||
|
|
||||
[Theory] |
|
||||
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.Rgba32| PixelTypes.Rgba32 | PixelTypes.Argb32)] |
|
||||
public void CopyStretchedRGBTo_FromOrigo<TPixel>(TestImageProvider<TPixel> provider) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
using (Image<TPixel> src = provider.GetImage()) |
|
||||
using (Image<TPixel> dest = new Image<TPixel>(8,8)) |
|
||||
using (PixelArea<TPixel> area = new PixelArea<TPixel>(8, 8, ComponentOrder.Xyz)) |
|
||||
using (PixelAccessor<TPixel> s = src.Lock()) |
|
||||
using (PixelAccessor<TPixel> d = dest.Lock()) |
|
||||
{ |
|
||||
s.CopyRGBBytesStretchedTo(area, 0, 0); |
|
||||
d.CopyFrom(area, 0, 0); |
|
||||
|
|
||||
Assert.Equal(s[0, 0], d[0, 0]); |
|
||||
Assert.Equal(s[7, 0], d[7, 0]); |
|
||||
Assert.Equal(s[0, 7], d[0, 7]); |
|
||||
Assert.Equal(s[7, 7], d[7, 7]); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
[Theory] |
|
||||
[WithMemberFactory(nameof(CreateTestImage), PixelTypes.Rgba32| PixelTypes.Rgba32 | PixelTypes.Argb32)] |
|
||||
public void CopyStretchedRGBTo_WithOffset<TPixel>(TestImageProvider<TPixel> provider) |
|
||||
where TPixel : struct, IPixel<TPixel> |
|
||||
{ |
|
||||
using (Image<TPixel> src = provider.GetImage()) |
|
||||
using (PixelArea<TPixel> area = new PixelArea<TPixel>(8, 8, ComponentOrder.Xyz)) |
|
||||
using (Image<TPixel> dest = new Image<TPixel>(8, 8)) |
|
||||
using (PixelAccessor<TPixel> s = src.Lock()) |
|
||||
using (PixelAccessor<TPixel> d = dest.Lock()) |
|
||||
{ |
|
||||
s.CopyRGBBytesStretchedTo(area, 7, 6); |
|
||||
d.CopyFrom(area, 0, 0); |
|
||||
|
|
||||
Assert.Equal(s[6, 7], d[0, 0]); |
|
||||
Assert.Equal(s[6, 8], d[0, 1]); |
|
||||
Assert.Equal(s[7, 8], d[1, 1]); |
|
||||
|
|
||||
Assert.Equal(s[6, 9], d[0, 2]); |
|
||||
Assert.Equal(s[6, 9], d[0, 3]); |
|
||||
Assert.Equal(s[6, 9], d[0, 7]); |
|
||||
|
|
||||
Assert.Equal(s[7, 9], d[1, 2]); |
|
||||
Assert.Equal(s[7, 9], d[1, 3]); |
|
||||
Assert.Equal(s[7, 9], d[1, 7]); |
|
||||
|
|
||||
Assert.Equal(s[9, 9], d[3, 2]); |
|
||||
Assert.Equal(s[9, 9], d[3, 3]); |
|
||||
Assert.Equal(s[9, 9], d[3, 7]); |
|
||||
|
|
||||
Assert.Equal(s[9, 7], d[3, 0]); |
|
||||
Assert.Equal(s[9, 7], d[4, 0]); |
|
||||
Assert.Equal(s[9, 7], d[7, 0]); |
|
||||
|
|
||||
Assert.Equal(s[9, 9], d[3, 2]); |
|
||||
Assert.Equal(s[9, 9], d[4, 2]); |
|
||||
Assert.Equal(s[9, 9], d[7, 2]); |
|
||||
|
|
||||
Assert.Equal(s[9, 9], d[4, 3]); |
|
||||
Assert.Equal(s[9, 9], d[7, 7]); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue