2
2
// Anti-Grain Geometry - Version 2.4
3
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5
// Permission to copy, use, modify, sell and distribute this software
6
// is granted provided this copyright notice appears in all copies.
5
// Permission to copy, use, modify, sell and distribute this software
6
// is granted provided this copyright notice appears in all copies.
7
7
// This software is provided "as is" without express or implied
8
8
// warranty, and with no claim as to its suitability for any purpose.
13
13
// http://www.antigrain.com
14
14
//----------------------------------------------------------------------------
16
// Adaptation for high precision colors has been sponsored by
16
// Adaptation for high precision colors has been sponsored by
17
17
// Liberty Technology Systems, Inc., visit http://lib-sys.com
19
19
// Liberty Technology Systems, Inc. is the provider of
20
20
// PostScript and PDF technology for software developers.
22
22
//----------------------------------------------------------------------------
23
23
#ifndef AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
24
24
#define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
34
34
//===============================================span_image_filter_rgb_nn
35
template<class Source, class Interpolator>
36
class span_image_filter_rgb_nn :
35
template<class Source, class Interpolator>
36
class span_image_filter_rgb_nn :
37
37
public span_image_filter<Source, Interpolator>
53
53
//--------------------------------------------------------------------
54
54
span_image_filter_rgb_nn() {}
55
span_image_filter_rgb_nn(source_type& src,
55
span_image_filter_rgb_nn(source_type& src,
56
56
interpolator_type& inter) :
57
base_type(src, inter, 0)
57
base_type(src, inter, 0)
60
60
//--------------------------------------------------------------------
61
61
void generate(color_type* span, int x, int y, unsigned len)
63
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
63
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
64
64
y + base_type::filter_dy_dbl(), len);
67
67
base_type::interpolator().coordinates(&x, &y);
68
68
const value_type* fg_ptr = (const value_type*)
69
base_type::source().span(x >> image_subpixel_shift,
70
y >> image_subpixel_shift,
69
base_type::source().span(x >> image_subpixel_shift,
70
y >> image_subpixel_shift,
72
72
span->r = fg_ptr[order_type::R];
73
73
span->g = fg_ptr[order_type::G];
85
85
//==========================================span_image_filter_rgb_bilinear
86
template<class Source, class Interpolator>
87
class span_image_filter_rgb_bilinear :
86
template<class Source, class Interpolator>
87
class span_image_filter_rgb_bilinear :
88
88
public span_image_filter<Source, Interpolator>
104
104
//--------------------------------------------------------------------
105
105
span_image_filter_rgb_bilinear() {}
106
span_image_filter_rgb_bilinear(source_type& src,
106
span_image_filter_rgb_bilinear(source_type& src,
107
107
interpolator_type& inter) :
108
base_type(src, inter, 0)
108
base_type(src, inter, 0)
112
112
//--------------------------------------------------------------------
113
113
void generate(color_type* span, int x, int y, unsigned len)
115
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
115
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
116
116
y + base_type::filter_dy_dbl(), len);
118
118
const value_type *fg_ptr;
136
136
fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
138
138
x_hr &= image_subpixel_mask;
139
139
y_hr &= image_subpixel_mask;
141
141
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
142
weight = (image_subpixel_scale - x_hr) *
142
weight = (image_subpixel_scale - x_hr) *
143
143
(image_subpixel_scale - y_hr);
144
144
fg[0] += weight * *fg_ptr++;
145
145
fg[1] += weight * *fg_ptr++;
180
180
//=====================================span_image_filter_rgb_bilinear_clip
181
template<class Source, class Interpolator>
182
class span_image_filter_rgb_bilinear_clip :
181
template<class Source, class Interpolator>
182
class span_image_filter_rgb_bilinear_clip :
183
183
public span_image_filter<Source, Interpolator>
199
199
//--------------------------------------------------------------------
200
200
span_image_filter_rgb_bilinear_clip() {}
201
span_image_filter_rgb_bilinear_clip(source_type& src,
201
span_image_filter_rgb_bilinear_clip(source_type& src,
202
202
const color_type& back_color,
203
203
interpolator_type& inter) :
204
204
base_type(src, inter, 0),
210
210
//--------------------------------------------------------------------
211
211
void generate(color_type* span, int x, int y, unsigned len)
213
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
213
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
214
214
y + base_type::filter_dy_dbl(), len);
216
216
calc_type src_alpha;
241
241
if(x_lr >= 0 && y_lr >= 0 &&
242
x_lr < maxx && y_lr < maxy)
242
x_lr < maxx && y_lr < maxy)
246
246
fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
248
248
x_hr &= image_subpixel_mask;
251
251
fg_ptr = (const value_type*)
252
252
base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
254
weight = (image_subpixel_scale - x_hr) *
254
weight = (image_subpixel_scale - x_hr) *
255
255
(image_subpixel_scale - y_hr);
256
256
fg[0] += weight * *fg_ptr++;
257
257
fg[1] += weight * *fg_ptr++;
299
299
src_alpha = image_subpixel_scale * image_subpixel_scale / 2;
301
301
x_hr &= image_subpixel_mask;
302
302
y_hr &= image_subpixel_mask;
304
weight = (image_subpixel_scale - x_hr) *
304
weight = (image_subpixel_scale - x_hr) *
305
305
(image_subpixel_scale - y_hr);
306
306
if(x_lr >= 0 && y_lr >= 0 &&
307
307
x_lr <= maxx && y_lr <= maxy)
414
414
//===============================================span_image_filter_rgb_2x2
415
template<class Source, class Interpolator>
416
class span_image_filter_rgb_2x2 :
415
template<class Source, class Interpolator>
416
class span_image_filter_rgb_2x2 :
417
417
public span_image_filter<Source, Interpolator>
433
433
//--------------------------------------------------------------------
434
434
span_image_filter_rgb_2x2() {}
435
span_image_filter_rgb_2x2(source_type& src,
435
span_image_filter_rgb_2x2(source_type& src,
436
436
interpolator_type& inter,
437
437
const image_filter_lut& filter) :
438
base_type(src, inter, &filter)
438
base_type(src, inter, &filter)
442
442
//--------------------------------------------------------------------
443
443
void generate(color_type* span, int x, int y, unsigned len)
445
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
445
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
446
446
y + base_type::filter_dy_dbl(), len);
450
450
const value_type *fg_ptr;
451
const int16* weight_array = base_type::filter().weight_array() +
452
((base_type::filter().diameter()/2 - 1) <<
451
const int16* weight_array = base_type::filter().weight_array() +
452
((base_type::filter().diameter()/2 - 1) <<
453
453
image_subpixel_shift);
471
471
y_hr &= image_subpixel_mask;
473
473
fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
474
weight = (weight_array[x_hr + image_subpixel_scale] *
475
weight_array[y_hr + image_subpixel_scale] +
476
image_filter_scale / 2) >>
474
weight = (weight_array[x_hr + image_subpixel_scale] *
475
weight_array[y_hr + image_subpixel_scale] +
476
image_filter_scale / 2) >>
477
477
image_filter_shift;
478
478
fg[0] += weight * *fg_ptr++;
479
479
fg[1] += weight * *fg_ptr++;
480
480
fg[2] += weight * *fg_ptr;
482
482
fg_ptr = (const value_type*)base_type::source().next_x();
483
weight = (weight_array[x_hr] *
484
weight_array[y_hr + image_subpixel_scale] +
485
image_filter_scale / 2) >>
483
weight = (weight_array[x_hr] *
484
weight_array[y_hr + image_subpixel_scale] +
485
image_filter_scale / 2) >>
486
486
image_filter_shift;
487
487
fg[0] += weight * *fg_ptr++;
488
488
fg[1] += weight * *fg_ptr++;
489
489
fg[2] += weight * *fg_ptr;
491
491
fg_ptr = (const value_type*)base_type::source().next_y();
492
weight = (weight_array[x_hr + image_subpixel_scale] *
494
image_filter_scale / 2) >>
492
weight = (weight_array[x_hr + image_subpixel_scale] *
494
image_filter_scale / 2) >>
495
495
image_filter_shift;
496
496
fg[0] += weight * *fg_ptr++;
497
497
fg[1] += weight * *fg_ptr++;
498
498
fg[2] += weight * *fg_ptr;
500
500
fg_ptr = (const value_type*)base_type::source().next_x();
501
weight = (weight_array[x_hr] *
503
image_filter_scale / 2) >>
501
weight = (weight_array[x_hr] *
503
image_filter_scale / 2) >>
504
504
image_filter_shift;
505
505
fg[0] += weight * *fg_ptr++;
506
506
fg[1] += weight * *fg_ptr++;
531
531
//===================================================span_image_filter_rgb
532
template<class Source, class Interpolator>
533
class span_image_filter_rgb :
532
template<class Source, class Interpolator>
533
class span_image_filter_rgb :
534
534
public span_image_filter<Source, Interpolator>
550
550
//--------------------------------------------------------------------
551
551
span_image_filter_rgb() {}
552
span_image_filter_rgb(source_type& src,
552
span_image_filter_rgb(source_type& src,
553
553
interpolator_type& inter,
554
554
const image_filter_lut& filter) :
555
base_type(src, inter, &filter)
555
base_type(src, inter, &filter)
558
558
//--------------------------------------------------------------------
559
559
void generate(color_type* span, int x, int y, unsigned len)
561
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
561
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
562
562
y + base_type::filter_dy_dbl(), len);
590
590
unsigned y_count = diameter;
592
592
y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
593
fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
593
fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
600
600
x_hr = image_subpixel_mask - x_fract;
603
int weight = (weight_y * weight_array[x_hr] +
604
image_filter_scale / 2) >>
603
int weight = (weight_y * weight_array[x_hr] +
604
image_filter_scale / 2) >>
605
605
image_filter_shift;
607
607
fg[0] += weight * *fg_ptr++;
667
667
//--------------------------------------------------------------------
668
668
span_image_resample_rgb_affine() {}
669
span_image_resample_rgb_affine(source_type& src,
669
span_image_resample_rgb_affine(source_type& src,
670
670
interpolator_type& inter,
671
671
const image_filter_lut& filter) :
672
base_type(src, inter, filter)
672
base_type(src, inter, filter)
676
676
//--------------------------------------------------------------------
677
677
void generate(color_type* span, int x, int y, unsigned len)
679
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
679
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
680
680
y + base_type::filter_dy_dbl(), len);
685
685
int filter_scale = diameter << image_subpixel_shift;
686
686
int radius_x = (diameter * base_type::m_rx) >> 1;
687
687
int radius_y = (diameter * base_type::m_ry) >> 1;
689
(diameter * base_type::m_rx + image_subpixel_mask) >>
689
(diameter * base_type::m_rx + image_subpixel_mask) >>
690
690
image_subpixel_shift;
692
692
const int16* weight_array = base_type::filter().weight_array();
701
701
fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
703
703
int y_lr = y >> image_subpixel_shift;
704
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
705
base_type::m_ry_inv) >>
704
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
705
base_type::m_ry_inv) >>
706
706
image_subpixel_shift;
707
707
int total_weight = 0;
708
708
int x_lr = x >> image_subpixel_shift;
709
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
710
base_type::m_rx_inv) >>
709
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
710
base_type::m_rx_inv) >>
711
711
image_subpixel_shift;
713
713
int x_hr2 = x_hr;
714
const value_type* fg_ptr =
714
const value_type* fg_ptr =
715
715
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
722
int weight = (weight_y * weight_array[x_hr] +
723
image_filter_scale / 2) >>
722
int weight = (weight_y * weight_array[x_hr] +
723
image_filter_scale / 2) >>
726
726
fg[0] += *fg_ptr++ * weight;
764
764
//=================================================span_image_resample_rgb
765
765
template<class Source, class Interpolator>
766
class span_image_resample_rgb :
766
class span_image_resample_rgb :
767
767
public span_image_resample<Source, Interpolator>
784
784
//--------------------------------------------------------------------
785
785
span_image_resample_rgb() {}
786
span_image_resample_rgb(source_type& src,
786
span_image_resample_rgb(source_type& src,
787
787
interpolator_type& inter,
788
788
const image_filter_lut& filter) :
789
789
base_type(src, inter, filter)
792
792
//--------------------------------------------------------------------
793
793
void generate(color_type* span, int x, int y, unsigned len)
795
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
795
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
796
796
y + base_type::filter_dy_dbl(), len);
816
816
int radius_x = (diameter * rx) >> 1;
817
817
int radius_y = (diameter * ry) >> 1;
819
(diameter * rx + image_subpixel_mask) >>
819
(diameter * rx + image_subpixel_mask) >>
820
820
image_subpixel_shift;
822
822
x += base_type::filter_dx_int() - radius_x;
825
825
fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
827
827
int y_lr = y >> image_subpixel_shift;
828
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
828
int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
830
830
image_subpixel_shift;
831
831
int total_weight = 0;
832
832
int x_lr = x >> image_subpixel_shift;
833
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
833
int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
835
835
image_subpixel_shift;
836
836
int x_hr2 = x_hr;
837
const value_type* fg_ptr =
837
const value_type* fg_ptr =
838
838
(const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
846
int weight = (weight_y * weight_array[x_hr] +
847
image_filter_scale / 2) >>
846
int weight = (weight_y * weight_array[x_hr] +
847
image_filter_scale / 2) >>
849
849
fg[0] += *fg_ptr++ * weight;
850
850
fg[1] += *fg_ptr++ * weight;