88#include " agg_image_accessors.h"
99#include " agg_path_storage.h"
1010#include " agg_pixfmt_gray.h"
11+ #include " agg_pixfmt_rgb.h"
1112#include " agg_pixfmt_rgba.h"
1213#include " agg_renderer_base.h"
1314#include " agg_renderer_scanline.h"
1617#include " agg_span_allocator.h"
1718#include " agg_span_converter.h"
1819#include " agg_span_image_filter_gray.h"
20+ #include " agg_span_image_filter_rgb.h"
1921#include " agg_span_image_filter_rgba.h"
2022#include " agg_span_interpolator_adaptor.h"
2123#include " agg_span_interpolator_linear.h"
@@ -496,16 +498,38 @@ typedef enum {
496498} interpolation_e;
497499
498500
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.
500502template <typename T, typename = void > struct is_grayscale : std::true_type {};
501503template <typename T> struct is_grayscale <T, std::void_t <decltype (T::r)>> : std::false_type {};
502504template <typename T> constexpr bool is_grayscale_v = is_grayscale<T>::value;
503505
504506
505- template <typename color_type>
507+ template <typename color_type, bool input_has_alpha >
506508struct type_mapping
507509{
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 <
509533 is_grayscale_v<color_type>,
510534 agg::blender_gray<color_type>,
511535 std::conditional_t <
@@ -514,25 +538,37 @@ struct type_mapping
514538 agg::blender_rgba_plain<color_type, agg::order_rgba>
515539 >
516540 >;
517- using pixfmt_type = std::conditional_t <
541+ using output_pixfmt_type = std::conditional_t <
518542 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>
521545 >;
522546 template <typename A> using span_gen_affine_type = std::conditional_t <
523547 is_grayscale_v<color_type>,
524548 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+ >
526554 >;
527555 template <typename A, typename B> using span_gen_filter_type = std::conditional_t <
528556 is_grayscale_v<color_type>,
529557 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+ >
531563 >;
532564 template <typename A, typename B> using span_gen_nn_type = std::conditional_t <
533565 is_grayscale_v<color_type>,
534566 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+ >
536572 >;
537573};
538574
@@ -686,16 +722,16 @@ static void get_filter(const resample_params_t ¶ms,
686722}
687723
688724
689- template <typename color_type>
725+ template <typename color_type, bool input_has_alpha = true >
690726void 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,
693729 resample_params_t ¶ms)
694730{
695- using type_mapping_t = type_mapping<color_type>;
731+ using type_mapping_t = type_mapping<color_type, input_has_alpha >;
696732
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 ;
699735
700736 using renderer_t = agg::renderer_base<output_pixfmt_t >;
701737 using rasterizer_t = agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl>;
@@ -711,11 +747,6 @@ void resample(
711747 using arbitrary_interpolator_t =
712748 agg::span_interpolator_adaptor<agg::span_interpolator_linear<>, lookup_distortion>;
713749
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-
719750 if (params.interpolation != NEAREST &&
720751 params.is_affine &&
721752 fabs (params.affine .sx ) == 1.0 &&
@@ -732,14 +763,12 @@ void resample(
732763 span_conv_alpha_t conv_alpha (params.alpha );
733764
734765 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);
737767 input_pixfmt_t input_pixfmt (input_buffer);
738768 image_accessor_t input_accessor (input_pixfmt);
739769
740770 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);
743772 output_pixfmt_t output_pixfmt (output_buffer);
744773 renderer_t renderer (output_pixfmt);
745774
0 commit comments