AVIR
High-quality pro image resizing library
 
Loading...
Searching...
No Matches
avir_dil.h
Go to the documentation of this file.
1//$ nobt
2//$ nocpp
3
14
15namespace avir {
16
27
28template< class fptype, class fptypesimd >
30 public CImageResizerFilterStep< fptype, fptype >
31{
32public:
33 using CImageResizerFilterStep< fptype, fptype > :: IsUpsample;
34 using CImageResizerFilterStep< fptype, fptype > :: ResampleFactor;
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;
51 using CImageResizerFilterStep< fptype, fptype > :: EdgePixelCount;
52
62
63 template< class Tin >
64 void packScanline( const Tin* const ip0, fptype* const op0,
65 const int l ) const
66 {
67 const int ElCount = Vars -> ElCount;
68 int j;
69
70 if( !Vars -> UseSRGBGamma )
71 {
72 for( j = 0; j < ElCount; j++ )
73 {
74 const Tin* ip = ip0 + j;
75 fptype* const op = op0 + j * InElIncr;
76 int i;
77
78 for( i = 0; i < l; i++ )
79 {
80 op[ i ] = (fptype) *ip;
81 ip += ElCount;
82 }
83 }
84 }
85 else
86 {
87 const fptype gm = (fptype) Vars -> InGammaMult;
88
89 for( j = 0; j < ElCount; j++ )
90 {
91 const Tin* ip = ip0 + j;
92 fptype* const op = op0 + j * InElIncr;
93 int i;
94
95 for( i = 0; i < l; i++ )
96 {
97 op[ i ] = convertSRGB2Lin( (fptype) *ip * gm );
98 ip += ElCount;
99 }
100 }
101 }
102 }
103
112
113 static void applySRGBGamma( fptype* const p0, const int l,
114 const CImageResizerVars& Vars0 )
115 {
116 const int ElCount = Vars0.ElCount;
117 const fptype gm = (fptype) Vars0.OutGammaMult;
118 int j;
119
120 for( j = 0; j < ElCount; j++ )
121 {
122 fptype* const p = p0 + j * l;
123 int i;
124
125 for( i = 0; i < l; i++ )
126 {
127 p[ i ] = convertLin2SRGB( p[ i ]) * gm;
128 }
129 }
130 }
131
147
148 void convertVtoH( const fptype* ip, fptype* op, const int SrcLen,
149 const int SrcIncr ) const
150 {
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;
156 const int ops1 = InElIncr;
157 const int ops2 = InElIncr * 2;
158 const int ops3 = InElIncr * 3;
159 int j;
160
161 if( ElCount == 1 )
162 {
163 for( j = 0; j < SrcLen; j++ )
164 {
165 op[ 0 ] = ip[ 0 ];
166 ip += SrcIncr;
167 op++;
168 }
169 }
170 else
171 if( ElCount == 4 )
172 {
173 for( j = 0; j < SrcLen; j++ )
174 {
175 op[ 0 ] = ip[ 0 ];
176 op[ ops1 ] = ip[ ips1 ];
177 op[ ops2 ] = ip[ ips2 ];
178 op[ ops3 ] = ip[ ips3 ];
179 ip += SrcIncr;
180 op++;
181 }
182 }
183 else
184 if( ElCount == 3 )
185 {
186 for( j = 0; j < SrcLen; j++ )
187 {
188 op[ 0 ] = ip[ 0 ];
189 op[ ops1 ] = ip[ ips1 ];
190 op[ ops2 ] = ip[ ips2 ];
191 ip += SrcIncr;
192 op++;
193 }
194 }
195 else
196 if( ElCount == 2 )
197 {
198 for( j = 0; j < SrcLen; j++ )
199 {
200 op[ 0 ] = ip[ 0 ];
201 op[ ops1 ] = ip[ ips1 ];
202 ip += SrcIncr;
203 op++;
204 }
205 }
206 }
207
221
222 template< class Tout >
223 static void unpackScanline( const fptype* const ip0, Tout* const op0,
224 const int l, const CImageResizerVars& Vars0 )
225 {
226 const int ElCount = Vars0.ElCount;
227 int j;
228
229 for( j = 0; j < ElCount; j++ )
230 {
231 const fptype* const ip = ip0 + j * l;
232 Tout* op = op0 + j;
233 int i;
234
235 for( i = 0; i < l; i++ )
236 {
237 *op = (Tout) ip[ i ];
238 op += ElCount;
239 }
240 }
241 }
242
251
252 void calcScanlineBias( const fptype* const p0, const int SrcLen,
253 fptype* const ElBiases ) const
254 {
255 const int ElCount = Vars -> ElCount;
256 int j;
257
258 for( j = 0; j < ElCount; j++ )
259 {
260 const fptype* const p = p0 + j * InElIncr;
261 fptype b = (fptype) 0;
262 int i;
263
264 for( i = 0; i < SrcLen; i++ )
265 {
266 b += p[ i ];
267 }
268
269 ElBiases[ j ] = b / (fptype) SrcLen;
270 }
271 }
272
281
282 void unbiasScanline( fptype* const p0, const int l,
283 const fptype* const ElBiases ) const
284 {
285 const int ElCount = Vars -> ElCount;
286 int j;
287
288 for( j = 0; j < ElCount; j++ )
289 {
290 fptype* const p = p0 + j * InElIncr;
291 const fptype b = ElBiases[ j ];
292 int i;
293
294 for( i = 0; i < l; i++ )
295 {
296 p[ i ] -= b;
297 }
298 }
299 }
300
309
310 void prepareInBuf( fptype* Src ) const
311 {
312 if( IsUpsample || InPrefix + InSuffix == 0 )
313 {
314 return;
315 }
316
317 int j;
318
319 for( j = 0; j < Vars -> ElCount; j++ )
320 {
321 replicateArray( Src, 1, Src - InPrefix, InPrefix, 1 );
322 fptype* const Src2 = Src + InLen - 1;
323 replicateArray( Src2, 1, Src2 + 1, InSuffix, 1 );
324 Src += InElIncr;
325 }
326 }
327
335
336 void doUpsample( const fptype* Src, fptype* Dst ) const
337 {
338 const int elalign = Vars -> elalign;
339 const int opstep = ResampleFactor;
340 const fptype* const f = Flt;
341 const int flen = Flt.getCapacity();
342 int l;
343 int i;
344 int j;
345
346 for( j = 0; j < Vars -> ElCount; j++ )
347 {
348 const fptype* ip = Src;
349 fptype* op0 = &Dst[ -OutPrefix ];
350 memset( op0, 0, ( OutPrefix + OutLen + OutSuffix ) *
351 sizeof( fptype ));
352
353 if( FltOrig.getCapacity() > 0 )
354 {
355 // Do not perform filtering, only upsample.
356
357 op0 += OutPrefix % ResampleFactor;
359
360 while( l > 0 )
361 {
362 op0[ 0 ] = ip[ 0 ];
363 op0 += opstep;
364 l--;
365 }
366
367 l = InLen - 1;
368
369 while( l > 0 )
370 {
371 op0[ 0 ] = ip[ 0 ];
372 op0 += opstep;
373 ip++;
374 l--;
375 }
376
378
379 while( l >= 0 )
380 {
381 op0[ 0 ] = ip[ 0 ];
382 op0 += opstep;
383 l--;
384 }
385
386 Src += InElIncr;
387 Dst += OutElIncr;
388 continue;
389 }
390
391 l = InPrefix;
392 fptypesimd ipv = (fptypesimd) ip[ 0 ];
393
394 while( l > 0 )
395 {
396 for( i = 0; i < flen; i += elalign )
397 {
398 fptypesimd :: addu( op0 + i,
399 fptypesimd :: load( f + i ) * ipv );
400 }
401
402 op0 += opstep;
403 l--;
404 }
405
406 l = InLen - 1;
407
408 while( l > 0 )
409 {
410 ipv = (fptypesimd) ip[ 0 ];
411
412 for( i = 0; i < flen; i += elalign )
413 {
414 fptypesimd :: addu( op0 + i,
415 fptypesimd :: load( f + i ) * ipv );
416 }
417
418 ip++;
419 op0 += opstep;
420 l--;
421 }
422
423 l = InSuffix;
424 ipv = (fptypesimd) ip[ 0 ];
425
426 while( l >= 0 )
427 {
428 for( i = 0; i < flen; i += elalign )
429 {
430 fptypesimd :: addu( op0 + i,
431 fptypesimd :: load( f + i ) * ipv );
432 }
433
434 op0 += opstep;
435 l--;
436 }
437
438 const fptype* dc = SuffixDC;
439 l = SuffixDC.getCapacity();
440
441 for( i = 0; i < l; i += elalign )
442 {
443 fptypesimd :: addu( op0 + i,
444 fptypesimd :: load( dc + i ) * ipv );
445 }
446
447 ipv = (fptypesimd) Src[ 0 ];
448 op0 = Dst - InPrefix * opstep;
449 dc = PrefixDC;
450 l = PrefixDC.getCapacity();
451
452 for( i = 0; i < l; i += elalign )
453 {
454 fptypesimd :: addu( op0 + i,
455 fptypesimd :: load( dc + i ) * ipv );
456 }
457
458 Src += InElIncr;
459 Dst += OutElIncr;
460 }
461 }
462
473
474 void doFilter( const fptype* const Src, fptype* Dst,
475 const int DstIncr ) const
476 {
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();
481 const int ipstep = ResampleFactor;
482 int i;
483 int j;
484
485 if( ElCount == 1 )
486 {
487 const fptype* ip = Src - EdgePixelCount * ipstep - FltLatency;
488 fptype* op = Dst;
489 int l = OutLen;
490
491 while( l > 0 )
492 {
493 fptypesimd s = fptypesimd :: load( f ) *
494 fptypesimd :: loadu( ip );
495
496 for( i = elalign; i < flen; i += elalign )
497 {
498 s += fptypesimd :: load( f + i ) *
499 fptypesimd :: loadu( ip + i );
500 }
501
502 op[ 0 ] = s.hadd();
503 op += DstIncr;
504 ip += ipstep;
505 l--;
506 }
507 }
508 else
509 if( DstIncr == 1 )
510 {
511 for( j = 0; j < ElCount; j++ )
512 {
513 const fptype* ip = Src - EdgePixelCount * ipstep -
514 FltLatency + j * InElIncr;
515
516 fptype* op = Dst + j * OutElIncr;
517 int l = OutLen;
518
519 while( l > 0 )
520 {
521 fptypesimd s = fptypesimd :: load( f ) *
522 fptypesimd :: loadu( ip );
523
524 for( i = elalign; i < flen; i += elalign )
525 {
526 s += fptypesimd :: load( f + i ) *
527 fptypesimd :: loadu( ip + i );
528 }
529
530 op[ 0 ] = s.hadd();
531 op += DstIncr;
532 ip += ipstep;
533 l--;
534 }
535 }
536 }
537 else
538 {
539 const fptype* ip0 = Src - EdgePixelCount * ipstep - FltLatency;
540 fptype* op0 = Dst;
541 int l = OutLen;
542
543 while( l > 0 )
544 {
545 const fptype* ip = ip0;
546 fptype* op = op0;
547
548 for( j = 0; j < ElCount; j++ )
549 {
550 fptypesimd s = fptypesimd :: load( f ) *
551 fptypesimd :: loadu( ip );
552
553 for( i = elalign; i < flen; i += elalign )
554 {
555 s += fptypesimd :: load( f + i ) *
556 fptypesimd :: loadu( ip + i );
557 }
558
559 op[ 0 ] = s.hadd();
560 ip += InElIncr;
561 op += OutElIncr;
562 }
563
564 ip0 += ipstep;
565 op0 += DstIncr;
566 l--;
567 }
568 }
569 }
570
587
588 void doResize( const fptype* SrcLine, fptype* DstLine,
589 int DstLineIncr, const fptype* const ElBiases,
590 fptype* const xx ) const
591 {
592 const int IntFltLen = FltBank -> getFilterLen();
593 const int ElCount = Vars -> ElCount;
594 const int elalign = Vars -> elalign;
596 CResizePos* rpos = &(*RPosBuf)[ 0 ];
597
598 int DstLineLen = OutLen;
599 int i;
600 int j;
601
602#define AVIR_RESIZE_PART1 \
603 while( DstLineLen > 0 ) \
604 { \
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;
609
610#define AVIR_RESIZE_PART1nx \
611 while( DstLineLen > 0 ) \
612 { \
613 const fptype* ftp = rpos -> ftp; \
614 const fptype* Src = SrcLine + rpos -> SrcOffs;
615
616#define AVIR_RESIZE_PART2 \
617 DstLine += DstLineIncr; \
618 rpos++; \
619 DstLineLen--; \
620 }
621
622 if( ElCount == 1 )
623 {
624 const fptype b = ElBiases[ 0 ];
625
626 if( FltBank -> getOrder() == 1 )
627 {
628 AVIR_RESIZE_PART1
629
630 fptypesimd sum = ( fptypesimd :: load( ftp ) +
631 fptypesimd :: load( ftp2 ) * x ) *
632 fptypesimd :: loadu( Src );
633
634 for( i = elalign; i < IntFltLen; i += elalign )
635 {
636 sum += ( fptypesimd :: load( ftp + i ) +
637 fptypesimd :: load( ftp2 + i ) * x ) *
638 fptypesimd :: loadu( Src + i );
639 }
640
641 DstLine[ 0 ] = sum.hadd() + b;
642
643 AVIR_RESIZE_PART2
644 }
645 else
646 {
647 AVIR_RESIZE_PART1nx
648
649 fptypesimd sum = fptypesimd :: load( ftp ) *
650 fptypesimd :: loadu( Src );
651
652 for( i = elalign; i < IntFltLen; i += elalign )
653 {
654 sum += fptypesimd :: load( ftp + i ) *
655 fptypesimd :: loadu( Src + i );
656 }
657
658 DstLine[ 0 ] = sum.hadd() + b;
659
660 AVIR_RESIZE_PART2
661 }
662 }
663 else
664 if( DstLineIncr == 1 )
665 {
666 // Horizontal-oriented processing, element loop is outer.
667
668 const int SrcIncr = InElIncr;
669 const int DstLineElIncr = OutElIncr - DstLineIncr * DstLineLen;
670
671 if( FltBank -> getOrder() == 1 )
672 {
673 for( j = 0; j < ElCount; j++ )
674 {
675 const fptype b = ElBiases[ j ];
676
677 AVIR_RESIZE_PART1
678
679 fptypesimd sum = 0.0;
680
681 for( i = 0; i < IntFltLen; i += elalign )
682 {
683 sum += ( fptypesimd :: load( ftp + i ) +
684 fptypesimd :: load( ftp2 + i ) * x ) *
685 fptypesimd :: loadu( Src + i );
686 }
687
688 DstLine[ 0 ] = sum.hadd() + b;
689
690 AVIR_RESIZE_PART2
691
692 DstLine += DstLineElIncr;
693 SrcLine += SrcIncr;
694 DstLineLen = OutLen;
695 rpos = &(*RPosBuf)[ 0 ];
696 }
697 }
698 else
699 {
700 for( j = 0; j < ElCount; j++ )
701 {
702 const fptype b = ElBiases[ j ];
703
704 AVIR_RESIZE_PART1nx
705
706 fptypesimd sum = fptypesimd :: load( ftp ) *
707 fptypesimd :: loadu( Src );
708
709 for( i = elalign; i < IntFltLen; i += elalign )
710 {
711 sum += fptypesimd :: load( ftp + i ) *
712 fptypesimd :: loadu( Src + i );
713 }
714
715 DstLine[ 0 ] = sum.hadd() + b;
716
717 AVIR_RESIZE_PART2
718
719 DstLine += DstLineElIncr;
720 SrcLine += SrcIncr;
721 DstLineLen = OutLen;
722 rpos = &(*RPosBuf)[ 0 ];
723 }
724 }
725 }
726 else
727 {
728 const int SrcIncr = InElIncr;
729 const int DstLineElIncr = OutElIncr;
730 DstLineIncr -= DstLineElIncr * ElCount;
731
732 if( FltBank -> getOrder() == 1 )
733 {
734 AVIR_RESIZE_PART1
735
736 for( i = 0; i < IntFltLen; i += elalign )
737 {
738 ( fptypesimd :: load( ftp + i ) +
739 fptypesimd :: load( ftp2 + i ) * x ).store( xx + i );
740 }
741
742 for( j = 0; j < ElCount; j++ )
743 {
744 fptypesimd sum = fptypesimd :: load( xx ) *
745 fptypesimd :: loadu( Src );
746
747 for( i = elalign; i < IntFltLen; i += elalign )
748 {
749 sum += fptypesimd :: load( xx + i ) *
750 fptypesimd :: loadu( Src + i );
751 }
752
753 DstLine[ 0 ] = sum.hadd() + ElBiases[ j ];
754 DstLine += DstLineElIncr;
755 Src += SrcIncr;
756 }
757
758 AVIR_RESIZE_PART2
759 }
760 else
761 {
762 AVIR_RESIZE_PART1nx
763
764 for( j = 0; j < ElCount; j++ )
765 {
766 fptypesimd sum = fptypesimd :: load( ftp ) *
767 fptypesimd :: loadu( Src );
768
769 for( i = elalign; i < IntFltLen; i += elalign )
770 {
771 sum += fptypesimd :: load( ftp + i ) *
772 fptypesimd :: loadu( Src + i );
773 }
774
775 DstLine[ 0 ] = sum.hadd() + ElBiases[ j ];
776 DstLine += DstLineElIncr;
777 Src += SrcIncr;
778 }
779
780 AVIR_RESIZE_PART2
781 }
782 }
783
784#undef AVIR_RESIZE_PART2
785#undef AVIR_RESIZE_PART1nx
786#undef AVIR_RESIZE_PART1
787 }
788
793
794 void doResize2( const fptype* SrcLine, fptype* DstLine,
795 int DstLineIncr, const fptype* const ElBiases,
796 fptype* const xx ) const
797 {
798 doResize( SrcLine, DstLine, DstLineIncr, ElBiases, xx );
799 }
800};
801
815
816template< class fptype, class fptypesimd >
818{
819public:
829
830 void init( const int aLen, const CImageResizerVars& aVars,
831 const double aTrMul, const double aPkOut )
832 {
833 Len = aLen;
834 Vars = &aVars;
835 LenE = aLen * Vars -> ElCount;
836 TrMul0 = aTrMul;
837 PkOut0 = aPkOut;
838 }
839
844
845 static bool isRecursive()
846 {
847 return( false );
848 }
849
855
856 void dither( fptype* const ResScanline ) const
857 {
858 const int elalign = Vars -> elalign;
859 const fptypesimd c0 = 0.0;
860 const fptypesimd PkOut = (fptypesimd) PkOut0;
861 int j;
862
863 if( TrMul0 == 1.0 )
864 {
865 // Optimization - do not perform bit truncation.
866
867 for( j = 0; j < LenE - elalign; j += elalign )
868 {
869 const fptypesimd z0 = round(
870 fptypesimd :: loadu( ResScanline + j ));
871
872 clamp( z0, c0, PkOut ).storeu( ResScanline + j );
873 }
874
875 const int lim = LenE - j;
876 const fptypesimd z0 = round(
877 fptypesimd :: loadu( ResScanline + j, lim ));
878
879 clamp( z0, c0, PkOut ).storeu( ResScanline + j, lim );
880 }
881 else
882 {
883 const fptypesimd TrMul = (fptypesimd) TrMul0;
884
885 for( j = 0; j < LenE - elalign; j += elalign )
886 {
887 const fptypesimd z0 = round(
888 fptypesimd :: loadu( ResScanline + j ) / TrMul ) * TrMul;
889
890 clamp( z0, c0, PkOut ).storeu( ResScanline + j );
891 }
892
893 const int lim = LenE - j;
894 const fptypesimd z0 = round(
895 fptypesimd :: loadu( ResScanline + j, lim ) / TrMul ) * TrMul;
896
897 clamp( z0, c0, PkOut ).storeu( ResScanline + j, lim );
898 }
899 }
900
901protected:
902 int Len;
906 int LenE;
908 double TrMul0;
910 double PkOut0;
912};
913
925
926template< class fptype, class fptypesimd >
928{
929public:
939
940 void init( const int aLen, const CImageResizerVars& aVars,
941 const double aTrMul, const double aPkOut )
942 {
943 Len = aLen;
944 Vars = &aVars;
945 LenE = aLen * Vars -> ElCount;
946 TrMul0 = aTrMul;
947 PkOut0 = aPkOut;
948
949 ResScanlineDith0.alloc( LenE + Vars -> ElCount, sizeof( fptype ));
951 int i;
952
953 for( i = 0; i < LenE + Vars -> ElCount; i++ )
954 {
955 ResScanlineDith0[ i ] = 0.0;
956 }
957 }
958
959 static bool isRecursive()
960 {
961 return( true );
962 }
963
964 void dither( fptype* const ResScanline )
965 {
966 const int ea = Vars -> elalign;
967 const fptypesimd c0 = 0.0;
968 const fptypesimd TrMul = (fptypesimd) TrMul0;
969 const fptypesimd PkOut = (fptypesimd) PkOut0;
970 int j;
971
972 for( j = 0; j < LenE - ea; j += ea )
973 {
974 fptypesimd :: addu( ResScanline + j,
975 fptypesimd :: loadu( ResScanlineDith + j ));
976
977 c0.storeu( ResScanlineDith + j );
978 }
979
980 int lim = LenE - j;
981 fptypesimd :: addu( ResScanline + j,
982 fptypesimd :: loadu( ResScanlineDith + j, lim ), lim );
983
984 c0.storeu( ResScanlineDith + j, lim );
985
986 const int Len1 = Len - 1;
987 fptype* rs = ResScanline;
988 fptype* rsd = ResScanlineDith;
989 int i;
990
991 for( i = 0; i < Vars -> ElCount; i++ )
992 {
993 for( j = 0; j < Len1; j++ )
994 {
995 // Perform rounding, noise estimation and saturation.
996
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 );
1001
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;
1007 }
1008
1009 // Process the last pixel element in scanline.
1010
1011 const fptype z1 = round( rs[ Len1 ] / TrMul ) * TrMul;
1012 const fptype Noise2 = rs[ Len1 ] - z1;
1013 rs[ Len1 ] = clamp( z1, c0, PkOut );
1014
1015 rsd[ Len1 - 1 ] += Noise2 * (fptype) 0.207305;
1016 rsd[ Len1 ] += Noise2 * (fptype) 0.364842;
1017
1018 rs += Len;
1019 rsd += Len;
1020 }
1021 }
1022
1023protected:
1024 int Len;
1028 int LenE;
1030 double TrMul0;
1032 double PkOut0;
1040};
1041
1055
1056template< class afptype, class afptypesimd,
1059{
1060public:
1061 typedef afptype fptype;
1063 typedef afptype fptypeatom;
1065 static const int fppack = 1;
1068 static const int fpalign = sizeof( afptypesimd );
1074 static const int elalign = sizeof( afptypesimd ) / sizeof( afptype );
1080 static const int packmode = 1;
1086 typedef adith CDitherer;
1088};
1089
1090} // namespace avir
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
CBuffer< fptype > SuffixDC
Definition avir.h:2516
CFltBuffer FltOrig
Definition avir.h:2462
CBuffer< fptype > Flt
Definition avir.h:2460
const CImageResizerVars * Vars
Definition avir.h:2474
CRPosBuf * RPosBuf
Definition avir.h:2623
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