1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2019 Touboul Nathane
4    Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com>
5 
6    This file is part of the SANE package.
7 
8    SANE is free software; you can redistribute it and/or modify it under
9    the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 3 of the License, or (at your
11    option) any later version.
12 
13    SANE is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16    for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with sane; see the file COPYING.
20    If not, see <https://www.gnu.org/licenses/>.
21 
22    This file implements a SANE backend for eSCL scanners.  */
23 
24 
25 #ifndef __ESCL_H__
26 #define __ESCL_H__
27 
28 #include "../include/sane/config.h"
29 
30 
31 #if !(HAVE_LIBCURL && defined(WITH_AVAHI) && defined(HAVE_LIBXML2))
32 #error "The escl backend requires libcurl, libavahi and libxml2"
33 #endif
34 
35 
36 
37 #ifndef HAVE_LIBJPEG
38 /* FIXME: Make JPEG support optional.
39    Support for PNG and PDF is to be added later but currently only
40    JPEG is supported.  Absence of JPEG support makes the backend a
41    no-op at present.
42  */
43 #error "The escl backend currently requires libjpeg"
44 #endif
45 
46 #include "../include/sane/sane.h"
47 
48 #include <stdio.h>
49 #include <math.h>
50 
51 #include <curl/curl.h>
52 
53 #ifndef BACKEND_NAME
54 #define BACKEND_NAME escl
55 #endif
56 
57 #define DEBUG_NOT_STATIC
58 #include "../include/sane/sanei_debug.h"
59 
60 #ifndef DBG_LEVEL
61 #define DBG_LEVEL       PASTE(sanei_debug_, BACKEND_NAME)
62 #endif
63 #ifndef NDEBUG
64 # define DBGDUMP(level, buf, size) \
65     do { if (DBG_LEVEL >= (level)) sanei_escl_dbgdump(buf, size); } while (0)
66 #else
67 # define DBGDUMP(level, buf, size)
68 #endif
69 
70 #define ESCL_CONFIG_FILE "escl.conf"
71 
72 
73 enum {
74    PLATEN = 0,
75    ADFSIMPLEX,
76    ADFDUPLEX
77 };
78 
79 
80 typedef struct {
81     int             p1_0;
82     int             p2_0;
83     int             p3_3;
84     int             DocumentType;
85     int             p4_0;
86     int             p5_0;
87     int             p6_1;
88     int             reserve[11];
89 } ESCL_SCANOPTS;
90 
91 
92 typedef struct ESCL_Device {
93     struct ESCL_Device *next;
94 
95     char     *model_name;
96     int       port_nb;
97     char     *ip_address;
98     char     *is;
99     char     *uuid;
100     char     *type;
101     SANE_Bool https;
102     struct curl_slist *hack;
103     char     *unix_socket;
104 } ESCL_Device;
105 
106 typedef struct capst
107 {
108     int height;
109     int width;
110     int pos_x;
111     int pos_y;
112     SANE_String default_color;
113     SANE_String default_format;
114     SANE_Int default_resolution;
115     int MinWidth;
116     int MaxWidth;
117     int MinHeight;
118     int MaxHeight;
119     int MaxScanRegions;
120     SANE_String_Const *ColorModes;
121     int ColorModesSize;
122     SANE_String_Const *ContentTypes;
123     int ContentTypesSize;
124     SANE_String_Const *DocumentFormats;
125     int DocumentFormatsSize;
126     int format_ext;
127     SANE_Int *SupportedResolutions;
128     int SupportedResolutionsSize;
129     SANE_String_Const *SupportedIntents;
130     int SupportedIntentsSize;
131     SANE_String_Const SupportedIntentDefault;
132     int MaxOpticalXResolution;
133     int RiskyLeftMargin;
134     int RiskyRightMargin;
135     int RiskyTopMargin;
136     int RiskyBottomMargin;
137     int duplex;
138     int have_jpeg;
139     int have_png;
140     int have_tiff;
141     int have_pdf;
142 } caps_t;
143 
144 typedef struct support
145 {
146     int min;
147     int max;
148     int normal;
149     int step;
150 } support_t;
151 
152 typedef struct capabilities
153 {
154     caps_t caps[3];
155     int source;
156     SANE_String_Const *Sources;
157     int SourcesSize;
158     FILE *tmp;
159     unsigned char *img_data;
160     long img_size;
161     long img_read;
162     size_t real_read;
163     SANE_Bool work;
164     support_t *brightness;
165     support_t *contrast;
166     support_t *sharpen;
167     support_t *threshold;
168     int use_brightness;
169     int val_brightness;
170     int use_contrast;
171     int val_contrast;
172     int use_sharpen;
173     int val_sharpen;
174     int use_threshold;
175     int val_threshold;
176 } capabilities_t;
177 
178 typedef struct {
179     int                             XRes;
180     int                             YRes;
181     int                             Left;
182     int                             Top;
183     int                             Right;
184     int                             Bottom;
185     int                             ScanMode;
186     int                             ScanMethod;
187     ESCL_SCANOPTS  opts;
188 } ESCL_ScanParam;
189 
190 
191 enum
192 {
193     OPT_NUM_OPTS = 0,
194     OPT_MODE_GROUP,
195     OPT_MODE,
196     OPT_RESOLUTION,
197     OPT_SCAN_SOURCE,
198 
199     OPT_GEOMETRY_GROUP,
200     OPT_TL_X,
201     OPT_TL_Y,
202     OPT_BR_X,
203     OPT_BR_Y,
204 
205     OPT_ENHANCEMENT_GROUP,
206     OPT_PREVIEW,
207     OPT_GRAY_PREVIEW,
208     OPT_BRIGHTNESS,
209     OPT_CONTRAST,
210     OPT_SHARPEN,
211     OPT_THRESHOLD,
212 
213     NUM_OPTIONS
214 };
215 
216 #define PIXEL_TO_MM(pixels, dpi) SANE_FIX((double)pixels * 25.4 / (dpi))
217 #define MM_TO_PIXEL(millimeters, dpi) (SANE_Word)round(SANE_UNFIX(millimeters) * (dpi) / 25.4)
218 
219 ESCL_Device *escl_devices(SANE_Status *status);
220 SANE_Status escl_device_add(int port_nb,
221                             const char *model_name,
222                             char *ip_address,
223                             const char *is,
224                             const char *uuid,
225                             char *type);
226 
227 SANE_Status escl_status(const ESCL_Device *device,
228                         int source,
229                         const char* jobId,
230                         SANE_Status *job);
231 
232 capabilities_t *escl_capabilities(ESCL_Device *device,
233                                   SANE_Status *status);
234 
235 char *escl_newjob(capabilities_t *scanner,
236                   const ESCL_Device *device,
237                   SANE_Status *status);
238 
239 SANE_Status escl_scan(capabilities_t *scanner,
240                       const ESCL_Device *device,
241                       char *result);
242 
243 void escl_scanner(const ESCL_Device *device,
244                   char *result);
245 
246 typedef void CURL;
247 
248 void escl_curl_url(CURL *handle,
249                    const ESCL_Device *device,
250                    SANE_String_Const path);
251 
252 unsigned char *escl_crop_surface(capabilities_t *scanner,
253                                  unsigned char *surface,
254                                  int w,
255                                  int h,
256                                  int bps,
257                                  int *width,
258                                  int *height);
259 
260 // JPEG
261 SANE_Status get_JPEG_data(capabilities_t *scanner,
262                           int *width,
263                           int *height,
264                           int *bps);
265 
266 // PNG
267 SANE_Status get_PNG_data(capabilities_t *scanner,
268                          int *width,
269                          int *height,
270                          int *bps);
271 
272 // TIFF
273 SANE_Status get_TIFF_data(capabilities_t *scanner,
274                           int *width,
275                           int *height,
276                           int *bps);
277 
278 // PDF
279 SANE_Status get_PDF_data(capabilities_t *scanner,
280                          int *width,
281                          int *height,
282                          int *bps);
283 
284 #endif
285