@@ -56,6 +56,19 @@ STATIC mp_obj_t qrio_qrdecoder_make_new(const mp_obj_type_t *type, size_t n_args
5656 return self ;
5757}
5858
59+
60+ STATIC void verify_buffer_size (qrio_qrdecoder_obj_t * self , mp_obj_t * buffer , size_t len , qrio_pixel_policy_t policy ) {
61+ int width = shared_module_qrio_qrdecoder_get_width (self );
62+ int height = shared_module_qrio_qrdecoder_get_height (self );
63+
64+ // verify that the buffer is big enough
65+ int sz = width * height ;
66+ if (policy != QRIO_EVERY_BYTE ) {
67+ sz *= 2 ;
68+ }
69+ mp_get_index (mp_obj_get_type (* buffer ), len , MP_OBJ_NEW_SMALL_INT (sz - 1 ), false);
70+ }
71+
5972//| def decode(
6073//| self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE
6174//| ) -> List[QRInfo]:
@@ -73,22 +86,39 @@ STATIC mp_obj_t qrio_qrdecoder_decode(size_t n_args, const mp_obj_t *pos_args, m
7386
7487 mp_buffer_info_t bufinfo ;
7588 mp_get_buffer_raise (args [ARG_buffer ].u_obj , & bufinfo , MP_BUFFER_READ );
76-
77- int width = shared_module_qrio_qrdecoder_get_width (self );
78- int height = shared_module_qrio_qrdecoder_get_height (self );
79-
80- // verify that the buffer is big enough
81- int sz = width * height ;
8289 qrio_pixel_policy_t policy = cp_enum_value (& qrio_pixel_policy_type , args [ARG_pixel_policy ].u_obj , MP_QSTR_pixel_policy );
83- if (policy != QRIO_EVERY_BYTE ) {
84- sz *= 2 ;
85- }
86- mp_get_index (mp_obj_get_type (args [ARG_buffer ].u_obj ), bufinfo .len , MP_OBJ_NEW_SMALL_INT (sz - 1 ), false);
90+ verify_buffer_size (self , & args [ARG_buffer ].u_obj , bufinfo .len , policy );
8791
8892 return shared_module_qrio_qrdecoder_decode (self , & bufinfo , policy );
8993}
9094MP_DEFINE_CONST_FUN_OBJ_KW (qrio_qrdecoder_decode_obj , 1 , qrio_qrdecoder_decode );
9195
96+
97+ //| def find(
98+ //| self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE
99+ //| ) -> List[QRPosition]:
100+ //| """Find all visible QR codes from the given image. The size of the buffer must be at least ``length``×``width`` bytes for `EVERY_BYTE`, and 2×``length``×``width`` bytes for `EVEN_BYTES` or `ODD_BYTES`."""
101+ STATIC mp_obj_t qrio_qrdecoder_find (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
102+ qrio_qrdecoder_obj_t * self = MP_OBJ_TO_PTR (pos_args [0 ]);
103+
104+ enum { ARG_buffer , ARG_pixel_policy };
105+ static const mp_arg_t allowed_args [] = {
106+ { MP_QSTR_buffer , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_int = 0 } },
107+ { MP_QSTR_pixel_policy , MP_ARG_OBJ , {.u_obj = MP_ROM_PTR ((mp_obj_t * )& qrio_pixel_policy_EVERY_BYTE_obj )} },
108+ };
109+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
110+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
111+
112+ mp_buffer_info_t bufinfo ;
113+ mp_get_buffer_raise (args [ARG_buffer ].u_obj , & bufinfo , MP_BUFFER_READ );
114+ qrio_pixel_policy_t policy = cp_enum_value (& qrio_pixel_policy_type , args [ARG_pixel_policy ].u_obj , MP_QSTR_pixel_policy );
115+ verify_buffer_size (self , & args [ARG_buffer ].u_obj , bufinfo .len , policy );
116+
117+ return shared_module_qrio_qrdecoder_find (self , & bufinfo , policy );
118+ }
119+ MP_DEFINE_CONST_FUN_OBJ_KW (qrio_qrdecoder_find_obj , 1 , qrio_qrdecoder_find );
120+
121+
92122//| width: int
93123//| """The width of image the decoder expects"""
94124STATIC mp_obj_t qrio_qrdecoder_get_width (mp_obj_t self_in ) {
@@ -135,6 +165,7 @@ STATIC const mp_rom_map_elem_t qrio_qrdecoder_locals_table[] = {
135165 { MP_ROM_QSTR (MP_QSTR_width ), MP_ROM_PTR (& qrio_qrdecoder_width_obj ) },
136166 { MP_ROM_QSTR (MP_QSTR_height ), MP_ROM_PTR (& qrio_qrdecoder_height_obj ) },
137167 { MP_ROM_QSTR (MP_QSTR_decode ), MP_ROM_PTR (& qrio_qrdecoder_decode_obj ) },
168+ { MP_ROM_QSTR (MP_QSTR_find ), MP_ROM_PTR (& qrio_qrdecoder_find_obj ) },
138169};
139170
140171STATIC MP_DEFINE_CONST_DICT (qrio_qrdecoder_locals , qrio_qrdecoder_locals_table );
0 commit comments