home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3514 < prev    next >
Internet Message Format  |  1991-06-19  |  41KB

  1. From: gunnar@falcon.ericsson.se (Was a Sunny day)
  2. Newsgroups: alt.sources
  3. Subject: Scantool part 3(5)  (shar)
  4. Message-ID: <1991Jun18.124732.11195@ericsson.se>
  5. Date: 18 Jun 91 12:47:32 GMT
  6.  
  7. #!/bin/sh
  8. # this is scan.03 (part 3 of a multipart archive)
  9. # do not concatenate these parts, unpack them in order with /bin/sh
  10. # file notify.h continued
  11. #
  12. if test ! -r _shar_seq_.tmp; then
  13.     echo 'Please unpack part 1 first!'
  14.     exit 1
  15. fi
  16. (read Scheck
  17.  if test "$Scheck" != 3; then
  18.     echo Please unpack part "$Scheck" next!
  19.     exit 1
  20.  else
  21.     exit 0
  22.  fi
  23. ) < _shar_seq_.tmp || exit 1
  24. if test ! -f _shar_wnt_.tmp; then
  25.     echo 'x - still skipping notify.h'
  26. else
  27. echo 'x - continuing file notify.h'
  28. sed 's/^X//' << 'SHAR_EOF' >> 'notify.h' &&
  29. EXTERN_FUNCTION (Notify_error     notify_remove_exception_func, (Notify_client nclient, Notify_func func, int fd));
  30. EXTERN_FUNCTION (Notify_error    notify_remove_input_func, (Notify_client nclient, Notify_func func, int fd));
  31. EXTERN_FUNCTION (Notify_error     notify_remove_itimer_func, (Notify_client nclient, Notify_func func, int which));
  32. EXTERN_FUNCTION (Notify_error    notify_remove_output_func, (Notify_client nclient, Notify_func func, int fd));
  33. EXTERN_FUNCTION (Notify_error     notify_remove_signal_func, (Notify_client nclient, Notify_func func, int signal, Notify_signal_mode mode));
  34. EXTERN_FUNCTION (Notify_error     notify_remove_wait3_func, (Notify_client nclient, Notify_func func, int pid));
  35. EXTERN_FUNCTION (Notify_func     notify_set_prioritizer_func, (Notify_client nclient, Notify_func func));
  36. EXTERN_FUNCTION (Notify_func     notify_set_scheduler_func, (Notify_func nclient));
  37. EXTERN_FUNCTION (Notify_error     notify_signal, (Notify_client nclient, int sig));
  38. EXTERN_FUNCTION (Notify_error     notify_wait3, (Notify_client nclient));
  39. X
  40. extern    Notify_error    notify_errno;
  41. X
  42. /*
  43. X * FD manipulation functions
  44. X */
  45. X
  46. EXTERN_FUNCTION (int         ntfy_fd_cmp_and, (fd_set *a, fd_set *b));
  47. EXTERN_FUNCTION (int         ntfy_fd_cmp_or, (fd_set *a, fd_set *b));
  48. EXTERN_FUNCTION (int         ntfy_fd_anyset, (fd_set *a));
  49. EXTERN_FUNCTION (fd_set *    ntfy_fd_cpy_or, (fd_set *a, fd_set *b));
  50. EXTERN_FUNCTION (fd_set *    ntfy_fd_cpy_and, (fd_set *a, fd_set *b));
  51. EXTERN_FUNCTION (fd_set *    ntfy_fd_cpy_xor, (fd_set *a, fd_set *b));
  52. X
  53. /*
  54. X * Debugging Utility 
  55. X */
  56. X
  57. EXTERN_FUNCTION (void         notify_dump, (Notify_client nclient, Notify_dump_type type, FILE * file));
  58. X
  59. #endif ~_NOTIFY_MIN_SYMBOLS
  60. X
  61. #endif    xview_notify_DEFINED
  62. SHAR_EOF
  63. echo 'File notify.h is complete' &&
  64. chmod 0644 notify.h ||
  65. echo 'restore of notify.h failed'
  66. Wc_c="`wc -c < 'notify.h'`"
  67. test 12908 -eq "$Wc_c" ||
  68.     echo 'notify.h: original size 12908, current size' "$Wc_c"
  69. rm -f _shar_wnt_.tmp
  70. fi
  71. # ============= patchlevel.h ==============
  72. if test -f 'patchlevel.h' -a X"$1" != X"-c"; then
  73.     echo 'x - skipping patchlevel.h (File already exists)'
  74.     rm -f _shar_wnt_.tmp
  75. else
  76. > _shar_wnt_.tmp
  77. echo 'x - extracting patchlevel.h (Text)'
  78. sed 's/^X//' << 'SHAR_EOF' > 'patchlevel.h' &&
  79. X
  80. /*  @(#)patchlevel.h 1.4 90/04/10
  81. X *
  82. X *  Current patchlevel for this version of scantool.
  83. X *
  84. X *  Copyright (c) Rich Burridge.
  85. X *                Sun Microsystems, Australia - All rights reserved.
  86. X *
  87. X *  Permission is given to distribute these sources, as long as the
  88. X *  copyright messages are not removed, and no monies are exchanged.
  89. X *
  90. X *  No responsibility is taken for any errors or inaccuracies inherent
  91. X *  either to the comments or the code of this program, but if
  92. X *  reported to me, then an attempt will be made to fix them.
  93. X */
  94. X
  95. #define  PATCHLEVEL  3
  96. SHAR_EOF
  97. chmod 0644 patchlevel.h ||
  98. echo 'restore of patchlevel.h failed'
  99. Wc_c="`wc -c < 'patchlevel.h'`"
  100. test 563 -eq "$Wc_c" ||
  101.     echo 'patchlevel.h: original size 563, current size' "$Wc_c"
  102. rm -f _shar_wnt_.tmp
  103. fi
  104. # ============= scan.1 ==============
  105. if test -f 'scan.1' -a X"$1" != X"-c"; then
  106.     echo 'x - skipping scan.1 (File already exists)'
  107.     rm -f _shar_wnt_.tmp
  108. else
  109. > _shar_wnt_.tmp
  110. echo 'x - extracting scan.1 (Text)'
  111. sed 's/^X//' << 'SHAR_EOF' > 'scan.1' &&
  112. .\" @(#)scan.1 1.3 90/04/03
  113. .TH SCAN 1L "2 April 1990"
  114. .SH NAME
  115. scan \- a batch type program to scan images using a Microtek MS300A scanner.
  116. .SH SYNOPSIS
  117. .B "scan
  118. [
  119. .B -b
  120. .I brightness
  121. ]
  122. [
  123. .B -c
  124. .I contrast
  125. ]
  126. [
  127. .B -d
  128. .I "data transfer mode"
  129. ]
  130. [
  131. .B -f
  132. .I x1 y1 x2 y2
  133. ]
  134. [
  135. .B -g
  136. .I grain
  137. ]
  138. [
  139. .B -m
  140. .I mode
  141. ]
  142. [
  143. .B -p
  144. .I picname
  145. ]
  146. [
  147. .B -r
  148. .I resolution
  149. ]
  150. [
  151. .B -s
  152. .I speed
  153. ]
  154. [
  155. .B -t
  156. .I ttyport
  157. ]
  158. [
  159. .B -v
  160. ]
  161. .SH DESCRIPTION
  162. .I Scan
  163. is the program called by
  164. .I scantool
  165. to allow a user to scan a document using a Microtek MS300A scanner, and
  166. turn the resulting image into a Sun rasterfile. This program could actually
  167. be run on it's own, or through a frontend shell script, but there are a
  168. plethora of command line options that need to be passed to the program, so
  169. it is probably easier to run it automatically using
  170. .I scantool.
  171. .LP
  172. .I Scan
  173. can exit with a variety of different status values, a non zero value indicating
  174. an error of some kind. There error values are:
  175. .TP
  176. .B "1"
  177. Cannot open the tty port.
  178. .TP
  179. .B "2"
  180. Cannot open the temporary image file.
  181. .TP
  182. .B "3"
  183. Cannot open raster header file.
  184. .TP
  185. .B "4"
  186. Scanner not responding aborting this scan.
  187. .TP
  188. .B "5"
  189. Invalid command line argument.
  190. .TP
  191. .B "100 + 0xnn"
  192. Scanning error 0xnn was received from the scanner. This scan is aborted.
  193. .TP
  194. .B "200 + n"
  195. The
  196. .I scan
  197. program received signal
  198. .I n
  199. .SH OPTIONS
  200. .TP
  201. .BI \-b " brightness"
  202. Brightness value. There are 14 brightness values to choose from, ranging from
  203. 1 (-24% darker) to 14 (+28% lighter).
  204. .TP
  205. .BI \-c " contrast"
  206. Contrast value. There are 14 contrast values to choose from, ranging from
  207. 1 (-24% lower) to 14 (+28% higher).
  208. .TP
  209. .BI \-d " data transfer method"
  210. Data transfer method. This is the form in which data is transfer between
  211. the scanner and the Sun. Currently this option can take two value; 0 is
  212. uncompressed and 1 (the default) is compressed.
  213. .TP
  214. .BI \-f " x1 y1 x2 y2"
  215. Scanning frame. The frame is the area to be scanned. This option needs the
  216. two coordinate pairs; the top left of the scanning frame, and the bottom
  217. right. These values are expressed in 1/8" increments.
  218. .TP
  219. .BI \-g " grain"
  220. Grain value. There are twelve levels of grain to choose from, ranging from
  221. 0 (grain size: 8x8, grey levels: 33) to 11 (grain size: 2x2, grey levels 5).
  222. .TP
  223. .BI \-m " mode"
  224. The scanner can operate in two modes; line art mode (value 0; the default) and
  225. halftone mode (value 1).
  226. .TP
  227. .BI \-p " picname"
  228. Output picture name. This is the name of the file which will contain the
  229. scaned image in Sun rasterfile output format. By default, the name of the
  230. file in NoName.rf.
  231. .TP
  232. .BI \-r " resolution"
  233. Resolution value. There are 16 resolution values to choose from, ranging from
  234. 0 (300 dpi, scale full size) to 15 (75 dpi, scale 25%).
  235. .TP
  236. .BI \-s " speed"
  237. Speed of the serial connection between the scanner and the Sun. A value of
  238. 0 is 960 baud. A value of 1 (the default) is 1920 baud.
  239. .TP
  240. .BI \-t " tty port"
  241. This is the tty port to use. By default this is the Sun's A port (value 0).
  242. It is also possibly to use the Sun's B port (value 1).
  243. .TP
  244. .B \-v
  245. Version number of this release of the
  246. .I scan
  247. program. The third number is the current patch level.
  248. .SH FILES
  249. .TP
  250. /usr/local/lib/scantool/black.codes
  251. .TP
  252. /usr/local/lib/scantool/white.codes
  253. .SH AUTHOR
  254. Rich Burridge,        Domain: richb@Aus.Sun.COM
  255. .nf
  256. PHONE: +61 2 413 2666   Path: {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  257. .fi
  258. SHAR_EOF
  259. chmod 0644 scan.1 ||
  260. echo 'restore of scan.1 failed'
  261. Wc_c="`wc -c < 'scan.1'`"
  262. test 3375 -eq "$Wc_c" ||
  263.     echo 'scan.1: original size 3375, current size' "$Wc_c"
  264. rm -f _shar_wnt_.tmp
  265. fi
  266. # ============= scan.c ==============
  267. if test -f 'scan.c' -a X"$1" != X"-c"; then
  268.     echo 'x - skipping scan.c (File already exists)'
  269.     rm -f _shar_wnt_.tmp
  270. else
  271. > _shar_wnt_.tmp
  272. echo 'x - extracting scan.c (Text)'
  273. sed 's/^X//' << 'SHAR_EOF' > 'scan.c' &&
  274. X
  275. /*  @(#)scan.c 1.4 90/04/04
  276. X *
  277. X *  Program which will read a scanned image from a Microtek
  278. X *  MS-300A scanner and convert it to a Sun rasterfile.
  279. X *
  280. X *  Copyright (c) Rich Burridge.
  281. X *                Sun Microsystems, Australia - All rights reserved.
  282. X *
  283. X *  Permission is given to distribute these sources, as long as the
  284. X *  copyright messages are not removed, and no monies are exchanged.
  285. X *
  286. X *  No responsibility is taken for any errors or inaccuracies inherent
  287. X *  either to the comments or the code of this program, but if
  288. X *  reported to me, then an attempt will be made to fix them.
  289. X */
  290. X
  291. #include <stdio.h>
  292. #include <strings.h>
  293. #include <signal.h>
  294. #include <sgtty.h>
  295. #include <rasterfile.h>
  296. #include <sys/time.h>
  297. #include <sys/types.h>
  298. #include "patchlevel.h"
  299. #include "scan.h"
  300. X
  301. char cksum ;               /* Packets checksum. */
  302. char cntbytes ;            /* Number of count bytes received. */
  303. char finalimage[MAXLINE] ; /* Name of uncompressed image file. */
  304. char from_rs[BUFSIZE] ;    /* Data received from the RS232. */
  305. char line[MAXLINE] ;
  306. char picname[MAXLINE] ;    /* Picture name for rasterfile output. */
  307. char progname[MAXLINE] ;   /* Name of this program. */
  308. char rscksum ;             /* RS232 read packet checksum. */
  309. char rsdata[BUFSIZE] ;     /* Latest packet to/from the scanner. */
  310. char rsrhold = XON ;       /* RS232 host hand shaking state. */
  311. char rsrstate = RSSOR ;    /* State of RS232 read automation. */
  312. char rsrtype ;             /* Record type received. */
  313. char rswstate ;            /* RS232 write acknowledgement state. */
  314. char scantype[MAXLINE] ;   /* Scanner details. */
  315. char temphead[MAXLINE] ;   /* Temporary filename for header file. */
  316. char tempimage[MAXLINE] ;  /* Temporary filename for saved scanned data. */
  317. X
  318. int brightness ;           /* Brightness value. */
  319. int cancel ;               /* Indicates if should cancel current scan. */
  320. int complete ;             /* Indicates if scanning is completed. */
  321. int contrast ;             /* Contrast value. */
  322. int error ;                /* Has an error report has been received? */
  323. int fd = -1 ;              /* File descriptor for RS232 line. */
  324. int finished ;             /* Indicates if we have finished uncompressing. */
  325. int fwidth ;               /* Final width of rasterfile. */
  326. int height ;               /* Height in scan lines of raster file image. */
  327. int pic_compressed = 0 ;   /* Whether any picture data was compressed. */
  328. int pkt_started = 0 ;      /* Is a data packet coming from the scanner? */
  329. int pktdone ;              /* Indicates if a complete packet received. */
  330. int rc ;                   /* Current character from scanned file. */
  331. int rcount ;               /* Count of bit position within read character. */
  332. int rscnt ;                /* Number of data bytes to read. */
  333. int rsptr ;                /* Character buffer pointer. */
  334. int wc ;                   /* Current character to write to final image file. */
  335. int wcount ;               /* Count of bit position within write character. */
  336. int width ;                /* Width in pixels of rasterfile image. */
  337. int grain ;                /* Grain value. */
  338. int resolution ;           /* Resolution value. */
  339. int retval ;               /* This programs exit status. */
  340. int rf ;                   /* File descriptor for raster image. */
  341. X
  342. int switches[4] =
  343. X      {
  344. X        0,                 /* Mode (Line Art). */
  345. X        1,                 /* Data Transfer (Compressed). */
  346. X        0,                 /* Serial Port (A). */
  347. X        1                  /* Baud Rate (19200). */
  348. X      } ;
  349. X
  350. int framevals[4] =            /* Initial frame in 1/8th inch intervals. */
  351. X      {
  352. X        16,                /* X1. */
  353. X        16,                /* Y1. */
  354. X        48,                /* X2. */
  355. X        48,                /* Y2. */
  356. X     } ;
  357. X
  358. FILE *rd ;                 /* File descriptor for input files. */
  359. FILE *wd ;                 /* File descriptor for final image. */
  360. X
  361. #ifdef NO_4.3SELECT
  362. int readmask ;                /* File descriptors with outstanding reads. */
  363. #else
  364. fd_set readmask ;             /* Readmask used in select call. */
  365. #endif NO_4.3SELECT
  366. X
  367. struct timeval timeout = { MAXTIME, 0 } ;
  368. X
  369. struct code *whites[16] ;   /* White initial starting pointers. */
  370. struct code *blacks[4] ;    /* Black initial starting pointers. */
  371. X
  372. X
  373. /*  The scan program can exit is a variety of ways. These are:
  374. X *
  375. X *  0          - successful   - image saved in picname.
  376. X *  1          - unsuccessful - cannot open ttyline.
  377. X *  2          - unsuccessful - cannot open temporary image file.
  378. X *  3          - unsuccessful - cannot open raster header file.
  379. X *  4          - unsuccessful - scanner not responding. Aborting this scan.
  380. X *  5          - unsuccessful - invalid command line argument.
  381. X *  100 + 0xnn - unsuccessful - scanning error 0xnn received. Scan aborted.
  382. X *  200 + n    - unsuccessful - scan program terminated with signal n.
  383. X *
  384. X *  It is upto the calling program or shell script to display the
  385. X *  appropriate message back to the user.
  386. X */
  387. X
  388. main(argc, argv)
  389. int argc ;
  390. char *argv[] ;
  391. {
  392. X  retval = 0 ;
  393. X  set_signals() ;              /* Set up a signal handler. */
  394. X  STRCPY(progname, argv[0]) ;  /* Save program name. */
  395. X  get_options(argc, argv) ;    /* Extract scanning parameters. */
  396. X  do_scan() ;                  /* Perform a scan using given parameters. */
  397. X  exit(retval) ;
  398. }
  399. X
  400. X
  401. SIGRET
  402. do_exit(sig)   /* Signal received; exit gracefully. */
  403. int sig ;
  404. {
  405. X  char outval ;
  406. X
  407. X  if (fd != -1)     /* Terminate the scan properly, if started. */
  408. X    {
  409. X      outval = ETX ;
  410. X      WRITE(fd, &outval, 1) ;
  411. X      CLOSE(fd) ;
  412. X    }
  413. X  exit(200 + sig) ;
  414. }
  415. X
  416. X
  417. do_handshake(value)            /* Send RS232 handshake XON/XOFF. */
  418. char value ;
  419. {
  420. X  WRITE(fd, &value, 1) ;
  421. X  rsrhold = value ;
  422. }
  423. X
  424. X
  425. do_scan()                      /* Perform a scan using given parameters. */
  426. {
  427. X  char c ;                     /* Next character for RS232 output. */
  428. X
  429. X  pic_compressed = 0 ;
  430. X  height = 0 ;
  431. X  error = 0 ;                           /* Set to 1 on error. */
  432. X  if (open_temp_file() < 0) return ;    /* Open file for raster image. */
  433. X  if (init_rs_port(SERIAL_PORT, BAUD_RATE) < 0) return ;
  434. /* Set scanning parameters. */
  435. X  if (make_packet('!', 1, 0) < 0) return ;    /* Get scanner model number. */
  436. X  if (make_packet('X', 1, 0) < 0) return ; ;  /* Reset scanning parameters. */
  437. X
  438. X  if (make_packet('C', 2, DATA_TRANSFER) < 0) return ;
  439. X
  440. X  if (MODE)
  441. X    {
  442. X      if (make_packet('H', 2, 0) < 0) return ;
  443. X    }
  444. X  else if (make_packet('T', 2, 0) < 0) return ;
  445. X
  446. X  if (make_packet('G', 2, grain) < 0) return ;       
  447. X  if (make_packet('B', 2, brightness) < 0) return ; 
  448. X  if (make_packet('K', 2, contrast) < 0) return ;  
  449. X  if (make_packet('R', 2, resolution+16) < 0) return ;
  450. X
  451. X  if (make_frame_packet() < 0) return ;
  452. X  if (make_packet('S', 1, 0) < 0) return ;     /* Send a start scan packet. */ 
  453. X  complete = 0 ;
  454. X  cancel = 0 ;
  455. X  for (;;)
  456. X    {
  457. #ifdef NO_4.3SELECT
  458. X      readmask = 1 << fd ;
  459. X      SELECT(32, &readmask, (int *) 0,(int *) 0, &timeout) ;
  460. X      if (readmask & (1 << fd))
  461. #else
  462. X      FD_ZERO(&readmask) ;
  463. X      FD_SET(fd, &readmask) ;
  464. X      SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) ;
  465. X      if (FD_ISSET(fd, &readmask))
  466. #endif NO_4.3SELECT
  467. X
  468. X        read_rs232() ;
  469. X      else
  470. X        { 
  471. X          if (rsrhold == XOFF) do_handshake(XON) ;
  472. X          if (pkt_started)
  473. X            {
  474. X              c = NAK ;
  475. X              WRITE(fd, &c, 1) ;
  476. X              rsrstate = RSSOR ;
  477. X              pkt_started = 0 ;
  478. X            }
  479. X        }    
  480. X      if (complete || error || cancel) break ;
  481. X    }
  482. X  CLOSE(rf) ;                     /* Close temporary image file. */
  483. X  if (!error)
  484. X    {
  485. X      save_picture() ;            /* Create Sun rasterfile picture. */
  486. X      retval = 0 ;                /* Successful exit - image saved. */
  487. X    }
  488. X  else UNLINK(tempimage) ;
  489. X  CLOSE(fd) ;
  490. }
  491. X
  492. X
  493. get_options(argc, argv)        /* Extract command line options. */
  494. int argc ;
  495. char *argv[] ;
  496. {
  497. X  char next[MAXLINE] ;    /* The next command line parameter. */
  498. X
  499. X  INC ;
  500. X  while (argc > 0)
  501. X    {
  502. X      if (argv[0][0] == '-')
  503. X        switch (argv[0][1])
  504. X          {
  505. X            case 'c' : INC ;                         /* Contrast. */
  506. X                       getparam(next, argv, "-c needs contrast value") ;
  507. X                       contrast = atoi(next) ;
  508. X                       break ;
  509. X            case 'b' : INC ;                         /* Brightness. */
  510. X                       getparam(next, argv, "-b needs brightness value") ;
  511. X                       brightness = atoi(next) ;
  512. X                       break ;
  513. X            case 'd' : INC ;                         /* Data transfer. */
  514. X                       getparam(next, argv, "-d needs data transfer value") ;
  515. X                       switches[DATA_TRANSFER] = atoi(next) ;
  516. X                       break ;
  517. X            case 'f' : INC ;                         /* Frame. */
  518. X                       getparam(next, argv, "-f needs X1 coordinate") ;
  519. X                       framevals[X1] = atoi(next) ;
  520. X                       INC ;
  521. X                       getparam(next, argv, "-f needs Y1 coordinate") ;
  522. X                       framevals[Y1] = atoi(next) ;
  523. X                       INC ;
  524. X                       getparam(next, argv, "-f needs X2 coordinate") ;
  525. X                       framevals[X2] = atoi(next) ;
  526. X                       INC ;
  527. X                       getparam(next, argv, "-f needs Y2 coordinate") ;
  528. X                       framevals[Y2] = atoi(next) ;
  529. X                       break ;
  530. X            case 'g' : INC ;                         /* Grain. */
  531. X                       getparam(next, argv, "-g needs grain value") ;
  532. X                       grain = atoi(next) ;
  533. X                       break ;
  534. X            case 'm' : INC ;                         /* Mode. */
  535. X                       getparam(next, argv, "-m needs mode value") ;
  536. X                       switches[MODE] = atoi(next) ;
  537. X                       break ;
  538. X            case 'p' : INC ;                         /* Picture name. */
  539. X                       getparam(picname, argv, "-p needs picture name") ;
  540. X                       break ;
  541. X            case 'r' : INC ;                         /* Resolution. */
  542. X                       getparam(next, argv, "-r needs resolution value") ;
  543. X                       resolution = atoi(next);
  544. X                       break ;
  545. X            case 's' : INC ;              /* Speed of RS232 connection. */
  546. X                       getparam(next, argv, "-s needs speed value") ;
  547. X                       switches[BAUD_RATE] = atoi(next) ;
  548. X                       break ;
  549. X            case 't' : INC ;                         /* Tty port. */
  550. X                       getparam(next, argv, "-t needs tty port") ;
  551. X                       switches[SERIAL_PORT] = atoi(next) ;
  552. X                       break ;
  553. X            case 'v' : FPRINTF(stderr, "%s version 1.4.%1d\n",
  554. X                                       progname, PATCHLEVEL) ;
  555. X                       break ;
  556. X            case '?' : usage() ;
  557. X          }
  558. X      INC ;
  559. X    }
  560. }
  561. X
  562. X
  563. getparam(s, argv, errmes)
  564. char *s, *argv[], *errmes ;
  565. {
  566. X  if (*argv != NULL && argv[0][0] != '-') STRCPY(s, *argv) ;
  567. X  else
  568. X    { 
  569. X      FPRINTF(stderr,"%s: %s as next argument.\n", progname, errmes) ;
  570. X      exit(5) ;
  571. X    }
  572. }
  573. X
  574. X
  575. init_rs_port(port, speed)              /* Initialise RS232 port. */
  576. int port, speed ;
  577. {
  578. X  char ttyline[MAXLINE] ;
  579. X  struct sgttyb sgttyb ;
  580. X  if (port) STRCPY(ttyline, "/dev/ttyb") ;
  581. X  else      STRCPY(ttyline, "/dev/ttya") ;
  582. X  if ((fd = open(ttyline,2)) < 0)
  583. X    {
  584. X      retval = 1 ;      /* Cannot open ttyline. */
  585. X      return(-1) ;
  586. X    }
  587. X  GTTY(fd, &sgttyb) ;
  588. X  sgttyb.sg_flags |= RAW ;
  589. X  sgttyb.sg_flags &= ~(ECHO | CRMOD) ;
  590. X  if (speed) sgttyb.sg_ispeed = sgttyb.sg_ospeed = EXTA ;
  591. X  else       sgttyb.sg_ispeed = sgttyb.sg_ospeed = B9600 ;
  592. X  STTY(fd, &sgttyb) ;             /* Implement tty line setup changes. */
  593. X  return(0) ;
  594. }
  595. X
  596. X
  597. make_frame_packet()        /* Construct and send scanning frame packet. */
  598. {
  599. X  char cksum ;             /* For creating the packet checksum. */
  600. X  int i ;
  601. X
  602. X  rsdata[0] = '\\' ;       /* Construct packet. */
  603. X  rsdata[1] = 0x80 ;
  604. X  rsdata[2] = 0x00 ;
  605. X  rsdata[3] = 5 ;
  606. X  rsdata[4] = 'F' ;
  607. X  rsdata[5] = framevals[X1] ;
  608. X  rsdata[6] = framevals[Y1] ;
  609. X  rsdata[7] = framevals[X2] ;
  610. X  rsdata[8] = framevals[Y2] ;
  611. X  cksum = 0 ;
  612. X  for (i = 1; i < 9; i++) cksum += rsdata[i] ;
  613. X  rsdata[9] = (~cksum) + 1 ;
  614. X  return(send_packet('F', 10)) ;
  615. }
  616. X
  617. X
  618. make_header(width, height)       /* Make Sun rasterfile header. */
  619. int width, height ;
  620. {
  621. X  struct rasterfile header ;
  622. X  FILE *hd ;                    /* File descriptor for header file. */
  623. X
  624. X  SPRINTF(temphead, "/usr/tmp/%s.header", mktemp("XXXXXX")) ;
  625. X  if ((hd = fopen(temphead,"w")) == NULL)
  626. X    {
  627. X      retval = 3 ;              /* Can't open raster header file. */
  628. X      return(-1) ;
  629. X    }
  630. X  header.ras_magic = 0x59a66a95 ;        /* Generate rasterfile header. */
  631. X  header.ras_width = width ;
  632. X  header.ras_height = height ;
  633. X  header.ras_depth = 1 ;
  634. X  header.ras_length = width * height ;
  635. X  header.ras_type = RT_STANDARD ;
  636. X  header.ras_maptype = RMT_RAW ;
  637. X  header.ras_maplength = 0 ;
  638. X  FWRITE((char *) &header, sizeof(struct rasterfile), 1, hd) ;
  639. X  FCLOSE(hd) ;
  640. X  return(0) ;
  641. }
  642. X
  643. X
  644. make_packet(ptype, count, value)   /* Sent a packet to the scanner. */
  645. char ptype, count, value ;
  646. {
  647. X  char cksum ;                     /* For creating the packet checksum. */
  648. X  int i ;
  649. X  int len ;                        /* Length of this scanner packet. */
  650. X
  651. X  len = count + 5 ;
  652. X  rsdata[0] = '\\' ;               /* Construct packet. */
  653. X  rsdata[1] = 0x80 ;
  654. X  rsdata[2] = 0x00 ;
  655. X  rsdata[3] = count ;
  656. X  rsdata[4] = ptype ;
  657. X  if (count == 2) rsdata[5] = value ;
  658. X  cksum = 0 ;
  659. X  for (i = 1; i < len-1; i++) cksum += rsdata[i] ;
  660. X  rsdata[len-1] = (~cksum) + 1 ;
  661. X  return(send_packet(ptype, len)) ;
  662. }
  663. X
  664. X
  665. open_temp_file()          /* Open a temporary file for the scanned image. */
  666. {
  667. X  SPRINTF(tempimage, "/usr/tmp/%s.image", mktemp("XXXXXX")) ;
  668. X  if ((rf = open(tempimage, 2)) < 0)
  669. X    if ((rf = creat(tempimage, 0777)) < 0)
  670. X      {
  671. X        retval = 2 ;   /* Can't open temporary image file. */
  672. X        return(-1) ;
  673. X      }
  674. X  return(0) ;
  675. }
  676. X
  677. X
  678. process_packet(ptype)     /* Process RS232 packet received. */
  679. char ptype ;
  680. {
  681. X  int errorval ;          /* To extract error value. */
  682. X  char outval ;           /* ACK or NAK value to be sent. */
  683. X
  684. X  if (rscksum == cksum)
  685. X    {
  686. X      outval = ACK ;
  687. X      switch (ptype)
  688. X        {
  689. X          case 'D' : if ((rsrtype >> 5) & 1) pic_compressed++ ;
  690. X                     height++ ;
  691. X                     if (!((rsrtype >> 5) & 1)) rsptr = ((rsptr >> 2) << 2) ;
  692. X                     WRITE(rf, from_rs, rsptr) ;
  693. X                     width = rsptr * 8 ;
  694. X                     break ;
  695. X          case 'E' : outval = ETX ;    /* Complete scanning and eject paper. */
  696. X                     WRITE(fd, &outval, 1) ;
  697. X                     complete = 1 ;
  698. X                     break ;
  699. X          case '!' : STRNCPY(scantype, from_rs, rsptr) ;
  700. X                     break ;
  701. X          case '?' : errorval = (from_rs[1] & 0xFF) ;
  702. X                     retval = 100 + errorval ;  /* Scanning error received. */
  703. X                     printf("Error=0x%x",errorval);
  704. X                     outval = ETX ;
  705. X                     WRITE(fd, &outval, 1) ;
  706. X                     error = 1 ;
  707. X        }
  708. X    }    
  709. X  else outval = NAK ;
  710. X  WRITE(fd, &outval, 1) ;        /* Send ACK or NAK. */
  711. X  pktdone = 1 ;
  712. }
  713. X
  714. X
  715. read_rs232()      /* Read upto end of next packet. */
  716. {
  717. X  char c ;        /* Next character read from RS232. */
  718. X  int count ;     /* Number of RS232 characters to read. */
  719. X  int i ;
  720. X
  721. X  IOCTL(fd,(int) FIONREAD,(char *) &count) ;   /* Any data to read. */
  722. X  if (count > MAXREAD) do_handshake(XOFF) ;
  723. X  else if (count < 20 && rsrhold == XOFF) do_handshake(XON) ;
  724. X  if (!count) return ;                         /* NO: exit routine. */
  725. X  for (i = 0; i < count; i++)
  726. X    {
  727. X      READ(fd, &c, 1) ;                        /* Read next character. */
  728. X      if (rsrstate == RSSOR && (c == ACK || c == NAK)) rswstate = c ;
  729. X      else
  730. X        switch (rsrstate)
  731. X          {
  732. X            case RSSOR   : rscksum = 0 ;
  733. X                           if (c == SOR) rsrstate = RSRTYPE ;
  734. X                           break ;
  735. X            case RSRTYPE : rsrtype = c ;
  736. X                           rscksum += c ;
  737. X                           cntbytes = 0 ;
  738. X                           rscnt = 0 ;
  739. X                           rsrstate = RSCOUNT ;
  740. X                           break ;
  741. X            case RSCOUNT : rscksum += c ;
  742. X                           rscnt = rscnt*256 + c ;
  743. X                           if (++cntbytes == 2)
  744. X                             {
  745. X                               rsrstate = RSDATA ;
  746. X                               rsptr = 0 ;
  747. X                             }
  748. X                           pkt_started = 1 ;
  749. X                           break ;
  750. X            case RSDATA  : from_rs[rsptr++] = c ;  /* Save data character. */
  751. X                           rscksum += c ;
  752. X                           if (!--rscnt) rsrstate = RSCKSUM ;
  753. X                           break ;
  754. X            case RSCKSUM : rscksum = (~rscksum) + 1 ;
  755. X                           cksum = c ;
  756. X                           if (rsrtype >> 7) process_packet(from_rs[0]) ;
  757. X                           else process_packet('D') ;
  758. X                           pkt_started = 0 ;
  759. X                           rsrstate = RSSOR ;
  760. X                           return ;
  761. X          }
  762. X    }
  763. }
  764. X
  765. X
  766. save_picture()    /* Combine header file and image to make a Sun rasterfile. */
  767. {
  768. X  char line[MAXLINE] ;          /* For constructing the system command. */
  769. X
  770. X  if (pic_compressed)
  771. X    {
  772. X      initialise_white("white.codes") ;
  773. X      initialise_black("black.codes") ;
  774. X      uncompress(tempimage) ;
  775. X    }
  776. X  else
  777. X    { 
  778. X      if (!make_header(width, height))   /* Write out Sun rasterfile header. */
  779. X        {
  780. X          SPRINTF(line, "cat %s %s > %s", temphead, tempimage, picname) ;
  781. X          SYSTEM(line) ;                 /* Create Sun rasterfile. */
  782. X          UNLINK(temphead) ;             /* Remove header file. */
  783. X        }
  784. X      UNLINK(tempimage) ;                /* Remove image file. */
  785. X    }
  786. }
  787. X
  788. X
  789. send_packet(ptype, len)
  790. char ptype,len ;
  791. {
  792. X  int done ;        /* Packet read or ACK/NAK found. */
  793. X  int i ;
  794. X
  795. X  for (i = 0; i < MAXRETRIES; i++)
  796. X    {
  797. X      WRITE(fd, rsdata, len) ;
  798. X      rswstate = NOANSWER ;
  799. X      pktdone = 0 ;
  800. X      done = 0 ;
  801. X      do
  802. X        {
  803. #ifdef NO_4.3SELECT
  804. X          readmask = 1 << fd ;
  805. X          SELECT(32, &readmask, (int *) 0, (int *) 0, &timeout) ;
  806. X          if (readmask & (1 << fd))
  807. #else
  808. X          FD_ZERO(&readmask) ;
  809. X          FD_SET(fd, &readmask) ;
  810. X          SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) ;
  811. X          if (FD_ISSET(fd, &readmask))
  812. #endif NO_4.3SELECT
  813. X            {
  814. X              read_rs232() ;
  815. X              switch (ptype)
  816. X                {
  817. X                  case '!' : if (pktdone) done = 1 ;
  818. X                             break ;
  819. X                  default  : if (rswstate == ACK || rswstate == NAK) done = 1 ;
  820. X                }
  821. X              if (done) break ;
  822. X            }
  823. X          else break ;
  824. X        }
  825. X      while (!done) ;
  826. X      if (rswstate == ACK) return(0) ;
  827. X    }
  828. X  retval = 4 ;   /* Scanner not responding. Aborting this scan. */
  829. X  CLOSE(rf) ;
  830. X  return(-1) ;
  831. }
  832. X
  833. X
  834. set_signals()   /* Setup a signal handler for a range of signals. */
  835. {
  836. X  SIGNAL(SIGHUP,  do_exit) ;
  837. X  SIGNAL(SIGQUIT, do_exit) ;
  838. X  SIGNAL(SIGILL,  do_exit) ;
  839. X  SIGNAL(SIGTRAP, do_exit) ;
  840. X  SIGNAL(SIGIOT,  do_exit) ;
  841. X  SIGNAL(SIGEMT,  do_exit) ;
  842. X  SIGNAL(SIGFPE,  do_exit) ;
  843. X  SIGNAL(SIGBUS,  do_exit) ;
  844. X  SIGNAL(SIGSEGV, do_exit) ;
  845. }
  846. X
  847. X
  848. usage()
  849. {
  850. X  FPRINTF(stderr, "Usage: %s: [-b brightness] [-c contrast] ", progname) ;
  851. X  FPRINTF(stderr, "[-d] [-f x1 y1 x2 y2] [-g grain] [-m] [-p picname]\n") ;
  852. X  FPRINTF(stderr, "[-s] [-t] [-v] [-?] [-Wi] [-Wp x y] [-WP x y]\n") ;
  853. X  exit(5) ;
  854. }
  855. SHAR_EOF
  856. chmod 0644 scan.c ||
  857. echo 'restore of scan.c failed'
  858. Wc_c="`wc -c < 'scan.c'`"
  859. test 19810 -eq "$Wc_c" ||
  860.     echo 'scan.c: original size 19810, current size' "$Wc_c"
  861. rm -f _shar_wnt_.tmp
  862. fi
  863. # ============= scan.h ==============
  864. if test -f 'scan.h' -a X"$1" != X"-c"; then
  865.     echo 'x - skipping scan.h (File already exists)'
  866.     rm -f _shar_wnt_.tmp
  867. else
  868. > _shar_wnt_.tmp
  869. echo 'x - extracting scan.h (Text)'
  870. sed 's/^X//' << 'SHAR_EOF' > 'scan.h' &&
  871. X
  872. /*  @(#)scan.h 1.3 90/04/03
  873. X *
  874. X *  Definitions used by scan.
  875. X *
  876. X *  Copyright (c) Rich Burridge.
  877. X *                Sun Microsystems, Australia - All rights reserved.
  878. X *
  879. X *  Permission is given to distribute these sources, as long as the
  880. X *  copyright messages are not removed, and no monies are exchanged.
  881. X *
  882. X *  No responsibility is taken for any errors or inaccuracies inherent
  883. X *  either to the comments or the code of this program, but if
  884. X *  reported to me, then an attempt will be made to fix them.
  885. X */
  886. X
  887. #define  CLOSE       (void) close      /* To make lint happy. */
  888. #define  FCLOSE      (void) fclose
  889. #define  FPRINTF     (void) fprintf
  890. #define  FWRITE      (void) fwrite
  891. #define  GTTY        (void) gtty
  892. #define  IOCTL       (void) ioctl
  893. #define  PUTC        (void) putc
  894. #define  READ        (void) read
  895. #define  SELECT      (void) select
  896. #define  SIGNAL      (void) signal
  897. #define  SSCANF      (void) sscanf
  898. #define  SPRINTF     (void) sprintf
  899. #define  STRCPY      (void) strcpy
  900. #define  STRNCPY     (void) strncpy
  901. #define  STTY        (void) stty
  902. #define  SYSTEM      (void) system
  903. #define  UNLINK      (void) unlink
  904. #define  WRITE       (void) write
  905. X
  906. char *malloc(), *mktemp() ;
  907. X
  908. #define  BUFSIZE        512     /* RS232 data buffer size. */
  909. #define  ETX            3       /* End of scanning code for scanner. */
  910. #define  INC            argc-- ; argv++ ;
  911. #define  MAXLINE        80      /* Length of character strings. */
  912. #define  MAXREAD        100     /* Maximum amount of outstanding data. */
  913. #define  MAXRETRIES     5       /* Number of attempts to send packet. */
  914. #define  MAXTIME        2       /* RS232 read timeout in seconds. */
  915. #define  SOR            '\\'    /* Start of record character. */
  916. #define  XOFF           19      /* Stop sending data. */
  917. #define  XON            17      /* Start sending data again. */
  918. #define  X1             0       /* Coordinate values within framevals. */
  919. #define  Y1             1
  920. #define  X2             2
  921. #define  Y2             3
  922. X
  923. /* RS232 read automation states. */
  924. #define  RSSOR       0            /* Start of packet. */
  925. #define  RSRTYPE     1            /* Record type. */
  926. #define  RSCOUNT     2            /* Data count. */
  927. #define  RSDATA      3            /* Packet data. */
  928. #define  RSCKSUM     4            /* Packet checksum. */
  929. X
  930. /* States for packet acknowledgement. */
  931. #define  NOANSWER    '-'        /* No acknowledgement received. */
  932. #define  ACK         6          /* Positive acknowledgement. */
  933. #define  NAK         21         /* Negative acknowledgement. */
  934. X
  935. /* Abbreviations for box switch values. */
  936. #define  MODE           switches[0]
  937. #define  DATA_TRANSFER  switches[1]
  938. #define  SERIAL_PORT    switches[2]
  939. #define  BAUD_RATE      switches[3]
  940. X
  941. /* Color definitions used with uncompressing. */
  942. #define  WHITE          4
  943. #define  BLACK          2
  944. X
  945. #ifndef  SIGRET
  946. #define  SIGRET         void
  947. #endif /* SIGRET */
  948. X
  949. #ifndef LINT_CAST
  950. #ifdef lint
  951. #define LINT_CAST(arg)  (arg ? 0 : 0)
  952. #else
  953. #define LINT_CAST(arg)  (arg)
  954. #endif lint
  955. #endif LINT_CAST
  956. X
  957. struct code                     /* Huffman code record. */
  958. X         {
  959. X           struct code *next[2] ;
  960. X           int value[2] ;
  961. X         } ;
  962. SHAR_EOF
  963. chmod 0644 scan.h ||
  964. echo 'restore of scan.h failed'
  965. Wc_c="`wc -c < 'scan.h'`"
  966. test 3171 -eq "$Wc_c" ||
  967.     echo 'scan.h: original size 3171, current size' "$Wc_c"
  968. rm -f _shar_wnt_.tmp
  969. fi
  970. # ============= scan_compress.c ==============
  971. if test -f 'scan_compress.c' -a X"$1" != X"-c"; then
  972.     echo 'x - skipping scan_compress.c (File already exists)'
  973.     rm -f _shar_wnt_.tmp
  974. else
  975. > _shar_wnt_.tmp
  976. echo 'x - extracting scan_compress.c (Text)'
  977. sed 's/^X//' << 'SHAR_EOF' > 'scan_compress.c' &&
  978. X
  979. /*  @(#)scan_compress.c 1.2 90/04/02
  980. X *
  981. X *  Routines for uncompressing a scanned file, which has been compressed
  982. X *  using the CCITT Recommendation T.4 (modified Huffman code).
  983. X *
  984. X *  Copyright (c) Rich Burridge.
  985. X *                Sun Microsystems, Australia - All rights reserved.
  986. X *
  987. X *  Permission is given to distribute these sources, as long as the
  988. X *  copyright messages are not removed, and no monies are exchanged.
  989. X *
  990. X *  No responsibility is taken for any errors or inaccuracies inherent
  991. X *  either to the comments or the code of this program, but if
  992. X *  reported to me, then an attempt will be made to fix them.
  993. X */
  994. X
  995. #include <stdio.h>
  996. #include "scan.h"
  997. #include "scan_extern.h"
  998. X
  999. X
  1000. initialise_white(filename)    /* Read white Make Up and Terminating Codes. */
  1001. char filename[MAXLINE] ;
  1002. {
  1003. X  char bitstring[MAXLINE] ;     /* This lines huffman encoded bit string. */
  1004. X  char line[MAXLINE] ;          /* Current line read from file. */
  1005. X  int bvalue, i, indexval, n, runlength ;
  1006. X  struct code *ptr ;            /* Current codes structure pointer. */
  1007. X
  1008. X  for (i = 0; i < 16; i++)
  1009. X    {
  1010. X      whites[i] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
  1011. X      whites[i]->next[0] = NULL ;
  1012. X      whites[i]->next[1] = NULL ;
  1013. X    }
  1014. X
  1015. X  if ((rd = fopen(filename,"r")) == NULL)
  1016. X    {
  1017. X      FPRINTF(stderr, "%s: can't open %s\n", progname, filename) ;
  1018. X      exit(1) ;
  1019. X    }
  1020. X
  1021. X  while (fgets(line, MAXLINE, rd) != NULL)
  1022. X    {
  1023. X      SSCANF(line, "%d %s", &runlength, bitstring) ;
  1024. X      n = 0 ;
  1025. X      indexval = 0 ;
  1026. X      for (i = 0; i < 4; i++)
  1027. X        {
  1028. X          bvalue = bitstring[n++] - '0' ;
  1029. X          indexval = (indexval << 1) + bvalue ;
  1030. X        }
  1031. X      ptr = whites[indexval] ;
  1032. X      for (i = n ; i < strlen(bitstring); i++)
  1033. X        {
  1034. X          if (ptr->next[bvalue] == NULL)
  1035. X            {
  1036. X              ptr->next[bvalue] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
  1037. X              ptr->next[bvalue]->next[0] = NULL ;
  1038. X              ptr->next[bvalue]->next[1] = NULL ;
  1039. X            }
  1040. X          ptr = ptr->next[bvalue] ;
  1041. X          bvalue = bitstring[i] - '0' ;
  1042. X        }
  1043. X      ptr->value[bvalue] = runlength ;
  1044. X    }
  1045. X  FCLOSE(rd) ;
  1046. }
  1047. X
  1048. X
  1049. initialise_black(filename)    /* Read black Make Up and Terminating Codes. */
  1050. char filename[MAXLINE] ;
  1051. {
  1052. X  char bitstring[MAXLINE] ;     /* This lines huffman encoded bit string. */
  1053. X  char line[MAXLINE] ;          /* Current line read from file. */
  1054. X  int bvalue, i, indexval, n, runlength ;
  1055. X  struct code *ptr ;            /* Current codes structure pointer. */
  1056. X
  1057. X  for (i = 0; i < 4; i++)
  1058. X    {
  1059. X      blacks[i] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
  1060. X      blacks[i]->next[0] = NULL ; 
  1061. X      blacks[i]->next[1] = NULL ; 
  1062. X    }
  1063. X  if ((rd = fopen(filename,"r")) == NULL)
  1064. X    {
  1065. X      FPRINTF(stderr, "%s: can't open %s\n", progname, filename) ;
  1066. X      exit(1) ;
  1067. X    } 
  1068. X  while (fgets(line, MAXLINE, rd) != NULL)
  1069. X    {
  1070. X      SSCANF(line, "%d %s", &runlength, bitstring) ;
  1071. X      n = 0 ;
  1072. X      indexval = 0 ;
  1073. X      for (i = 0; i < 2; i++)
  1074. X        {
  1075. X          bvalue = bitstring[n++] - '0' ;
  1076. X          indexval = (indexval << 1) + bvalue ;
  1077. X        }
  1078. X      ptr = blacks[indexval] ;
  1079. X      for (i = n ; i < strlen(bitstring); i++)
  1080. X        {
  1081. X          if (ptr->next[bvalue] == NULL)
  1082. X            {
  1083. X              ptr->next[bvalue] = (struct code *) LINT_CAST(malloc(sizeof(struct code))) ;
  1084. X              ptr->next[bvalue]->next[0] = NULL ;
  1085. X              ptr->next[bvalue]->next[1] = NULL ;
  1086. X            }
  1087. X          ptr = ptr->next[bvalue] ;
  1088. X          bvalue = bitstring[i] - '0' ;
  1089. X        } 
  1090. X      ptr->value[bvalue] = runlength ;
  1091. X    }   
  1092. X  FCLOSE(rd) ;
  1093. }
  1094. X
  1095. X
  1096. get_bitval()        /* Get next bit value from compressed scanned file. */
  1097. {
  1098. X  if (rcount == 8)
  1099. X    {
  1100. X      if ((rc = getc(rd)) == EOF)
  1101. X        {
  1102. X          finished = 1 ;
  1103. X          return(-1) ;
  1104. X        }
  1105. X      rcount = 0 ;
  1106. X    }
  1107. X  return((rc >> (7-rcount++)) & 1) ;
  1108. }
  1109. X
  1110. X
  1111. get_code(color)        /* Get next huffman code for this color. */
  1112. int color ;
  1113. {
  1114. X  int bvalue, i, indexval ;
  1115. X  struct code *ptr ;
  1116. X
  1117. X  indexval = 0 ;
  1118. X  for (i = 0; i < color; i++)
  1119. X    {
  1120. X      if ((bvalue = get_bitval()) == -1) return(-1) ;
  1121. X      indexval = (indexval << 1) + bvalue ;
  1122. X    }
  1123. X  if (color == WHITE) ptr = whites[indexval] ;
  1124. X  else ptr = blacks[indexval] ;
  1125. X  for (;;)
  1126. X    {
  1127. X      if (ptr->next[bvalue] == NULL) return(ptr->value[bvalue]) ;
  1128. X      ptr = ptr->next[bvalue] ;
  1129. X      if ((bvalue = get_bitval()) == -1) return(-1) ;
  1130. X    }
  1131. }
  1132. X
  1133. X
  1134. write_code(color, length)   /* Send uncompressed data to temporary file. */
  1135. int color, length ;
  1136. {
  1137. X  int i ;
  1138. X
  1139. X  for (i = 0; i < length; i++)
  1140. X    {
  1141. X      if (color == BLACK) wc |= (1 << 7 - wcount) ;
  1142. X      if (++wcount == 8)
  1143. X        {
  1144. X          PUTC(wc, wd) ;
  1145. X          wc = 0 ;
  1146. X          wcount = 0 ;
  1147. X        }
  1148. X    }
  1149. }
  1150. X
  1151. X
  1152. uncompress(filename)     /* Uncompress the scanned file using huffman codes. */
  1153. char filename[MAXLINE] ;
  1154. {
  1155. X  int rem, runlength ;
  1156. X
  1157. X  finished = 0 ;
  1158. X  if ((rd = fopen(filename, "r")) == NULL)
  1159. X    {
  1160. X      FPRINTF(stderr, "%s: can't open %s\n", progname, filename) ;
  1161. X      exit(1) ;
  1162. X    }
  1163. X  SPRINTF(finalimage, "/usr/tmp/%s.unc.image", mktemp("XXXXXX")) ;
  1164. X  if ((wd = fopen(finalimage, "w")) == NULL)
  1165. X    {
  1166. X      FPRINTF(stderr, "%s: can't open %s\n", progname, finalimage) ;
  1167. X      exit(1) ;
  1168. X    }
  1169. X
  1170. X  width = 0 ;
  1171. X  height = 0 ;
  1172. X  rcount = 8 ;            /* Force a character read. */
  1173. X  wcount = 0 ;
  1174. X  do
  1175. X    {
  1176. X      runlength = get_code(WHITE) ;
  1177. X      if (runlength != -1) width += runlength ;
  1178. X      if (finished) break ;
  1179. X      if (runlength == -1)
  1180. X        {
  1181. X          height++ ;
  1182. X          rem = width % 16 ;
  1183. X          if (rem) write_code(WHITE, rem) ;
  1184. X          fwidth = width + rem ;
  1185. X          if (!finished) width = 0 ;
  1186. X          rcount = 8 ;
  1187. X          continue ;
  1188. X        }
  1189. X      write_code(WHITE, runlength) ;
  1190. X      if (runlength >= 64)
  1191. X        {
  1192. X          runlength = get_code(WHITE) ;
  1193. X          if (runlength != -1) width += runlength ;
  1194. X          write_code(WHITE, runlength) ;
  1195. X        }
  1196. X
  1197. X      runlength = get_code(BLACK) ;
  1198. X      if (runlength != -1) width += runlength ;
  1199. X      if (finished) break ;
  1200. X      if (runlength == -1)
  1201. X        {
  1202. X          height++ ;
  1203. X          rem = width % 16 ;
  1204. X          if (rem) write_code(WHITE, rem) ;
  1205. X          fwidth = width + rem ;
  1206. X          if (!finished) width = 0 ;
  1207. X          rcount = 8 ;
  1208. X          continue ;
  1209. X        }
  1210. X      write_code(BLACK, runlength) ;
  1211. X      if (runlength >= 64)
  1212. X        {
  1213. X          runlength = get_code(BLACK) ;
  1214. X          if (runlength != -1) width += runlength ;
  1215. X          write_code(BLACK, runlength) ;
  1216. X        }
  1217. X    }
  1218. X  while (!finished) ;
  1219. X  FCLOSE(rd) ;
  1220. X  FCLOSE(wd) ;
  1221. X  if (!make_header(fwidth, height))     /* Write out Sun rasterfile header. */
  1222. X    {
  1223. X      SPRINTF(line, "cat %s %s > %s", temphead, finalimage, picname) ;
  1224. X      SYSTEM(line) ;                    /* Create Sun rasterfile. */
  1225. X      UNLINK(temphead) ;                /* Remove header file. */
  1226. X    }
  1227. X  UNLINK(tempimage) ;
  1228. X  UNLINK(finalimage) ;
  1229. }
  1230. SHAR_EOF
  1231. chmod 0644 scan_compress.c ||
  1232. echo 'restore of scan_compress.c failed'
  1233. Wc_c="`wc -c < 'scan_compress.c'`"
  1234. test 6931 -eq "$Wc_c" ||
  1235.     echo 'scan_compress.c: original size 6931, current size' "$Wc_c"
  1236. rm -f _shar_wnt_.tmp
  1237. fi
  1238. # ============= scan_extern.h ==============
  1239. if test -f 'scan_extern.h' -a X"$1" != X"-c"; then
  1240.     echo 'x - skipping scan_extern.h (File already exists)'
  1241.     rm -f _shar_wnt_.tmp
  1242. else
  1243. > _shar_wnt_.tmp
  1244. echo 'x - extracting scan_extern.h (Text)'
  1245. sed 's/^X//' << 'SHAR_EOF' > 'scan_extern.h' &&
  1246. X
  1247. /*  @(#)scan_extern.h 1.2 90/04/02
  1248. X *
  1249. X *  External variables used by the scan program.
  1250. X *
  1251. X *  Copyright (c) Rich Burridge.
  1252. X *                Sun Microsystems, Australia - All rights reserved.
  1253. X *
  1254. X *  Permission is given to distribute these sources, as long as the
  1255. X *  copyright messages are not removed, and no monies are exchanged.
  1256. X *
  1257. X *  No responsibility is taken for any errors or inaccuracies inherent
  1258. X *  either to the comments or the code of this program, but if
  1259. X *  reported to me, then an attempt will be made to fix them.
  1260. SHAR_EOF
  1261. true || echo 'restore of scan_extern.h failed'
  1262. fi
  1263. echo 'End of  part 3'
  1264. echo 'File scan_extern.h is continued in part 4'
  1265. echo 4 > _shar_seq_.tmp
  1266. exit 0
  1267.