28template<
class fptype,
class fptypesimd >
30 public CImageResizerFilterStep< fptype, fptype >
33 using CImageResizerFilterStep< fptype, fptype >
:: IsUpsample;
35 using CImageResizerFilterStep< fptype, fptype >
:: Flt;
36 using CImageResizerFilterStep< fptype, fptype >
:: FltOrig;
37 using CImageResizerFilterStep< fptype, fptype >
:: FltLatency;
38 using CImageResizerFilterStep< fptype, fptype >
:: Vars;
39 using CImageResizerFilterStep< fptype, fptype >
:: InLen;
40 using CImageResizerFilterStep< fptype, fptype >
:: InPrefix;
41 using CImageResizerFilterStep< fptype, fptype >
:: InSuffix;
42 using CImageResizerFilterStep< fptype, fptype >
:: InElIncr;
43 using CImageResizerFilterStep< fptype, fptype >
:: OutLen;
44 using CImageResizerFilterStep< fptype, fptype >
:: OutPrefix;
45 using CImageResizerFilterStep< fptype, fptype >
:: OutSuffix;
46 using CImageResizerFilterStep< fptype, fptype >
:: OutElIncr;
47 using CImageResizerFilterStep< fptype, fptype >
:: PrefixDC;
48 using CImageResizerFilterStep< fptype, fptype >
:: SuffixDC;
49 using CImageResizerFilterStep< fptype, fptype >
:: RPosBuf;
50 using CImageResizerFilterStep< fptype, fptype >
:: FltBank;
67 const int ElCount =
Vars -> ElCount;
70 if( !
Vars -> UseSRGBGamma )
72 for( j = 0; j < ElCount; j++ )
74 const Tin* ip = ip0 + j;
75 fptype*
const op = op0 + j *
InElIncr;
78 for( i = 0; i < l; i++ )
80 op[ i ] = (fptype) *ip;
87 const fptype gm = (fptype)
Vars -> InGammaMult;
89 for( j = 0; j < ElCount; j++ )
91 const Tin* ip = ip0 + j;
92 fptype*
const op = op0 + j *
InElIncr;
95 for( i = 0; i < l; i++ )
116 const int ElCount = Vars0.
ElCount;
120 for( j = 0; j < ElCount; j++ )
122 fptype*
const p = p0 + j * l;
125 for( i = 0; i < l; i++ )
149 const int SrcIncr )
const
151 const int ElCount =
Vars -> ElCount;
152 const int SrcElIncr = SrcIncr / ElCount;
153 const int ips1 = SrcElIncr;
154 const int ips2 = SrcElIncr * 2;
155 const int ips3 = SrcElIncr * 3;
163 for( j = 0; j < SrcLen; j++ )
173 for( j = 0; j < SrcLen; j++ )
176 op[ ops1 ] = ip[ ips1 ];
177 op[ ops2 ] = ip[ ips2 ];
178 op[ ops3 ] = ip[ ips3 ];
186 for( j = 0; j < SrcLen; j++ )
189 op[ ops1 ] = ip[ ips1 ];
190 op[ ops2 ] = ip[ ips2 ];
198 for( j = 0; j < SrcLen; j++ )
201 op[ ops1 ] = ip[ ips1 ];
222 template<
class Tout >
226 const int ElCount = Vars0.
ElCount;
229 for( j = 0; j < ElCount; j++ )
231 const fptype*
const ip = ip0 + j * l;
235 for( i = 0; i < l; i++ )
237 *op = (Tout) ip[ i ];
253 fptype*
const ElBiases )
const
255 const int ElCount =
Vars -> ElCount;
258 for( j = 0; j < ElCount; j++ )
260 const fptype*
const p = p0 + j *
InElIncr;
261 fptype b = (fptype) 0;
264 for( i = 0; i < SrcLen; i++ )
269 ElBiases[ j ] = b / (fptype) SrcLen;
283 const fptype*
const ElBiases )
const
285 const int ElCount =
Vars -> ElCount;
288 for( j = 0; j < ElCount; j++ )
290 fptype*
const p = p0 + j *
InElIncr;
291 const fptype b = ElBiases[ j ];
294 for( i = 0; i < l; i++ )
319 for( j = 0; j <
Vars -> ElCount; j++ )
322 fptype*
const Src2 = Src +
InLen - 1;
338 const int elalign =
Vars -> elalign;
340 const fptype*
const f =
Flt;
341 const int flen =
Flt.getCapacity();
346 for( j = 0; j <
Vars -> ElCount; j++ )
348 const fptype* ip = Src;
353 if(
FltOrig.getCapacity() > 0 )
392 fptypesimd ipv = (fptypesimd) ip[ 0 ];
396 for( i = 0; i < flen; i += elalign )
398 fptypesimd :: addu( op0 + i,
399 fptypesimd :: load( f + i ) * ipv );
410 ipv = (fptypesimd) ip[ 0 ];
412 for( i = 0; i < flen; i += elalign )
414 fptypesimd :: addu( op0 + i,
415 fptypesimd :: load( f + i ) * ipv );
424 ipv = (fptypesimd) ip[ 0 ];
428 for( i = 0; i < flen; i += elalign )
430 fptypesimd :: addu( op0 + i,
431 fptypesimd :: load( f + i ) * ipv );
441 for( i = 0; i < l; i += elalign )
443 fptypesimd :: addu( op0 + i,
444 fptypesimd :: load( dc + i ) * ipv );
447 ipv = (fptypesimd) Src[ 0 ];
452 for( i = 0; i < l; i += elalign )
454 fptypesimd :: addu( op0 + i,
455 fptypesimd :: load( dc + i ) * ipv );
474 void doFilter(
const fptype*
const Src, fptype* Dst,
475 const int DstIncr )
const
477 const int ElCount =
Vars -> ElCount;
478 const int elalign =
Vars -> elalign;
479 const fptype*
const f = &
Flt[ 0 ];
480 const int flen =
Flt.getCapacity();
493 fptypesimd s = fptypesimd :: load( f ) *
494 fptypesimd :: loadu( ip );
496 for( i = elalign; i < flen; i += elalign )
498 s += fptypesimd :: load( f + i ) *
499 fptypesimd :: loadu( ip + i );
511 for( j = 0; j < ElCount; j++ )
521 fptypesimd s = fptypesimd :: load( f ) *
522 fptypesimd :: loadu( ip );
524 for( i = elalign; i < flen; i += elalign )
526 s += fptypesimd :: load( f + i ) *
527 fptypesimd :: loadu( ip + i );
545 const fptype* ip = ip0;
548 for( j = 0; j < ElCount; j++ )
550 fptypesimd s = fptypesimd :: load( f ) *
551 fptypesimd :: loadu( ip );
553 for( i = elalign; i < flen; i += elalign )
555 s += fptypesimd :: load( f + i ) *
556 fptypesimd :: loadu( ip + i );
588 void doResize(
const fptype* SrcLine, fptype* DstLine,
589 int DstLineIncr,
const fptype*
const ElBiases,
590 fptype*
const xx )
const
592 const int IntFltLen =
FltBank -> getFilterLen();
593 const int ElCount =
Vars -> ElCount;
594 const int elalign =
Vars -> elalign;
596 CResizePos* rpos = &(*RPosBuf)[ 0 ];
602#define AVIR_RESIZE_PART1 \
603 while( DstLineLen > 0 ) \
605 const fptypesimd x = (fptypesimd) rpos -> x; \
606 const fptype* ftp = rpos -> ftp; \
607 const fptype* ftp2 = rpos -> ftp + IntFltLen; \
608 const fptype* Src = SrcLine + rpos -> SrcOffs;
610#define AVIR_RESIZE_PART1nx \
611 while( DstLineLen > 0 ) \
613 const fptype* ftp = rpos -> ftp; \
614 const fptype* Src = SrcLine + rpos -> SrcOffs;
616#define AVIR_RESIZE_PART2 \
617 DstLine += DstLineIncr; \
624 const fptype b = ElBiases[ 0 ];
626 if(
FltBank -> getOrder() == 1 )
630 fptypesimd sum = ( fptypesimd :: load( ftp ) +
631 fptypesimd :: load( ftp2 ) * x ) *
632 fptypesimd :: loadu( Src );
634 for( i = elalign; i < IntFltLen; i += elalign )
636 sum += ( fptypesimd :: load( ftp + i ) +
637 fptypesimd :: load( ftp2 + i ) * x ) *
638 fptypesimd :: loadu( Src + i );
641 DstLine[ 0 ] = sum.hadd() + b;
649 fptypesimd sum = fptypesimd :: load( ftp ) *
650 fptypesimd :: loadu( Src );
652 for( i = elalign; i < IntFltLen; i += elalign )
654 sum += fptypesimd :: load( ftp + i ) *
655 fptypesimd :: loadu( Src + i );
658 DstLine[ 0 ] = sum.hadd() + b;
664 if( DstLineIncr == 1 )
669 const int DstLineElIncr =
OutElIncr - DstLineIncr * DstLineLen;
671 if(
FltBank -> getOrder() == 1 )
673 for( j = 0; j < ElCount; j++ )
675 const fptype b = ElBiases[ j ];
679 fptypesimd sum = 0.0;
681 for( i = 0; i < IntFltLen; i += elalign )
683 sum += ( fptypesimd :: load( ftp + i ) +
684 fptypesimd :: load( ftp2 + i ) * x ) *
685 fptypesimd :: loadu( Src + i );
688 DstLine[ 0 ] = sum.hadd() + b;
692 DstLine += DstLineElIncr;
695 rpos = &(*RPosBuf)[ 0 ];
700 for( j = 0; j < ElCount; j++ )
702 const fptype b = ElBiases[ j ];
706 fptypesimd sum = fptypesimd :: load( ftp ) *
707 fptypesimd :: loadu( Src );
709 for( i = elalign; i < IntFltLen; i += elalign )
711 sum += fptypesimd :: load( ftp + i ) *
712 fptypesimd :: loadu( Src + i );
715 DstLine[ 0 ] = sum.hadd() + b;
719 DstLine += DstLineElIncr;
722 rpos = &(*RPosBuf)[ 0 ];
730 DstLineIncr -= DstLineElIncr * ElCount;
732 if(
FltBank -> getOrder() == 1 )
736 for( i = 0; i < IntFltLen; i += elalign )
738 ( fptypesimd :: load( ftp + i ) +
739 fptypesimd :: load( ftp2 + i ) * x ).store( xx + i );
742 for( j = 0; j < ElCount; j++ )
744 fptypesimd sum = fptypesimd :: load( xx ) *
745 fptypesimd :: loadu( Src );
747 for( i = elalign; i < IntFltLen; i += elalign )
749 sum += fptypesimd :: load( xx + i ) *
750 fptypesimd :: loadu( Src + i );
753 DstLine[ 0 ] = sum.hadd() + ElBiases[ j ];
754 DstLine += DstLineElIncr;
764 for( j = 0; j < ElCount; j++ )
766 fptypesimd sum = fptypesimd :: load( ftp ) *
767 fptypesimd :: loadu( Src );
769 for( i = elalign; i < IntFltLen; i += elalign )
771 sum += fptypesimd :: load( ftp + i ) *
772 fptypesimd :: loadu( Src + i );
775 DstLine[ 0 ] = sum.hadd() + ElBiases[ j ];
776 DstLine += DstLineElIncr;
784#undef AVIR_RESIZE_PART2
785#undef AVIR_RESIZE_PART1nx
786#undef AVIR_RESIZE_PART1
795 int DstLineIncr,
const fptype*
const ElBiases,
796 fptype*
const xx )
const
798 doResize( SrcLine, DstLine, DstLineIncr, ElBiases, xx );
816template<
class fptype,
class fptypesimd >
831 const double aTrMul,
const double aPkOut )
856 void dither( fptype*
const ResScanline )
const
858 const int elalign =
Vars -> elalign;
859 const fptypesimd c0 = 0.0;
860 const fptypesimd PkOut = (fptypesimd)
PkOut0;
867 for( j = 0; j <
LenE - elalign; j += elalign )
869 const fptypesimd z0 =
round(
870 fptypesimd :: loadu( ResScanline + j ));
872 clamp( z0, c0, PkOut ).storeu( ResScanline + j );
875 const int lim =
LenE - j;
876 const fptypesimd z0 =
round(
877 fptypesimd :: loadu( ResScanline + j, lim ));
879 clamp( z0, c0, PkOut ).storeu( ResScanline + j, lim );
883 const fptypesimd TrMul = (fptypesimd)
TrMul0;
885 for( j = 0; j <
LenE - elalign; j += elalign )
887 const fptypesimd z0 =
round(
888 fptypesimd :: loadu( ResScanline + j ) / TrMul ) * TrMul;
890 clamp( z0, c0, PkOut ).storeu( ResScanline + j );
893 const int lim =
LenE - j;
894 const fptypesimd z0 =
round(
895 fptypesimd :: loadu( ResScanline + j, lim ) / TrMul ) * TrMul;
897 clamp( z0, c0, PkOut ).storeu( ResScanline + j, lim );
926template<
class fptype,
class fptypesimd >
941 const double aTrMul,
const double aPkOut )
953 for( i = 0; i <
LenE +
Vars -> ElCount; i++ )
959 static bool isRecursive()
964 void dither( fptype*
const ResScanline )
966 const int ea =
Vars -> elalign;
967 const fptypesimd c0 = 0.0;
968 const fptypesimd TrMul = (fptypesimd)
TrMul0;
969 const fptypesimd PkOut = (fptypesimd)
PkOut0;
972 for( j = 0; j <
LenE - ea; j += ea )
974 fptypesimd :: addu( ResScanline + j,
981 fptypesimd :: addu( ResScanline + j,
986 const int Len1 =
Len - 1;
987 fptype* rs = ResScanline;
991 for( i = 0; i <
Vars -> ElCount; i++ )
993 for( j = 0; j < Len1; j++ )
997 fptype*
const rsj = rs + j;
998 const fptype z0 =
round( rsj[ 0 ] / TrMul ) * TrMul;
999 const fptype Noise = rsj[ 0 ] - z0;
1000 rsj[ 0 ] =
clamp( z0, (fptype) 0.0, PkOut );
1002 fptype*
const rsdj = rsd + j;
1003 rsj[ 1 ] += Noise * (fptype) 0.364842;
1004 rsdj[ -1 ] += Noise * (fptype) 0.207305;
1005 rsdj[ 0 ] += Noise * (fptype) 0.364842;
1006 rsdj[ 1 ] += Noise * (fptype) 0.063011;
1011 const fptype z1 =
round( rs[ Len1 ] / TrMul ) * TrMul;
1012 const fptype Noise2 = rs[ Len1 ] - z1;
1013 rs[ Len1 ] =
clamp( z1, c0, PkOut );
1015 rsd[ Len1 - 1 ] += Noise2 * (fptype) 0.207305;
1016 rsd[ Len1 ] += Noise2 * (fptype) 0.364842;
1056template<
class afptype,
class afptypesimd,
1074 static const int elalign =
sizeof( afptypesimd ) /
sizeof( afptype );
T convertSRGB2Lin(const T s)
Definition avir.h:185
T clamp(const T &Value, const T minv, const T maxv)
Definition avir.h:121
T convertLin2SRGB(const T s)
Definition avir.h:205
void replicateArray(const T1 *const ip, const int ipl, T2 *op, int l, const int opinc)
Definition avir.h:281
T round(const T d)
Definition avir.h:104
Image resizing variables class.
Definition avir.h:2350
double OutGammaMult
Output gamma multiplier, used to convert data to 0 to 255/65535 range. 0.0 if no gamma is in use.
Definition avir.h:2392
int ElCount
The number of "fptype" elements used to store 1 pixel.
Definition avir.h:2352
int OutLen
Definition avir.h:2496
int ResampleFactor
Definition avir.h:2457
int InElIncr
Definition avir.h:2492
bool IsUpsample
Definition avir.h:2453
int OutPrefix
Definition avir.h:2500
CBuffer< fptype > SuffixDC
Definition avir.h:2516
int OutElIncr
Definition avir.h:2508
int EdgePixelCount
Definition avir.h:2520
int InPrefix
Definition avir.h:2480
int InLen
Definition avir.h:2476
CFltBuffer FltOrig
Definition avir.h:2462
int FltLatency
Definition avir.h:2472
CBuffer< fptype > Flt
Definition avir.h:2460
int OutSuffix
Definition avir.h:2504
const CImageResizerVars * Vars
Definition avir.h:2474
CRPosBuf * RPosBuf
Definition avir.h:2623
int InSuffix
Definition avir.h:2486
CBuffer< fptype > PrefixDC
Definition avir.h:2512
CDSPFracFilterBankLin< fptype > * FltBank
Definition avir.h:2626
De-interleaved filtering steps implementation class.
Definition avir_dil.h:31
void doFilter(const fptype *const Src, fptype *Dst, const int DstIncr) const
Definition avir_dil.h:474
void convertVtoH(const fptype *ip, fptype *op, const int SrcLen, const int SrcIncr) const
Definition avir_dil.h:148
void calcScanlineBias(const fptype *const p0, const int SrcLen, fptype *const ElBiases) const
Definition avir_dil.h:252
void unbiasScanline(fptype *const p0, const int l, const fptype *const ElBiases) const
Definition avir_dil.h:282
void packScanline(const Tin *const ip0, fptype *const op0, const int l) const
Definition avir_dil.h:64
void prepareInBuf(fptype *Src) const
Definition avir_dil.h:310
static void applySRGBGamma(fptype *const p0, const int l, const CImageResizerVars &Vars0)
Definition avir_dil.h:113
static void unpackScanline(const fptype *const ip0, Tout *const op0, const int l, const CImageResizerVars &Vars0)
Definition avir_dil.h:223
void doResize(const fptype *SrcLine, fptype *DstLine, int DstLineIncr, const fptype *const ElBiases, fptype *const xx) const
Definition avir_dil.h:588
void doResize2(const fptype *SrcLine, fptype *DstLine, int DstLineIncr, const fptype *const ElBiases, fptype *const xx) const
Definition avir_dil.h:794
void doUpsample(const fptype *Src, fptype *Dst) const
Definition avir_dil.h:336
Image resizer's default de-interleaved dithering class.
Definition avir_dil.h:818
void dither(fptype *const ResScanline) const
Definition avir_dil.h:856
double PkOut0
Peak output value allowed.
Definition avir_dil.h:910
int LenE
= LenE * ElCount.
Definition avir_dil.h:906
double TrMul0
Bit-depth truncation multiplier.
Definition avir_dil.h:908
const CImageResizerVars * Vars
Image resizing-related variables.
Definition avir_dil.h:904
static bool isRecursive()
Definition avir_dil.h:845
void init(const int aLen, const CImageResizerVars &aVars, const double aTrMul, const double aPkOut)
Definition avir_dil.h:830
int Len
Scanline's length in pixels.
Definition avir_dil.h:902
Image resizer's error-diffusion dithering class, de-interleaved mode.
Definition avir_dil.h:928
int LenE
= LenE * ElCount.
Definition avir_dil.h:1028
const CImageResizerVars * Vars
Image resizing-related variables.
Definition avir_dil.h:1026
void init(const int aLen, const CImageResizerVars &aVars, const double aTrMul, const double aPkOut)
Definition avir_dil.h:940
double PkOut0
Peak output value allowed.
Definition avir_dil.h:1032
fptype * ResScanlineDith
Error propagation buffer pointer which skips the first ElCount elements.
Definition avir_dil.h:1037
double TrMul0
Bit-depth truncation multiplier.
Definition avir_dil.h:1030
CBuffer< fptype > ResScanlineDith0
Error propagation buffer for dithering, first pixel unused.
Definition avir_dil.h:1034
int Len
Scanline's length in pixels.
Definition avir_dil.h:1024
Floating-point processing definition and abstraction class for de-interleaved processing.
Definition avir_dil.h:1059
static const int elalign
Definition avir_dil.h:1074
static const int packmode
Definition avir_dil.h:1080
afptype fptypeatom
Atomic type "fptype" consists of.
Definition avir_dil.h:1063
static const int fpalign
Definition avir_dil.h:1068
afptype fptype
Floating-point type to use during processing.
Definition avir_dil.h:1061
static const int fppack
Definition avir_dil.h:1065
adith CDitherer
Ditherer class to use during processing.
Definition avir_dil.h:1086
CImageResizerFilterStepDIL< fptype, afptypesimd > CFilterStep
Filtering step class to use during processing.
Definition avir_dil.h:1083