1use anyhow::Error;
2use image::{GenericImageView, GrayImage, Rgba};
3
4use crate::decode::{Decode, QRDecoder, QRDecoderWithInfo};
5use crate::detect::{Detect, LineScan, Location};
6use crate::extract::{Extract, QRExtractor};
7use crate::prepare::{BlockedMean, Prepare};
8
9use crate::util::qr::{QRData, QRError, QRInfo, QRLocation};
10
11pub struct Decoder<IMG, PREPD, RESULT> {
13 prepare: Box<dyn Prepare<IMG, PREPD>>,
14 detect: Box<dyn Detect<PREPD>>,
15 qr: ExtractDecode<PREPD, QRLocation, QRData, RESULT, QRError>,
16}
17
18impl<IMG, PREPD, RESULT> Decoder<IMG, PREPD, RESULT> {
19 pub fn decode(&self, source: &IMG) -> Vec<Result<RESULT, Error>> {
26 let prepared = self.prepare.prepare(source);
27 let locations = self.detect.detect(&prepared);
28
29 if locations.is_empty() {
30 return vec![];
31 }
32
33 let mut all_decoded = vec![];
34
35 for location in locations {
36 match location {
37 Location::QR(qrloc) => {
38 let extracted = self.qr.extract.extract(&prepared, qrloc);
39 let decoded = self.qr.decode.decode(extracted);
40
41 all_decoded.push(decoded.map_err(Error::from));
42 }
43 }
44 }
45
46 all_decoded
47 }
48}
49
50pub fn default_decoder<D>() -> Decoder<D, GrayImage, String> where D: GenericImageView<Pixel = Rgba<u8>> {
61 default_builder().build()
62}
63
64pub fn default_decoder_with_info<D>() -> Decoder<D, GrayImage, (String, QRInfo)> where D: GenericImageView<Pixel = Rgba<u8>> {
75 default_builder_with_info().build()
76}
77
78pub struct DecoderBuilder<IMG, PREPD, RESULT> {
87 prepare: Option<Box<dyn Prepare<IMG, PREPD>>>,
88 detect: Option<Box<dyn Detect<PREPD>>>,
89 qr: Option<ExtractDecode<PREPD, QRLocation, QRData, RESULT, QRError>>,
90}
91
92impl<IMG, PREPD, RESULT> DecoderBuilder<IMG, PREPD, RESULT> {
93 pub fn new() -> DecoderBuilder<IMG, PREPD, RESULT> {
95 DecoderBuilder {
96 prepare: None,
97 detect: None,
98 qr: None,
99 }
100 }
101
102 pub fn prepare(
104 &mut self,
105 prepare: Box<dyn Prepare<IMG, PREPD>>,
106 ) -> &mut DecoderBuilder<IMG, PREPD, RESULT> {
107 self.prepare = Some(prepare);
108 self
109 }
110
111 pub fn detect(
113 &mut self,
114 detect: Box<dyn Detect<PREPD>>,
115 ) -> &mut DecoderBuilder<IMG, PREPD, RESULT> {
116 self.detect = Some(detect);
117 self
118 }
119
120 pub fn qr(
122 &mut self,
123 extract: Box<dyn Extract<PREPD, QRLocation, QRData, QRError>>,
124 decode: Box<dyn Decode<QRData, RESULT, QRError>>,
125 ) -> &mut DecoderBuilder<IMG, PREPD, RESULT> {
126 self.qr = Some(ExtractDecode { extract, decode });
127 self
128 }
129
130 pub fn build(self) -> Decoder<IMG, PREPD, RESULT> {
136 if self.prepare.is_none() {
137 panic!("Cannot build Decoder without Prepare component");
138 }
139
140 if self.detect.is_none() {
141 panic!("Cannot build Decoder without Detect component");
142 }
143
144 Decoder {
145 prepare: self.prepare.unwrap(),
146 detect: self.detect.unwrap(),
147 qr: self.qr.unwrap(),
148 }
149 }
150}
151
152pub fn default_builder<D>() -> DecoderBuilder<D, GrayImage, String> where D: GenericImageView<Pixel = Rgba<u8>> {
163 let mut db = DecoderBuilder::new();
164
165 db.prepare(Box::new(BlockedMean::new(5, 7)));
166 db.detect(Box::new(LineScan::new()));
167 db.qr(Box::new(QRExtractor::new()), Box::new(QRDecoder::new()));
168
169 db
170}
171
172pub fn default_builder_with_info<D>() -> DecoderBuilder<D, GrayImage, (String, QRInfo)> where D: GenericImageView<Pixel = Rgba<u8>> {
183 let mut db = DecoderBuilder::new();
184
185 db.prepare(Box::new(BlockedMean::new(5, 7)));
186 db.detect(Box::new(LineScan::new()));
187 db.qr(
188 Box::new(QRExtractor::new()),
189 Box::new(QRDecoderWithInfo::new()),
190 );
191
192 db
193}
194
195struct ExtractDecode<PREPD, LOC, DATA, RESULT, ERROR> {
196 extract: Box<dyn Extract<PREPD, LOC, DATA, ERROR>>,
197 decode: Box<dyn Decode<DATA, RESULT, ERROR>>,
198}