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     double    version;
96     char     *model_name;
97     int       port_nb;
98     char     *ip_address;
99     char     *is;
100     int       tls;
101     char     *uuid;
102     char     *type;
103     SANE_Bool https;
104     struct curl_slist *hack;
105     char     *unix_socket;
106 } ESCL_Device;
107 
108 typedef struct capst
109 {
110     int height;
111     int width;
112     int pos_x;
113     int pos_y;
114     SANE_String default_color;
115     SANE_String default_format;
116     SANE_Int default_resolution;
117     int MinWidth;
118     int MaxWidth;
119     int MinHeight;
120     int MaxHeight;
121     int MaxScanRegions;
122     SANE_String_Const *ColorModes;
123     int ColorModesSize;
124     SANE_String_Const *ContentTypes;
125     int ContentTypesSize;
126     SANE_String_Const *DocumentFormats;
127     int DocumentFormatsSize;
128     int format_ext;
129     SANE_Int *SupportedResolutions;
130     int SupportedResolutionsSize;
131     SANE_String_Const *SupportedIntents;
132     int SupportedIntentsSize;
133     SANE_String_Const SupportedIntentDefault;
134     int MaxOpticalXResolution;
135     int RiskyLeftMargin;
136     int RiskyRightMargin;
137     int RiskyTopMargin;
138     int RiskyBottomMargin;
139     int duplex;
140     int have_jpeg;
141     int have_png;
142     int have_tiff;
143     int have_pdf;
144 } caps_t;
145 
146 typedef struct support
147 {
148     int min;
149     int max;
150     int normal;
151     int value;
152     int step;
153 } support_t;
154 
155 typedef struct capabilities
156 {
157     caps_t caps[3];
158     int source;
159     SANE_String_Const *Sources;
160     int SourcesSize;
161     FILE *tmp;
162     char *scanJob;
163     unsigned char *img_data;
164     long img_size;
165     long img_read;
166     size_t real_read;
167     SANE_Bool work;
168     support_t *brightness;
169     support_t *contrast;
170     support_t *sharpen;
171     support_t *threshold;
172     int use_brightness;
173     int val_brightness;
174     int use_contrast;
175     int val_contrast;
176     int use_sharpen;
177     int val_sharpen;
178     int use_threshold;
179     int val_threshold;
180 } capabilities_t;
181 
182 typedef struct {
183     int                             XRes;
184     int                             YRes;
185     int                             Left;
186     int                             Top;
187     int                             Right;
188     int                             Bottom;
189     int                             ScanMode;
190     int                             ScanMethod;
191     ESCL_SCANOPTS  opts;
192 } ESCL_ScanParam;
193 
194 
195 enum
196 {
197     OPT_NUM_OPTS = 0,
198     OPT_MODE_GROUP,
199     OPT_MODE,
200     OPT_RESOLUTION,
201     OPT_SCAN_SOURCE,
202 
203     OPT_GEOMETRY_GROUP,
204     OPT_TL_X,
205     OPT_TL_Y,
206     OPT_BR_X,
207     OPT_BR_Y,
208 
209     OPT_ENHANCEMENT_GROUP,
210     OPT_PREVIEW,
211     OPT_GRAY_PREVIEW,
212     OPT_BRIGHTNESS,
213     OPT_CONTRAST,
214     OPT_SHARPEN,
215     OPT_THRESHOLD,
216 
217     NUM_OPTIONS
218 };
219 
220 #define PIXEL_TO_MM(pixels, dpi) SANE_FIX((double)pixels * 25.4 / (dpi))
221 #define MM_TO_PIXEL(millimeters, dpi) (SANE_Word)round(SANE_UNFIX(millimeters) * (dpi) / 25.4)
222 
223 ESCL_Device *escl_devices(SANE_Status *status);
224 SANE_Status escl_device_add(int port_nb,
225                             const char *model_name,
226                             char *ip_address,
227                             const char *is,
228                             const char *uuid,
229                             char *type);
230 
231 SANE_Status escl_status(const ESCL_Device *device,
232                         int source,
233                         const char* jobId,
234                         SANE_Status *job);
235 
236 capabilities_t *escl_capabilities(ESCL_Device *device,
237                                   char *blacklist,
238                                   SANE_Status *status);
239 
240 char *escl_newjob(capabilities_t *scanner,
241                   const ESCL_Device *device,
242                   SANE_Status *status);
243 
244 SANE_Status escl_scan(capabilities_t *scanner,
245                       const ESCL_Device *device,
246                       char *scanJob,
247                       char *result);
248 
249 void escl_scanner(const ESCL_Device *device,
250                   char *scanJob,
251                   char *result);
252 
253 typedef void CURL;
254 
255 void escl_curl_url(CURL *handle,
256                    const ESCL_Device *device,
257                    SANE_String_Const path);
258 
259 unsigned char *escl_crop_surface(capabilities_t *scanner,
260                                  unsigned char *surface,
261                                  int w,
262                                  int h,
263                                  int bps,
264                                  int *width,
265                                  int *height);
266 
267 // JPEG
268 SANE_Status get_JPEG_data(capabilities_t *scanner,
269                           int *width,
270                           int *height,
271                           int *bps);
272 
273 // PNG
274 SANE_Status get_PNG_data(capabilities_t *scanner,
275                          int *width,
276                          int *height,
277                          int *bps);
278 
279 // TIFF
280 SANE_Status get_TIFF_data(capabilities_t *scanner,
281                           int *width,
282                           int *height,
283                           int *bps);
284 
285 // PDF
286 SANE_Status get_PDF_data(capabilities_t *scanner,
287                          int *width,
288                          int *height,
289                          int *bps);
290 
291 #endif
292