1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2002 Henning Meier-Geinitz <henning@meier-geinitz.de>
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 This file implements test picture functions for the test backend.
40 */
41
42 #define BUFFER_SIZE (64 * 1024)
43
44 static SANE_Bool little_endian (void);
45
46 static SANE_Status
init_picture_buffer(Test_Device * test_device, SANE_Byte ** buffer, size_t * buffer_size)47 init_picture_buffer (Test_Device * test_device, SANE_Byte ** buffer,
48 size_t * buffer_size)
49 {
50 SANE_Word pattern_size = 0, pattern_distance = 0;
51 SANE_Word line_count;
52 size_t b_size;
53 SANE_Word lines = 0;
54 SANE_Word bpl = test_device->bytes_per_line;
55 SANE_Word ppl = test_device->pixels_per_line;
56 SANE_Byte *b;
57 SANE_Bool is_little_endian = little_endian ();
58
59 if (test_device->val[opt_invert_endianess].w)
60 is_little_endian ^= 1;
61
62 DBG (2, "(child) init_picture_buffer test_device=%p, buffer=%p, "
63 "buffer_size=%p\n",(void*)test_device,(void*)buffer,(void*)buffer_size);
64
65 if (strcmp (test_device->val[opt_test_picture].s, "Solid black") == 0
66 || strcmp (test_device->val[opt_test_picture].s, "Solid white") == 0)
67 {
68 SANE_Byte pattern = 0;
69
70 b_size = BUFFER_SIZE;
71 if (buffer_size)
72 *buffer_size = b_size;
73
74 b = malloc (b_size);
75 if (!b)
76 {
77 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
78 return SANE_STATUS_NO_MEM;
79 }
80
81 if (buffer)
82 *buffer = b;
83
84 if (strcmp (test_device->val[opt_test_picture].s, "Solid black") == 0)
85 {
86 DBG (3, "(child) init_picture_buffer: drawing solid black test "
87 "picture %zu bytes\n", b_size);
88 if (test_device->params.format == SANE_FRAME_GRAY
89 && test_device->params.depth == 1)
90 pattern = 0xff;
91 else
92 pattern = 0x00;
93 }
94 else
95 {
96 DBG (3, "(child) init_picture_buffer: drawing solid white test "
97 "picture %zu bytes\n", b_size);
98 if (test_device->params.format == SANE_FRAME_GRAY
99 && test_device->params.depth == 1)
100 pattern = 0x00;
101 else
102 pattern = 0xff;
103 }
104 memset (b, pattern, b_size);
105 return SANE_STATUS_GOOD;
106 }
107
108 /* Grid */
109 if (strcmp (test_device->val[opt_test_picture].s, "Grid") == 0)
110 {
111 double p_size = (10.0 * SANE_UNFIX (test_device->val[opt_resolution].w)
112 / MM_PER_INCH);
113 SANE_Word increment = 1;
114 if (test_device->params.format == SANE_FRAME_RGB)
115 increment *= 3;
116 if (test_device->params.depth == 16)
117 increment *= 2;
118
119 lines = (SANE_Word) (2 * p_size + 0.5);
120 b_size = (size_t) lines * (size_t) bpl;
121 if (buffer_size)
122 *buffer_size = b_size;
123 b = malloc (b_size);
124 if (!b)
125 {
126 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
127 return SANE_STATUS_NO_MEM;
128 }
129 if (buffer)
130 *buffer = b;
131 DBG (3, "(child) init_picture_buffer: drawing grid test picture "
132 "%zu bytes, %d bpl, %d ppl, %d lines\n", b_size, bpl, ppl, lines);
133
134 for (line_count = 0; line_count < lines; line_count++)
135 {
136 SANE_Word x = 0;
137
138 for (x = 0; x < bpl; x += increment)
139 {
140 SANE_Word x1;
141 SANE_Byte color = 0;
142
143 if (test_device->params.depth == 1)
144 {
145 if (test_device->params.format == SANE_FRAME_GRAY ||
146 (test_device->params.format >= SANE_FRAME_RED &&
147 test_device->params.format <= SANE_FRAME_BLUE))
148 {
149 SANE_Byte value = 0;
150 for (x1 = 0; x1 < 8; x1++)
151 {
152 SANE_Word xfull = x * 8 + (7 - x1);
153
154 if (xfull < ppl)
155 {
156 if ((((SANE_Word) (xfull / p_size)) % 2)
157 ^ (!(line_count >
158 (SANE_Word) (p_size + 0.5))))
159 color = 0x0;
160 else
161 color = 0x1;
162 }
163 else
164 color = (rand ()) & 0x01;
165 value |= (SANE_Byte) (color << x1);
166 }
167 b[line_count * bpl + x] = value;
168 }
169 else /* SANE_FRAME_RGB */
170 {
171 SANE_Byte value = 0;
172 for (x1 = 0; x1 < 8; x1++)
173 {
174 SANE_Word xfull = x * 8 / 3 + (7 - x1);
175
176 if (xfull < ppl)
177 {
178 if (((SANE_Word) (xfull / p_size) % 2)
179 ^ (line_count > (SANE_Word) (p_size + 0.5)))
180 color = 0x0;
181 else
182 color = 0x1;
183 }
184 else
185 color = (rand ()) & 0x01;
186 value |= (SANE_Byte) (color << x1);
187 }
188 for (x1 = 0; x1 < increment; x1++)
189 b[line_count * bpl + x + x1] = value;
190 }
191 }
192 else /* depth = 8, 16 */
193 {
194 if (x / increment < ppl)
195 if ((((SANE_Int) (x / increment / p_size)) % 2)
196 ^ (line_count > (SANE_Int) (p_size + 0.5)))
197 color = 0x00;
198 else
199 color = 0xff;
200 else
201 color = (SANE_Byte) ((rand ()) & 0xff);
202
203 for (x1 = 0; x1 < increment; x1++)
204 b[line_count * bpl + x + x1] = color;
205 }
206 }
207 }
208 return SANE_STATUS_GOOD;
209 }
210
211 /* Color patterns */
212 if (test_device->params.format == SANE_FRAME_GRAY
213 && test_device->params.depth == 1)
214 {
215 /* 1 bit black/white */
216 pattern_size = 16;
217 pattern_distance = 0;
218 lines = 2 * (pattern_size + pattern_distance);
219 b_size = (size_t) lines * (size_t) bpl;
220
221 if (buffer_size)
222 *buffer_size = b_size;
223 b = malloc (b_size);
224 if (!b)
225 {
226 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
227 return SANE_STATUS_NO_MEM;
228 }
229 if (buffer)
230 *buffer = b;
231 DBG (3, "(child) init_picture_buffer: drawing b/w test picture "
232 "%zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
233 memset (b, 255, b_size);
234 for (line_count = 0; line_count < lines; line_count++)
235 {
236 SANE_Word x = 0;
237
238 if (line_count >= lines / 2)
239 x += (pattern_size + pattern_distance) / 8;
240
241 while (x < bpl)
242 {
243 SANE_Word width;
244
245 width = pattern_size / 8;
246 if (x + width >= bpl)
247 width = bpl - x;
248 memset (b + line_count * bpl + x, 0x00, (size_t) width);
249 x += (pattern_size + pattern_distance) * 2 / 8;
250 }
251 }
252 }
253 else if (test_device->params.format == SANE_FRAME_GRAY
254 && test_device->params.depth == 8)
255 {
256 /* 8 bit gray */
257 pattern_size = 4;
258 pattern_distance = 1;
259 lines = 2 * (pattern_size + pattern_distance);
260 b_size = (size_t) lines * (size_t) bpl;
261
262 if (buffer_size)
263 *buffer_size = b_size;
264 b = malloc (b_size);
265 if (!b)
266 {
267 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
268 return SANE_STATUS_NO_MEM;
269 }
270 if (buffer)
271 *buffer = b;
272 DBG (3, "(child) init_picture_buffer: drawing 8 bit gray test picture "
273 "%zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
274 memset (b, 0x55, b_size);
275 for (line_count = 0; line_count < lines; line_count++)
276 {
277 SANE_Word x = pattern_distance;
278
279 if (line_count % (pattern_size + pattern_distance)
280 < pattern_distance)
281 continue;
282
283 while (x < bpl)
284 {
285 SANE_Word width;
286 SANE_Byte color;
287
288 width = pattern_size;
289 if (x + width >= bpl)
290 width = bpl - x;
291 if (line_count > (pattern_size + pattern_distance))
292 color =
293 (SANE_Byte) (0xff - ((x / (pattern_size + pattern_distance)) & 0xff));
294 else
295 color = (SANE_Byte) ((x / (pattern_size + pattern_distance)) & 0xff);
296 memset (b + line_count * bpl + x, color, (size_t) width);
297 x += (pattern_size + pattern_distance);
298 }
299 }
300
301 }
302 else if (test_device->params.format == SANE_FRAME_GRAY
303 && test_device->params.depth == 16)
304 {
305 /* 16 bit gray */
306 pattern_size = 256;
307 pattern_distance = 4;
308 lines = 1 * (pattern_size + pattern_distance);
309 b_size = (size_t) lines * (size_t) bpl;
310
311 if (buffer_size)
312 *buffer_size = b_size;
313 b = malloc (b_size);
314 if (!b)
315 {
316 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
317 return SANE_STATUS_NO_MEM;
318 }
319 if (buffer)
320 *buffer = b;
321 DBG (3, "(child) init_picture_buffer: drawing 16 bit gray test picture "
322 "%zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
323 memset (b, 0x55, b_size);
324 for (line_count = 0; line_count < lines; line_count++)
325 {
326 SANE_Word x = pattern_distance * 2;
327
328 if (line_count % (pattern_size + pattern_distance)
329 < pattern_distance)
330 continue;
331
332 while (x < bpl)
333 {
334 SANE_Word width;
335 SANE_Word x1;
336 SANE_Byte pattern_lo, pattern_hi;
337
338 width = pattern_size * 2;
339 if (x + width >= bpl)
340 width = bpl - x;
341 pattern_lo =
342 (SANE_Byte) (((line_count - pattern_distance)
343 % (pattern_size + pattern_distance)) & 0xff);
344 for (x1 = 0; x1 < width; x1 += 2)
345 {
346 pattern_hi = (SANE_Byte) ((x1 / 2) & 0xff);
347 if (is_little_endian)
348 {
349 b[line_count * bpl + x + x1 + 0] = pattern_lo;
350 b[line_count * bpl + x + x1 + 1] = pattern_hi;
351 }
352 else
353 {
354 b[line_count * bpl + x + x1 + 0] = pattern_hi;
355 b[line_count * bpl + x + x1 + 1] = pattern_lo;
356 }
357 }
358 x += ((pattern_size + pattern_distance) * 2);
359 }
360 }
361
362 }
363 else if (test_device->params.format == SANE_FRAME_RGB
364 && test_device->params.depth == 1)
365 {
366 /* 1 bit color */
367 pattern_size = 16;
368 pattern_distance = 0;
369 lines = 2 * (pattern_size + pattern_distance);
370 b_size = (size_t) lines * (size_t) bpl;
371
372 if (buffer_size)
373 *buffer_size = b_size;
374 b = malloc (b_size);
375 if (!b)
376 {
377 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
378 return SANE_STATUS_NO_MEM;
379 }
380 if (buffer)
381 *buffer = b;
382 DBG (3, "(child) init_picture_buffer: drawing color lineart test "
383 "picture %zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
384 memset (b, 0x55, b_size);
385
386 for (line_count = 0; line_count < lines; line_count++)
387 {
388 SANE_Word x = 0;
389 SANE_Byte color = 0, color_r = 0, color_g = 0, color_b = 0;
390
391 if (line_count >= lines / 2)
392 color = 7;
393 while (x < bpl)
394 {
395 SANE_Word width;
396 SANE_Word x2 = 0;
397
398 width = pattern_size / 8 * 3;
399 if (x + width >= bpl)
400 width = bpl - x;
401
402 color_b = (color & 1) * 0xff;
403 color_g = ((color >> 1) & 1) * 0xff;
404 color_r = ((color >> 2) & 1) * 0xff;
405
406 for (x2 = 0; x2 < width; x2 += 3)
407 {
408 b[line_count * bpl + x + x2 + 0] = color_r;
409 b[line_count * bpl + x + x2 + 1] = color_g;
410 b[line_count * bpl + x + x2 + 2] = color_b;
411 }
412 if (line_count < lines / 2)
413 {
414 ++color;
415 if (color >= 8)
416 color = 0;
417 }
418 else
419 {
420 if (color == 0)
421 color = 8;
422 --color;
423 }
424 x += ((pattern_size + pattern_distance) / 8 * 3);
425 }
426 }
427 }
428 else if ((test_device->params.format == SANE_FRAME_RED
429 || test_device->params.format == SANE_FRAME_GREEN
430 || test_device->params.format == SANE_FRAME_BLUE)
431 && test_device->params.depth == 1)
432 {
433 /* 1 bit color three-pass */
434 pattern_size = 16;
435 pattern_distance = 0;
436 lines = 2 * (pattern_size + pattern_distance);
437 b_size = (size_t) lines * (size_t) bpl;
438
439 if (buffer_size)
440 *buffer_size = b_size;
441 b = malloc (b_size);
442 if (!b)
443 {
444 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
445 return SANE_STATUS_NO_MEM;
446 }
447 if (buffer)
448 *buffer = b;
449 DBG (3, "(child) init_picture_buffer: drawing color lineart three-pass "
450 "test picture %zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
451 memset (b, 0x55, b_size);
452
453 for (line_count = 0; line_count < lines; line_count++)
454 {
455 SANE_Word x = 0;
456 SANE_Byte color = 0, color_r = 0, color_g = 0, color_b = 0;
457
458 if (line_count >= lines / 2)
459 color = 7;
460 while (x < bpl)
461 {
462 SANE_Word width;
463 SANE_Word x2 = 0;
464
465 width = pattern_size / 8;
466 if (x + width >= bpl)
467 width = bpl - x;
468
469 color_b = (color & 1) * 0xff;
470 color_g = ((color >> 1) & 1) * 0xff;
471 color_r = ((color >> 2) & 1) * 0xff;
472
473 for (x2 = 0; x2 < width; x2++)
474 {
475 if (test_device->params.format == SANE_FRAME_RED)
476 b[line_count * bpl + x + x2] = color_r;
477 else if (test_device->params.format == SANE_FRAME_GREEN)
478 b[line_count * bpl + x + x2] = color_g;
479 else
480 b[line_count * bpl + x + x2] = color_b;
481 }
482 if (line_count < lines / 2)
483 {
484 ++color;
485 if (color >= 8)
486 color = 0;
487 }
488 else
489 {
490 if (color == 0)
491 color = 8;
492 --color;
493 }
494 x += (pattern_size + pattern_distance) / 8;
495 }
496 }
497 }
498 else if (test_device->params.format == SANE_FRAME_RGB
499 && test_device->params.depth == 8)
500 {
501 /* 8 bit color */
502 pattern_size = 4;
503 pattern_distance = 1;
504 lines = 6 * (pattern_size + pattern_distance);
505 b_size = (size_t) lines * (size_t) bpl;
506
507 if (buffer_size)
508 *buffer_size = b_size;
509 b = malloc (b_size);
510 if (!b)
511 {
512 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
513 return SANE_STATUS_NO_MEM;
514 }
515 if (buffer)
516 *buffer = b;
517 DBG (3, "(child) init_picture_buffer: drawing 8 bit color test picture "
518 "%zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
519 memset (b, 0x55, b_size);
520 for (line_count = 0; line_count < lines; line_count++)
521 {
522 SANE_Word x = pattern_distance * 3;
523
524 if (line_count % (pattern_size + pattern_distance)
525 < pattern_distance)
526 continue;
527
528 while (x < bpl)
529 {
530 SANE_Word width;
531 SANE_Byte color = 0, color_r = 0, color_g = 0, color_b = 0;
532 SANE_Word x1;
533
534 width = pattern_size * 3;
535 if (x + width >= bpl)
536 width = bpl - x;
537
538 if ((line_count / (pattern_size + pattern_distance)) & 1)
539 color =
540 (SANE_Byte) (0xff - ((x / ((pattern_size + pattern_distance) * 3))
541 & 0xff));
542 else
543 color = (SANE_Byte) ((x / ((pattern_size + pattern_distance) * 3)) & 0xff);
544
545 if (line_count / (pattern_size + pattern_distance) < 2)
546 {
547 color_r = color;
548 color_g = 0;
549 color_b = 0;
550 }
551 else if (line_count / (pattern_size + pattern_distance) < 4)
552 {
553 color_r = 0;
554 color_g = color;
555 color_b = 0;
556 }
557 else
558 {
559 color_r = 0;
560 color_g = 0;
561 color_b = color;
562 }
563
564 for (x1 = 0; x1 < width; x1 += 3)
565 {
566 b[line_count * bpl + x + x1 + 0] = color_r;
567 b[line_count * bpl + x + x1 + 1] = color_g;
568 b[line_count * bpl + x + x1 + 2] = color_b;
569 }
570
571 x += ((pattern_size + pattern_distance) * 3);
572 }
573 }
574
575 }
576 else if ((test_device->params.format == SANE_FRAME_RED
577 || test_device->params.format == SANE_FRAME_GREEN
578 || test_device->params.format == SANE_FRAME_BLUE)
579 && test_device->params.depth == 8)
580 {
581 /* 8 bit color three-pass */
582 pattern_size = 4;
583 pattern_distance = 1;
584 lines = 6 * (pattern_size + pattern_distance);
585 b_size = (size_t) lines * (size_t) bpl;
586
587 if (buffer_size)
588 *buffer_size = b_size;
589 b = malloc (b_size);
590 if (!b)
591 {
592 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
593 return SANE_STATUS_NO_MEM;
594 }
595 if (buffer)
596 *buffer = b;
597 DBG (3, "(child) init_picture_buffer: drawing 8 bit color three-pass "
598 "test picture %zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
599 memset (b, 0x55, b_size);
600 for (line_count = 0; line_count < lines; line_count++)
601 {
602 SANE_Word x = pattern_distance;
603
604 if (line_count % (pattern_size + pattern_distance)
605 < pattern_distance)
606 continue;
607
608 while (x < bpl)
609 {
610 SANE_Word width;
611 SANE_Byte color = 0;
612
613 width = pattern_size;
614 if (x + width >= bpl)
615 width = bpl - x;
616
617 if ((line_count / (pattern_size + pattern_distance)) & 1)
618 color = (SANE_Byte)
619 (0xff - (x / ((pattern_size + pattern_distance)) & 0xff));
620 else
621 color = (SANE_Byte) ((x / (pattern_size + pattern_distance)) & 0xff);
622
623 if (line_count / (pattern_size + pattern_distance) < 2)
624 {
625 if (test_device->params.format != SANE_FRAME_RED)
626 color = 0x00;
627 }
628 else if (line_count / (pattern_size + pattern_distance) < 4)
629 {
630 if (test_device->params.format != SANE_FRAME_GREEN)
631 color = 0x00;
632 }
633 else
634 {
635 if (test_device->params.format != SANE_FRAME_BLUE)
636 color = 0x00;
637 }
638 memset (b + line_count * bpl + x, color, (size_t) width);
639
640 x += (pattern_size + pattern_distance);
641 }
642 }
643 }
644 else if (test_device->params.format == SANE_FRAME_RGB
645 && test_device->params.depth == 16)
646 {
647 /* 16 bit color */
648 pattern_size = 256;
649 pattern_distance = 4;
650 lines = pattern_size + pattern_distance;
651 b_size = (size_t) lines * (size_t) bpl;
652
653 if (buffer_size)
654 *buffer_size = b_size;
655 b = malloc (b_size);
656 if (!b)
657 {
658 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
659 return SANE_STATUS_NO_MEM;
660 }
661 if (buffer)
662 *buffer = b;
663 DBG (3,
664 "(child) init_picture_buffer: drawing 16 bit color test picture "
665 "%zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
666 memset (b, 0x55, b_size);
667 for (line_count = 0; line_count < lines; line_count++)
668 {
669 SANE_Word x = pattern_distance * 2 * 3;
670
671 if (line_count % (pattern_size + pattern_distance)
672 < pattern_distance)
673 continue;
674
675 while (x < bpl)
676 {
677 SANE_Word width;
678 SANE_Word x1;
679 SANE_Byte color_hi = 0, color_lo = 0;
680 SANE_Byte color_hi_r = 0, color_lo_r = 0;
681 SANE_Byte color_hi_g = 0, color_lo_g = 0;
682 SANE_Byte color_hi_b = 0, color_lo_b = 0;
683
684 width = pattern_size * 2 * 3;
685 if (x + width >= bpl)
686 width = bpl - x;
687
688
689 for (x1 = 0; x1 < width; x1 += 6)
690 {
691 color_lo = (SANE_Byte)
692 (((line_count + pattern_size)
693 % (pattern_size + pattern_distance)) & 0xff);
694 color_hi = (SANE_Byte) ((x1 / 6) & 0xff);
695 if (((x / ((pattern_size + pattern_distance) * 6)) % 3) ==
696 0)
697 {
698 color_lo_r = color_lo;
699 color_hi_r = color_hi;
700 color_lo_g = 0;
701 color_hi_g = 0;
702 color_lo_b = 0;
703 color_hi_b = 0;
704 }
705 else if (((x / ((pattern_size + pattern_distance) * 6)) % 3)
706 == 1)
707 {
708 color_lo_r = 0;
709 color_hi_r = 0;
710 color_lo_g = color_lo;
711 color_hi_g = color_hi;
712 color_lo_b = 0;
713 color_hi_b = 0;
714 }
715 else
716 {
717 color_lo_r = 0;
718 color_hi_r = 0;
719 color_lo_g = 0;
720 color_hi_g = 0;
721 color_lo_b = color_lo;
722 color_hi_b = color_hi;
723 }
724 if (is_little_endian)
725 {
726 b[line_count * bpl + x + x1 + 0] = color_lo_r;
727 b[line_count * bpl + x + x1 + 1] = color_hi_r;
728 b[line_count * bpl + x + x1 + 2] = color_lo_g;
729 b[line_count * bpl + x + x1 + 3] = color_hi_g;
730 b[line_count * bpl + x + x1 + 4] = color_lo_b;
731 b[line_count * bpl + x + x1 + 5] = color_hi_b;
732 }
733 else
734 {
735 b[line_count * bpl + x + x1 + 0] = color_hi_r;
736 b[line_count * bpl + x + x1 + 1] = color_lo_r;
737 b[line_count * bpl + x + x1 + 2] = color_hi_g;
738 b[line_count * bpl + x + x1 + 3] = color_lo_g;
739 b[line_count * bpl + x + x1 + 4] = color_hi_b;
740 b[line_count * bpl + x + x1 + 5] = color_lo_b;
741 }
742 }
743 x += ((pattern_size + pattern_distance) * 2 * 3);
744 }
745 }
746
747 }
748 else if ((test_device->params.format == SANE_FRAME_RED
749 || test_device->params.format == SANE_FRAME_GREEN
750 || test_device->params.format == SANE_FRAME_BLUE)
751 && test_device->params.depth == 16)
752 {
753 /* 16 bit color three-pass */
754 pattern_size = 256;
755 pattern_distance = 4;
756 lines = pattern_size + pattern_distance;
757 b_size = (size_t) lines * (size_t) bpl;
758
759 if (buffer_size)
760 *buffer_size = b_size;
761 b = malloc (b_size);
762 if (!b)
763 {
764 DBG (1, "(child) init_picture_buffer: couldn't malloc buffer\n");
765 return SANE_STATUS_NO_MEM;
766 }
767 if (buffer)
768 *buffer = b;
769 DBG (3, "(child) init_picture_buffer: drawing 16 bit color three-pass "
770 "test picture %zu bytes, %d bpl, %d lines\n", b_size, bpl, lines);
771 memset (b, 0x55, b_size);
772 for (line_count = 0; line_count < lines; line_count++)
773 {
774 SANE_Word x = pattern_distance * 2;
775
776 if (line_count % (pattern_size + pattern_distance)
777 < pattern_distance)
778 continue;
779
780 while (x < bpl)
781 {
782 SANE_Word width;
783 SANE_Word x1;
784 SANE_Byte color_hi = 0, color_lo = 0;
785
786 width = pattern_size * 2;
787 if (x + width >= bpl)
788 width = bpl - x;
789
790
791 for (x1 = 0; x1 < width; x1 += 2)
792 {
793 color_lo = (SANE_Byte)
794 (((line_count + pattern_size)
795 % (pattern_size + pattern_distance)) & 0xff);
796 color_hi = (SANE_Byte) ((x1 / 2) & 0xff);
797 if (((x / ((pattern_size + pattern_distance) * 2)) % 3) ==
798 0)
799 {
800 if (test_device->params.format != SANE_FRAME_RED)
801 {
802 color_lo = 0x00;
803 color_hi = 0x00;
804 }
805 }
806 else if (((x / ((pattern_size + pattern_distance) * 2)) % 3)
807 == 1)
808 {
809 if (test_device->params.format != SANE_FRAME_GREEN)
810 {
811 color_lo = 0x00;
812 color_hi = 0x00;
813 }
814 }
815 else
816 {
817 if (test_device->params.format != SANE_FRAME_BLUE)
818 {
819 color_lo = 0x00;
820 color_hi = 0x00;
821 }
822 }
823
824 if (is_little_endian)
825 {
826 b[line_count * bpl + x + x1 + 0] = color_lo;
827 b[line_count * bpl + x + x1 + 1] = color_hi;
828 }
829 else
830 {
831 b[line_count * bpl + x + x1 + 0] = color_hi;
832 b[line_count * bpl + x + x1 + 1] = color_lo;
833 }
834
835 }
836 x += ((pattern_size + pattern_distance) * 2);
837 }
838 }
839
840 }
841 else /* Huh? */
842 {
843 DBG (1, "(child) init_picture_buffer: unknown mode\n");
844 return SANE_STATUS_INVAL;
845 }
846
847 return SANE_STATUS_GOOD;
848 }
849