• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
4    Copyright (C) 2002-2007 Henning Geinitz <sane@geinitz.org>
5 
6    This file is part of the SANE package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 
21    As a special exception, the authors of SANE give permission for
22    additional uses of the libraries contained in this release of SANE.
23 
24    The exception is that, if you link a SANE library with other files
25    to produce an executable, this does not by itself cause the
26    resulting executable to be covered by the GNU General Public
27    License.  Your use of that executable is in no way restricted on
28    account of linking the SANE library code into it.
29 
30    This exception does not, however, invalidate any other reasons why
31    the executable file might be covered by the GNU General Public
32    License.
33 
34    If you submit changes to SANE to the maintainers to be included in
35    a subsequent release, you agree by submitting the changes that
36    those changes may be distributed with this exception intact.
37 
38    If you write modifications of your own for SANE, it is your choice
39    whether to permit this exception to apply to your modifications.
40    If you do not wish that, delete this exception notice.
41 */
42 
43 #ifndef GT68XX_HIGH_H
44 #define GT68XX_HIGH_H
45 
46 #include "gt68xx_mid.h"
47 
48 typedef struct GT68xx_Calibrator GT68xx_Calibrator;
49 typedef struct GT68xx_Calibration GT68xx_Calibration;
50 typedef struct GT68xx_Scanner GT68xx_Scanner;
51 
52 /** Calibration data for one channel.
53  */
54 struct GT68xx_Calibrator
55 {
56   unsigned int *k_white;	/**< White point vector */
57   unsigned int *k_black;	/**< Black point vector */
58 
59   double *white_line;		/**< White average */
60   double *black_line;		/**< Black average */
61 
62   SANE_Int width;		/**< Image width */
63   SANE_Int white_level;		/**< Desired white level */
64 
65   SANE_Int white_count;		/**< Number of white lines scanned */
66   SANE_Int black_count;		/**< Number of black lines scanned */
67 
68 #ifdef TUNE_CALIBRATOR
69   SANE_Int min_clip_count;	 /**< Count of too low values */
70   SANE_Int max_clip_count;	 /**< Count of too high values */
71 #endif				/* TUNE_CALIBRATOR */
72 };
73 
74 
75 /** Calibration data for a given resolution
76  */
77 struct GT68xx_Calibration
78 {
79   SANE_Int dpi;                 /**< optical horizontal dpi used to
80                                   build the calibration data */
81   SANE_Int pixel_x0;            /**< x start position used at calibration time */
82 
83   GT68xx_Calibrator *gray;	    /**< Calibrator for grayscale data */
84   GT68xx_Calibrator *red;	    /**< Calibrator for the red channel */
85   GT68xx_Calibrator *green;	    /**< Calibrator for the green channel */
86   GT68xx_Calibrator *blue;	    /**< Calibrator for the blue channel */
87 };
88 
89 /** Create a new calibrator for one (color or mono) channel.
90  *
91  * @param width       Image width in pixels.
92  * @param white_level Desired white level (65535 max).
93  * @param cal_return  Returned pointer to the created calibrator object.
94  *
95  * @return
96  * - SANE_STATUS_GOOD   - the calibrator object was created.
97  * - SANE_STATUS_INVAL  - invalid parameters.
98  * - SANE_STATUS_NO_MEM - not enough memory to create the object.
99  */
100 static SANE_Status
101 gt68xx_calibrator_new (SANE_Int width,
102 		       SANE_Int white_level, GT68xx_Calibrator ** cal_return);
103 
104 /** Destroy the channel calibrator object.
105  *
106  * @param cal Calibrator object.
107  */
108 static SANE_Status gt68xx_calibrator_free (GT68xx_Calibrator * cal);
109 
110 /** Add a white calibration line to the calibrator.
111  *
112  * This function should be called after scanning each white calibration line.
113  * The line width must be equal to the value passed to gt68xx_calibrator_new().
114  *
115  * @param cal  Calibrator object.
116  * @param line Pointer to the line data.
117  *
118  * @return
119  * - #SANE_STATUS_GOOD - the line data was processed successfully.
120  */
121 static SANE_Status
122 gt68xx_calibrator_add_white_line (GT68xx_Calibrator * cal,
123 				  unsigned int *line);
124 
125 /** Calculate the white point for the calibrator.
126  *
127  * This function should be called when all white calibration lines have been
128  * scanned.  After doing this, gt68xx_calibrator_add_white_line() should not be
129  * called again for this calibrator.
130  *
131  * @param cal    Calibrator object.
132  * @param factor White point correction factor.
133  *
134  * @return
135  * - #SANE_STATUS_GOOD - the white point was calculated successfully.
136  */
137 static SANE_Status
138 gt68xx_calibrator_eval_white (GT68xx_Calibrator * cal, double factor);
139 
140 /** Add a black calibration line to the calibrator.
141  *
142  * This function should be called after scanning each black calibration line.
143  * The line width must be equal to the value passed to gt68xx_calibrator_new().
144  *
145  * @param cal  Calibrator object.
146  * @param line Pointer to the line data.
147  *
148  * @return
149  * - #SANE_STATUS_GOOD - the line data was processed successfully.
150  */
151 static SANE_Status
152 gt68xx_calibrator_add_black_line (GT68xx_Calibrator * cal,
153 				  unsigned int *line);
154 
155 /** Calculate the black point for the calibrator.
156  *
157  * This function should be called when all black calibration lines have been
158  * scanned.  After doing this, gt68xx_calibrator_add_black_line() should not be
159  * called again for this calibrator.
160  *
161  * @param cal    Calibrator object.
162  * @param factor Black point correction factor.
163  *
164  * @return
165  * - #SANE_STATUS_GOOD - the white point was calculated successfully.
166  */
167 static SANE_Status
168 gt68xx_calibrator_eval_black (GT68xx_Calibrator * cal, double factor);
169 
170 /** Finish the calibrator setup and prepare for real scanning.
171  *
172  * This function must be called after gt68xx_calibrator_eval_white() and
173  * gt68xx_calibrator_eval_black().
174  *
175  * @param cal Calibrator object.
176  *
177  * @return
178  * - #SANE_STATUS_GOOD - the calibrator setup completed successfully.
179  */
180 static SANE_Status gt68xx_calibrator_finish_setup (GT68xx_Calibrator * cal);
181 
182 /** Process the image line through the calibrator.
183  *
184  * This function must be called only after gt68xx_calibrator_finish_setup().
185  * The image line is modified in place.
186  *
187  * @param cal  Calibrator object.
188  * @param line Pointer to the image line data.
189  *
190  * @return
191  * - #SANE_STATUS_GOOD - the image line was processed successfully.
192  */
193 static SANE_Status
194 gt68xx_calibrator_process_line (GT68xx_Calibrator * cal, unsigned int *line);
195 
196 /** List of SANE options
197  */
198 enum GT68xx_Option
199 {
200   OPT_NUM_OPTS = 0,
201 
202   OPT_MODE_GROUP,
203   OPT_MODE,
204   OPT_GRAY_MODE_COLOR,
205   OPT_SOURCE,
206   OPT_PREVIEW,
207   OPT_BIT_DEPTH,
208   OPT_RESOLUTION,
209   OPT_LAMP_OFF_AT_EXIT,
210   OPT_BACKTRACK,
211 
212   OPT_DEBUG_GROUP,
213   OPT_AUTO_WARMUP,
214   OPT_FULL_SCAN,
215   OPT_COARSE_CAL,
216   OPT_COARSE_CAL_ONCE,
217   OPT_QUALITY_CAL,
218   OPT_BACKTRACK_LINES,
219 
220   OPT_ENHANCEMENT_GROUP,
221   OPT_GAMMA_VALUE,
222   OPT_THRESHOLD,
223 
224   OPT_GEOMETRY_GROUP,
225   OPT_TL_X,			/* top-left x */
226   OPT_TL_Y,			/* top-left y */
227   OPT_BR_X,			/* bottom-right x */
228   OPT_BR_Y,			/* bottom-right y */
229 
230   OPT_SENSOR_GROUP,
231   OPT_NEED_CALIBRATION_SW,      /* signals calibration is needed */
232   OPT_PAGE_LOADED_SW,           /* signals that a document is inserted in feeder */
233 
234   OPT_BUTTON_GROUP,
235   OPT_CALIBRATE,                /* button option to trigger call
236                                    to sheetfed calibration */
237   OPT_CLEAR_CALIBRATION,        /* clear calibration */
238 
239   /* must come last: */
240   NUM_OPTIONS
241 };
242 
243 /** Scanner object.
244  */
245 struct GT68xx_Scanner
246 {
247   struct GT68xx_Scanner *next;	    /**< Next scanner in list */
248   GT68xx_Device *dev;		    /**< Low-level device object */
249 
250   GT68xx_Line_Reader *reader;	    /**< Line reader object */
251 
252   GT68xx_Calibrator *cal_gray;	    /**< Calibrator for grayscale data */
253   GT68xx_Calibrator *cal_r;	    /**< Calibrator for the red channel */
254   GT68xx_Calibrator *cal_g;	    /**< Calibrator for the green channel */
255   GT68xx_Calibrator *cal_b;	    /**< Calibrator for the blue channel */
256 
257   /* SANE data */
258   SANE_Bool scanning;			   /**< We are currently scanning */
259   SANE_Option_Descriptor opt[NUM_OPTIONS]; /**< Option descriptors */
260   Option_Value val[NUM_OPTIONS];	   /**< Option values */
261   SANE_Parameters params;		   /**< SANE Parameters */
262   SANE_Int line;			   /**< Current line */
263   SANE_Int total_bytes;			   /**< Bytes already transmitted */
264   SANE_Int byte_count;			   /**< Bytes transmitted in this line */
265   SANE_Bool calib;			   /**< Apply calibration data */
266   SANE_Bool auto_afe;			   /**< Use automatic gain/offset */
267   SANE_Bool first_scan;			   /**< Is this the first scan? */
268   struct timeval lamp_on_time;		   /**< Time when the lamp was turned on */
269   struct timeval start_time;		   /**< Time when the scan was started */
270   SANE_Int bpp_list[5];			   /**< */
271   SANE_Int *gamma_table;		   /**< Gray gamma table */
272 #ifdef DEBUG_BRIGHTNESS
273   SANE_Int average_white;	    /**< For debugging brightness problems */
274   SANE_Int max_white;
275   SANE_Int min_black;
276 #endif
277 
278   /** SANE_TRUE when the scanner has been calibrated */
279   SANE_Bool calibrated;
280 
281   /** per horizontal resolution calibration data */
282   GT68xx_Calibration calibrations[MAX_RESOLUTIONS];
283 
284   /* AFE and exposure settings */
285   GT68xx_AFE_Parameters afe_params;
286   GT68xx_Exposure_Parameters exposure_params;
287 };
288 
289 
290 /** Create a new scanner object.
291  *
292  * @param dev            Low-level device object.
293  * @param scanner_return Returned pointer to the created scanner object.
294  */
295 static SANE_Status
296 gt68xx_scanner_new (GT68xx_Device * dev, GT68xx_Scanner ** scanner_return);
297 
298 /** Destroy the scanner object.
299  *
300  * The low-level device object is not destroyed.
301  *
302  * @param scanner Scanner object.
303  */
304 static SANE_Status gt68xx_scanner_free (GT68xx_Scanner * scanner);
305 
306 /** Calibrate the scanner before the main scan.
307  *
308  * @param scanner Scanner object.
309  * @param request Scan request data.
310  * @param use_autogain Enable automatic offset/gain control
311  */
312 static SANE_Status
313 gt68xx_scanner_calibrate (GT68xx_Scanner * scanner,
314 			  GT68xx_Scan_Request * request);
315 
316 /** Start scanning the image.
317  *
318  * This function does not perform calibration - it needs to be performed before
319  * by calling gt68xx_scanner_calibrate().
320  *
321  * @param scanner Scanner object.
322  * @param request Scan request data.
323  * @param params  Returned scan parameters (calculated from the request).
324  */
325 static SANE_Status
326 gt68xx_scanner_start_scan (GT68xx_Scanner * scanner,
327 			   GT68xx_Scan_Request * request,
328 			   GT68xx_Scan_Parameters * params);
329 
330 /** Read one image line from the scanner.
331  *
332  * This function can be called only during the scan - after calling
333  * gt68xx_scanner_start_scan() and before calling gt68xx_scanner_stop_scan().
334  *
335  * @param scanner Scanner object.
336  * @param buffer_pointers Array of pointers to the image lines.
337  */
338 static SANE_Status
339 gt68xx_scanner_read_line (GT68xx_Scanner * scanner,
340 			  unsigned int **buffer_pointers);
341 
342 /** Stop scanning the image.
343  *
344  * This function must be called to finish the scan started by
345  * gt68xx_scanner_start_scan().  It may be called before all lines are read to
346  * cancel the scan prematurely.
347  *
348  * @param scanner Scanner object.
349  */
350 static SANE_Status gt68xx_scanner_stop_scan (GT68xx_Scanner * scanner);
351 
352 /** Save calibration data to file
353  *
354  * This function stores in memory calibration data created at calibration
355  * time into file
356  * @param scanner Scanner object.
357  * @return SANE_STATUS_GOOD when successful
358  */
359 static SANE_Status gt68xx_write_calibration (GT68xx_Scanner * scanner);
360 
361 /** Read calibration data from file
362  *
363  * This function sets in memory calibration data from data saved into file.
364  *
365  * @param scanner Scanner object.
366  * @return SANE_STATUS_GOOD when successful
367  */
368 static SANE_Status gt68xx_read_calibration (GT68xx_Scanner * scanner);
369 
370 #endif /* not GT68XX_HIGH_H */
371 
372 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
373