1 #################################################################################
2 # Xestia Scanner Server - Scan System Module #
5 # Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk> #
7 # This module is licensed under the same license as Xestia Scanner Server which #
8 # is licensed under the GPL version 3. #
10 # This program is free software: you can redistribute it and/or modify #
11 # it under the terms of the GNU General Public License as published by #
12 # the Free Software Foundation, version 3 of the License. #
14 # This program is distributed in the hope that it will be useful, #
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
17 # GNU General Public License for more details. #
19 # You should have received a copy of the GNU General Public License #
20 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
21 #################################################################################
23 package Modules::System::Scan;
25 use Modules::System::Common;
35 our @ISA = qw(Exporter);
36 our @EXPORT = qw(xestiascan_scan_preview xestiascan_scan_final xestiascan_scan_getpreviewimage xestiascan_scan_getoutputmodules xestiascan_scan_getexportmodules);
39 sub xestiascan_scan_getoutputmodules{
40 #################################################################################
41 # xestiascan_scan_getoutputmodules: Gets the list of available output modules. #
45 # @outputmodules = xestiascan_scan_getoutputmodules; #
46 #################################################################################
48 my (@outputmoduleslist, @outputmoduleslist_final);
51 opendir(OUTPUTMODULEDIR, "Modules/Output");
52 @outputmoduleslist = grep /m*\.pm$/, sort(readdir(OUTPUTMODULEDIR));
53 closedir(OUTPUTMODULEDIR);
55 foreach $outputmodulefile (@outputmoduleslist){
56 next if $outputmodulefile =~ m/^\./;
57 next if $outputmodulefile !~ m/.pm$/;
58 $outputmodulefile =~ s/.pm$//;
59 push(@outputmoduleslist_final, $outputmodulefile);
62 return @outputmoduleslist_final;
66 sub xestiascan_scan_getexportmodules{
67 #################################################################################
68 # xestiascan_scan_getexportmodules: Gets the list of available export modules. #
72 # @exportmodules = xestiascan_scan_getexportmodules; #
73 #################################################################################
75 my (@exportmoduleslist, @exportmoduleslist_final);
78 opendir(EXPORTMODULEDIR, "Modules/Export");
79 @exportmoduleslist = grep /m*\.pm$/, sort(readdir(EXPORTMODULEDIR));
80 closedir(EXPORTMODULEDIR);
82 foreach $exportmodulefile (@exportmoduleslist){
83 next if $exportmodulefile =~ m/^\./;
84 next if $exportmodulefile !~ m/.pm$/;
85 $exportmodulefile =~ s/.pm$//;
86 push(@exportmoduleslist_final, $exportmodulefile);
89 return @exportmoduleslist_final;
93 sub xestiascan_scan_preview{
94 #################################################################################
95 # xestiascan_scan_preview: Previews a scanning. #
99 # xestiascan_scan_preview(previewdocument, previewoptions); #
101 # previewdocument Specifies a preview of the document should be made. #
102 # previewoptions Specifies the options for the document preview. #
103 #################################################################################
105 # Get the values passed to this subroutine.
107 my $previewdocument = shift;
109 if (!$previewdocument){
111 $previewdocument = "off";
115 # Setup some variables for later.
117 my $scan_settings = 0;
119 my $picture_resolution = "75";
120 my $picture_brightness = "100";
121 my $picture_contrast = "100";
122 my $picture_topleftx = 0;
123 my $picture_toplefty = 0;
124 my $picture_bottomrightx = 0;
125 my $picture_bottomrighty = 0;
127 # Check if the preview document checkbox is selected and if it is then
128 # scan the image and preview it.
130 my $randomhex = int(0);
133 my $scannerpermission;
135 if ($previewdocument eq "on"){
137 (%previewoptions) = @_;
139 # Check the parameters passed to the subroutine.
143 xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
144 my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
145 xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
147 # Rotate. (Should be either 0, 90, 180, 270 degrees).
149 xestiascan_error("rotateblank") if !$previewoptions{Rotate};
150 if ($previewoptions{Rotate} eq "0deg" || $previewoptions{Rotate} eq "90deg" || $previewoptions{Rotate} eq "180deg" || $previewoptions{Rotate} eq "270deg"){
154 xestiascan_error("rotateinvalidoption");
160 xestiascan_error("colourblank") if !$previewoptions{Colour};
161 if ($previewoptions{Colour} eq "rgb" || $previewoptions{Colour} eq "grey" ){
165 xestiascan_error("colourinvalidoption");
171 xestiascan_error("resolutionblank") if !defined($previewoptions{Resolution});
172 my $resolution_numberscheck = xestiascan_variablecheck($previewoptions{Resolution}, "numbers", 0, 1);
173 xestiascan_error("resolutioninvalidnumber") if $resolution_numberscheck eq 1;
175 # Top Left X (Pointy figure);
177 xestiascan_error("topleftxblank") if !defined($previewoptions{TopLeftX});
178 my $topleftx_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftX}, "decimal", 0, 1);
179 xestiascan_error("topleftxinvalidnumber") if $topleftx_decimalcheck eq 1;
181 # Top Left Y (Pointy figure).
183 xestiascan_error("topleftyblank") if !defined($previewoptions{TopLeftY});
184 my $toplefty_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftY}, "decimal", 0, 1);
185 xestiascan_error("topleftyinvalidnumber") if $toplefty_decimalcheck eq 1;
187 # Bottom Right X (Pointy figure).
189 xestiascan_error("bottomrightx") if !defined($previewoptions{BottomRightX});
190 my $bottomrightx_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightX}, "decimal", 0, 1);
191 xestiascan_error("bottomrightxinvalidnumber") if $bottomrightx_decimalcheck eq 1;
193 # Bottom Right Y (Pointy figure).
195 xestiascan_error("bottomrighty") if !defined($previewoptions{BottomRightY});
196 my $bottomrighty_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightY}, "decimal", 0, 1);
197 xestiascan_error("bottomrightyinvalidnumber") if $bottomrighty_decimalcheck eq 1;
199 # Check to see if the user has permission to use the scanner.
201 $scannerpermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Scanner", PermissionName => $previewoptions{ScannerID} });
203 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
204 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
205 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
207 if ($scannerpermission eq 1){
209 # User has permission to use the scanner so start scanning.
211 # Generate a random hex value and use this to write a temporary file.
213 $randomhex = hex(int(rand(16777216)));
215 # Set variables for scanner and return an error if they were
218 $scan_device = Sane::Device->open($previewoptions{ScannerID});
219 xestiascan_error("scannererror", $Sane::STATUS) if $Sane::STATUS;
221 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_RESOLUTION, $previewoptions{Resolution});
222 xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedpictureresolution}, $Sane::STATUS)) if $Sane::STATUS;
224 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_X, $previewoptions{TopLeftX});
225 xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedtopleftx}, $Sane::STATUS)) if $Sane::STATUS;
227 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_Y, $previewoptions{TopLeftY});
228 xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedtoplefty}, $Sane::STATUS)) if $Sane::STATUS;
230 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_X, $previewoptions{BottomRightX});
231 xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedbottomrightx}, $Sane::STATUS)) if $Sane::STATUS;
233 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_Y, $previewoptions{BottomRightY});
234 xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedbottomrighty}, $Sane::STATUS)) if $Sane::STATUS;
236 # Get Sane to scan based on what has been passed (scanner name).
238 if ($Sane::STATUS == SANE_STATUS_GOOD){
242 # An error occured whilst trying to use the scanner
243 # so return an error.
245 xestiascan_error("scannererror", $Sane::STATUS);
249 my $param = $scan_device->get_parameters;
251 open ($fh, '>', "/tmp/xestiascanserver-" . $randomhex . ".pnm") or xestiascan_error("filepermissionerror", $!);
252 $scan_device->write_pnm_header($fh, $param->{format},
253 $param->{pixels_per_line},
254 $param->{lines}, $param->{depth});
257 ($data, $len) = $scan_device->read ($param->{bytes_per_line});
258 print $fh $data if $data;
259 } until ($Sane::STATUS == SANE_STATUS_EOF);
262 # Get the current scanner values.
264 $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
265 $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
266 $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
267 $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
268 $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
272 $picture_topleftx = int(0) if $picture_topleftx eq 0;
274 # Convert the PNM based image into PNG format.
276 my $im = new Image::Magick;
277 $im->Read("/tmp/xestiascanserver-" . $randomhex . ".pnm");
279 # Rotate the document if needed.
281 my $rotate = $previewoptions{Rotate};
283 my $numrotateseek = 0;
285 if ($previewoptions{Rotate} ne "0deg" ){
286 $numrotate = 1 if $rotate eq "90deg";
287 $numrotate = 2 if $rotate eq "180deg";
288 $numrotate = 3 if $rotate eq "270deg";
289 #$im->Rotate({ degrees => "180" }) if $rotate eq "180deg";
290 #$im->Rotate({ degrees => "270" }) if $rotate eq "270deg";
295 } until ($numrotateseek eq $numrotate || $numrotateseek > $numrotate);
299 # Change the colour type of the document if needed.
301 if ($previewoptions{Colour} eq "rgb"){
303 # Set the document to colour.
305 $im->Quantize(colorspace => 'RGB');
307 } elsif ($previewoptions{Colour} eq "grey"){
309 # Set the document to greyscale.
311 $im->Quantize(colorspace =>'gray');
315 # Adjust the brightness.
317 xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
319 my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
320 xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
322 $picture_brightness = $previewoptions{Brightness};
323 $im->Modulate(brightness=> $picture_brightness);
325 $im->Minify; # As it is a preview, Minify it.
327 $im->Write("/tmp/xestiascanserver-preview-" . $randomhex . ".png");
329 # Delete the PNM file.
331 unlink("/tmp/xestiascanserver-preview-" . $randomhex . ".pnm");
337 my $selectedscandevice;
341 (%previewoptions) = @_;
343 $selectedscandevice = $previewoptions{ScannerID};
347 $selectedscandevice = "" if !$selectedscandevice;
349 # Get the list of available scanners and process the list.
352 tie(%scanners, "Tie::IxHash");
353 %scanners = xestiascan_scan_getscannerlist();
355 # Print out the form.
357 $main::xestiascan_presmodule->startform("xsdss.cgi", "POST");
358 $main::xestiascan_presmodule->addhiddendata("mode", "scan");
359 $main::xestiascan_presmodule->addhiddendata("action", "scan");
360 $main::xestiascan_presmodule->startbox("scannermenu");
364 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noscanners});
365 $main::xestiascan_presmodule->endbox();
366 return $main::xestiascan_presmodule->grab();
370 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{scanner});
371 $main::xestiascan_presmodule->addselectbox("scanner");
375 my $notfirstscanner = 0;
377 foreach $scandevice (keys %scanners){
379 # Check if scanner matches the name of the selected
382 if ($scanners{$scandevice}{name} eq $selectedscandevice){
384 $main::xestiascan_presmodule->addoption($scanners{$scandevice}{vendor} . ": ". $scanners{$scandevice}{model}, {Value => $scanners{$scandevice}{name}, Selected => 1});
388 $main::xestiascan_presmodule->addoption($scanners{$scandevice}{vendor} . ": ". $scanners{$scandevice}{model}, {Value => $scanners{$scandevice}{name}});
392 if ($notfirstscanner ne 1){
394 $scannername = $scanners{$scandevice}{name};
395 $notfirstscanner = 1;
401 $main::xestiascan_presmodule->endselectbox();
403 # Check to see if the user has permission to use this scanner.
404 # Otherwise return an error message.
406 $scannerpermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Scanner", PermissionName => $scannername });
408 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
409 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
410 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
412 $scannerpermission = 0 if !$scannerpermission;
414 if ($scannerpermission eq 1){
416 # The user has permission to use this scanner.
418 if (!$previewoptions{ScannerID}){
420 $scan_device = Sane::Device->open($scannername);
422 xestiascan_error("scannererror", $Sane::STATUS) if $Sane::STATUS;
424 $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
425 $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
426 $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
427 $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
428 $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
432 $scan_device = Sane::Device->open($previewoptions{ScannerID}) if !$scan_device;
434 $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
435 $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
436 $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
437 $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
438 $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
442 $main::xestiascan_presmodule->addtext(" | ");
443 $main::xestiascan_presmodule->addbutton("switch", { Value => "switched", Description => $main::xestiascan_lang{scan}{switchscanner} });
445 $main::xestiascan_presmodule->addtext(" | ");
447 if ($previewdocument eq "on"){
448 $main::xestiascan_presmodule->addcheckbox("previewdocument", { OptionDescription => $main::xestiascan_lang{scan}{previewdocument}, Checked => 1 });
450 $main::xestiascan_presmodule->addcheckbox("previewdocument", { OptionDescription => $main::xestiascan_lang{scan}{previewdocument} });
453 $main::xestiascan_presmodule->addtext(" | ");
454 $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{scan}{startscanning});
455 $main::xestiascan_presmodule->endbox();
457 if ($previewdocument eq "on"){
459 $main::xestiascan_presmodule->startbox("sectionbox");
460 $main::xestiascan_presmodule->startbox("sectiontitle");
461 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{documentpreview});
462 $main::xestiascan_presmodule->endbox();
463 $main::xestiascan_presmodule->startbox("secondbox");
464 $main::xestiascan_presmodule->addimage("xsdss.cgi?mode=scan&action=getpreviewimage&pictureid=" . $randomhex);
465 $main::xestiascan_presmodule->endbox();
466 $main::xestiascan_presmodule->endbox();
470 $main::xestiascan_presmodule->startbox("sectionbox");
471 $main::xestiascan_presmodule->startbox("sectiontitle");
472 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{documentsettings});
473 $main::xestiascan_presmodule->endbox();
474 $main::xestiascan_presmodule->startbox("secondbox");
476 $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{scan}{picturedimensions});
477 $main::xestiascan_presmodule->addlinebreak();
478 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{topleftx});
479 $main::xestiascan_presmodule->addinputbox("topleftx", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_topleftx });
480 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
481 $main::xestiascan_presmodule->addlinebreak();
483 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{toplefty});
484 $main::xestiascan_presmodule->addinputbox("toplefty", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_toplefty });
485 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
486 $main::xestiascan_presmodule->addlinebreak();
488 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{bottomrightx});
489 $main::xestiascan_presmodule->addinputbox("bottomrightx", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_bottomrightx });
490 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
491 $main::xestiascan_presmodule->addlinebreak();
493 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{bottomrighty});
494 $main::xestiascan_presmodule->addinputbox("bottomrighty", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_bottomrighty });
495 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
496 $main::xestiascan_presmodule->addlinebreak();
498 $main::xestiascan_presmodule->addhorizontalline();
500 $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{scan}{picturesettings});
501 $main::xestiascan_presmodule->addlinebreak();
502 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{pictureresolution});
503 $main::xestiascan_presmodule->addinputbox("imagedpi", { MaxLength => "4", Size => "4", Value => $picture_resolution});
504 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{dpi});
505 $main::xestiascan_presmodule->addlinebreak();
506 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{rotate});
507 $main::xestiascan_presmodule->addselectbox("rotate");
509 if ($previewoptions{Rotate}){
511 # If the value matches with one of these in the list then
512 # set that as the selected value.
514 if ($previewoptions{Rotate} eq "0deg"){
516 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r0deg}, { Value => "0deg", Selected => 1 });
520 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r0deg}, { Value => "0deg" });
524 if ($previewoptions{Rotate} eq "90deg"){
526 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r90deg}, { Value => "90deg", Selected => 1 });
530 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r90deg}, { Value => "90deg" });
534 if ($previewoptions{Rotate} eq "180deg"){
536 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r180deg}, { Value => "180deg", Selected => 1 });
540 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r180deg}, { Value => "180deg" });
544 if ($previewoptions{Rotate} eq "270deg"){
546 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r270deg}, { Value => "270deg", Selected => 1 });
550 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r270deg}, { Value => "270deg" });
558 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r0deg}, { Value => "0deg", Selected => 1 });
559 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r90deg}, { Value => "90deg" });
560 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r180deg}, { Value => "180deg" });
561 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r270deg}, { Value => "270deg" });
565 $main::xestiascan_presmodule->endselectbox();
566 $main::xestiascan_presmodule->addlinebreak();
567 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{brightness});
568 $main::xestiascan_presmodule->addinputbox("brightness", { MaxLength => "3", Size => "3", Value => $picture_brightness });
569 $main::xestiascan_presmodule->addtext("%");
570 $main::xestiascan_presmodule->addlinebreak();
571 #$main::xestiascan_presmodule->addtext("Contrast: ");
572 #$main::xestiascan_presmodule->addinputbox("contrast", { MaxLength => "3", Size => "3", Value => $picture_contrast })#;
573 #$main::xestiascan_presmodule->addtext("%");
574 #$main::xestiascan_presmodule->addlinebreak();
575 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{colour});
576 $main::xestiascan_presmodule->addselectbox("colourtype");
578 if (!$previewoptions{Colour} || $previewoptions{Colour} eq "rgb"){
580 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{colourrgb}, { Value => "rgb", Selected => 1 });
584 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{colourrgb}, { Value => "rgb" });
588 if ($previewoptions{Colour} && $previewoptions{Colour} eq "grey"){
590 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{grey}, { Value => "grey", Selected => 1 });
594 $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{grey}, { Value => "grey" });
598 $main::xestiascan_presmodule->endselectbox();
601 $main::xestiascan_presmodule->addlinebreak();
603 $main::xestiascan_presmodule->endbox();
604 $main::xestiascan_presmodule->endbox();
606 $main::xestiascan_presmodule->endform();
610 # The user does not have permission to use this scanner.
612 $main::xestiascan_presmodule->addtext(" | ");
613 $main::xestiascan_presmodule->addbutton("switch", { Value => "switched", Description => $main::xestiascan_lang{scan}{switchscanner} });
614 $main::xestiascan_presmodule->endbox();
616 $main::xestiascan_presmodule->startbox("errorsectionbox");
617 $main::xestiascan_presmodule->startbox("errorboxheader");
618 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
619 $main::xestiascan_presmodule->endbox();
620 $main::xestiascan_presmodule->startbox("errorbox");
621 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{scannerpermissioninvalid});
622 $main::xestiascan_presmodule->endbox();
623 $main::xestiascan_presmodule->endbox();
627 return $main::xestiascan_presmodule->grab();
631 sub xestiascan_scan_final{
632 #################################################################################
633 # xestiascan_scan_final: Get the final image and present a list of available #
638 # xestiascan_scan_final(confirm, pageoptions); #
640 # confirm Specifies to confirm the processing of the page. #
641 # pageoptions Specifies the options for the page. #
642 #################################################################################
644 # Get the variables passed to the subroutine.
650 # The confirm value is not set so set it to 0.
656 my (%previewoptions) = @_;
658 # Check if the user has permission to use the scanner
659 # and return an error if this is not the case.
661 my $scannerpermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Scanner", PermissionName => $previewoptions{ScannerID} });
663 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
664 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
665 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
667 $scannerpermission = 0 if !$scannerpermission;
669 if ($scannerpermission ne 1 && !$previewoptions{OutputFormat}){
671 # The user does not have permission to use this scanner,
672 # so return an error message.
674 $main::xestiascan_presmodule->startbox("errorsectionbox");
675 $main::xestiascan_presmodule->startbox("errorboxheader");
676 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
677 $main::xestiascan_presmodule->endbox();
678 $main::xestiascan_presmodule->startbox("errorbox");
679 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{scannerpermissioninvalid});
680 $main::xestiascan_presmodule->endbox();
681 $main::xestiascan_presmodule->endbox();
683 return $main::xestiascan_presmodule->grab();
689 # The action to process the page has been confirmed so process the image.
691 # Convert the PNM image into the correct format.
693 my $outputmodule = $previewoptions{OutputFormat};
694 my $hexnumber = int($previewoptions{ImageHex});
696 # Check if the output module has a valid name.
698 my $outputmodulevalid = xestiascan_variablecheck($previewoptions{OutputFormat}, "module", 0, 1);
700 if ($outputmodulevalid eq 1){
702 # The output module is missing so write a message saying
703 # the name is invalid.
705 $main::xestiascan_presmodule->startbox("errorsectionbox");
706 $main::xestiascan_presmodule->startbox("errorboxheader");
707 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
708 $main::xestiascan_presmodule->endbox();
709 $main::xestiascan_presmodule->startbox("errorbox");
710 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvalidname});
711 $main::xestiascan_presmodule->endbox();
712 $main::xestiascan_presmodule->endbox();
714 return $main::xestiascan_presmodule->grab();
718 # Check if the module exists.
720 my $outputmoduleexists = xestiascan_fileexists("Modules/Output/" . $previewoptions{OutputFormat} . ".pm");
722 if ($outputmoduleexists eq 1){
724 # The output module is missing so write a message saying
727 $main::xestiascan_presmodule->startbox("errorsectionbox");
728 $main::xestiascan_presmodule->startbox("errorboxheader");
729 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
730 $main::xestiascan_presmodule->endbox();
731 $main::xestiascan_presmodule->startbox("errorbox");
732 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmodulemissing});
733 $main::xestiascan_presmodule->endbox();
734 $main::xestiascan_presmodule->endbox();
736 return $main::xestiascan_presmodule->grab();
740 # Check if the module has valid file permissions.
742 my $outputmodulefilepermission = xestiascan_filepermissions("Modules/Output/" . $previewoptions{OutputFormat} . ".pm", 1, 0, 0);
744 if ($outputmodulefilepermission eq 1){
746 # The output module has invalid file permissions so
749 $main::xestiascan_presmodule->startbox("errorsectionbox");
750 $main::xestiascan_presmodule->startbox("errorboxheader");
751 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
752 $main::xestiascan_presmodule->endbox();
753 $main::xestiascan_presmodule->startbox("errorbox");
754 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvalidfilepermissions});
755 $main::xestiascan_presmodule->endbox();
756 $main::xestiascan_presmodule->endbox();
758 return $main::xestiascan_presmodule->grab();
762 # Check to see if the user has permission to use the output module and return an error if not.
764 my $outputmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "OutputModule", PermissionName => $outputmodule });
766 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
767 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
768 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
770 $outputmodulepermission = 0 if !$outputmodulepermission;
772 if ($outputmodulepermission eq 0){
774 # The user does not have permission so write an error message
775 # saying the user does not have permission.
777 $main::xestiascan_presmodule->startbox("errorsectionbox");
778 $main::xestiascan_presmodule->startbox("errorboxheader");
779 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
780 $main::xestiascan_presmodule->endbox();
781 $main::xestiascan_presmodule->startbox("errorbox");
782 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvaliddbpermissions});
783 $main::xestiascan_presmodule->endbox();
784 $main::xestiascan_presmodule->endbox();
786 return $main::xestiascan_presmodule->grab();
790 my $outputmodulename = "Modules::Output::" . $outputmodule;
791 eval "use " . $outputmodulename;
792 my $xestiascan_outputmodule = $outputmodulename->new();
793 my ($outputmodule_options, %outputmodule_options);
794 tie(%outputmodule_options, "Tie::IxHash");
795 $xestiascan_outputmodule->initialise();
796 $xestiascan_outputmodule->loadsettings($main::xestiascan_config{"system_language"});
797 %outputmodule_options = $xestiascan_outputmodule->getoptions();
799 my $outputmodule_selected = 0;
800 my $outputmodule_readonly = 0;
801 my $combobox_count = 0;
802 my @outputmodule_comboboxnames;
803 my @outputmodule_comboboxvalues;
804 my $outputmodule_comboboxname;
805 my $outputmodule_comboboxvalue;
807 # Setup the original filename.
809 my $original_filename = "";
810 my $processed_filename = "";
812 # Get the output module settings.
814 my ($outputmodule_passedoptions, %outputmodule_passedoptions);
815 my %outputmodulesettings;
816 my %outputmodulesettings_final;
817 tie(%outputmodule_passedoptions, "Tie::IxHash");
819 my $hs = new Hash::Search;
820 my $cgilite = new CGI::Lite;
821 my %form_data = $cgilite->parse_form_data;
823 $hs->hash_search("^outputmodule_", %form_data);
824 %outputmodulesettings = $hs->hash_search_resultdata;
826 # Strip the outputmodule_ prefix.
828 my $outputmodule_settings_unprocessed;
829 my $outputmodule_settings_regex;
831 foreach $outputmodule_settings_unprocessed (keys %outputmodulesettings){
833 $outputmodule_settings_regex = "^outputmodule_";
834 $outputmodule_settings_unprocessed =~ s/^$outputmodule_settings_regex//;
836 $outputmodulesettings_final{$outputmodule_settings_unprocessed} = $outputmodulesettings{"outputmodule_" . $outputmodule_settings_unprocessed};
840 # Proceed with the output module processing.
842 $main::xestiascan_presmodule->startbox("sectionboxnofloat");
843 $main::xestiascan_presmodule->startbox("sectiontitle");
844 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleresults});
845 $main::xestiascan_presmodule->endbox();
846 $main::xestiascan_presmodule->startbox("secondbox");
848 $main::xestiascan_presmodule->startbox("outputmoduletitle");
849 $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{resultsuffix}, $outputmodule));
850 $main::xestiascan_presmodule->endbox();
852 $processed_filename = $xestiascan_outputmodule->processimage($hexnumber, %outputmodulesettings_final);
854 $main::xestiascan_presmodule->startbox("outputmoduleoptions");
856 if ($xestiascan_outputmodule->errorflag ne 0){
858 # An error occurred so stop processing and end the script.
860 $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{outputmodulefailed}, $xestiascan_outputmodule->errormessage));
861 $main::xestiascan_presmodule->addlinebreak();
862 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleunable});
863 $main::xestiascan_presmodule->endbox();
865 $main::xestiascan_presmodule->endbox();
866 $main::xestiascan_presmodule->endbox();
867 $main::xestiascan_presmodule->endbox();
869 return $main::xestiascan_presmodule->grab();
873 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmodulecomplete});
877 $main::xestiascan_presmodule->endbox();
879 $main::xestiascan_presmodule->endbox();
880 $main::xestiascan_presmodule->endbox();
882 # Process the selected export modules.
884 $main::xestiascan_presmodule->startbox("sectionboxnofloat");
885 $main::xestiascan_presmodule->startbox("sectiontitle");
886 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmoduleresults});
887 $main::xestiascan_presmodule->endbox();
888 $main::xestiascan_presmodule->startbox("secondbox");
890 # Check the list of selected export modules.
892 my (%selectedmodules, $selectedmodules);
894 my (%exportmodulesettings, $exportmodulesettings);
895 my (%exportmodulesettings_final);
897 $hs->hash_search("^module_", %form_data);
898 %selectedmodules = $hs->hash_search_resultdata;
900 my $exportmodule_count = 0;
901 my $exportmodule_name = "";
902 my $exportmodule_unprocessed = "";
904 my $exportmodule_settings_unprocessed = "";
905 my $exportmodule_settings_regex = "";
909 foreach $exportmodule_unprocessed (keys %selectedmodules){
911 # Skip if the module wasn't selected in the first place.
913 next if $selectedmodules{$exportmodule_unprocessed} ne "on";
915 # Add the module to the selected modules list.
917 $exportmodule_unprocessed =~ s/^module_//;
918 push(@activemodules, $exportmodule_unprocessed);
919 $exportmodule_count++;
923 @activemodules = sort(@activemodules);
925 # Process the export modules.
927 foreach $exportmodule_name (@activemodules){
929 # Write the beginning part of the box for the results of the module.
931 $main::xestiascan_presmodule->startbox("exportmoduletitle");
932 $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{resultsuffix}, $exportmodule_name));
933 $main::xestiascan_presmodule->endbox();
934 $main::xestiascan_presmodule->startbox("exportmoduleoptions");
936 # Check to see if the export module exists and process the next
937 # one if this is not the case.
939 my $exportmodulecheck = xestiascan_variablecheck($exportmodule_name, "module", 0, 1);
941 if ($exportmodulecheck eq 1){
943 # The export module name given is invalid. Skip and
944 # process the next one.
946 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmoduleinvalidname});
947 $main::xestiascan_presmodule->endbox();
953 my $exportmoduleexists = xestiascan_fileexists("Modules/Export/" . $exportmodule_name . ".pm");
955 if ($exportmoduleexists eq 1){
957 # The export moudle with the name given is missing.
958 # Skip and process the next one.
960 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmodulemissing});
961 $main::xestiascan_presmodule->endbox();
968 my $exportmodulefilepermission = xestiascan_filepermissions("Modules/Export/" . $exportmodule_name . ".pm");
970 if ($exportmodulefilepermission eq 1){
972 # The export module with the name given has invalid
975 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmodulemissing});
976 $main::xestiascan_presmodule->endbox();
982 # Check if the user has permission to use this export
983 # module and write a message if not.
985 my $exportmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "ExportModule", PermissionName => $exportmodule_name });
987 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
988 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
989 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
991 $exportmodulepermission = 0 if !$exportmodulepermission;
993 if ($exportmodulepermission eq 0){
995 # The user does not have permission to use this export
996 # module so write a message.
998 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmoduleinvaliddbpermissions});
999 $main::xestiascan_presmodule->endbox();
1005 # Get the module settings.
1007 my ($exportmodule_options, %exportmodule_options);
1008 tie(%exportmodule_options, "Tie::IxHash");
1010 $hs->hash_search("^exportmodule_" . $exportmodule_name . "_", %form_data);
1011 %exportmodulesettings = $hs->hash_search_resultdata;
1013 # Strip the module settings.
1015 foreach $exportmodule_settings_unprocessed (keys %exportmodulesettings){
1017 $exportmodule_settings_regex = "^exportmodule_" . $exportmodule_name . "_";
1018 $exportmodule_settings_unprocessed =~ s/^$exportmodule_settings_regex//;
1020 $exportmodule_options{$exportmodule_settings_unprocessed} = $exportmodulesettings{"exportmodule_" . $exportmodule_name . "_" . $exportmodule_settings_unprocessed};
1024 # Load the export module.
1026 my $exportmodulename = "Modules::Export::" . $exportmodule_name;
1027 eval "use " . $exportmodulename;
1028 my $xestiascan_exportmodule = $exportmodulename->new();
1030 $xestiascan_exportmodule->initialise();
1031 $xestiascan_exportmodule->loadsettings($main::xestiascan_config{"system_language"});
1033 # Process the outputted file.
1035 $xestiascan_exportmodule->exportimage($processed_filename, $main::xestiascan_config{"directory_noncgi_scans"}, $main::xestiascan_config{"directory_fs_scans"}, %exportmodule_options);
1037 # Check if an error occured.
1039 $main::xestiascan_presmodule->addhorizontalline();
1041 if ($xestiascan_exportmodule->errorflag ne 0){
1043 $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{exportmodulefailed}, $xestiascan_exportmodule->errormessage));
1047 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmodulecomplete});
1051 # Delete the export module.
1053 undef($xestiascan_exportmodule);
1055 # Finish the results box for this export module.
1057 $main::xestiascan_presmodule->endbox();
1061 if (!@activemodules){
1063 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noexportmoduleselected});
1067 $main::xestiascan_presmodule->endbox();
1068 $main::xestiascan_presmodule->endbox();
1074 if ($previewoptions{Switched} eq "no"){
1076 # Get the image, generate a random number, write the file as PNM and display
1077 # some options for the scanned image.
1081 xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
1082 my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
1083 xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
1085 # Rotate. (Should be either 0, 90, 180, 270 degrees).
1087 xestiascan_error("rotateblank") if !$previewoptions{Rotate};
1088 if ($previewoptions{Rotate} eq "0deg" || $previewoptions{Rotate} eq "90deg" || $previewoptions{Rotate} eq "180deg" || $previewoptions{Rotate} eq "270deg"){
1092 xestiascan_error("rotateinvalidoption");
1098 xestiascan_error("colourblank") if !$previewoptions{Colour};
1099 if ($previewoptions{Colour} eq "rgb" || $previewoptions{Colour} eq "grey" ){
1103 xestiascan_error("colourinvalidoption");
1109 xestiascan_error("resolutionblank") if !defined($previewoptions{Resolution});
1110 my $resolution_numberscheck = xestiascan_variablecheck($previewoptions{Resolution}, "numbers", 0, 1);
1111 xestiascan_error("resolutioninvalidnumber") if $resolution_numberscheck eq 1;
1113 # Top Left X (Pointy figure);
1115 xestiascan_error("topleftxblank") if !defined($previewoptions{TopLeftX});
1116 my $topleftx_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftX}, "decimal", 0, 1);
1117 xestiascan_error("topleftxinvalidnumber") if $topleftx_decimalcheck eq 1;
1119 # Top Left Y (Pointy figure).
1121 xestiascan_error("topleftyblank") if !defined($previewoptions{TopLeftY});
1122 my $toplefty_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftY}, "decimal", 0, 1);
1123 xestiascan_error("topleftyinvalidnumber") if $toplefty_decimalcheck eq 1;
1125 # Bottom Right X (Pointy figure).
1127 xestiascan_error("bottomrightx") if !defined($previewoptions{BottomRightX});
1128 my $bottomrightx_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightX}, "decimal", 0, 1);
1129 xestiascan_error("bottomrightxinvalidnumber") if $bottomrightx_decimalcheck eq 1;
1131 # Bottom Right Y (Pointy figure).
1133 xestiascan_error("bottomrighty") if !defined($previewoptions{BottomRightY});
1134 my $bottomrighty_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightY}, "decimal", 0, 1);
1135 xestiascan_error("bottomrightyinvalidnumber") if $bottomrighty_decimalcheck eq 1;
1137 # Generate a random hex value and use this to write a temporary file.
1141 if (!$previewoptions{ImageHex}){
1143 $randomhex = hex(int(rand(16777216)));
1145 # Set variables for scanner.
1147 $scan_device = Sane::Device->open($previewoptions{ScannerID});
1149 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_RESOLUTION, $previewoptions{Resolution});
1150 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_X, $previewoptions{TopLeftX});
1151 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_Y, $previewoptions{TopLeftY});
1152 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_X, $previewoptions{BottomRightX});
1153 xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_Y, $previewoptions{BottomRightY});
1155 # Get Sane to scan based on what has been passed (scanner name).
1157 if ($Sane::STATUS == SANE_STATUS_GOOD){
1158 $scan_device->start;
1161 my $param = $scan_device->get_parameters;
1163 open ($fh, '>', "/tmp/xestiascanserver-preview-" . $randomhex . ".pnm") or die("error: $!");
1164 $scan_device->write_pnm_header($fh, $param->{format},
1165 $param->{pixels_per_line},
1166 $param->{lines}, $param->{depth});
1169 ($data, $len) = $scan_device->read ($param->{bytes_per_line});
1170 print $fh $data if $data;
1171 } until ($Sane::STATUS == SANE_STATUS_EOF);
1174 # Get the current scanner values.
1176 my $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
1177 my $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
1178 my $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
1179 my $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
1180 my $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
1182 $picture_topleftx = int(0) if $picture_topleftx eq 0;
1184 # Convert the PNM based image into PNG format.
1186 my $im = new Image::Magick;
1187 $im->Read("/tmp/xestiascanserver-preview-" . $randomhex . ".pnm");
1189 # Rotate the document if needed.
1191 my $rotate = $previewoptions{Rotate};
1193 my $numrotateseek = 0;
1195 if ($previewoptions{Rotate} ne "0deg" ){
1196 $numrotate = 1 if $rotate eq "90deg";
1197 $numrotate = 2 if $rotate eq "180deg";
1198 $numrotate = 3 if $rotate eq "270deg";
1203 } until ($numrotateseek eq $numrotate || $numrotateseek > $numrotate);
1207 # Change the colour type of the document if needed.
1209 if ($previewoptions{Colour} eq "rgb"){
1211 # Set the document to colour.
1213 $im->Quantize(colorspace => 'RGB');
1215 } elsif ($previewoptions{Colour} eq "grey"){
1217 # Set the document to greyscale.
1219 $im->Quantize(colorspace =>'gray');
1223 # Adjust the brightness.
1225 xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
1227 my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
1228 xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
1230 my $picture_brightness = $previewoptions{Brightness};
1231 $im->Modulate( brightness=> $picture_brightness );
1233 $im->Write("/tmp/xestiascanserver-preview-" . $randomhex . ".pnm");
1237 $im->Write("/tmp/xestiascanserver-preview-" . $randomhex . ".png");
1241 $randomhex = $previewoptions{ImageHex};
1247 $randomhex = $previewoptions{ImageHex};
1251 my ($outputmodule, $outputmodulesname, $exportmodule);
1253 # Get the output modules.
1255 my @outputmodules = xestiascan_scan_getoutputmodules;
1256 $outputmodule = $previewoptions{OutputFormat} if $previewoptions{OutputFormat};
1258 # Get the export modules.
1260 my @exportmodules = xestiascan_scan_getexportmodules;
1262 $main::xestiascan_presmodule->startform("xsdss.cgi", "GET");
1263 $main::xestiascan_presmodule->addhiddendata("mode", "scan");
1264 $main::xestiascan_presmodule->addhiddendata("action", "scan");
1265 $main::xestiascan_presmodule->addhiddendata("confirm", "1");
1266 $main::xestiascan_presmodule->addhiddendata("imagehex", $randomhex);
1268 $main::xestiascan_presmodule->startbox("sectionboxnofloat");
1269 $main::xestiascan_presmodule->startbox("sectiontitle");
1271 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{imagepreview});
1272 $main::xestiascan_presmodule->endbox();
1273 $main::xestiascan_presmodule->startbox("secondbox, previewimage");
1275 # Get a preview of the image.
1277 $main::xestiascan_presmodule->addimage("xsdss.cgi?mode=scan&action=getpreviewimage&dontclear=1&pictureid=" . $randomhex);
1278 $main::xestiascan_presmodule->endbox();
1279 $main::xestiascan_presmodule->endbox();
1281 $main::xestiascan_presmodule->startbox("sectionboxnofloat");
1282 $main::xestiascan_presmodule->startbox("sectiontitle");
1283 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputformatsettings});
1284 $main::xestiascan_presmodule->endbox();
1285 $main::xestiascan_presmodule->startbox("secondbox");
1287 $main::xestiascan_presmodule->startbox("outputmoduletitle");
1289 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmodule});
1291 $outputmodule = $main::xestiascan_config{"system_outputmodule"} if !$outputmodule;
1293 if (!@outputmodules){
1295 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noneavailable});
1296 $main::xestiascan_presmodule->endbox();
1297 $main::xestiascan_presmodule->startbox("outputmoduleoptions");
1298 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{nooutputmodulesavail});
1299 $main::xestiascan_presmodule->endbox();
1300 return $main::xestiascan_presmodule->grab();
1304 $main::xestiascan_presmodule->addselectbox("outputformat");
1306 foreach $outputmodulesname (@outputmodules){
1307 if ($outputmodule eq $outputmodulesname){
1308 $main::xestiascan_presmodule->addoption($outputmodulesname, { Value => $outputmodulesname, Selected => 1 });
1310 $main::xestiascan_presmodule->addoption($outputmodulesname, { Value => $outputmodulesname });
1314 $main::xestiascan_presmodule->endselectbox();
1315 $main::xestiascan_presmodule->addbutton("formatswitch", { Value => "yes", Description => "Switch Module" });
1319 $main::xestiascan_presmodule->endbox();
1321 $outputmodule = $outputmodules[0] if !$outputmodule;
1323 # Check to see if the user has permission to use this
1326 my $outputmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "OutputModule", PermissionName => $outputmodule });
1328 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
1329 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
1330 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
1332 $outputmodulepermission = 0 if !$outputmodulepermission;
1334 # Get the settings for the active output module.
1337 my $combobox_count = 0;
1339 my $outputmodulefilepermissions = xestiascan_filepermissions("Modules/Output/" . $outputmodule . ".pm", 1, 0, 0);
1341 if ($outputmodulepermission eq 1 && $outputmodulefilepermissions eq 0){
1343 # Load the output module.
1345 my $outputmodulename = "Modules::Output::" . $outputmodule;
1346 eval "use " . $outputmodulename;
1347 my $xestiascan_outputmodule = $outputmodulename->new();
1348 my ($outputmodule_options, %outputmodule_options);
1349 tie(%outputmodule_options, "Tie::IxHash");
1350 $xestiascan_outputmodule->initialise();
1351 $xestiascan_outputmodule->loadsettings($main::xestiascan_config{"system_language"});
1352 %outputmodule_options = $xestiascan_outputmodule->getoptions();
1353 my $outputmodule_selected = 0;
1354 my $outputmodule_readonly = 0;
1355 my @outputmodule_comboboxnames;
1356 my @outputmodule_comboboxvalues;
1357 my $outputmodule_comboboxname;
1358 my $outputmodule_comboboxvalue;
1360 $main::xestiascan_presmodule->startbox("outputmoduleoptions");
1362 foreach $option_name (keys %outputmodule_options){
1364 # Check if the option is a checkbox option.
1366 if ($outputmodule_options{$option_name}{type} eq "checkbox"){
1368 $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $option_name, { Checked => $outputmodule_options{$option_name}{checked}, OptionDescription => $outputmodule_options{$option_name}{string}, ReadOnly => $outputmodule_readonly });
1372 # Check if the option is a string option.
1374 if ($outputmodule_options{$option_name}{type} eq "textbox"){
1376 if (!$outputmodule_options{$option_name}{password}){
1377 $outputmodule_options{$option_name}{password} = 0;
1380 $main::xestiascan_presmodule->addtext($outputmodule_options{$option_name}{string} . " ");
1381 $main::xestiascan_presmodule->addinputbox("outputmodule_" . $option_name, { Size => $outputmodule_options{$option_name}{size}, MaxLength => $outputmodule_options->{$option_name}{maxlength}, Value => $outputmodule_options{$option_name}{value}, Password => $outputmodule_options{$option_name}{password}, ReadOnly => $outputmodule_readonly });
1385 # Check if the option is a combobox option.
1387 if ($outputmodule_options{$option_name}{type} eq "combobox"){
1389 $combobox_count = 0;
1391 @outputmodule_comboboxnames = split(/\|/, $outputmodule_options{$option_name}{optionnames});
1392 @outputmodule_comboboxvalues = split(/\|/, $outputmodule_options{$option_name}{optionvalues});
1394 $main::xestiascan_presmodule->addtext($outputmodule_options{$option_name}{string} . " ");
1395 $main::xestiascan_presmodule->addselectbox("outputmodule_" . $option_name);
1397 foreach $outputmodule_comboboxname (@outputmodule_comboboxnames){
1399 $main::xestiascan_presmodule->addoption($outputmodule_comboboxname, { Value => $outputmodule_comboboxvalues[$combobox_count], ReadOnly => $outputmodule_readonly });
1404 $main::xestiascan_presmodule->endselectbox;
1408 # Check if the option is a radio option.
1410 if ($outputmodule_options{$option_name}{type} eq "radio"){
1412 # Check if the selected value is blank and if it is then
1415 if (!$outputmodule_options{$option_name}{selected}){
1416 $outputmodule_selected = 0;
1418 $outputmodule_selected = 1;
1421 $main::xestiascan_presmodule->addradiobox("outputmodule_" . $outputmodule_options{$option_name}{name}, { Description => $outputmodule_options{$option_name}{string}, Value => $outputmodule_options{$option_name}{value}, Selected => $outputmodule_selected, ReadOnly => $outputmodule_readonly });
1425 $main::xestiascan_presmodule->addlinebreak();
1429 # If there are no options available then write a message
1430 # to say no options are available for this module.
1432 if (!%outputmodule_options){
1434 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{nooutputmoduleopts});
1438 } elsif ($outputmodulefilepermissions eq 1) {
1440 $main::xestiascan_presmodule->startbox("outputmoduleoptions");
1441 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvalidfilepermissions});
1445 $main::xestiascan_presmodule->startbox("outputmoduleoptions");
1446 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvaliddbpermissions});
1450 $main::xestiascan_presmodule->endbox();
1451 $main::xestiascan_presmodule->endbox();
1452 $main::xestiascan_presmodule->endbox();
1454 $main::xestiascan_presmodule->startbox("sectionboxnofloat");
1455 $main::xestiascan_presmodule->startbox("sectiontitle");
1456 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportformatsettings});
1457 $main::xestiascan_presmodule->endbox();
1458 $main::xestiascan_presmodule->startbox("secondbox");
1460 # Process the list of export modules.
1462 my $exportmodulename;
1463 my $xestiascan_exportmodule;
1464 my ($exportmodule_options, %exportmodule_options);
1465 my $exportmodule_readonly = 0;
1466 my $exportmodule_selected = 0;
1467 my @exportmodule_comboboxnames;
1468 my @exportmodule_comboboxvalues;
1469 my $exportmodule_comboboxname;
1470 my $exportmodule_comboboxvalue;
1472 if (!@exportmodules){
1474 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noexportmodulesavail});
1475 $main::xestiascan_presmodule->endbox();
1476 $main::xestiascan_presmodule->endbox();
1477 $main::xestiascan_presmodule->endbox();
1478 return $main::xestiascan_presmodule->grab();
1482 my $exportmodulepermission;
1483 my $exportmodulefilepermission;
1485 foreach $exportmodule (@exportmodules){
1487 # Check to see if the user has permission to use the export
1488 # module and return an error if this is not the case.
1490 $exportmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "ExportModule", PermissionName => $exportmodule });
1492 xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
1493 xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
1494 xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
1496 $exportmodulepermission = 0 if !$exportmodulepermission;
1498 # Check the file permissions for the export module
1499 # has been set correctly.
1501 $exportmodulefilepermission = xestiascan_filepermissions("Modules/Export/" . $exportmodule . ".pm", 1, 0, 0);
1503 if ($exportmodulepermission eq 0){
1505 # We don't have permission so write an error message.
1507 $main::xestiascan_presmodule->startbox("exportmoduletitle");
1508 $main::xestiascan_presmodule->addtext($exportmodule);
1509 $main::xestiascan_presmodule->endbox();
1511 $main::xestiascan_presmodule->startbox("exportmoduleoptions");
1512 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmoduleinvalidfilepermissions});
1513 $main::xestiascan_presmodule->endbox();
1519 if ($exportmodulefilepermission ne 0){
1521 # The file permissions are invalid so write an error message.
1523 $main::xestiascan_presmodule->startbox("exportmoduletitle");
1524 $main::xestiascan_presmodule->addtext($exportmodule);
1525 $main::xestiascan_presmodule->endbox();
1527 $main::xestiascan_presmodule->startbox("exportmoduleoptions");
1528 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmoduleinvaliddbpermissions});
1529 $main::xestiascan_presmodule->endbox();
1535 # Load the export module.
1537 $exportmodulename = "Modules::Export::" . $exportmodule;
1538 eval "use " . $exportmodulename;
1539 $xestiascan_exportmodule = $exportmodulename->new();
1540 tie(%exportmodule_options, "Tie::IxHash");
1541 $xestiascan_exportmodule->initialise();
1542 $xestiascan_exportmodule->loadsettings($main::xestiascan_config{"system_language"});
1543 %exportmodule_options = $xestiascan_exportmodule->getoptions();
1545 $main::xestiascan_presmodule->startbox("exportmoduletitle");
1546 $main::xestiascan_presmodule->addcheckbox("module_" . $exportmodule, { OptionDescription => "" });
1547 $main::xestiascan_presmodule->addtext($exportmodule);
1548 $main::xestiascan_presmodule->endbox();
1550 $main::xestiascan_presmodule->startbox("exportmoduleoptions");
1551 foreach $option_name (keys %exportmodule_options){
1553 # Check if the option is a checkbox option.
1555 if ($exportmodule_options{$option_name}{type} eq "checkbox"){
1557 $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodule . "_" . $option_name, { Checked => $exportmodule_options{$option_name}{checked}, OptionDescription => $exportmodule_options{$option_name}{string}, ReadOnly => $exportmodule_readonly });
1561 # Check if the option is a string option.
1563 if ($exportmodule_options{$option_name}{type} eq "textbox"){
1565 if (!$exportmodule_options{$option_name}{password}){
1566 $exportmodule_options{$option_name}{password} = 0;
1569 $main::xestiascan_presmodule->addtext($exportmodule_options{$option_name}{string} . " ");
1570 $main::xestiascan_presmodule->addinputbox("exportmodule_" . $exportmodule . "_" . $option_name, { Size => $exportmodule_options{$option_name}{size}, MaxLength => $exportmodule_options->{$option_name}{maxlength}, Value => $exportmodule_options{$option_name}{value}, Password => $exportmodule_options{$option_name}{password}, ReadOnly => $exportmodule_readonly });
1574 # Check if the option is a combobox option.
1576 if ($exportmodule_options{$option_name}{type} eq "combobox"){
1578 $combobox_count = 0;
1580 @exportmodule_comboboxnames = split(/\|/, $exportmodule_options{$option_name}{optionnames});
1581 @exportmodule_comboboxvalues = split(/\|/, $exportmodule_options{$option_name}{optionvalues});
1583 $main::xestiascan_presmodule->addtext($exportmodule_options{$option_name}{string} . " ");
1584 $main::xestiascan_presmodule->addselectbox("exportmodule_" . $exportmodule . "_" . $option_name);
1586 foreach $exportmodule_comboboxname (@exportmodule_comboboxnames){
1588 $main::xestiascan_presmodule->addoption($exportmodule_comboboxname, { Value => $exportmodule_comboboxvalues[$combobox_count], ReadOnly => $exportmodule_readonly });
1593 $main::xestiascan_presmodule->endselectbox;
1597 # Check if the option is a radio option.
1599 if ($exportmodule_options{$option_name}{type} eq "radio"){
1601 # Check if the selected value is blank and if it is then
1604 if (!$exportmodule_options{$option_name}{selected}){
1605 $exportmodule_selected = 0;
1607 $exportmodule_selected = 1;
1610 $main::xestiascan_presmodule->addradiobox("exportmodule_" . $exportmodule . "_" . $exportmodule_options{$option_name}{name}, { Description => $exportmodule_options{$option_name}{string}, Value => $exportmodule_options{$option_name}{value}, Selected => $exportmodule_selected, ReadOnly => $exportmodule_readonly });
1614 $main::xestiascan_presmodule->addlinebreak();
1617 $main::xestiascan_presmodule->endbox();
1619 if (!%exportmodule_options){
1621 $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noexportmoduleopts});
1625 # Delete (free) the export module.
1627 undef($xestiascan_exportmodule);
1631 $main::xestiascan_presmodule->endbox();
1632 $main::xestiascan_presmodule->endbox();
1633 $main::xestiascan_presmodule->endbox();
1635 $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{scan}{process});
1636 $main::xestiascan_presmodule->addreset($main::xestiascan_lang{common}{restoredefault});
1638 $main::xestiascan_presmodule->endform();
1642 return $main::xestiascan_presmodule->grab();
1647 sub xestiascan_scan_getpreviewimage{
1648 #################################################################################
1649 # xestiascan_scan_getpreviewimage: Get the preview image. #
1653 # xestiascan_scan_getpreviewimage(previewid); #
1655 # previewid Specifies the picture ID. #
1656 #################################################################################
1658 # Get the values from the subroutine.
1660 my $pictureid = shift;
1661 my $dontclear = shift;
1669 # Return an error message if picture ID is blank.
1673 xestiascan_error("blankpictureid");
1677 xestiascan_error("invalidpictureid") if xestiascan_variablecheck($pictureid, "numbers", 0, 1) eq 1;
1679 print "Content-Type: image/png\r\n\r\n";
1681 binmode(STDOUT, ":bytes");
1684 open($imgfh, "/tmp/xestiascanserver-preview-" . $pictureid . ".png");
1685 my @lines = <$imgfh>;
1689 unlink("/tmp/xestiascanserver-preview-" . $pictureid . ".png") if $dontclear < 1;
1693 sub xestiascan_scan_getscannerlist{
1694 #################################################################################
1695 # xestiascan_scan_getscannerlist: Gets the list of available scanners. #
1699 # xestiascan_scan_getscannerlist; #
1700 #################################################################################
1705 tie(%scannerlist, 'Tie::IxHash');
1707 foreach $scanner (Sane->get_devices){
1708 $scannerlist{$scanner->{'name'}}{name} = $scanner->{'name'};
1709 $scannerlist{$scanner->{'name'}}{model} = $scanner->{'model'};
1710 $scannerlist{$scanner->{'name'}}{vendor} = $scanner->{'vendor'};
1711 # if ($scanner->{'name'} eq $http_scannerdevice){
1712 # print "<option value=\"" . $scanner->{'name'} . "\"
1713 #selected=selected>" . $scanner->{'vendor'} . ": " . $scanner->{'model'} . "</option>";
1715 # print "<option value=\"" . $scanner->{'name'} . "\">" .
1716 #$scanner->{'vendor'} . ": " . $scanner->{'model'} . "</option>";
1720 return %scannerlist;
1724 sub xestiascan_scan_getscannervalue{
1725 #################################################################################
1726 # xestiascan_scan_getscannervalue: Gets a specific option value. #
1730 # xestiascan_scan_getscannervalue(name); #
1732 # name Specifies the name of option. #
1733 #################################################################################
1735 my $option_name = shift;
1738 my $option_found = 0;
1741 my $option_total = $scan_device->get_option(0);
1742 my $option_seek = 0;
1748 $option = $scan_device->get_option_descriptor($option_seek);
1750 if (!$option->{name}){
1754 if ($option_name eq $option->{name}){
1756 if ($option->{type} eq SANE_TYPE_FIXED){
1757 $value = $scan_device->get_option($option_seek);
1758 $value = int(0) if !$value;
1760 $value = $scan_device->get_option($option_seek);
1770 } until ($option_seek > $option_total || $option_found eq 1);
1776 sub xestiascan_scan_setscannervalue{
1777 #################################################################################
1778 # xestiascan_scan_setscannervalue: Gets a specific option value. #
1782 # xestiascan_scan_setscannervalue(name, value); #
1784 # name Specifies the name of the option. #
1785 # value Specifies the value of the option. #
1786 #################################################################################
1788 my $option_name = shift;
1789 my $option_value = shift;
1791 my $option_total = $scan_device->get_option(0);
1792 my $option_seek = 0;
1794 my $option_found = 0;
1796 my $option_final_value;
1802 $option = $scan_device->get_option_descriptor($option_seek);
1804 if ($option_name eq $option->{name}){
1806 if ($option->{type} eq SANE_TYPE_FIXED){
1808 $scan_device->set_option($option_seek, $option_value) or return;
1812 $scan_device->set_option($option_seek, $option_value) or return;
1822 } until ($option_seek > $option_total || $option_found eq 1);
1824 return 1; # Setting set successfully.