8
8
#include " agg_image_accessors.h"
9
9
#include " agg_path_storage.h"
10
10
#include " agg_pixfmt_gray.h"
11
+ #include " agg_pixfmt_rgb.h"
11
12
#include " agg_pixfmt_rgba.h"
12
13
#include " agg_renderer_base.h"
13
14
#include " agg_renderer_scanline.h"
16
17
#include " agg_span_allocator.h"
17
18
#include " agg_span_converter.h"
18
19
#include " agg_span_image_filter_gray.h"
20
+ #include " agg_span_image_filter_rgb.h"
19
21
#include " agg_span_image_filter_rgba.h"
20
22
#include " agg_span_interpolator_adaptor.h"
21
23
#include " agg_span_interpolator_linear.h"
@@ -496,16 +498,38 @@ typedef enum {
496
498
} interpolation_e;
497
499
498
500
499
- // T is rgba if and only if it has an T::r field.
501
+ // T is rgb(a) if and only if it has an T::r field.
500
502
template <typename T, typename = void > struct is_grayscale : std::true_type {};
501
503
template <typename T> struct is_grayscale <T, std::void_t <decltype (T::r)>> : std::false_type {};
502
504
template <typename T> constexpr bool is_grayscale_v = is_grayscale<T>::value;
503
505
504
506
505
- template <typename color_type>
507
+ template <typename color_type, bool input_has_alpha >
506
508
struct type_mapping
507
509
{
508
- using blender_type = std::conditional_t <
510
+ using input_blender_type = std::conditional_t <
511
+ is_grayscale_v<color_type>,
512
+ agg::blender_gray<color_type>,
513
+ std::conditional_t <
514
+ input_has_alpha,
515
+ std::conditional_t <
516
+ std::is_same_v<color_type, agg::rgba8>,
517
+ fixed_blender_rgba_plain<color_type, agg::order_rgba>,
518
+ agg::blender_rgba_plain<color_type, agg::order_rgba>
519
+ >,
520
+ agg::blender_rgb<color_type, agg::order_rgb>
521
+ >
522
+ >;
523
+ using input_pixfmt_type = std::conditional_t <
524
+ is_grayscale_v<color_type>,
525
+ agg::pixfmt_alpha_blend_gray<input_blender_type, agg::rendering_buffer>,
526
+ std::conditional_t <
527
+ input_has_alpha,
528
+ agg::pixfmt_alpha_blend_rgba<input_blender_type, agg::rendering_buffer>,
529
+ agg::pixfmt_alpha_blend_rgb<input_blender_type, agg::rendering_buffer, 3 >
530
+ >
531
+ >;
532
+ using output_blender_type = std::conditional_t <
509
533
is_grayscale_v<color_type>,
510
534
agg::blender_gray<color_type>,
511
535
std::conditional_t <
@@ -514,25 +538,37 @@ struct type_mapping
514
538
agg::blender_rgba_plain<color_type, agg::order_rgba>
515
539
>
516
540
>;
517
- using pixfmt_type = std::conditional_t <
541
+ using output_pixfmt_type = std::conditional_t <
518
542
is_grayscale_v<color_type>,
519
- agg::pixfmt_alpha_blend_gray<blender_type , agg::rendering_buffer>,
520
- agg::pixfmt_alpha_blend_rgba<blender_type , agg::rendering_buffer>
543
+ agg::pixfmt_alpha_blend_gray<output_blender_type , agg::rendering_buffer>,
544
+ agg::pixfmt_alpha_blend_rgba<output_blender_type , agg::rendering_buffer>
521
545
>;
522
546
template <typename A> using span_gen_affine_type = std::conditional_t <
523
547
is_grayscale_v<color_type>,
524
548
agg::span_image_resample_gray_affine<A>,
525
- agg::span_image_resample_rgba_affine<A>
549
+ std::conditional_t <
550
+ input_has_alpha,
551
+ agg::span_image_resample_rgba_affine<A>,
552
+ agg::span_image_resample_rgb_affine<A>
553
+ >
526
554
>;
527
555
template <typename A, typename B> using span_gen_filter_type = std::conditional_t <
528
556
is_grayscale_v<color_type>,
529
557
agg::span_image_filter_gray<A, B>,
530
- agg::span_image_filter_rgba<A, B>
558
+ std::conditional_t <
559
+ input_has_alpha,
560
+ agg::span_image_filter_rgba<A, B>,
561
+ agg::span_image_filter_rgb<A, B>
562
+ >
531
563
>;
532
564
template <typename A, typename B> using span_gen_nn_type = std::conditional_t <
533
565
is_grayscale_v<color_type>,
534
566
agg::span_image_filter_gray_nn<A, B>,
535
- agg::span_image_filter_rgba_nn<A, B>
567
+ std::conditional_t <
568
+ input_has_alpha,
569
+ agg::span_image_filter_rgba_nn<A, B>,
570
+ agg::span_image_filter_rgb_nn<A, B>
571
+ >
536
572
>;
537
573
};
538
574
@@ -686,16 +722,16 @@ static void get_filter(const resample_params_t ¶ms,
686
722
}
687
723
688
724
689
- template <typename color_type>
725
+ template <typename color_type, bool input_has_alpha = true >
690
726
void resample (
691
- const void *input, int in_width, int in_height,
692
- void *output, int out_width, int out_height,
727
+ const void *input, int in_width, int in_height, int in_stride,
728
+ void *output, int out_width, int out_height, int out_stride,
693
729
resample_params_t ¶ms)
694
730
{
695
- using type_mapping_t = type_mapping<color_type>;
731
+ using type_mapping_t = type_mapping<color_type, input_has_alpha >;
696
732
697
- using input_pixfmt_t = typename type_mapping_t ::pixfmt_type ;
698
- using output_pixfmt_t = typename type_mapping_t ::pixfmt_type ;
733
+ using input_pixfmt_t = typename type_mapping_t ::input_pixfmt_type ;
734
+ using output_pixfmt_t = typename type_mapping_t ::output_pixfmt_type ;
699
735
700
736
using renderer_t = agg::renderer_base<output_pixfmt_t >;
701
737
using rasterizer_t = agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl>;
@@ -711,11 +747,6 @@ void resample(
711
747
using arbitrary_interpolator_t =
712
748
agg::span_interpolator_adaptor<agg::span_interpolator_linear<>, lookup_distortion>;
713
749
714
- size_t itemsize = sizeof (color_type);
715
- if (is_grayscale<color_type>::value) {
716
- itemsize /= 2 ; // agg::grayXX includes an alpha channel which we don't have.
717
- }
718
-
719
750
if (params.interpolation != NEAREST &&
720
751
params.is_affine &&
721
752
fabs (params.affine .sx ) == 1.0 &&
@@ -732,14 +763,12 @@ void resample(
732
763
span_conv_alpha_t conv_alpha (params.alpha );
733
764
734
765
agg::rendering_buffer input_buffer;
735
- input_buffer.attach (
736
- (unsigned char *)input, in_width, in_height, in_width * itemsize);
766
+ input_buffer.attach ((unsigned char *)input, in_width, in_height, in_stride);
737
767
input_pixfmt_t input_pixfmt (input_buffer);
738
768
image_accessor_t input_accessor (input_pixfmt);
739
769
740
770
agg::rendering_buffer output_buffer;
741
- output_buffer.attach (
742
- (unsigned char *)output, out_width, out_height, out_width * itemsize);
771
+ output_buffer.attach ((unsigned char *)output, out_width, out_height, out_stride);
743
772
output_pixfmt_t output_pixfmt (output_buffer);
744
773
renderer_t renderer (output_pixfmt);
745
774
0 commit comments