|
|
1.1 root 1: #include "I_lut.h"
2:
3: #define MAX 4096 /* max no of 16bit words per read */
4:
5: /*
6: set, on the scanner console:
7: off normalization (N menu) (press 'N' <enter>)
8: off log lookup tables (N menu)
9: ON log circuit (N menu)
10: off historical calibration (H menu)
11: */
12:
13: #define IMRESET (('i'<<8)|1)
14: #define IMWAIT (('i'<<8)|2)
15:
16: int printf; /* andrew doesn't like printf */
17:
18: int SCALE = 4; /* reduction factor of 4 */
19: int LENS = 0; /* defaults to 8.5 inch lens */
20: int TRANS = 0; /* reflection scanning is default */
21: int ALLOC = 0; /* pre-allocate memory */
22: int correct = 0;
23:
24: Usage()
25: {
26: print("usage: imscan [-sN] [-lN] [-t] [-r] file\n");
27: print("\t-sN reduction factor N:[1-9] (default is 4)\n");
28: print("\t-lN N=5 for 5 inch lens; N=8 for 8.5 inch lens\n");
29: print("\t 5=754 dpi, 8=480 dpi (the default is 8)\n");
30: print("\t-t transmission (glass plate)\n");
31: print("\t-r reflection (metal plate - default)\n");
32: print("\t-n apply image correction\n");
33: print("\t-aN pre-allocate for an Nbyte (N=wxh) image\n");
34: exit(1);
35: }
36:
37: main(argc, argv)
38: char **argv;
39: { int fd, ofd;
40:
41: while (argc > 1 && argv[1][0] == '-')
42: { switch (argv[1][1]) {
43: case 's': if (argv[1][2] < '1' || argv[1][2] > '9')
44: Usage();
45: SCALE = argv[1][2] - '0';
46: break;
47: case 'l': if (argv[1][2] != '5' && argv[1][2] != '8')
48: Usage();
49: LENS = (argv[1][2] == '5');
50: break;
51: case 't': TRANS = 1; break;
52: case 'r': TRANS = 0; break;
53: case 'n': correct = 1-correct; break;
54: case 'a': if (argv[1][2] < '1' || argv[1][2] > '9')
55: Usage();
56: ALLOC = atoi(&argv[1][2]);
57: break;
58: default : Usage();
59: }
60: argc--; argv++;
61: }
62: if (argc < 2)
63: Usage();
64:
65: print("reduction factor %d, ", SCALE);
66: print("%s lens, ", (LENS)?"5 inch":"8.5 inch");
67: print("%s scan, ", (TRANS)?"transmission":"reflection");
68: print("image file: %s\n", argv[1]);
69:
70: if ((fd = open("/dev/im0", 2)) < 0)
71: { perror("/dev/im0");
72: exit(1);
73: }
74: if ((ofd = creat(argv[1], 0666)) < 0)
75: { perror(argv[1]);
76: exit(1);
77: }
78: seticonfig(fd);
79: setmodes(fd);
80: scan(fd, ofd);
81:
82: exit(0);
83: }
84:
85: scan(fd, ofd)
86: { unsigned short buf1[32], buf2[32];
87: int tpix, mode, npix, nlin, spl, NLINES;
88: char *im, *sim, *malloc();
89: register char *pim;
90: register int n, tlin;
91:
92: if (ALLOC)
93: pim = im = (char *) malloc(ALLOC);
94:
95: print("scan preliminaries\n");
96: buf1[0] = 0x100; /* manual swab */
97: buf1[1] = 0x400; /* SCAN1START swabbed */
98:
99: if (write(fd, buf1, 4) != 4) { perror("write"); return; }
100: if (ioctl(fd, IMWAIT) < 0) { perror("imwait1"); return; }
101: if (read(fd, buf1, 12) != 12) { perror("read"); return; }
102:
103: swab(&buf1[1], buf2, 10);
104:
105: npix = (int) buf2[2];
106: nlin = (int) buf2[3];
107: mode = (int) buf2[4];
108:
109: buf1[0] = 5;
110: buf1[1] = 5; /* SCAN2START */
111: buf1[2] = SCALE*256; /* XSCALE */
112: buf1[3] = SCALE*256; /* YSCALE */
113: buf1[4] = 0; /* no run length encoding */
114: buf1[5] = 0; /* no pixel replication */
115: swab(buf1, buf2, 12);
116:
117: if (write(fd, buf2, 12) != 12) { perror("scan2 write"); return; }
118: if (read(fd, buf1, 12) != 12) { perror("scan2 read"); return; }
119:
120: swab(&buf1[1], buf2, 10);
121:
122: tpix = (int) buf2[2];
123: tlin = (int) buf2[3];
124: mode = (int) buf2[4];
125:
126: spl = (tpix+15)/16; /* line size, in 16-bit words */
127: spl *= 8; /* one byte per pixel */
128: NLINES = MAX/spl;
129: n = (NLINES*spl+3)*2; /* no of bytes to read per chunk */
130:
131: print("%dx%d -> %dx%d pixel\n", npix, nlin, 2*spl, tlin);
132: if (mode != 2) { print("error: not in b&w mode\n"); return; }
133: if (NLINES<=0) { print("error: line too wide\n"); return; }
134:
135: if (ALLOC == 0)
136: pim = im = (char *) malloc(npix*tlin); /* was n*tlin */
137: else
138: { if (npix*tlin > ALLOC)
139: { print("error: not enough memory allocated %d != %d*%d\n",
140: ALLOC, n, tlin);
141: return;
142: }
143: }
144:
145: buf1[0] = 2;
146: buf1[1] = 7;
147: buf1[2] = NLINES*spl;
148: swab(buf1, buf2, 6);
149:
150: for (tlin = 0; ; tlin++)
151: { if (write(fd, buf2, 6) != 6) { perror("!reset scanner"); break; }
152: if (read(fd, pim, n) != n) break;
153: pim += n;
154: }
155:
156: header(ofd, 2*spl, tlin*NLINES);
157: if (correct)
158: { register int j;
159: print("image correction...\n");
160: pim = im+6;
161: if (TRANS)
162: for (j = tlin*n; j > 0; j--, pim++)
163: *pim = 255 - *pim;
164: else
165: for (j = tlin*n; j > 0; j--, pim++)
166: *pim = cor_refl[*pim];
167: }
168: sim = im+6;
169: while (tlin-- > 0)
170: { write(ofd, sim, n-6);
171: sim += n;
172: }
173: return;
174: }
175:
176: header(ofd, a, b)
177: {
178: Fprint(ofd, "TYPE=dump\nWINDOW=0 0 %d %d\nNCHAN=1\n", a, b);
179: Fprint(ofd, "COMMAND=imscan -s%d ", SCALE);
180: if (!correct) Fprint(ofd, "-n ");
181: Fprint(ofd, "-l%d -%c\n\n", (LENS)?5:8, (TRANS)?'t':'r');
182: Fflush(ofd);
183: }
184:
185: seticonfig(fd)
186: { unsigned short buf1[7], buf2[7];
187:
188: buf1[0] = 6;
189: buf1[1] = 1; /* SETIMAGECONFIG */
190: buf1[2] = 4; /* nparams */
191: buf1[3] = 0; /* line art*/
192: buf1[4] = 0; /* bw */
193: buf1[5] = 24; /* colour */
194: buf1[6] = 40; /* speed (40-500) 80 is about as fast as you can go */
195: swab(buf1, buf2, 14);
196: if (write(fd, buf2, 14) != 14)
197: { perror("seticonfig write");
198: return;
199: }
200: if (read(fd, buf1, 6) != 6)
201: { perror("seticonfig read");
202: return;
203: }
204: }
205:
206: setmodes(fd)
207: { unsigned short buf1[7], buf2[7];
208:
209: buf1[0] = 6;
210: buf1[1] = 21; /* SETMODES */
211: buf1[2] = LENS; /* 1 = 5 inch, 0 = 8.5 inch lens */
212: buf1[3] = 0; /* line art (0=cont tone, 1=line art) */
213: buf1[4] = TRANS; /* 0=reflection, 1=transmission */
214: buf1[5] = 1; /* b/w */
215: buf1[6] = 1; /* autoscan */
216: swab(buf1, buf2, 14);
217: if (write(fd, buf2, 14) != 14)
218: { perror("setmodes write");
219: return;
220: }
221: if (read(fd, buf1, 6) != 6)
222: { perror("setmodes read");
223: return;
224: }
225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.