📄 gr32_resamplers.pas
字号:
unit GR32_Resamplers;
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Graphics32
*
* The Initial Developers of the Original Code is
* Mattias Andersson <mattias@centaurix.com>
* (parts of this unit were taken from GR32_Transforms.pas by Alex A. Denisov)
*
* Portions created by the Initial Developer are Copyright (C) 2000-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Hansen <dyster_tid@hotmail.com>
*
* ***** END LICENSE BLOCK ***** *)
interface
{$I GR32.inc}
uses
{$IFDEF CLX}
Qt, Types, {$IFDEF LINUX}Libc, {$ENDIF}
{$ELSE}
Windows,
{$ENDIF}
Classes, SysUtils, GR32, GR32_Transforms, GR32_Containers,
GR32_OrdinalMaps, GR32_Blend;
procedure BlockTransfer(
Dst: TBitmap32; DstX: Integer; DstY: Integer; DstClip: TRect;
Src: TBitmap32; SrcRect: TRect;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent = nil);
procedure BlockTransferX(
Dst: TBitmap32; DstX, DstY: TFixed;
Src: TBitmap32; SrcRect: TRect;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent = nil);
procedure StretchTransfer(
Dst: TBitmap32; const DstRect: TRect; DstClip: TRect;
Src: TBitmap32; const SrcRect: TRect;
Resampler: TCustomResampler;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent = nil);
procedure BlendTransfer(
Dst: TBitmap32; DstX, DstY: Integer; DstClip: TRect;
SrcF: TBitmap32; SrcRectF: TRect;
SrcB: TBitmap32; SrcRectB: TRect;
BlendCallback: TBlendReg); overload;
procedure BlendTransfer(
Dst: TBitmap32; DstX, DstY: Integer; DstClip: TRect;
SrcF: TBitmap32; SrcRectF: TRect;
SrcB: TBitmap32; SrcRectB: TRect;
BlendCallback: TBlendRegEx; MasterAlpha: Integer); overload;
type
PKernelEntry = ^TKernelEntry;
TKernelEntry = array [0..0] of Integer;
TArrayOfKernelEntry = array of TArrayOfInteger;
PKernelEntryArray = ^TKernelEntryArray;
TKernelEntryArray = array [0..0] of TArrayOfInteger;
TFilterMethod = function(Value: TFloat): TFloat of object;
EBitmapException = class(Exception);
ESrcInvalidException = class(Exception);
ENestedException = class(Exception);
TGetSampleInt = function(X, Y: Integer): TColor32 of object;
TGetSampleFloat = function(X, Y: TFloat): TColor32 of object;
TGetSampleFixed = function(X, Y: TFixed): TColor32 of object;
TBitmap32Resampler = class;
{ TCustomKernel }
TCustomKernel = class(TPersistent)
protected
FObserver: TNotifiablePersistent;
protected
procedure AssignTo(Dst: TPersistent); override;
function RangeCheck: Boolean; virtual;
public
constructor Create; virtual;
procedure Changed;
function Filter(Value: TFloat): TFloat; virtual; abstract;
function GetWidth: TFloat; virtual; abstract;
property Observer: TNotifiablePersistent read FObserver;
end;
TCustomKernelClass = class of TCustomKernel;
{ TBoxKernel }
TBoxKernel = class(TCustomKernel)
public
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
end;
{ TLinearKernel }
TLinearKernel = class(TCustomKernel)
public
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
end;
{ TCosineKernel }
TCosineKernel = class(TCustomKernel)
public
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
end;
{ TSplineKernel }
TSplineKernel = class(TCustomKernel)
protected
function RangeCheck: Boolean; override;
public
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
end;
{ TMitchellKernel }
TMitchellKernel = class(TCustomKernel)
protected
function RangeCheck: Boolean; override;
public
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
end;
{ TCubicKernel }
TCubicKernel = class(TCustomKernel)
private
FCoeff: TFloat;
procedure SetCoeff(const Value: TFloat);
protected
function RangeCheck: Boolean; override;
public
constructor Create; override;
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
published
property Coeff: TFloat read FCoeff write SetCoeff;
end;
{ THermiteKernel }
THermiteKernel = class(TCustomKernel)
private
FBias: TFloat;
FTension: TFloat;
procedure SetBias(const Value: TFloat);
procedure SetTension(const Value: TFloat);
protected
function RangeCheck: Boolean; override;
public
constructor Create; override;
function Filter(Value: TFloat): TFloat; override;
function GetWidth: TFloat; override;
published
property Bias: TFloat read FBias write SetBias;
property Tension: TFloat read FTension write SetTension;
end;
{ TWindowedSincKernel }
TWindowedSincKernel = class(TCustomKernel)
private
FWidth: TFloat;
protected
function RangeCheck: Boolean; override;
function Window(Value: TFloat): TFloat; virtual; abstract;
public
constructor Create; override;
function Filter(Value: TFloat): TFloat; override;
procedure SetWidth(Value: TFloat);
function GetWidth: TFloat; override;
published
property Width: TFloat read FWidth write SetWidth;
end;
{ TLanczosKernel }
TLanczosKernel = class(TWindowedSincKernel)
protected
function Window(Value: TFloat): TFloat; override;
end;
{ TGaussianKernel }
TGaussianKernel = class(TWindowedSincKernel)
private
FSigma: TFloat;
procedure SetSigma(const Value: TFloat);
protected
function Window(Value: TFloat): TFloat; override;
public
constructor Create; override;
published
property Sigma: TFloat read FSigma write SetSigma;
end;
{ TBlackmanKernel }
TBlackmanKernel = class(TWindowedSincKernel)
protected
function Window(Value: TFloat): TFloat; override;
end;
{ THannKernel }
THannKernel = class(TWindowedSincKernel)
protected
function Window(Value: TFloat): TFloat; override;
end;
{ THammingKernel }
THammingKernel = class(TWindowedSincKernel)
protected
function Window(Value: TFloat): TFloat; override;
end;
{ TSinshKernel }
TSinshKernel = class(TCustomKernel)
private
FWidth: TFloat;
FCoeff: TFloat;
procedure SetCoeff(const Value: TFloat);
protected
function RangeCheck: Boolean; override;
public
constructor Create; override;
procedure SetWidth(Value: TFloat);
function GetWidth: TFloat; override;
function Filter(Value: TFloat): TFloat; override;
published
property Coeff: TFloat read FCoeff write SetCoeff;
property Width: TFloat read GetWidth write SetWidth;
end;
TTransformer = class;
TTransformerClass = class of TTransformer;
TPixelAccessMode = (pamUnsafe, pamSafe, pamWrap);
{ TBitmap32Resampler }
{ Base class for TBitmap32 specific resamplers. }
TBitmap32Resampler = class(TCustomResampler)
private
FBitmap: TBitmap32;
FClipRect: TRect;
FTransformerClass: TTransformerClass;
FPixelAccessMode: TPixelAccessMode;
procedure SetPixelAccessMode(const Value: TPixelAccessMode);
protected
procedure AssignTo(Dst: TPersistent); override;
public
constructor Create(ABitmap: TBitmap32); reintroduce; virtual;
procedure Changed; override;
procedure PrepareSampling; override;
function HasBounds: Boolean; override;
function GetSampleBounds: TRect; override;
property Bitmap: TBitmap32 read FBitmap write FBitmap;
property TransformerClass: TTransformerClass read FTransformerClass write FTransformerClass;
published
property PixelAccessMode: TPixelAccessMode read FPixelAccessMode write SetPixelAccessMode default pamSafe;
end;
TBitmap32ResamplerClass = class of TBitmap32Resampler;
{ TNearestResampler }
TNearestResampler = class(TBitmap32Resampler)
private
FGetSampleInt: TGetSampleInt;
protected
function GetWidth: TFloat; override;
procedure Resample(
Dst: TBitmap32; DstRect: TRect; DstClip: TRect;
Src: TBitmap32; SrcRect: TRect;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent); override;
public
constructor Create(Bitmap: TBitmap32); override;
function GetSampleInt(X, Y: Integer): TColor32; override;
function GetSampleFixed(X, Y: TFixed): TColor32; override;
function GetSampleFloat(X, Y: TFloat): TColor32; override;
procedure PrepareSampling; override;
end;
{ TLinearResampler }
TLinearResampler = class(TBitmap32Resampler)
private
FLinearKernel: TLinearKernel;
FGetSampleFixed: TGetSampleFixed;
protected
function GetWidth: TFloat; override;
procedure Resample(
Dst: TBitmap32; DstRect: TRect; DstClip: TRect;
Src: TBitmap32; SrcRect: TRect;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent); override;
public
constructor Create(Bitmap: TBitmap32); override;
destructor Destroy; override;
function GetSampleFixed(X, Y: TFixed): TColor32; override;
function GetSampleFloat(X, Y: TFloat): TColor32; override;
procedure PrepareSampling; override;
end;
{ TDraftResampler }
TDraftResampler = class(TLinearResampler)
protected
procedure Resample(
Dst: TBitmap32; DstRect: TRect; DstClip: TRect;
Src: TBitmap32; SrcRect: TRect;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent); override;
end;
{ TKernelResampler }
{ This resampler class will perform resampling by using an arbitrary
reconstruction kernel. By using the kmTableNearest and kmTableLinear
kernel modes, kernel values are precomputed in a look-up table. This
allows GetSample to execute faster for complex kernels. }
TKernelMode = (kmDynamic, kmTableNearest, kmTableLinear);
TKernelResampler = class(TBitmap32Resampler)
private
FKernel: TCustomKernel;
FKernelMode: TKernelMode;
FWeightTable: TIntegerMap;
FTableSize: Integer;
FMappingX: TArrayOfInteger;
FVertKernel: TArrayOfInteger;
FHorzKernel: TArrayOfInteger;
FOuterColor: TColor32;
procedure SetKernel(const Value: TCustomKernel);
function GetKernelClassName: string;
procedure SetKernelClassName(Value: string);
procedure SetKernelMode(const Value: TKernelMode);
procedure SetTableSize(Value: Integer);
protected
function GetWidth: TFloat; override;
public
constructor Create(ABitmap: TBitmap32); override;
destructor Destroy; override;
function GetSampleFloat(X, Y: TFloat): TColor32; override;
procedure Resample(
Dst: TBitmap32; DstRect: TRect; DstClip: TRect;
Src: TBitmap32; SrcRect: TRect;
CombineOp: TDrawMode; CombineCallBack: TPixelCombineEvent); override;
procedure PrepareSampling; override;
procedure FinalizeSampling; override;
published
property KernelClassName: string read GetKernelClassName write SetKernelClassName;
property Kernel: TCustomKernel read FKernel write SetKernel;
property KernelMode: TKernelMode read FKernelMode write SetKernelMode;
property TableSize: Integer read FTableSize write SetTableSize;
end;
{ TNestedSampler }
TNestedSampler = class(TCustomSampler)
private
FSampler: TCustomSampler;
FGetSampleInt: TGetSampleInt;
FGetSampleFixed: TGetSampleFixed;
FGetSampleFloat: TGetSampleFloat;
procedure SetSampler(const Value: TCustomSampler);
protected
procedure AssignTo(Dst: TPersistent); override;
public
constructor Create(ASampler: TCustomSampler); reintroduce; virtual;
procedure PrepareSampling; override;
procedure FinalizeSampling; override;
function HasBounds: Boolean; override;
function GetSampleBounds: TRect; override;
published
property Sampler: TCustomSampler read FSampler write SetSampler;
end;
{ TTransformer }
TReverseTransformInt = procedure(DstX, DstY: Integer; out SrcX, SrcY: Integer) of object;
TReverseTransformFixed = procedure(DstX, DstY: TFixed; out SrcX, SrcY: TFixed) of object;
TReverseTransformFloat = procedure(DstX, DstY: TFloat; out SrcX, SrcY: TFloat) of object;
TTransformer = class(TNestedSampler)
private
FTransformation: TTransformation;
FTransformationReverseTransformInt: TReverseTransformInt;
FTransformationReverseTransformFixed: TReverseTransformFixed;
FTransformationReverseTransformFloat: TReverseTransformFloat;
procedure SetTransformation(const Value: TTransformation);
public
constructor Create(ASampler: TCustomSampler; ATransformation: TTransformation); reintroduce;
procedure PrepareSampling; override;
function GetSampleInt(X, Y: Integer): TColor32; override;
function GetSampleFixed(X, Y: TFixed): TColor32; override;
function GetSampleFloat(X, Y: TFloat): TColor32; override;
function HasBounds: Boolean; override;
function GetSampleBounds: TRect; override;
published
property Transformation: TTransformation read FTransformation write SetTransformation;
end;
{ TNearestTransformer }
TNearestTransformer = class(TTransformer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -