@ -2,8 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System ;
using System.Collections.Generic ;
using System.Linq ;
using SixLabors.ImageSharp.Advanced ;
using SixLabors.ImageSharp.Memory ;
@ -24,74 +22,34 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
internal class ResizeProcessor < TPixel > : TransformProcessor < TPixel >
where TPixel : struct , IPixel < TPixel >
{
private readonly ResizeProcessor parameterSource ;
private bool isDisposed ;
private readonly int targetWidth ;
private readonly int targetHeight ;
private readonly IResampler resampler ;
private Rectangle targetRectangle ;
private readonly bool compand ;
// The following fields are not immutable but are optionally created on demand.
private ResizeKernelMap horizontalKernelMap ;
private ResizeKernelMap verticalKernelMap ;
public ResizeProcessor ( ResizeProcessor parameterSource , Image < TPixel > source , Rectangle sourceRectangle )
public ResizeProcessor ( ResizeProcessor definition , Image < TPixel > source , Rectangle sourceRectangle )
: base ( source , sourceRectangle )
{
this . parameterSource = parameterSource ;
this . targetWidth = definition . TargetWidth ;
this . targetHeight = definition . TargetHeight ;
this . targetRectangle = definition . TargetRectangle ;
this . resampler = definition . Sampler ;
this . compand = definition . Compand ;
}
/// <summary>
/// Gets the sampler to perform the resize operation.
/// </summary>
public IResampler Sampler = > this . parameterSource . Sampler ;
/// <summary>
/// Gets the target width.
/// </summary>
public int TargetWidth = > this . parameterSource . TargetWidth ;
/// <summary>
/// Gets the target height.
/// </summary>
public int TargetHeight = > this . parameterSource . TargetHeight ;
/// <summary>
/// Gets the target resize rectangle.
/// </summary>
public Rectangle TargetRectangle = > this . parameterSource . TargetRectangle ;
/// <summary>
/// Gets a value indicating whether to compress or expand individual pixel color values on processing.
/// </summary>
public bool Compand = > this . parameterSource . Compand ;
/// <summary>
/// This is a shim for tagging the CreateDestination virtual generic method for the AoT iOS compiler.
/// This method should never be referenced outside of the AotCompiler code.
/// </summary>
/// <returns>The result returned from <see cref="M:CreateDestination"/>.</returns>
internal Image < TPixel > AotCreateDestination ( )
= > this . CreateDestination ( ) ;
/// <inheritdoc/>
protected override Image < TPixel > CreateDestination ( )
{
Image < TPixel > source = this . Source ;
Configuration configuration = this . Configuration ;
// We will always be creating the clone even for mutate because we may need to resize the canvas
IEnumerable < ImageFrame < TPixel > > frames = source . Frames . Select < ImageFrame < TPixel > , ImageFrame < TPixel > > (
x = > new ImageFrame < TPixel > (
configuration ,
this . TargetWidth ,
this . TargetHeight ,
x . Metadata . DeepClone ( ) ) ) ;
// Use the overload to prevent an extra frame being added
return new Image < TPixel > ( configuration , source . Metadata . DeepClone ( ) , frames ) ;
}
protected override Size GetTargetSize ( ) = > new Size ( this . targetWidth , this . targetHeight ) ;
/// <inheritdoc/>
protected override void BeforeImageApply ( Image < TPixel > destination )
{
if ( ! ( this . S ampler is NearestNeighborResampler ) )
if ( ! ( this . resampler is NearestNeighborResampler ) )
{
Image < TPixel > source = this . Source ;
Rectangle sourceRectangle = this . SourceRectangle ;
@ -99,14 +57,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Since all image frame dimensions have to be the same we can calculate this for all frames.
MemoryAllocator memoryAllocator = source . GetMemoryAllocator ( ) ;
this . horizontalKernelMap = ResizeKernelMap . Calculate (
this . S ampler,
this . T argetRectangle. Width ,
this . res ampler,
this . t argetRectangle. Width ,
sourceRectangle . Width ,
memoryAllocator ) ;
this . verticalKernelMap = ResizeKernelMap . Calculate (
this . S ampler,
this . T argetRectangle. Height ,
this . res ampler,
this . t argetRectangle. Height ,
sourceRectangle . Height ,
memoryAllocator ) ;
}
@ -121,29 +79,29 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
Configuration configuration = this . Configuration ;
// Handle resize dimensions identical to the original
if ( source . Width = = destination . Width & & source . Height = = destination . Height & & sourceRectangle = = this . T argetRectangle)
if ( source . Width = = destination . Width & & source . Height = = destination . Height & & sourceRectangle = = this . t argetRectangle)
{
// The cloned will be blank here copy all the pixel data over
source . GetPixelSpan ( ) . CopyTo ( destination . GetPixelSpan ( ) ) ;
return ;
}
int width = this . T argetWidth;
int height = this . T argetHeight;
int width = this . t argetWidth;
int height = this . t argetHeight;
int sourceX = sourceRectangle . X ;
int sourceY = sourceRectangle . Y ;
int startY = this . T argetRectangle. Y ;
int startX = this . T argetRectangle. X ;
int startY = this . t argetRectangle. Y ;
int startX = this . t argetRectangle. X ;
var targetWorkingRect = Rectangle . Intersect (
this . T argetRectangle,
this . t argetRectangle,
new Rectangle ( 0 , 0 , width , height ) ) ;
if ( this . S ampler is NearestNeighborResampler )
if ( this . res ampler is NearestNeighborResampler )
{
// Scaling factors
float widthFactor = sourceRectangle . Width / ( float ) this . T argetRectangle. Width ;
float heightFactor = sourceRectangle . Height / ( float ) this . T argetRectangle. Height ;
float widthFactor = sourceRectangle . Width / ( float ) this . t argetRectangle. Width ;
float heightFactor = sourceRectangle . Height / ( float ) this . t argetRectangle. Height ;
ParallelHelper . IterateRows (
targetWorkingRect ,
@ -153,8 +111,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
for ( int y = rows . Min ; y < rows . Max ; y + + )
{
// Y coordinates of source points
Span < TPixel > sourceRow =
source . GetPixelRowSpan ( ( int ) ( ( ( y - startY ) * heightFactor ) + sourceY ) ) ;
Span < TPixel > sourceRow = source . GetPixelRowSpan ( ( int ) ( ( ( y - startY ) * heightFactor ) + sourceY ) ) ;
Span < TPixel > targetRow = destination . GetPixelRowSpan ( y ) ;
for ( int x = targetWorkingRect . Left ; x < targetWorkingRect . Right ; x + + )
@ -169,7 +126,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
}
PixelConversionModifiers conversionModifiers =
PixelConversionModifiers . Premultiply . ApplyCompanding ( this . C ompand) ;
PixelConversionModifiers . Premultiply . ApplyCompanding ( this . c ompand) ;
BufferArea < TPixel > sourceArea = source . PixelBuffer . GetArea ( sourceRectangle ) ;
@ -183,7 +140,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
this . verticalKernelMap ,
width ,
targetWorkingRect ,
this . T argetRectangle. Location ) )
this . t argetRectangle. Location ) )
{
worker . Initialize ( ) ;