25
25
*/
26
26
27
27
#include "shared-bindings/displayio/Bitmap.h"
28
+ #include "shared-bindings/displayio/Palette.h"
29
+ #include "shared-bindings/displayio/ColorConverter.h"
28
30
#include "shared-bindings/bitmaptools/__init__.h"
29
31
30
32
#include <stdint.h>
31
33
32
34
#include "py/binary.h"
35
+ #include "py/enum.h"
33
36
#include "py/obj.h"
34
37
#include "py/runtime.h"
35
38
@@ -642,9 +645,92 @@ STATIC mp_obj_t bitmaptools_readinto(size_t n_args, const mp_obj_t *pos_args, mp
642
645
643
646
return mp_const_none ;
644
647
}
645
-
646
648
MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_readinto_obj , 0 , bitmaptools_readinto );
647
649
650
+ //| class DitherAlgorithm:
651
+ //| """Identifies the algorith for dither to use"""
652
+ //|
653
+ //| Atkinson: "DitherAlgorithm"
654
+ //| """The classic Atkinson dither, often associated with the Hypercard esthetic"""
655
+ //|
656
+ //| FloydStenberg: "DitherAlgorithm"
657
+ //| """The Floyd-Stenberg dither"""
658
+ //|
659
+ MAKE_ENUM_VALUE (bitmaptools_dither_algorithm_type , dither_algorithm , Atkinson , DITHER_ALGORITHM_ATKINSON );
660
+ MAKE_ENUM_VALUE (bitmaptools_dither_algorithm_type , dither_algorithm , FloydStenberg , DITHER_ALGORITHM_ATKINSON );
661
+
662
+ MAKE_ENUM_MAP (bitmaptools_dither_algorithm ) {
663
+ MAKE_ENUM_MAP_ENTRY (dither_algorithm , Atkinson ),
664
+ MAKE_ENUM_MAP_ENTRY (dither_algorithm , FloydStenberg ),
665
+ };
666
+ STATIC MP_DEFINE_CONST_DICT (bitmaptools_dither_algorithm_locals_dict , bitmaptools_dither_algorithm_locals_table );
667
+
668
+ MAKE_PRINTER (bitmaptools , bitmaptools_dither_algorithm );
669
+
670
+ MAKE_ENUM_TYPE (bitmaptools , DitherAlgorithm , bitmaptools_dither_algorithm );
671
+
672
+ //| def dither(dest_bitmap: displayio.Bitmap, source_bitmapp: displayio.Bitmap, source_colorspace: displayio.Colorspace, algorithm: DitherAlgorithm=DitherAlgorithm.Atkinson) -> None:
673
+ //| """Convert the input image into a 2-level output image using the given dither algorithm.
674
+ //|
675
+ //| :param bitmap dest_bitmap: Destination bitmap. It must have a value_count of 2 or 65536. The stored values are 0 and the maximum pixel value.
676
+ //| :param bitmap source_bitmap: Source bitmap that contains the graphical region to be dithered. It must have a value_count of 65536.
677
+ //| :param colorspace: The colorspace of the image. The supported colorspaces are ``RGB565``, ``BGR565``, ``RGB565_SWAPPED``, and ``BGR565_SWAPPED``
678
+ //| :param algorithm: The dither algorithm to use, one of the `DitherAlgorithm` values.
679
+ //| """
680
+ //| ...
681
+ //|
682
+ STATIC mp_obj_t bitmaptools_dither (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
683
+ enum { ARG_dest_bitmap , ARG_source_bitmap , ARG_source_colorspace , ARG_algorithm };
684
+ static const mp_arg_t allowed_args [] = {
685
+ { MP_QSTR_dest_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ },
686
+ { MP_QSTR_source_bitmap , MP_ARG_REQUIRED | MP_ARG_OBJ },
687
+ { MP_QSTR_source_colorspace , MP_ARG_REQUIRED | MP_ARG_OBJ },
688
+ { MP_QSTR_algorithm , MP_ARG_OBJ , { .u_obj = MP_ROM_PTR ((void * )& dither_algorithm_Atkinson_obj ) } },
689
+ };
690
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
691
+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
692
+ displayio_bitmap_t * source_bitmap = mp_arg_validate_type (args [ARG_source_bitmap ].u_obj , & displayio_bitmap_type , MP_QSTR_source_bitmap );
693
+ displayio_bitmap_t * dest_bitmap = mp_arg_validate_type (args [ARG_dest_bitmap ].u_obj , & displayio_bitmap_type , MP_QSTR_dest_bitmap );
694
+ bitmaptools_dither_algorithm_t algorithm = cp_enum_value (& bitmaptools_dither_algorithm_type , args [ARG_algorithm ].u_obj );
695
+ displayio_colorspace_t colorspace = cp_enum_value (& displayio_colorspace_type , args [ARG_source_colorspace ].u_obj );
696
+
697
+ if (source_bitmap -> width != dest_bitmap -> width || source_bitmap -> height != dest_bitmap -> height ) {
698
+ mp_raise_TypeError (translate ("bitmap sizes must match" ));
699
+ }
700
+
701
+ if (dest_bitmap -> bits_per_value != 16 && dest_bitmap -> bits_per_value != 1 ) {
702
+ mp_raise_TypeError (translate ("source_bitmap must have value_count of 2 or 65536" ));
703
+ }
704
+
705
+
706
+ switch (colorspace ) {
707
+ case DISPLAYIO_COLORSPACE_RGB565 :
708
+ case DISPLAYIO_COLORSPACE_RGB565_SWAPPED :
709
+ case DISPLAYIO_COLORSPACE_BGR565 :
710
+ case DISPLAYIO_COLORSPACE_BGR565_SWAPPED :
711
+ if (source_bitmap -> bits_per_value != 16 ) {
712
+ mp_raise_TypeError (translate ("source_bitmap must have value_count of 65536" ));
713
+ }
714
+ break ;
715
+
716
+ case DISPLAYIO_COLORSPACE_L8 :
717
+ if (source_bitmap -> bits_per_value != 8 ) {
718
+ mp_raise_TypeError (translate ("source_bitmap must have value_count of 8" ));
719
+ }
720
+ break ;
721
+
722
+ default :
723
+ mp_raise_TypeError (translate ("unsupported colorspace for dither" ));
724
+ }
725
+
726
+
727
+ common_hal_bitmaptools_dither (dest_bitmap , source_bitmap , colorspace , algorithm );
728
+
729
+ return mp_const_none ;
730
+ }
731
+ MP_DEFINE_CONST_FUN_OBJ_KW (bitmaptools_dither_obj , 0 , bitmaptools_dither );
732
+
733
+
648
734
STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table [] = {
649
735
{ MP_ROM_QSTR (MP_QSTR___name__ ), MP_ROM_QSTR (MP_QSTR_bitmaptools ) },
650
736
{ MP_ROM_QSTR (MP_QSTR_readinto ), MP_ROM_PTR (& bitmaptools_readinto_obj ) },
@@ -654,6 +740,8 @@ STATIC const mp_rom_map_elem_t bitmaptools_module_globals_table[] = {
654
740
{ MP_ROM_QSTR (MP_QSTR_fill_region ), MP_ROM_PTR (& bitmaptools_fill_region_obj ) },
655
741
{ MP_ROM_QSTR (MP_QSTR_boundary_fill ), MP_ROM_PTR (& bitmaptools_boundary_fill_obj ) },
656
742
{ MP_ROM_QSTR (MP_QSTR_draw_line ), MP_ROM_PTR (& bitmaptools_draw_line_obj ) },
743
+ { MP_ROM_QSTR (MP_QSTR_dither ), MP_ROM_PTR (& bitmaptools_dither_obj ) },
744
+ { MP_ROM_QSTR (MP_QSTR_DitherAlgorithm ), MP_ROM_PTR (& bitmaptools_dither_algorithm_type ) },
657
745
};
658
746
STATIC MP_DEFINE_CONST_DICT (bitmaptools_module_globals , bitmaptools_module_globals_table );
659
747
0 commit comments