1 /*
2 SANE EPSON backend
3 Copyright (C) 2001, 2005, 2008 SEIKO EPSON Corporation
4
5 Date Author Reason
6 06/01/2001 N.Sasaki New
7
8 This file is part of the `iscan' program.
9
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; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 As a special exception, the copyright holders give permission
25 to link the code of this program with the esmod library and
26 distribute linked combinations including the two. You must obey
27 the GNU General Public License in all respects for all of the
28 code used other then esmod.
29 */
30
31 /*------------------------------------------------------------*/
32 #include <assert.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <new>
37 using std::bad_alloc;
38
39 #include "filter.hh"
40
41 /*------------------------------------------------------------*/
42 #include "pisa_scan_manager.h"
43 #include "pisa_error.h"
44 #include "pisa_scan_tool.h"
45 #include "pisa_change_unit.h"
46
47 /*------------------------------------------------------------*/
open_device(char * name)48 void scan_manager::open_device ( char * name )
49 {
50 sane_scan::init ( );
51
52 m_resize_cls = 0;
53 m_moire_cls = 0;
54 m_sharp_cls = 0;
55 m_resize_img_info = 0;
56 m_moire_img_info = 0;
57 m_sharp_img_info = 0;
58
59 sane_scan::open_device (name);
60 max_descreen_resolution = get_max_resolution (is_dumb () ? 600 : 800);
61 }
62
63 void
init_scan(int * width,int * height,bool reset_params)64 scan_manager::init_scan (int *width, int *height, bool reset_params)
65 {
66 if (reset_params)
67 {
68 for (int i = 0; i < 2; ++i)
69 {
70 adjust_scan_param (¶m.resolution[i], ¶m.zoom[i]);
71 }
72
73 init_img_process_info (param);
74 sane_scan::set_scan_parameter (param);
75 }
76
77 if (area_is_too_large (param))
78 {
79 if (getenv ("ISCAN_DEBUG"))
80 {
81 fprintf (stderr, "Backend will try to scan with these settings\n");
82 fprintf (stderr, "Resolution (main,sub): %ld,%ld\n",
83 param.resolution[0], param.resolution[1]);
84 fprintf (stderr, "Zoom (main,sub): %ld,%ld\n",
85 param.zoom[0], param.zoom[1]);
86 fprintf (stderr, "Offset (main,sub): %ld,%ld\n",
87 inch2pixel (param.offset[0], param.resolution[0],
88 param.zoom[0]),
89 inch2pixel (param.offset[1], param.resolution[1],
90 param.zoom[1]));
91 fprintf (stderr, "Area (main,sub): %ld,%ld\n",
92 inch2pixel (true,
93 param.area[0], param.resolution[0],
94 param.zoom[0]),
95 inch2pixel (false,
96 param.area[1], param.resolution[1],
97 param.zoom[1]));
98 }
99
100 throw pisa_error (PISA_ERR_AREALARGE);
101 }
102
103 sane_scan::start_scan ( width, height );
104
105 modify_img_info ( width, height );
106
107 create_img_cls ( );
108 }
109
110 /*------------------------------------------------------------*/
acquire_image(unsigned char * img,int row_bytes,int height,int cancel)111 void scan_manager::acquire_image ( unsigned char * img,
112 int row_bytes,
113 int height,
114 int cancel )
115 {
116 if ( m_resize || m_moire || m_sharp )
117 {
118 int in_rowbytes = 0, in_line;
119 unsigned char * in_img = 0;
120
121 if ( m_sharp )
122 in_rowbytes = m_sharp_info.in_rowbytes;
123 if ( m_moire )
124 in_rowbytes = m_moire_info.in_rowbytes;
125 if ( m_resize )
126 in_rowbytes = m_resize_info.in_rowbytes;
127
128 if ( cancel || img == 0 )
129 {
130 sane_scan::acquire_image ( 0, 0, 1, 1 );
131 }
132 else
133 {
134 in_line = get_send_in_line ( 1 );
135
136 if ( 0 < in_line )
137 {
138 int buf_size = in_line * in_rowbytes;
139
140 in_img = new unsigned char [ buf_size + in_rowbytes ];
141
142 if ( in_img == 0 )
143 {
144 sane_scan::acquire_image ( 0, 0, 1, 1 );
145
146 throw pisa_error ( PISA_ERR_OUTOFMEMORY );
147 }
148
149 sane_scan::acquire_image ( in_img,
150 in_rowbytes,
151 in_line,
152 cancel );
153 }
154 }
155
156 ::memset ( img, 128, row_bytes );
157 if ( cancel == 0 && PISA_ERR_SUCCESS != image_process ( in_img, img ) )
158 {
159 delete [ ] in_img;
160 sane_scan::acquire_image ( 0, 0, 1, 1 );
161 throw pisa_error ( PISA_ERR_OUTOFMEMORY );
162 }
163
164 if ( in_img )
165 delete [ ] in_img;
166 }
167 else
168 sane_scan::acquire_image ( img, row_bytes, height, cancel );
169 }
170
171 void
finish_acquire(void)172 scan_manager::finish_acquire (void)
173 {
174 sane_scan::finish_acquire ();
175 release_memory ();
176 }
177
178 int
init_img_process_info(scan_parameter & param)179 scan_manager::init_img_process_info (scan_parameter& param)
180 {
181 // set flag
182 if (!has_zoom ())
183 m_resize = 1;
184 else
185 m_resize = 0;
186
187 if ( param.de_screening ) // color or B/W document
188 {
189 m_moire = 1;
190 m_resize = 0;
191 }
192 else
193 m_moire = 0;
194
195 m_sharp = param.usm;
196
197 if ( m_resize )
198 init_zoom ( & m_resize_info, param );
199
200 if ( m_moire )
201 init_moire ( & m_moire_info, param );
202
203 if ( m_sharp )
204 init_sharp ( & m_sharp_info, param );
205
206 return PISA_ERR_PARAMETER;
207 }
208
209 int
init_zoom(resize_img_info * info,scan_parameter & param)210 scan_manager::init_zoom (resize_img_info *info, scan_parameter& param)
211 {
212 long act_res[2];
213
214 info->resolution = param.resolution[0];
215
216 for (int i = 0; i < 2; ++i)
217 {
218 act_res[i] = param.resolution[i] * param.zoom[i] / 100;
219 }
220
221 info->out_width = ::inch2width ( param.area [ 0 ],
222 act_res [ 0 ] );
223 info->out_height = ::inch2height ( param.area [ 1 ],
224 act_res [ 1 ] );
225 info->out_rowbytes = calc_rowbytes ( info->out_width,
226 static_cast <pisa_pixel_type>
227 ( param.pixeltype ) );
228
229 for (int i = 0; i < 2; ++i)
230 {
231 param.resolution[i] = act_res[i];
232 param.zoom[i] = 100;
233 }
234
235 try
236 {
237 get_valid_resolution (¶m.resolution[0], ¶m.resolution[1], true);
238 }
239 catch (const pisa_error& e)
240 {
241 if (pisa_error (PISA_STATUS_UNSUPPORTED) != e)
242 throw (e);
243 }
244
245 if ( act_res[0] == param.resolution[0]
246 && act_res[1] == param.resolution[1])
247 {
248 m_resize = 0;
249 return PISA_ERR_SUCCESS;
250 }
251
252 info->in_width = ::inch2width ( param.area [ 0 ],
253 param.resolution [ 0 ] );
254 info->in_height = ::inch2height ( param.area [ 1 ],
255 param.resolution [ 1 ] );
256 info->in_rowbytes = calc_rowbytes ( info->in_width,
257 static_cast <pisa_pixel_type>
258 ( param.pixeltype ) );
259
260 info->bits_per_pixel = calc_bitperpix ( static_cast <pisa_pixel_type>
261 ( param.pixeltype ),
262 static_cast <pisa_bitdepth_type>
263 ( param.bitdepth ) );
264
265 if ( param.pixeltype == PISA_PT_BW )
266 info->resize_flag = PISA_RS_NN;
267 else
268 info->resize_flag = PISA_RS_BC;
269
270 return PISA_ERR_SUCCESS;
271 }
272
273 int
init_moire(moire_img_info * info,scan_parameter & param)274 scan_manager::init_moire (moire_img_info *info, scan_parameter& param)
275 {
276 info->resolution = param.resolution [ 0 ] * param.zoom [ 0 ] / 100;
277
278 param.resolution [ 0 ] =
279 param.resolution [ 1 ] =
280 iscan::moire::get_res_quote (info->resolution, is_dumb ());
281
282 if (!has_zoom ())
283 {
284 try
285 {
286 get_valid_resolution (¶m.resolution[0],
287 ¶m.resolution[1]);
288 }
289 catch (const pisa_error& e)
290 {
291 if (pisa_error (PISA_STATUS_UNSUPPORTED) != e)
292 throw (e);
293 // else do nothing
294 }
295 }
296
297 info->in_resolution = param.resolution [ 0 ];
298
299 param.zoom [ 0 ] = 100;
300 param.zoom [ 1 ] = 100;
301
302 info->in_width = ::inch2width ( param.area [ 0 ],
303 param.resolution [ 0 ] );
304 info->in_height = ::inch2height ( param.area [ 1 ],
305 param.resolution [ 1 ] );
306 info->in_rowbytes = calc_rowbytes ( info->in_width,
307 static_cast <pisa_pixel_type>
308 ( param.pixeltype ) );
309
310 info->out_width = ::inch2width ( param.area [ 0 ],
311 info->resolution );
312 info->out_height = ::inch2height ( param.area [ 1 ],
313 info->resolution );
314 info->out_rowbytes = calc_rowbytes ( info->out_width,
315 static_cast <pisa_pixel_type>
316 (param.pixeltype ) );
317
318 info->bits_per_pixel = calc_bitperpix ( static_cast <pisa_pixel_type>
319 ( param.pixeltype ),
320 static_cast <pisa_bitdepth_type>
321 ( param.bitdepth ) );
322
323 return PISA_ERR_SUCCESS;
324 }
325
326 /*------------------------------------------------------------*/
327 int
init_sharp(sharp_img_info * info,scan_parameter & param)328 scan_manager::init_sharp (sharp_img_info *info, scan_parameter& param)
329 {
330 long resolution;
331
332 if ( m_resize )
333 {
334 info->in_width = m_resize_info.out_width;
335 info->in_height = m_resize_info.out_height;
336
337 resolution = m_resize_info.resolution;
338 }
339 else if ( m_moire )
340 {
341 info->in_width = m_moire_info.out_width;
342 info->in_height = m_moire_info.out_height;
343
344 resolution = m_moire_info.resolution;
345 }
346 else
347 {
348 info->in_width = ::inch2width ( param.area [ 0 ],
349 param.resolution [ 0 ],
350 param.zoom [ 0 ] );
351 info->in_height = ::inch2height ( param.area [ 1 ],
352 param.resolution [ 1 ],
353 param.zoom [ 1 ] );
354
355 resolution = param.resolution [ 0 ];
356 }
357
358 info->in_rowbytes = calc_rowbytes ( info->in_width,
359 static_cast <pisa_pixel_type>
360 ( param.pixeltype ) );
361
362 info->bits_per_pixel = calc_bitperpix ( static_cast <pisa_pixel_type>
363 ( param.pixeltype ),
364 static_cast <pisa_bitdepth_type>
365 ( param.bitdepth ) );
366
367 info->out_width = info->in_width;
368 info->out_height = info->in_height;
369 info->out_rowbytes = info->in_rowbytes;
370
371 m_sharp_cls->set_parms (resolution,
372 param.film == PISA_FT_NEGA
373 || param.film == PISA_FT_POSI,
374 is_dumb (),
375 & info->strength,
376 & info->radius,
377 & info->clipping);
378
379 info->sharp_flag = PISA_SH_UMASK;
380
381 return PISA_ERR_SUCCESS;
382 }
383
384 /*------------------------------------------------------------*/
modify_img_info(int * width,int * height)385 int scan_manager::modify_img_info ( int * width, int * height )
386 {
387 // resize
388 if ( m_resize )
389 {
390 if ( m_resize_info.in_width == m_resize_info.out_width )
391 {
392 m_resize_info.out_width = * width;
393 m_resize_info.out_rowbytes = ( m_resize_info.out_width *
394 m_resize_info.bits_per_pixel +
395 7 ) / 8;
396 }
397
398 m_resize_info.in_width = * width;
399 m_resize_info.in_rowbytes = ( m_resize_info.in_width *
400 m_resize_info.bits_per_pixel +
401 7 ) / 8;
402
403 if ( m_resize_info.in_height == m_resize_info.out_height )
404 {
405 m_resize_info.out_height = * height;
406 }
407
408 m_resize_info.in_height = * height;
409 }
410
411 if ( m_sharp )
412 {
413 m_sharp_info.in_width = * width;
414 m_sharp_info.in_height = * height;
415 m_sharp_info.in_rowbytes = ( m_sharp_info.in_width *
416 m_sharp_info.bits_per_pixel +
417 7 ) / 8;
418
419 if ( m_resize )
420 {
421 m_sharp_info.in_width = m_resize_info.out_width;
422 m_sharp_info.in_height = m_resize_info.out_height;
423 m_sharp_info.in_rowbytes = m_resize_info.out_rowbytes;
424 }
425
426 if ( m_moire )
427 {
428 m_sharp_info.in_width = m_moire_info.out_width;
429 m_sharp_info.in_height = m_moire_info.out_height;
430 m_sharp_info.in_rowbytes = m_moire_info.out_rowbytes;
431 }
432
433 m_sharp_info.out_width = m_sharp_info.in_width;
434 m_sharp_info.out_height = m_sharp_info.in_height;
435 m_sharp_info.out_rowbytes = m_sharp_info.in_rowbytes;
436 }
437
438 // update width and height
439 if ( m_resize )
440 {
441 * width = m_resize_info.out_width;
442 * height = m_resize_info.out_height;
443 }
444
445 if ( m_moire )
446 {
447 * width = m_moire_info.out_width;
448 * height = m_moire_info.out_height;
449 }
450
451 if ( m_sharp )
452 {
453 * width = m_sharp_info.out_width;
454 * height = m_sharp_info.out_height;
455 }
456
457
458 return PISA_ERR_SUCCESS;
459 }
460
461 /*------------------------------------------------------------*/
create_img_cls(void)462 int scan_manager::create_img_cls ( void )
463 {
464 release_memory ();
465
466 if (m_sharp)
467 {
468 m_sharp_img_info = new IMAGE_INFO [ 2 ];
469
470 set_img_info ( & m_sharp_img_info [ _IN ],
471 & m_sharp_img_info [ _OUT ],
472 m_sharp_info );
473
474 m_sharp_cls = new iscan::focus (m_sharp_info);
475 }
476
477 if ( m_moire )
478 {
479 m_moire_img_info = new IMAGE_INFO [ 2 ];
480
481 set_img_info ( & m_moire_img_info [ _IN ],
482 & m_moire_img_info [ _OUT ],
483 m_moire_info );
484
485 m_moire_cls = new iscan::moire (m_moire_info, is_dumb ());
486 }
487
488 if ( m_resize )
489 {
490 m_resize_img_info = new IMAGE_INFO [ 2 ];
491
492 set_img_info ( & m_resize_img_info [ _IN ],
493 & m_resize_img_info [ _OUT ],
494 m_resize_info );
495
496 m_resize_cls = new iscan::scale (m_resize_info);
497 }
498
499 return PISA_ERR_SUCCESS;
500 }
501
502 /*------------------------------------------------------------*/
release_memory(void)503 int scan_manager::release_memory ( void )
504 {
505 if ( m_resize_cls )
506 delete m_resize_cls;
507 m_resize_cls = 0;
508
509 if ( m_moire_cls )
510 delete m_moire_cls;
511 m_moire_cls = 0;
512
513 if ( m_sharp_cls )
514 delete m_sharp_cls;
515 m_sharp_cls = 0;
516
517 if ( m_resize_img_info )
518 delete m_resize_img_info;
519 m_resize_img_info = 0;
520
521 if ( m_moire_img_info )
522 delete m_moire_img_info;
523 m_moire_img_info = 0;
524
525 if ( m_sharp_img_info )
526 delete m_sharp_img_info;
527 m_sharp_img_info = 0;
528
529 return PISA_ERR_SUCCESS;
530 }
531
532 /*------------------------------------------------------------*/
set_img_info(LPIMAGE_INFO in_img_info,LPIMAGE_INFO out_img_info,const img_size & size)533 void scan_manager::set_img_info ( LPIMAGE_INFO in_img_info,
534 LPIMAGE_INFO out_img_info,
535 const img_size & size )
536 {
537 in_img_info->pImg_Buf = 0;
538 in_img_info->Img_Width = size.in_width;
539 in_img_info->Img_Height = size.in_height;
540 in_img_info->Img_RowBytes = size.in_rowbytes;
541 in_img_info->BitsPerPixel = size.bits_per_pixel;
542
543 out_img_info->pImg_Buf = 0;
544 out_img_info->Img_Width = size.out_width;
545 out_img_info->Img_Height = size.out_height;
546 out_img_info->Img_RowBytes = size.out_rowbytes;
547 out_img_info->BitsPerPixel = size.bits_per_pixel;
548 }
549
550 /*------------------------------------------------------------*/
get_send_in_line(int out_line)551 int scan_manager::get_send_in_line ( int out_line )
552 {
553 size_t quote = out_line;
554
555 if (m_sharp)
556 {
557 m_sharp_img_info [ _OUT ].Img_Height = quote;
558 quote = m_sharp_cls->get_line_quote (quote);
559 m_sharp_img_info [ _IN ].Img_Height = quote;
560 }
561 if (m_moire)
562 {
563 m_moire_img_info [ _OUT ].Img_Height = quote;
564 quote = m_moire_cls->get_line_quote (quote);
565 m_moire_img_info [ _IN ].Img_Height = quote;
566 }
567 if (m_resize)
568 {
569 m_resize_img_info [ _OUT ].Img_Height = quote;
570 quote = m_resize_cls->get_line_quote (quote);
571 m_resize_img_info [ _IN ].Img_Height = quote;
572 }
573
574 return quote;
575 }
576
577 /*------------------------------------------------------------*/
image_process(unsigned char * in_img,unsigned char * out_img)578 int scan_manager::image_process ( unsigned char * in_img,
579 unsigned char * out_img )
580 {
581 unsigned char *inbuf, *outbuf;
582 size_t in_sz, out_sz;
583
584 unsigned char *tmpbuf = NULL;
585 size_t tmp_sz = 0;
586 bool zapbuf = false;
587
588 try
589 {
590 if (m_resize)
591 {
592 in_sz = m_resize_img_info [ _IN ].Img_Height * m_resize_img_info [ _IN].Img_RowBytes;
593 inbuf = in_img;
594
595 if (m_sharp)
596 {
597 out_sz = tmp_sz = (m_resize_img_info [ _OUT ].Img_Height
598 * m_resize_img_info [ _OUT ].Img_RowBytes);
599 outbuf = tmpbuf = new unsigned char [out_sz];
600 zapbuf = true;
601 }
602 else
603 {
604 out_sz = m_resize_img_info [ _OUT ].Img_Height * m_resize_img_info [ _OUT ].Img_RowBytes;
605 outbuf = out_img;
606 }
607 m_resize_cls->exec (inbuf, in_sz, outbuf, out_sz);
608 }
609
610 if (m_moire)
611 {
612 in_sz = m_moire_img_info [ _IN ].Img_Height * m_moire_img_info [ _IN ].Img_RowBytes;
613 inbuf = in_img;
614
615 if (m_sharp)
616 {
617 out_sz = tmp_sz = (m_moire_img_info [ _OUT ].Img_Height
618 * m_moire_img_info [ _OUT ].Img_RowBytes);
619 outbuf = tmpbuf = new unsigned char [out_sz];
620 zapbuf = true;
621 }
622 else
623 {
624 out_sz = m_moire_img_info [ _OUT ].Img_Height * m_moire_img_info [ _OUT ].Img_RowBytes;
625 outbuf = out_img;
626 }
627 m_moire_cls->exec (inbuf, in_sz, outbuf, out_sz);
628 }
629
630 if (m_sharp)
631 {
632 out_sz = m_sharp_img_info [ _OUT ].Img_Height * m_sharp_img_info [ _OUT ].Img_RowBytes;
633 outbuf = out_img;
634
635 if (m_resize || m_moire)
636 {
637 in_sz = tmp_sz;
638 inbuf = tmpbuf;
639 }
640 else
641 {
642 in_sz = m_sharp_img_info [ _IN ].Img_Height * m_sharp_img_info [ _IN ].Img_RowBytes;
643 inbuf = in_img;
644 }
645 m_sharp_cls->exec (inbuf, in_sz, outbuf, out_sz);
646 }
647
648 if (zapbuf)
649 {
650 delete [] tmpbuf;
651 }
652 }
653 catch (bad_alloc& oops)
654 {
655 if (zapbuf)
656 {
657 delete [] tmpbuf;
658 }
659 return PISA_ERR_OUTOFMEMORY;
660 }
661
662 return PISA_ERR_SUCCESS;
663 }
664
665 void
adjust_scan_param(long * resolution,long * scale) const666 scan_manager::adjust_scan_param (long *resolution, long *scale) const
667 {
668 int min_res = 50;
669 int max_res = get_max_resolution ();
670 int adj_res = *resolution;
671
672 int min_scale = 50;
673 int max_scale = 200;
674 int adj_scale = 100; // assume no scaling is needed
675
676 if (adj_res < min_res)
677 {
678 adj_scale = adj_res * 100 / min_res;
679
680 if (adj_scale < min_scale)
681 {
682 adj_scale = min_scale;
683 }
684 adj_res = min_res;
685 }
686
687 if (max_res < adj_res)
688 {
689 adj_scale = adj_res * 100 / max_res;
690
691 if (adj_scale > max_scale)
692 {
693 adj_scale = max_scale;
694 }
695 adj_res = max_res;
696 }
697
698 *resolution = adj_res;
699 *scale = adj_scale;
700 }
701
702 /*! Sets main and sub resolutions to the best available value.
703
704 The best available value is the first resolution not smaller than
705 the value passed. If no such value is available, the largest
706 available resolution will be used unless \a use_max is \c false.
707
708 In the latter case an exception will be thrown instead.
709 */
710 void
get_valid_resolution(long int * x_res,long int * y_res,bool use_max) const711 scan_manager::get_valid_resolution (long int *x_res, long int *y_res,
712 bool use_max) const
713 {
714 if (!x_res || !y_res)
715 throw pisa_error (PISA_ERR_PARAMETER);
716
717 SANE_Int res_x = get_resolution (SANE_NAME_SCAN_X_RESOLUTION, *x_res);
718 SANE_Int res_y = get_resolution (SANE_NAME_SCAN_Y_RESOLUTION, *y_res);
719
720 if (0 == res_x || 0 == res_y)
721 {
722 if (!use_max)
723 throw pisa_error (PISA_STATUS_UNSUPPORTED);
724 if (0 == res_x)
725 res_x = get_max_resolution (SANE_NAME_SCAN_X_RESOLUTION);
726 if (0 == res_y)
727 res_y = get_max_resolution (SANE_NAME_SCAN_Y_RESOLUTION);
728 }
729
730 *x_res = res_x;
731 *y_res = res_y;
732 }
733
734 void
set_option(pisa_option_type option)735 scan_manager::set_option (pisa_option_type option)
736 {
737 sane_scan::set_option (option);
738 max_descreen_resolution = get_max_resolution (is_dumb () ? 600 : 800);
739 }
740
741 pisa_error_id
set_scan_parameters(const settings & set,const marquee & marq)742 scan_manager::set_scan_parameters (const settings& set, const marquee& marq)
743 {
744 memset (¶m, 0, sizeof (scan_parameter));
745
746 param.option = set.option;
747 param.film = set.film;
748
749 param.pixeltype = set.imgtype.pixeltype;
750 param.bitdepth = set.imgtype.bitdepth;
751 param.scanspeed = set.imgtype.scanspeed;
752 param.dropout = set.imgtype.dropout;
753 param.monoopt = set.imgtype.monoopt;
754 param.halftone = set.imgtype.halftone;
755
756 param.offset[0] = marq.offset.x;
757 param.offset[1] = marq.offset.y;
758 param.area[0] = marq.area.x;
759 param.area[1] = marq.area.y;
760 param.resolution[0] = (set.resolution * marq.scale + 50) / 100;
761 param.resolution[1] = (set.resolution * marq.scale + 50) / 100;
762 param.zoom[0] = 100;
763 param.zoom[1] = 100;
764
765 for (int i = 0; i < 256; ++i)
766 {
767 param.gamma.gamma_r[i] = marq.lut.gamma_r[i];
768 param.gamma.gamma_g[i] = marq.lut.gamma_g[i];
769 param.gamma.gamma_b[i] = marq.lut.gamma_b[i];
770 }
771
772 if (set.imgtype.pixeltype == PISA_PT_RGB)
773 {
774 generate_color_coef (param.coef, set.coef, marq.saturation);
775 }
776 else // use identity matrix
777 { // FIXME: fold into generate_color_coef()
778 for (int i = 0; i < 9; ++i)
779 param.coef[i] = 0.0;
780
781 param.coef[0] = 1.0;
782 param.coef[4] = 1.0;
783 param.coef[8] = 1.0;
784 }
785
786 param.threshold = marq.threshold;
787 param.speed = 0;
788 param.focus = marq.focus;
789
790 if (PISA_PT_BW == set.imgtype.pixeltype)
791 param.usm = 0;
792 else
793 param.usm = set.usm;
794
795 if (PISA_DESCREEN_ON == set.imgtype.de_screening)
796 param.de_screening = 1;
797 else
798 param.de_screening = 0;
799
800
801 // check for error conditions
802 pisa_error_id err = PISA_ERR_SUCCESS;
803
804 if (area_is_too_large (param))
805 err = PISA_ERR_AREALARGE;
806
807 if (set.imgtype.de_screening == PISA_DESCREEN_ON)
808 {
809 if ( param.resolution[0] > max_descreen_resolution
810 || param.resolution[1] > max_descreen_resolution)
811 err = PISA_ERR_MRRESTOOHIGH;
812 }
813 return err;
814 }
815
816 #include "pisa_view_manager.h"
817 pisa_error_id
set_scan_parameters(const settings & set,const marquee & marq,pisa_preview_type type,int resolution)818 scan_manager::set_scan_parameters (const settings& set, const marquee& marq,
819 pisa_preview_type type, int resolution)
820 {
821 memset (¶m, 0, sizeof (scan_parameter));
822
823 param.option = set.option;
824 param.film = set.film;
825
826 param.pixeltype = PISA_PT_RGB;
827 param.bitdepth = PISA_BD_8;
828 param.scanspeed = PISA_SS_DRAFT;
829 param.dropout = PISA_DO_NONE;
830 param.monoopt = PISA_MO_NONE;
831 param.halftone = PISA_HT_NONE;
832
833 param.offset[0] = marq.offset.x;
834 param.offset[1] = marq.offset.y;
835 param.area[0] = marq.area.x;
836 param.area[1] = marq.area.y;
837 param.resolution[0] = resolution;
838 param.resolution[1] = resolution;
839 param.zoom[0] = 100;
840 param.zoom[1] = 100;
841
842 // gamma table
843 for (int i = 0; i < 256; ++i)
844 {
845 param.gamma.gamma_r[i] = i;
846 param.gamma.gamma_g[i] = i;
847 param.gamma.gamma_b[i] = i;
848 }
849
850 // profile matrix
851 for (int i = 0; i < 9; ++i)
852 param.coef[i] = 0.0;
853
854 param.coef[0] = 1.0;
855 param.coef[4] = 1.0;
856 param.coef[8] = 1.0;
857
858 param.threshold = 0;
859 param.speed = 1;
860 param.focus = marq.focus;
861 param.usm = 0;
862 param.de_screening = 0;
863
864 return PISA_ERR_SUCCESS;
865 }
866