home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / image < prev    next >
Encoding:
Internet Message Format  |  1991-08-07  |  57.5 KB

  1. From: everson@compsci.bristol.ac.uk (Phill Everson)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i019: Image processing programs
  4. Message-ID: <7130@ncoast.UUCP>
  5. Date: 26 Jan 88 04:07:33 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. Comp.sources.misc: Volume 2, Issue 19
  9. Submitted-By: Phill Everson <everson@compsci.bristol.ac.uk>
  10. Archive-Name: image
  11.  
  12. # To unbundle, sh this file
  13.  echo README 1>&2
  14. cat >README <<'End of README'
  15. In response to a plea on the net:
  16.  
  17. This is a family of image processing programs written by
  18. Phill Everson <everson@uk.aucc.bristol.cs: JANET
  19.                everson%uk.aucc.bristol.cs@nss.cs.ucl.ac.uk: ARPA ? >
  20. with help from Gareth Waddell (notably for the dynamic array library)
  21. at Bristol University in the UK for SUN workstations, both colour and 
  22. black/white.  It includes tools to display images on Colour monitors, 
  23. B/W monitors, to convolve a filter over an image, to create a histogram 
  24. of the greylevels in an image, to normalise an image, to threshold an image, 
  25. to convert an image to Postscript and ... (read the manual page alv(1) 
  26. for other features).
  27.  
  28. Alv stands for Autonomous Land Vehicle, the research project that these
  29. were originally developed for. Some of the tools have been used MUCH
  30. more than others and so can be regarded as being pretty much correct
  31. (dsp, cdsp, convolve, pixval, imagelw, subarea, subsample, coltable, hist
  32. & invert).
  33. If any of the others seem to be playing up it is possible that 
  34. there is a bug in there somewhere -- some tools were added at the 
  35. request of others who promised to test them and have never been heard 
  36. of since! Please send me any bug reports (&fixes?) to me.
  37.  
  38. *************************************************************************
  39. To get this system up and on the road:
  40.  
  41.     1. Edit the Makefile, changing the directory paths for
  42.        BINDIR, LIBDIR, INCDIR, MANDIR & FILDIR to suit your system.
  43.     2. Type 'make' and everything will be compiled and installed.
  44.     3. Read the manual page alv(1). It can be formatted from this 
  45.        directory by typing 'nroff -man alv.1 | more'.
  46. *************************************************************************
  47.  
  48. This family of programs has 3 manual pages; alv(1), alv(3) & alv(5).
  49. alv(1) has a general description of each of the programs and what each 
  50. of them should do. alv(3) is a description of the library created 
  51. and alv(5) is a description of the file format used for an image.
  52. (I've also included the manual page dynamem(3) for a dynamic memory 
  53. allocation library which is used by the alv library and which someone may 
  54. find useful.)
  55.  
  56. The method that we have found works best is that everyone working
  57. on vision-type programs uses the same file format (see alv(5)) and
  58. most people will use the core tools to display images etc and the
  59. library functions for their own programs.
  60.  
  61. These are and will be used a lot here, so if anybody adds or modifies them,
  62. please send me details and I'll collect, collate and possibly post notable 
  63. additions at a later date. Thanks.
  64.  
  65. I hope they're of some use.
  66.  
  67.                 Phill Everson
  68. End of README
  69.  echo Makefile 1>&2
  70. cat >Makefile <<'End of Makefile'
  71. #
  72. # ALV image processing programs
  73. # written by Phill Everson
  74. #            Computer Science Dept.
  75. #            Bristol University UK
  76. #            21st January, 1988
  77. #
  78. # <everson@uk.aucc.bristol.cs: JANET
  79. #  everson%uk.aucc.bristol.cs@nss.cs.ucl.ac.uk: ARPA ? >
  80. #
  81.  
  82. # BINDIR - location of compiled binaries
  83. # LIBDIR - location of compiled libraries
  84. # INCDIR - location of include files
  85. # MANDIR - location of top level of manual
  86. # FILDIR - location of filters (for convolve)
  87.  
  88. BINDIR = /usr/kukini/alv/vision/bin
  89. LIBDIR = /usr/kukini/alv/vision/lib
  90. INCDIR = /usr/kukini/alv/vision/include
  91. MANDIR = /usr/kukini/alv/vision/man
  92. FILDIR = /usr/kukini/alv/vision/usr/filters
  93. CFLAGS = -g -I$(INCDIR) 
  94.    ARC = vision.a
  95.  DLIBS = -lsuntool -lsunwindow -lpixrect -L$(LIBDIR) -lalv
  96.  OLIBS = -L$(LIBDIR) -lalv
  97.  PROGS = cdsp dsp convert addhead hist imagelw invert pixval retitle \
  98.          subarea subsample thresh normalise ffill convolve range striphead 
  99.  
  100. install: setup all docs filters
  101.     mv $(PROGS) $(BINDIR)
  102.  
  103. setup:
  104.     cp image.h $(INCDIR)
  105.  
  106. all: lib cdsp dsp convert addhead hist imagelw invert pixval retitle \
  107.      subarea subsample thresh normalise ffill convolve range striphead
  108.  
  109. filters: 
  110.     @cp avg1 lap1 sobel1 xdiff1 $(FILDIR)
  111.  
  112. archive: clean
  113.     @ar crv $(ARC) *
  114.     @compress $(ARC)
  115.     @mv $(ARC).Z $(ARCHIVE_DIR)
  116.     
  117. docs:
  118.     @cp alv.1 $(MANDIR)/man1
  119.     @cp alv.3 $(MANDIR)/man3
  120.     @cp alv.5 $(MANDIR)/man5
  121.     @cp dynamem.3 $(MANDIR)/man3
  122.  
  123. cdsp: cdsp.o 
  124.     cc $(CFLAGS) cdsp.o -o cdsp $(DLIBS)
  125.  
  126. dsp: dsp.o
  127.     cc $(CFLAGS) dsp.o -o dsp $(DLIBS)
  128.  
  129. hist: hist.o
  130.     cc $(CFLAGS) hist.o -o hist $(DLIBS) -lm
  131.  
  132. convert: convert.o
  133.     cc $(CFLAGS) convert.o -o convert -L$(LIBDIR) -ldynamem
  134.  
  135. addhead: addhead.o
  136.     cc $(CFLAGS) addhead.o -o addhead -L$(LIBDIR) -ldynamem
  137.  
  138. striphead: striphead.o
  139.     cc $(CFLAGS) striphead.o -o striphead $(OLIBS)
  140.  
  141. convolve.o: convolve.c
  142.     cc $(CFLAGS) -DFILTERS_DIR=$(FILDIR) -c convolve.c
  143.  
  144. convolve: convolve.o
  145.     cc $(CFLAGS) convolve.o -o convolve $(OLIBS)
  146.  
  147. invert: invert.o
  148.     cc $(CFLAGS) invert.o -o invert $(OLIBS)
  149.  
  150. pixval: pixval.o
  151.     cc $(CFLAGS) pixval.o -o pixval $(OLIBS)
  152.  
  153. retitle: retitle.o
  154.     cc $(CFLAGS) retitle.o -o retitle $(OLIBS)
  155.  
  156. range: range.o
  157.     cc $(CFLAGS) range.o -o range $(OLIBS)
  158.  
  159. imagelw: imagelw.o
  160.     cc $(CFLAGS) imagelw.o -o imagelw $(OLIBS)
  161.  
  162. subsample: subsample.o
  163.     cc $(CFLAGS) subsample.o -o subsample $(OLIBS)
  164.  
  165. subarea: subarea.o
  166.     cc $(CFLAGS) subarea.o -o subarea $(OLIBS)
  167.  
  168. thresh: thresh.o
  169.     cc $(CFLAGS) thresh.o -o thresh $(OLIBS) -lm
  170.  
  171. normalise: normalise.o
  172.     cc $(CFLAGS) normalise.o -o normalise $(OLIBS)
  173.  
  174. ffill: ffill.o
  175.     cc $(CFLAGS) ffill.o -o ffill $(OLIBS)
  176.  
  177. lib: alvlib.o dynamem.o
  178.     ar rc libalv.a alvlib.o dynamem.o
  179.     ranlib libalv.a
  180.     ar rc libdynamem.a dynamem.o
  181.     ranlib libdynamem.a
  182.     mv libalv.a libdynamem.a $(LIBDIR)
  183.     touch lib
  184.     
  185. wc: 
  186.     @wc *.c | sort -n
  187.  
  188. clean:
  189.     @touch dummy.o
  190.     @/bin/rm *.o
  191.  
  192. troff:
  193.     troff -t -man alv.1 | thack | pspr
  194.     troff -t -man alv.3 | thack | pspr
  195.     troff -t -man alv.5 | thack | pspr
  196. End of Makefile
  197.  echo addhead.c 1>&2
  198. cat >addhead.c <<'End of addhead.c'
  199. #include <stdio.h>
  200.  
  201. main(argc,argv)
  202. int argc;
  203. char **argv;
  204. {
  205.     int i,j;
  206.     int xsize,ysize;
  207.     unsigned char **pic;
  208.     char *file, *title;
  209.     FILE *fp;
  210.  
  211.     if (argc!=5) {
  212.         fprintf(stderr,"Usage: %s: x y filename title\n",argv[0]);
  213.         exit(-1);
  214.         }
  215.  
  216.     xsize=atoi(argv[1]);
  217.     ysize=atoi(argv[2]);
  218.     file =argv[3];
  219.     title =argv[4];
  220.  
  221.     if (!(fp=fopen(file,"r"))) {
  222.         fprintf(stderr,"Cannot open %s\n",file);
  223.         exit(-1);
  224.         }
  225.  
  226.     pic = (unsigned char **) dynamem (&pic, sizeof(unsigned char), 2, ysize, xsize);
  227.  
  228.     putw(xsize<<16|ysize,stdout);
  229.  
  230.     for (i=0;i<252;i++,*title?title++:0)
  231.         putchar(*title?*title:0);
  232.     
  233.     for (j=0;j<ysize;j++)
  234.         for (i=0;i<xsize;i++)
  235.             pic[j][i]=getc(fp);
  236.  
  237.     for (j=0;j<ysize;j++)
  238.         for(i=0;i<xsize;i++)
  239.             putchar(pic[j][i]);
  240.     
  241.     fclose(fp);
  242. }
  243. End of addhead.c
  244.  echo alv.1 1>&2
  245. cat >alv.1 <<'End of alv.1'
  246. .\" .TH name section cent-foot
  247. .TH ALV 1 "4th December 1987"
  248. .SH NAME
  249. .\" name \- function
  250. alv \- standard ALV tools
  251. .SH SYNOPSIS
  252. .\" Bold keywords, Italic variables, [] options, | alternatives.
  253. wind_opts = [
  254. .BI -X n
  255. ] [
  256. .BI -Y n
  257. ] [
  258. .BI -x n
  259. ] [
  260. .BI -y n
  261. ]
  262. .br
  263. std_opts = 
  264. .RB [ -H ]
  265. [
  266. .BI -T title
  267. ]
  268. .RI [ filename ]
  269. .br
  270. .B dsp
  271. .RB [ -m ]
  272. .RB [ wind_opts ]
  273. .RB [ std_opts ]
  274. .br
  275. .B cdsp
  276. .RB [ -m ]
  277. .RB [ wind_opts ]
  278. .RB [ std_opts ]
  279. .br
  280. .B imagelw
  281. .RB [ wind_opts ]
  282. .RB [ std_opts ]
  283. .RB [ -t ]
  284. .RB [ -m ]
  285. .RB [ -c ]
  286. .RB [ - ]
  287. .br
  288. .B hist
  289. .RB [ -l ]
  290. .RB [ -v ]
  291. .RB [ wind_opts ]
  292. .RB [ std_opts ]
  293. .br
  294. .B thresh
  295. [
  296. .BI -t n
  297. ]
  298. .RB [ std_opts ]
  299. .br
  300. .B invert
  301. .RB [ std_opts ]
  302. .br
  303. .B normalise
  304. .RB [ std_opts ]
  305. .br
  306. .B range
  307. [
  308. .BI -l n
  309. ]
  310. [
  311. .BI -h n
  312. ]
  313. .RB [ std_opts ]
  314. .br
  315. .B convolve
  316. [
  317. .BI -f filtername
  318. ]
  319. .RB [ -e ]
  320. .RB [ -F ]
  321. .RB [ std_opts ]
  322. .br
  323. .B subsample
  324. .I xsize
  325. .I ysize
  326. .RB [ std_opts ]
  327. .br
  328. .B subarea
  329. [
  330. .BI -x n
  331. ]
  332. [
  333. .BI -y n
  334. ]
  335. [
  336. .BI -X n
  337. ]
  338. [
  339. .BI -Y n
  340. ]
  341. .RB [ std_opts ]
  342. .br
  343. .B pixval
  344. [
  345. .BI -x n
  346. ]
  347. [
  348. .BI -y n
  349. ]
  350. [
  351. .BI -X n
  352. ]
  353. [
  354. .BI -Y n
  355. ]
  356. .RB [ std_opts ]
  357. .br
  358. .B ffill
  359. .I "xpos ypos"
  360. .BI -b n 
  361. ]
  362. .RB [ std_opts ]
  363. .br
  364. .B retitle
  365. .RB [ std_opts ]
  366. .br
  367. .B convert
  368. .I xsize
  369. .I ysize
  370. .I filename
  371. .I title
  372. .br
  373. .B addhead
  374. .I xsize
  375. .I ysize
  376. .I filename
  377. .I title
  378. .br
  379. .B striphead
  380. .RB [ std_opts ]
  381. .br
  382.  
  383. .SH DESCRIPTION
  384. .\" Italic files, commands, IR manual-entry (manual-section)
  385. These tools comprise
  386. the majority of those
  387. needed for work on the
  388. .I ALV
  389. and
  390. .I Bubble
  391. projects.
  392. They use a standard
  393. file format, see 
  394. .IR alv (5).
  395. .I Dsp
  396. and
  397. .I cdsp
  398. display pictures
  399. on a monochrome
  400. and colour display
  401. respectively. (Place the mouse in the window
  402. created by 
  403. .I coltable 
  404. on a Colour Sun to see
  405. the image in false colour).
  406. .I Imagelw
  407. displays the picture on the
  408. Apple Laserwriter in
  409. The Sun Lounge.
  410. .I Hist
  411. displays histogram
  412. displays, either
  413. linearly or logorithmically.
  414. .I Thresh
  415. thresholds data on a
  416. picture using either
  417. a specified threshold
  418. value or an automatically
  419. generated one.
  420. .I Invert
  421. inverts all the data in
  422. an image.
  423. .I Normalise
  424. normalises the histogram
  425. of an image.
  426. .I Range 
  427. stretches the grey level distribution
  428. of an image.
  429. .I Convolve
  430. performs a convolution
  431. on an image using 
  432. a specified filter.
  433. .I Subsample
  434. reduces the picture
  435. size by subsampling
  436. the original picture
  437. (but can also be used
  438. to enlarge).
  439. .I Subarea
  440. creates a new picture
  441. which is a part of the
  442. original picture.
  443. .I Pixval
  444. enables a decimal valued
  445. print of an area of an
  446. image to be generated.
  447. .I Ffill
  448. flood fills an image based
  449. around a small point, with
  450. a specified boundary colour.
  451. .I Retitle
  452. gives a picture a new title.
  453. .I Convert
  454. converts a file stored in the old 
  455. alv file format to the new.
  456. .I Addhead
  457. adds a header, thus converting
  458. it to the standard file format, 
  459. to a file produced
  460. by, for example, the 
  461. .I "ALV Framegrabber."
  462. .I Striphead
  463. removes a header from an image.
  464. .SH OPTIONS
  465. .\" Itemised list of options
  466. .TP 4
  467. Window Options
  468. -Xn           window x size is n
  469. .br
  470. -Yn           window y size is n
  471. .br
  472. -xn           window x offset is n
  473. .br
  474. -yn           window y offset is n
  475. .br
  476. .TP 4
  477. Standard Options
  478. -H            give help list
  479. .br
  480. -Ttitle       output-image title
  481. .br
  482. filename      read from filename
  483. .br
  484. .TP 4
  485. Dsp/Cdsp Options
  486. -m            use backing pixrect
  487. .br
  488. .TP 4
  489. Imagelw Options
  490. -T            produce TeX special file
  491. .br
  492. -m            send mail on completion of print
  493. .br
  494. -c            automatically scale picture to fit page
  495. .br
  496. -             write Postscript program to standard output
  497. .br
  498. .TP 4
  499. Hist Options
  500. -l            logarithmic scaling
  501. .br
  502. -v            vertical lines off
  503. .br
  504. .TP 4
  505. Thresh Options
  506. -tn           threshold value
  507. .br
  508. .TP 4
  509. Normalise Options
  510. -ln           least normalise value
  511. .br
  512. -hn           highest normalise value
  513. .br
  514. .TP 4
  515. Convolve Options
  516. -ffiltername  use filter filtername
  517. .br
  518. -e            enhanced scaling
  519. .br
  520. -F            list all filters
  521. .br
  522. .TP 4
  523. Pixval Options
  524. -Xn           x size
  525. .br
  526. -Yn           y size
  527. .br
  528. -xn           x offset
  529. .br
  530. -yn           y offset
  531. .br
  532. .TP 4
  533. Ffill Options
  534. -bn           boundary grey level
  535. .br
  536. .\".SH FILES
  537. .\" List of all files used by the program
  538. .SH "SEE ALSO"
  539. .\" List of references, textual, and MAN pages.
  540. alv(3), alv(5).
  541. .\".SH DIAGNOSTICS
  542. .\" List of error messages and return codes the user may expect
  543. .SH BUGS
  544. .\" Known Limitations or Desirable additions to the command
  545. The code to pick out the filename from the command arguments 
  546. list is unreliable in some cases. (It will core dump). 
  547. This can be avoided by using cat to pipe the file into the
  548. command.
  549. End of alv.1
  550.  echo alv.3 1>&2
  551. cat >alv.3 <<'End of alv.3'
  552. .\" .TH name section cent-foot left-foot cent-head
  553. .TH ALV 3 "4th December 1987"
  554. .SH NAME
  555. .\" name \- function
  556. alv \- standard library functions
  557. .SH SYNOPSIS
  558. .\" Bold keywords, Italic variables, [] options, | alternatives.
  559. typedef struct img {
  560. .br
  561.     unsigned char **image;
  562. .br
  563.     short xsize, ysize;
  564. .br
  565.     char title[252];
  566. .br
  567. } IMAGE;
  568. .sp
  569. int winxsize, winysize,
  570. .br
  571.     winxoff,  winyoff;
  572. .br
  573. int helpflag;
  574. .br
  575. char *newtitle;
  576. .sp
  577. IMAGE *readimage(fp)
  578. .br
  579. FILE *fp;
  580. .sp
  581. writeimage(fp,image)
  582. .br
  583. FILE *fp;
  584. .br
  585. IMAGE *image;
  586. .sp
  587. IMAGE *newimage(xsize,ysize,title)
  588. .br
  589. int xsize,ysize;
  590. .br
  591. char *title
  592. .sp
  593. subsample(image1,image2)
  594. .br
  595. IMAGE *image1,*image2;
  596. .sp
  597. subarea(image1,image2,xoff,yoff)
  598. .br
  599. IMAGE *image1,*image2;
  600. .br
  601. int xoff,yoff;
  602. .sp
  603. stdopts(argc,argv)
  604. .br
  605. int *argc;
  606. .br
  607. char **argv;
  608. .sp
  609. windopts(argc,argv)
  610. .br
  611. int *argc;
  612. .br
  613. char **argv;
  614. .SH DESCRIPTION
  615. .\" Italic files, commands, IR manual-entry (manual-section)
  616. .I Readin
  617. reads in an image from
  618. the specified file, and
  619. creates an image structure
  620. with all the relevant
  621. data contained in it.
  622. .I Writeout
  623. writes the specified
  624. image to the specified
  625. file.
  626. .I Newimage
  627. creates a new
  628. image of the specified
  629. dimensions.
  630. .I Subsample
  631. reproduces the whole
  632. of
  633. .I image1
  634. in
  635. .I image2
  636. suitably scaled (up or
  637. down) so as to make
  638. it fit into the available
  639. room in
  640. .IR image2 .
  641. .I Subarea
  642. reproduces the relevant
  643. part of
  644. .I image1
  645. in
  646. .I image2
  647. so that
  648. .I image2
  649. has the same resolution as
  650. .I image1
  651. and is as full as possible
  652. (note that it is possible
  653. to use this also to increase
  654. the size of an image).
  655. .I Stdopts
  656. parses the
  657. .B -t
  658. and
  659. .B -h options
  660. setting
  661. .I helpflag
  662. and
  663. .IR newtitle .
  664. .I Windopts
  665. parses the
  666. .BR -x , -y , -X ,
  667. .B -Y
  668. options setting
  669. the variables
  670. .IR winxsize , winysize , winxoff ,
  671. .IR winyoff .
  672. .\".SH FILES
  673. .\" List of all files used by the program
  674. .SH "SEE ALSO"
  675. .\" List of references, textual, and MAN pages.
  676. alv(1),alv(3).
  677. .\".SH DIAGNOSTICS
  678. .\" List of error messages and return codes the user may expect
  679. .\".SH BUGS
  680. .\" Known Limitations or Desirable additions to the command
  681. End of alv.3
  682.  echo alv.5 1>&2
  683. cat >alv.5 <<'End of alv.5'
  684. .\" .TH name section cent-foot left-foot cent-head
  685. .TH ALV 5 "4th December 1987"
  686. .SH NAME
  687. .\" name \- function
  688. alv \- common file format
  689. .SH SYNOPSIS
  690. .\" Bold keywords, Italic variables, [] options, | alternatives.
  691. typedef struct img {
  692. .br
  693.     unsigned char **image;
  694. .br
  695.     short xsize, ysize;
  696. .br
  697.     char title[252];
  698. .br
  699. } IMAGE;
  700. .SH DESCRIPTION
  701. .\" Italic files, commands, IR manual-entry (manual-section)
  702. This is the newly approved
  703. "standard" file format for 
  704. image processing work
  705. done by the
  706. .I alv
  707. group at Bristol University.
  708. The file consists of a 256-byte
  709. header followed by
  710. .I ysize
  711. rows each
  712. .I xsize
  713. in length.
  714. The header consists of a
  715. two-byte value for
  716. .IR xsize ,
  717. a two-byte value for
  718. .IR ysize ,
  719. and a 252-byte title,
  720. which may be interpreted
  721. as appropriate by any tool.
  722. .\".SH OPTIONS
  723. .\" Itemised list of options
  724. .\".SH FILES
  725. .\" List of all files used by the program
  726. .SH "SEE ALSO"
  727. .\" List of references, textual, and MAN pages.
  728. alv(1),alv(3)
  729. .\".SH DIAGNOSTICS
  730. .\" List of error messages and return codes the user may expect
  731. .\".SH BUGS
  732. .\" Known Limitations or Desirable additions to the command
  733. End of alv.5
  734.  echo alvlib.c 1>&2
  735. cat >alvlib.c <<'End of alvlib.c'
  736. #include <stdio.h> 
  737. #include "image.h" 
  738.  
  739. int winxsize=0,winysize=0,
  740.     winxoff=0, winyoff=0;
  741. int helpflag;
  742. char *newtitle=0;
  743.  
  744. IMAGE *readimage(fp)
  745. FILE *fp;
  746. {
  747.     int i, j, xsize, ysize;
  748.     char title[252];
  749.     IMAGE *img, *newimage();
  750.  
  751.     i=getw(fp);
  752.  
  753.     for(j=0;j<252;j++)
  754.         title[j]=getc(fp);
  755.  
  756.     img = newimage(xsize=(i>>16),ysize=(i&65535),title);
  757.  
  758.     for(j=0;j<ysize;j++)
  759.         for(i=0;i<xsize;i++)
  760.             (img->image[j][i])=getc(fp);     /* UGH! */
  761.  
  762.     return img;
  763. }
  764.  
  765. writeimage(fp,image)
  766. FILE *fp;
  767. IMAGE *image;
  768. {
  769.     int i,j;
  770.  
  771.     putw(image->xsize<<16|image->ysize,fp);
  772.  
  773.     for(j=0;j<252;j++)
  774.         putc(image->title[j],fp);
  775.  
  776.     for(j=0;j<image->ysize;j++)
  777.         for(i=0;i<image->xsize;i++)
  778.             putc(image->image[j][i],fp);
  779.  
  780. }
  781.  
  782. IMAGE *newimage(xsize,ysize,title)
  783. int xsize,ysize;
  784. char *title;
  785. {
  786. IMAGE *img;
  787. int i;
  788.  
  789.     if ((img=(IMAGE *)malloc(sizeof(IMAGE)))==NULL)
  790.         return 0;
  791.     if ((img->image = (unsigned char **) dynamem (&(img->image), sizeof(unsigned char), 2, ysize, xsize))==NULL)
  792.         return 0;
  793.     img->xsize=xsize;
  794.     img->ysize=ysize;
  795.     for (i=0;i<252;i++)
  796.         img->title[i]=0;
  797.     strcpy(img->title,title);
  798.     return img;
  799. }
  800.  
  801. subsample(image1,image2)
  802. IMAGE *image1,*image2;
  803. {
  804. int cvx,cvy,lcx,lcy,hcx,hcy;
  805. register int i,j,i1,j1;
  806. int total;
  807.  
  808.     cvx=(100*image1->xsize)/image2->xsize;
  809.     cvy=(100*image1->ysize)/image2->ysize;
  810.  
  811.     for (j=0;j<image2->ysize;j++)
  812.         for (i=0;i<image2->xsize;i++)
  813.         {
  814.             hcx=i*cvx/100;
  815.             hcy=j*cvy/100;
  816.             lcx=(i-1)*cvx/100+1;
  817.             lcy=(j-1)*cvy/100+1;
  818.             lcx=(lcx<0)?0:(lcx>hcx)?hcx:lcx;
  819.             lcy=(lcy<0)?0:(lcy>hcy)?hcy:lcy;
  820.  
  821.             total=0;
  822.             for (j1=lcy;j1<=hcy;j1++)
  823.                 for (i1=lcx;i1<=hcx;i1++)
  824.                     total+=image1->image[j1][i1];
  825.             image2->image[j][i]=total/((hcx+1-lcx)*(hcy+1-lcy));
  826.         }
  827. }
  828.  
  829. subarea(image1,image2,xoff,yoff)
  830. IMAGE *image1,*image2;
  831. int xoff,yoff;
  832. {
  833. int xmin,ymin,
  834.     xmax,ymax;
  835. int i,j;
  836.  
  837.     xmin=(xoff<0)?0:xoff;
  838.     ymin=(yoff<0)?0:yoff;
  839.     xmax=image2->xsize+xoff;
  840.     ymax=image2->ysize+yoff;
  841.     xmax=(xmax>image1->xsize)?image1->xsize:xmax;
  842.     ymax=(ymax>image1->ysize)?image1->ysize:ymax;
  843.  
  844.     for (j=ymin;j<ymax;j++)
  845.         for (i=xmin;i<xmax;i++)
  846.             image2->image[j-yoff][i-xoff]=image1->image[j][i];
  847. }
  848.  
  849. stdopts(argc,argv)
  850. char **argv;
  851. int *argc;
  852. {
  853. int testflag;
  854. char **p;
  855.  
  856.     helpflag=0;
  857.     for (argv++;*argv;argv++)
  858.         if (**argv=='-') {
  859.             testflag=1;
  860.             switch ((*argv)[1]) {
  861.             case 'H': helpflag = 1;
  862.                       break;
  863.             case 'T': newtitle= *argv+2;
  864.                       break;
  865.             default:
  866.                 testflag=0;
  867.             }
  868.             if (testflag)
  869.             {
  870.                 for (p=argv;*p;p++)
  871.                     p[0] = p[1];
  872.                 (*argc)--;
  873.                 argv--;
  874.             }
  875.         }
  876. }
  877.  
  878. windopts(argc,argv)
  879. char **argv;
  880. int *argc;
  881. {
  882. int testflag;
  883. char **p;
  884.  
  885.     for (argv++;*argv;argv++)
  886.         if (**argv=='-') {
  887.             testflag=1;
  888.             switch ((*argv)[1]) {
  889.             case 'X': winxsize=atoi(*argv+2);
  890.                       break;
  891.             case 'Y': winysize=atoi(*argv+2);
  892.                       break;
  893.             case 'x': winxoff=atoi(*argv+2);
  894.                       break;
  895.             case 'y': winyoff=atoi(*argv+2);
  896.                       break;
  897.             default:
  898.                 testflag=0;
  899.             }
  900.             if (testflag)
  901.             {
  902.                 for (p=argv;*p;p++)
  903.                     p[0] = p[1];
  904.                 (*argc)--;
  905.                 argv--;
  906.             }
  907.         }
  908. }
  909. End of alvlib.c
  910.  echo avg1 1>&2
  911. cat >avg1 <<'End of avg1'
  912. 7 7
  913.  
  914. 1 1 1 1 1 1 1
  915. 1 1 1 1 1 1 1
  916. 1 1 1 1 1 1 1
  917. 1 1 1 1 1 1 1
  918. 1 1 1 1 1 1 1
  919. 1 1 1 1 1 1 1
  920. 1 1 1 1 1 1 1
  921. End of avg1
  922.  echo cdsp.c 1>&2
  923. cat >cdsp.c <<'End of cdsp.c'
  924. #include <suntool/sunview.h>
  925. #include <suntool/canvas.h>
  926. #include "image.h"
  927. #include <stdio.h>
  928.  
  929. int boxsize = 1, mflag = 0;
  930. static void getcoords();
  931. static void repaint_canvas();
  932. IMAGE *image;
  933.  
  934. main(argc, argv)
  935. int argc;
  936. char **argv;
  937.  
  938. {
  939.     Frame frame;
  940.     Canvas canvas;
  941.     Pixwin *pw;
  942.     Cursor cursor;
  943.     char cmsname[CMS_NAMESIZE];
  944.     u_char red[256], green[256], blue[256];
  945.     int i, j, x, y;
  946.     FILE *fp, *fopen();
  947.     u_char *pi;
  948.     char *imagefile=NULL;
  949.  
  950.     stdopts(&argc,argv);
  951.     windopts(&argc,argv);
  952.  
  953.     for (argv++;*argv;*argv++)
  954.         if (**argv=='-' && (*argv)[1]=='m') 
  955.             mflag = 1;
  956.         else imagefile= *argv;
  957.  
  958.     if (imagefile==NULL)
  959.         fp=stdin;
  960.     else if (!(fp = fopen(imagefile,"r"))) {
  961.         fprintf(stderr,"Cannot open %s\n",imagefile);
  962.         exit(-1);
  963.         }
  964.  
  965.     image = readimage(fp);
  966.  
  967.     /* Initialise variables used to set colour map segment */
  968.     for (i = 0; i < 256; i++) {
  969.         red[i] = i;
  970.         green[i] = i;
  971.         blue[i] = i;
  972.     }
  973.  
  974.     cursor = cursor_create(CURSOR_CROSSHAIR_COLOR, 255,
  975.                    CURSOR_SHOW_CURSOR, FALSE,
  976.                    CURSOR_SHOW_CROSSHAIRS, TRUE,
  977.                    CURSOR_CROSSHAIR_LENGTH, 20,
  978.                    CURSOR_CROSSHAIR_GAP, 5,
  979.                    0);
  980.  
  981.     /* create frame and canvas */
  982.     frame = window_create(NULL, FRAME,
  983.                   FRAME_LABEL, (newtitle)?newtitle:image->title,
  984.                   WIN_X, winxoff,
  985.                   WIN_Y, winyoff,
  986.                   WIN_HEIGHT, (winxsize)?winxsize:image->ysize * boxsize + 22,
  987.                   WIN_WIDTH, (winysize)?winysize:image->xsize * boxsize + 10,
  988.                   0);
  989.  
  990.     if (mflag)
  991.         canvas = window_create(frame, CANVAS,
  992.                        CANVAS_HEIGHT, image->ysize * boxsize,
  993.                        CANVAS_WIDTH, image->xsize * boxsize,
  994.                        WIN_CURSOR, cursor,
  995.                        WIN_EVENT_PROC, getcoords,
  996.                        0);
  997.     else
  998.         canvas = window_create(frame, CANVAS,
  999.                        CANVAS_HEIGHT, image->ysize * boxsize,
  1000.                        CANVAS_WIDTH, image->xsize * boxsize,
  1001.                        WIN_CURSOR, cursor,
  1002.                        WIN_EVENT_PROC, getcoords,
  1003.                        CANVAS_RETAINED, FALSE,
  1004.                        CANVAS_REPAINT_PROC, repaint_canvas,
  1005.                        0);
  1006.  
  1007.     /* get the canvas pixwin to draw into */
  1008.     pw = canvas_pixwin(canvas);
  1009.  
  1010.     /* Set colour map segment */
  1011.     pw_setcmsname(pw, "grays");
  1012.     pw_putcolormap(pw, 0, 256, red, green, blue);
  1013.  
  1014.     if (mflag) {
  1015.         /* Enable batching for efficiency */
  1016.         pw_batch_on(pw);
  1017.  
  1018.         /* Draw gray boxes */
  1019.         pi = image->image[0];
  1020.         for (y = 0; y < image->ysize; y++)
  1021.             for (x = 0; x < image->xsize; x++) {
  1022.                 pw_put(pw, x, y, *pi);
  1023.                 pi++;
  1024.             }
  1025.         pw_batch_off(pw);
  1026.     }
  1027.  
  1028.     window_main_loop(frame);
  1029. }
  1030.  
  1031. static void
  1032. repaint_canvas(canvas, pw, repaint_area)
  1033. Canvas canvas;
  1034. Pixwin *pw;
  1035. Rectlist *repaint_area;
  1036. {
  1037.     u_char *pi;
  1038.     int x, y;
  1039.     int xstart, ystart, xstop, ystop;
  1040.  
  1041.     xstart = repaint_area->rl_bound.r_left / boxsize;
  1042.     ystart = repaint_area->rl_bound.r_top / boxsize;
  1043.     xstop = xstart + 1 + repaint_area->rl_bound.r_width / boxsize;
  1044.     ystop = ystart + 1 + repaint_area->rl_bound.r_height / boxsize;
  1045.  
  1046.     xstop = (xstop > image->xsize) ? image->xsize : xstop;
  1047.     ystop = (ystop > image->ysize) ? image->ysize : ystop;
  1048.  
  1049.     /* Enable locking for efficiency */
  1050.  
  1051.     /* Draw gray boxes */
  1052.     for (y = ystart; y < ystop; y++) {
  1053.         pi = &(image->image[y][xstart]);
  1054.         pw_lock(pw, &(repaint_area->rl_bound));
  1055.         for (x = xstart; x < xstop; x++) {
  1056.             /* Fill in a square box */
  1057.             pw_put(pw, x, y, *pi);
  1058.             pi++;
  1059.         }
  1060.         pw_unlock(pw);
  1061.     }
  1062. }
  1063.  
  1064. static void
  1065. getcoords(canvas, event, arg)
  1066. Canvas canvas;
  1067. Event *event;
  1068. caddr_t arg;
  1069. {
  1070.     if ((event_id(event) == MS_LEFT) && event_is_down(event)) {
  1071.         printf("%s: locator x,y : %d %d \n", (newtitle)?newtitle:image->title,
  1072.                event_x(event) / boxsize, event_y(event) / boxsize);
  1073.     }
  1074. }
  1075. End of cdsp.c
  1076.  echo coltable.c 1>&2
  1077. cat >coltable.c <<'End of coltable.c'
  1078. #include <suntool/sunview.h>
  1079. #include <suntool/canvas.h>
  1080. #include <stdio.h>
  1081. #include <math.h>
  1082.  
  1083. #define MINC 0
  1084.  
  1085. main(argc,argv)
  1086. int argc;
  1087. char ** argv;
  1088.  
  1089.    {
  1090.     Frame frame;
  1091.     Canvas canvas;
  1092.     Pixwin *pw;
  1093.     char cmsname[CMS_NAMESIZE];
  1094.     u_char red[256], green[256], blue[256];
  1095.     int i,ii,j,x,y;
  1096.     int delt,rem,region;
  1097.     int range ;
  1098.     float factor;
  1099.     char *tabname;
  1100.  
  1101.     range = 255 - MINC;
  1102.     delt = 43;
  1103.     factor = ((double)range)/(delt-1);
  1104.     tabname = (argv[0][0] == 'i') ? "icols" : "cols";
  1105.  
  1106.     /* Initialise variables used to set colour map segment */
  1107.     for (ii=0 ; ii<256 ; ii++)
  1108.     {
  1109.        i = (argv[0][0] == 'i') ? 255 - ii : ii ;
  1110.  
  1111.        region = ii/delt;
  1112.        rem = ii % delt;
  1113.  
  1114.        switch (region) {
  1115.  
  1116.        case 0 :
  1117.           red[i]   =  range +MINC ;
  1118.           green[i] =  range - rem* factor +MINC ;
  1119.           blue[i]  =  range - rem* factor +MINC;
  1120.           break;
  1121.  
  1122.        case 1 :
  1123.           red[i] = range +MINC;
  1124.           green[i] = rem * factor +MINC ;
  1125.           blue[i] = 0 +MINC ;
  1126.           break;
  1127.  
  1128.        case 2:
  1129.           red[i] = range - rem* factor +MINC ;
  1130.           green[i] = range +MINC ;
  1131.           blue[i] = 0 +MINC ;
  1132.           break;
  1133.  
  1134.        case 3:
  1135.           red[i] = 0 +MINC ;
  1136.           green[i] = range +MINC ;
  1137.           blue[i] = rem * factor +MINC ;
  1138.           break;
  1139.    
  1140.        case 4:
  1141.           red[i] = 0 +MINC ;
  1142.           green[i] = range - rem * factor +MINC ;
  1143.           blue[i] = range +MINC ;
  1144.           break;
  1145.  
  1146.        case 5:
  1147.        default:
  1148.           red[i] = rem * factor +MINC ;
  1149.           blue[i] = range +MINC ;
  1150.           green[i] = 0 +MINC ;
  1151.           break;
  1152.  
  1153.        } /* end switch */
  1154.  
  1155.     /* cludge to give more yellow etc */
  1156.     red[i] = sqrt((double)(red[i]-MINC))*sqrt((double)range) +MINC;
  1157.     blue[i] = sqrt((double)(blue[i]-MINC))*sqrt((double)range) +MINC;
  1158.     green[i] = sqrt((double)(green[i]-MINC))*sqrt((double)range) +MINC;
  1159.     }
  1160.  
  1161.     /* create frame and canvas */
  1162.     frame = window_create(NULL, FRAME,
  1163.     WIN_HEIGHT,    50,
  1164.     WIN_WIDTH,     100,
  1165.     0);
  1166.     canvas = window_create(frame,CANVAS, 0);
  1167.  
  1168.  
  1169.     /* get the cancas pixwin to draw into */
  1170.     pw = canvas_pixwin(canvas);
  1171.  
  1172.     /* Set colour map segment */
  1173.     pw_setcmsname(pw, tabname);
  1174.     pw_putcolormap(pw, 0, 256, red, green, blue);
  1175.  
  1176.     pw_batch_on(pw);
  1177.  
  1178.     window_main_loop(frame);
  1179.  
  1180.     exit(0);
  1181.    }
  1182. End of coltable.c
  1183.  echo convert.c 1>&2
  1184. cat >convert.c <<'End of convert.c'
  1185. #include <stdio.h>
  1186.  
  1187. main(argc,argv)
  1188. int argc;
  1189. char **argv;
  1190. {
  1191.     int i,j;
  1192.     int xsize,ysize;
  1193.     unsigned char **pic;
  1194.     char *file, *title;
  1195.     FILE *fp;
  1196.  
  1197.     if (argc!=5) {
  1198.         fprintf(stderr,"Usage: %s: x y filename title\n",argv[0]);
  1199.         exit(-1);
  1200.         }
  1201.  
  1202.     xsize=atoi(argv[1]);
  1203.     ysize=atoi(argv[2]);
  1204.     file =argv[3];
  1205.     title =argv[4];
  1206.  
  1207.     if (!(fp=fopen(file,"r"))) {
  1208.         fprintf(stderr,"Cannot open %s\n",file);
  1209.         exit(-1);
  1210.         }
  1211.  
  1212.     pic = (unsigned char **) dynamem (&pic, sizeof(unsigned char), 2, ysize, xsize);
  1213.  
  1214.     putw(xsize<<16|ysize,stdout);
  1215.  
  1216.     for (i=0;i<252;i++,*title?title++:0)
  1217.         putchar(*title?*title:0);
  1218.     
  1219.     for (i=0;i<xsize;i++)
  1220.         for (j=0;j<ysize;j++)
  1221.             pic[j][i]=getc(fp);
  1222.  
  1223.     for (j=0;j<ysize;j++)
  1224.         for(i=0;i<xsize;i++)
  1225.             putchar(pic[j][i]);
  1226.     
  1227.     fclose(fp);
  1228. }
  1229. End of convert.c
  1230.  echo convolve.c 1>&2
  1231. cat >convolve.c <<'End of convolve.c'
  1232. #include <stdio.h>
  1233. #include "image.h"
  1234.  
  1235. char *filtername=NULL;
  1236. int eflag = 0,
  1237.     fflag = 0;
  1238.  
  1239. typedef struct {
  1240.     char **image;
  1241.     short xsize,ysize;
  1242.     char title[252];
  1243. } FILTER;
  1244.  
  1245. main(argc,argv)
  1246. char **argv;
  1247. {
  1248.     char *imagefile=NULL;
  1249.     FILE *fp;
  1250.     IMAGE *image, *outimage;
  1251.     FILTER *filter, *loadfilter();
  1252.  
  1253.     stdopts(&argc,argv);
  1254.  
  1255.     if (helpflag) {
  1256.         help(*argv);
  1257.         exit(0);
  1258.     }
  1259.     
  1260.     for(argv++;*argv;argv++) 
  1261.         if ((**argv)=='-')
  1262.             switch ((*argv)[1]) {
  1263.             case 'e':
  1264.                 eflag=1;
  1265.                 break;
  1266.             case 'f':
  1267.                 filtername=argv[0]+2;
  1268.                 break;
  1269.             case 'F':
  1270.                 fflag=1;
  1271.                 break;
  1272.             }
  1273.         else imagefile= *argv;
  1274.     
  1275.     if (fflag) 
  1276.         execlp("ls","ls","-C","FILTERS_DIR");
  1277.     
  1278.     if (filtername) 
  1279.         filter=loadfilter(filtername);
  1280.     
  1281.     if (imagefile) {
  1282.         if (!(fp=fopen(imagefile,"r"))) {
  1283.             fprintf(stderr,"Couldn't open %s\n",imagefile);
  1284.             exit(-1);
  1285.         }
  1286.     }
  1287.     else fp = stdin;
  1288.     
  1289.     image=readimage(fp);
  1290.     outimage=newimage(image->xsize,image->ysize,(newtitle)?newtitle:image->title);
  1291.     if (filtername) {
  1292.         strcat(outimage->title," | ");
  1293.         strcat(outimage->title,filtername);
  1294.     }
  1295.  
  1296.     runfilter(filter,image,outimage);
  1297.  
  1298.     writeimage(stdout,outimage);
  1299. }
  1300.  
  1301. FILTER *
  1302. loadfilter(name)
  1303. char *name;
  1304. {
  1305.     char buf[BUFSIZ];
  1306.     FILE *fp;
  1307.     FILTER *filter;
  1308.     int xsize,ysize,ival;
  1309.     register int i,j;
  1310.  
  1311.     strcpy(buf,"FILTERS_DIR");
  1312.     strcat(buf,"/");
  1313.     strcat(buf,name);
  1314.  
  1315.     if (!(fp=fopen(buf,"r"))) {
  1316.         fprintf(stderr,"Couldn't open filter %s\n",name);
  1317.         exit(-1);
  1318.     }
  1319.     
  1320.     fscanf(fp,"%d %d",&xsize,&ysize);
  1321.     filter=(FILTER *)newimage(xsize,ysize,name);
  1322.  
  1323.     for(j=0;j<ysize;j++)
  1324.         for(i=0;i<xsize;i++) {
  1325.             fscanf(fp,"%d",&ival);
  1326.             filter->image[j][i]=ival;
  1327.         }
  1328.     
  1329.     return filter;
  1330. }
  1331.  
  1332. runfilter(filter,image,outimage)
  1333. IMAGE *image, *outimage;
  1334. FILTER *filter;
  1335. {
  1336.     int nflag = 0,
  1337.         scale,
  1338.         total;
  1339.     short max= -32768,
  1340.           min=  32767,
  1341.           **tempimage;
  1342.     int mfy = filter->ysize>>1,
  1343.         mfx = filter->xsize>>1;
  1344.     register int fi,fj,i,j;
  1345.     int sneg=0,
  1346.         spos=0,
  1347.         fred;
  1348.  
  1349.     for(j=0;j<filter->ysize;j++)
  1350.         for(i=0;i<filter->xsize;i++)
  1351.             if (filter->image[j][i]<0) {
  1352.                 nflag=1;
  1353.                 sneg -= filter->image[j][i];
  1354.             }
  1355.             else spos += filter->image[j][i];
  1356.  
  1357.     scale = (sneg > spos) ? sneg : spos;
  1358.     scale = (nflag) ? scale*2 : scale;
  1359.  
  1360.     if (!eflag)
  1361.         for(j=0;j<image->ysize-filter->ysize;j++)
  1362.             for(i=0;i<image->xsize-filter->ysize;i++) {
  1363.                 total=0;
  1364.                 for(fj=0;fj<filter->ysize;fj++)
  1365.                     for(fi=0;fi<filter->xsize;fi++) {
  1366.                         fred = image->image[j+fj][i+fi];
  1367.                         total += fred * filter->image[fj][fi];
  1368.                     }
  1369.                 outimage->image[j+mfy][i+mfx] = total / scale + ((nflag) ? 128 : 0);
  1370.             }
  1371.     else {
  1372.         if (!(tempimage=(short **)
  1373.                 dynamem(&tempimage,sizeof(short),2,image->ysize,image->xsize))) {
  1374.             fprintf(stderr,"Get some more VM !!!\n");
  1375.             exit(-1);
  1376.         }
  1377.         for(j=0;j<image->ysize-filter->ysize;j++)
  1378.             for(i=0;i<image->xsize-filter->ysize;i++) {
  1379.                 total=0;
  1380.                 for(fj=0;fj<filter->ysize;fj++)
  1381.                     for(fi=0;fi<filter->xsize;fi++) {
  1382.                         fred = image->image[j+fj][i+fi];
  1383.                         total += filter->image[fj][fi] * fred;
  1384.                     }
  1385.                 tempimage[j+mfy][i+mfx] = total;
  1386.                 max=(max>total)?max:total;
  1387.                 min=(min<total)?min:total;
  1388.             }
  1389.  
  1390.         scale=(max>-min)?max:-min;
  1391.         scale=(nflag)?scale*2:scale;
  1392.  
  1393.         for (j=0; j< image->ysize; j++)
  1394.             for (i=0; i<image->xsize;i++)
  1395.                 outimage->image[j][i]=tempimage[j][i]*256/scale+((nflag)?128:0);
  1396.     }
  1397. }
  1398.  
  1399. help(name)
  1400. char *name;
  1401. {
  1402.     printf("Convolution Filter\n");
  1403.     printf("------------------\n");
  1404.     printf("\nUsage: %s [file]\n",name);
  1405.     printf("\nOptions:\n");
  1406.     printf("  -F       list filters\n");
  1407.     printf("  -ffilter use filter\n");
  1408.     printf("  -e       enhanced scaling\n");
  1409.     printf("  -h       help\n");
  1410. }
  1411. End of convolve.c
  1412.  echo defs.h 1>&2
  1413. cat >defs.h <<'End of defs.h'
  1414. #define YES     1
  1415. #define NO   0
  1416. #define FILTERS_DIR        "/usr/aloha/alv/everson/usr/filters"
  1417. #define ERROR(S)    { fprintf(stderr,"%s: %s\n",progname,S); exit(1); }
  1418. #define FIL_MAX     31            /* max dimension of a filter */
  1419. #define XSIZE        256
  1420. #define    YSIZE        240
  1421.  
  1422. int filter[FIL_MAX][FIL_MAX];            /* filter array */
  1423. char progname[10];        /* program name */
  1424. short old_maxch,        /* max pixel value in the picture */
  1425.       old_minch,        /* min pixel value in the picture */
  1426.       maxch,            /* max pixel value in image */
  1427.       minch,            /* min pixel value in image */
  1428.       abs_minch;        /* min absolute pixel value in image */
  1429.  
  1430. unsigned char **pic,
  1431.               **image;;
  1432. short **eimage;
  1433.  
  1434. int pic_trunc;                /* truncation value */
  1435. int xsize,
  1436.     ysize,
  1437.     m_fil,                /* height of filter */
  1438.     n_fil,                /* width of filter */
  1439.     fil_scale;            /* scaling factor used to scale image to character
  1440.                            values after running the filter */
  1441. extern int negfilter,
  1442.            enhanced;
  1443. End of defs.h
  1444.  echo dsp.c 1>&2
  1445. cat >dsp.c <<'End of dsp.c'
  1446. #include <suntool/sunview.h>
  1447. #include <suntool/canvas.h>
  1448. #include <stdio.h>
  1449. #include "image.h"
  1450. #include "pattern3.h"
  1451.  
  1452. int boxsize = 3;
  1453. static void getcoords();
  1454. static void repaint_canvas();
  1455. IMAGE *image;
  1456. int *p_pat;
  1457. int mflag = 0;
  1458. Pixrect *pattern;
  1459.  
  1460. main(argc, argv)
  1461. int argc;
  1462. char **argv;
  1463. {
  1464.     Frame frame;
  1465.     Canvas canvas;
  1466.     Pixwin *pw;
  1467.     char cmsname[CMS_NAMESIZE];
  1468.     int i, j, x, y;
  1469.     FILE *fp, *fopen();
  1470.     u_char *pi;
  1471.     char *imagefile=NULL;
  1472.  
  1473.     stdopts(&argc,argv);
  1474.     windopts(&argc,argv);
  1475.  
  1476.     for (argv++;*argv;*argv++)
  1477.         if (*argv[0]=='-' && (*argv)[1]=='m') 
  1478.             mflag = 1;
  1479.         else imagefile= *argv;
  1480.  
  1481.     if (imagefile==NULL)
  1482.         fp=stdin;
  1483.     else if (!(fp = fopen(imagefile,"r"))) {
  1484.         fprintf(stderr,"Cannot open %s\n",imagefile);
  1485.         exit(-1);
  1486.         }
  1487.     image = readimage(fp);
  1488.  
  1489.     /* create frame and canvas */
  1490.     frame = window_create(NULL, FRAME,
  1491.                   FRAME_LABEL, (newtitle)?newtitle:image->title,
  1492.                   WIN_X, winxoff,
  1493.                   WIN_Y, winyoff,
  1494.                   WIN_HEIGHT, (winxsize)?winxsize:image->ysize * boxsize + 22,
  1495.                   WIN_WIDTH, (winysize)?winysize:image->xsize * boxsize + 10,
  1496.                   0);
  1497.  
  1498.  
  1499.     if (mflag)
  1500.         canvas = window_create(frame, CANVAS,
  1501.                        CANVAS_HEIGHT, image->ysize * boxsize,
  1502.                        CANVAS_WIDTH, image->xsize * boxsize,
  1503.                        WIN_EVENT_PROC, getcoords,
  1504.                        0);
  1505.     else
  1506.         canvas = window_create(frame, CANVAS,
  1507.                        CANVAS_FAST_MONO, TRUE,
  1508.                        CANVAS_HEIGHT, image->ysize * boxsize,
  1509.                        CANVAS_WIDTH, image->xsize * boxsize,
  1510.                        WIN_EVENT_PROC, getcoords,
  1511.                        CANVAS_RETAINED, FALSE,
  1512.                        CANVAS_REPAINT_PROC, repaint_canvas,
  1513.                        0);
  1514.  
  1515.  
  1516.     /* get the canvas pixwin to draw into */
  1517.     pw = canvas_pixwin(canvas);
  1518.  
  1519.     /* create dot pattern */
  1520.     pattern = mem_create(boxsize, boxsize * 50, 1);
  1521.     p_pat = &pat[0];
  1522.     for (y = 0; y < boxsize * 10; y++)
  1523.         for (x = 0; x < boxsize; x++, p_pat++)
  1524.             pr_rop(pattern, x, y, 1, 1,
  1525.                    (*p_pat) ? PIX_CLR : PIX_SET,
  1526.                    (Pixrect *) 0, 0, 0);
  1527.  
  1528.     if (mflag) {
  1529.         /* Draw gray boxes */
  1530.         for (y = 0; y < image->ysize; y++) {
  1531.             pi = image->image[y];
  1532.             for (x = 0; x < image->xsize; x++) {
  1533.                 /* Fill in a square box */
  1534.                 pw_rop(pw, x * boxsize, y * boxsize,
  1535.                        boxsize, boxsize,
  1536.                        PIX_SRC, pattern, 0, boxsize * ((*pi + 26) / 27));
  1537.                 pi++;
  1538.             }
  1539.         }
  1540.     }
  1541.  
  1542.     window_main_loop(frame);
  1543. }
  1544.  
  1545. static void
  1546. repaint_canvas(canvas, pw, repaint_area)
  1547. Canvas canvas;
  1548. Pixwin *pw;
  1549. Rectlist *repaint_area;
  1550.  
  1551. {
  1552.     u_char *pi;
  1553.     int x, y;
  1554.     int xstart, ystart, xstop, ystop;
  1555.  
  1556.     xstart = repaint_area->rl_bound.r_left / boxsize;
  1557.     ystart = repaint_area->rl_bound.r_top / boxsize;
  1558.     xstop = xstart + 1 + repaint_area->rl_bound.r_width / boxsize;
  1559.     ystop = ystart + 1 + repaint_area->rl_bound.r_height / boxsize;
  1560.  
  1561.     xstop = (xstop > image->xsize) ? image->xsize : xstop;
  1562.     ystop = (ystop > image->ysize) ? image->ysize : ystop;
  1563.  
  1564.     /* Enable locking for efficiency */
  1565.  
  1566.     /* Draw gray boxes */
  1567.     for (y = ystart; y < ystop; y++) {
  1568.         pi = &(image->image[y][xstart]);
  1569.         pw_lock(pw, &(repaint_area->rl_bound));
  1570.         for (x = xstart; x < xstop; x++) {
  1571.             /* Fill in a square box */
  1572.             pw_rop(pw, x * boxsize, y * boxsize,
  1573.                    boxsize, boxsize,
  1574.               PIX_SRC, pattern, 0, boxsize * ((*pi + 26) / 27));
  1575.             pi++;
  1576.         }
  1577.         pw_unlock(pw);
  1578.     }
  1579. }
  1580.  
  1581. static void
  1582. getcoords(canvas, event, arg)
  1583. Canvas canvas;
  1584. Event *event;
  1585. caddr_t arg;
  1586.  
  1587. {
  1588.     if ((event_id(event) == MS_LEFT) && event_is_down(event)) {
  1589.         printf("%s: locator x,y : %d %d  greylevel = %d\n", (newtitle)?newtitle:image->title,
  1590.                event_x(event) / boxsize, event_y(event) / boxsize,
  1591.          image->image[event_y(event) / boxsize][event_x(event) / boxsize]);
  1592.     }
  1593. }
  1594. End of dsp.c
  1595.  echo dynamem.3 1>&2
  1596. cat >dynamem.3 <<'End of dynamem.3'
  1597. .\" .TH name section cent-foot left-foot cent-head
  1598. .TH DYNAMEM 3 "28 August 1987"
  1599. .SH NAME
  1600. .\" name \- function
  1601. dynamem, freeup \- multidimensional dynamic array handling
  1602. .SH SYNOPSIS
  1603. .\" Bold keywords, Italic variables, [] options, | alternatives.
  1604. .br
  1605. .B char *dynamem(pointer,element_size,
  1606. .br
  1607. .B                 number_dimensions,dimensions ...)
  1608. .br
  1609. .B char **pointer;
  1610.  
  1611. .br
  1612. .B freeup(pointer)
  1613. .br
  1614. .B char *pointer;
  1615.  
  1616. .SH DESCRIPTION
  1617. .\" Italic files, commands, IR manual-entry (manual-section)
  1618. .I dynamem 
  1619. is the multidimensional analogue to malloc().
  1620. It is passed a number of arguments: a pointer which on
  1621. exiting the procedure will point to the begining of the
  1622. array, the element size, the number of dimensions 
  1623. required, followed by a list of the dimension sizes. 
  1624. To declare a 4 dimensional array normally one would code:
  1625. .DS L
  1626.  
  1627. int array[10][11][12][13];
  1628.  
  1629. .DE
  1630. however, this array is then fixed at compile time. This
  1631. same array can be declared dynamically at run time 
  1632. using the following code:
  1633. .DS L
  1634.  
  1635. int ****array;
  1636.  
  1637. array = (int ****) dynamem(&array, sizeof(int), 4, 10, 11, 12, 13);
  1638.  
  1639. .DE
  1640. (Note that the number of levels of indirection in the cast
  1641. is equal to the number of dimensions in the array.)
  1642. This enables array sizes to be fixed via, for example, 
  1643. command line arguments. 
  1644. .PP
  1645. .I freeup
  1646. is the 
  1647. .I dynamem
  1648. analogue to free(). When passed an array previously 
  1649. dynamically declared by 
  1650. .I dynamem
  1651. the function returns this memory to the system.
  1652. .PP
  1653. .I dynamem
  1654. attempts to set up the array required in the same way that 
  1655. it would be set up by the compiler at compile time. Thus
  1656. a multidimensional dynamically array declared using 
  1657. .I dynamem
  1658. can be used in exactly the same way as a fixed array declared
  1659. by the compiler. There is obviously some overhead in the actual
  1660. setting up of the array; however, this is minimal: 
  1661. when dynamically allocating 2 arrays of 346000
  1662. unsigned characters and one of the same number of shorts all in
  1663. two dimensions, the run time of a convolution of a 7x7 Lapacian-
  1664. Marr filter over an image of size 720 by 480 varied as follows:
  1665. .sp 1
  1666. time convolve -fbfilt -X720 -Y480 -e < bubble2 > test.1
  1667. .br
  1668.       222.0 real       213.4 user         1.6 sys  
  1669. .sp 1
  1670. time convolve -fbfilt -e < bubble2 > test.2
  1671. .br
  1672.       225.2 real       212.5 user         2.7 sys  
  1673. .sp 1
  1674. which is probably adequate. From this we can see that 
  1675. it takes 1.1 secs for the fixed array to be set up
  1676. and zeroed and only 0.9 secs for the array to be
  1677. dynamically declared using
  1678. .IR dynamem ; 
  1679. however, using dynamem the array is not initialized to
  1680. 0 and this is the reason for the 0.2 speed increase.
  1681. .SH FILES
  1682. .\" List of all files used by the program
  1683. /users/alv/everson/usr/lib/dynamem.a
  1684. .SH "SEE ALSO"
  1685. .\" List of references, textual, and MAN pages.
  1686. malloc(3), convolve(1)
  1687. .SH DIAGNOSTICS
  1688. .\" List of error messages and return codes the user may expect
  1689. .br
  1690. .I dynamem
  1691. returns NULL if it is unable to allocate sufficient
  1692. memory for the array.
  1693. End of dynamem.3
  1694.  echo dynamem.c 1>&2
  1695. cat >dynamem.c <<'End of dynamem.c'
  1696.  
  1697. /*
  1698.  * dynamem allocates a d dimensional array, whose dimensions are stored in a
  1699.  * list starting at d1. Each array element is of size s. p is a pointer with
  1700.  * d levels of indirection to the memory area 
  1701.  */
  1702.  
  1703. char *
  1704. dynamem(p, s, d, d1)
  1705. char **p;
  1706. int s, d, d1;
  1707. {
  1708.     int max,        /* size of array to be declared */
  1709.     *q;            /* pointer to dimension list */
  1710.     char **r,        /* pointer to begining of the array of the
  1711.                  * pointers for a dimension */
  1712.     **s1, *t, *tree;    /* base pointer to begining of first array */
  1713.     int i,            /* loop counters */
  1714.      j;
  1715.  
  1716.     r = &tree;
  1717.     q = &d1;        /* first dimension */
  1718.     max = 1;
  1719.     for (i = 0; i < d - 1; i++, q++) {    /* for each of the dimensions
  1720.                          * but the last */
  1721.         max *= (*q);
  1722.         if ((r[0] = (char *) malloc((unsigned) max * sizeof (char **))) == 0) {
  1723.             freeup(tree);
  1724.             return 0;
  1725.         }
  1726.         r = (char **) r[0];    /* step through to begining of next
  1727.                      * dimension array */
  1728.     }
  1729.     max *= s * (*q);    /* grab actual array memory */
  1730.     if ((r[0] = (char *) malloc((unsigned) max)) == 0) {
  1731.         freeup(tree);
  1732.         return 0;
  1733.     }
  1734.  
  1735.     /*
  1736.      * r is now set to point to the begining of each array so that we can
  1737.      * use it to scan down each array rather than having to go across and
  1738.      * then down 
  1739.      */
  1740.     r = (char **) tree;    /* back to the begining of list of arrays */
  1741.     q = &d1;        /* back to the first dimension */
  1742.     max = 1;
  1743.     for (i = 0; i < d - 2; i++, q++) {    /* we deal with the last
  1744.                          * array of pointers later on */
  1745.         max *= (*q);    /* number of elements in this dimension */
  1746.         for (j = 1, s1 = r + 1, t = r[0]; j < max; j++)    /* scans down array for
  1747.                                  * first and subsequent
  1748.                                  * elements */
  1749.  
  1750.             /*
  1751.              *  modify each of the pointers so that it points to
  1752.              * the correct position (sub-array) of the next
  1753.              * dimension array. s1 is the current position in the
  1754.              * current array. t is the current position in the
  1755.              * next array. t is incremented before s is, but it
  1756.              * starts off one behind. *(q+1) is the dimension of
  1757.              * the next array. 
  1758.              */
  1759.             *s1++ = (t += sizeof (char **) * *(q + 1));
  1760.         r = (char **) r[0];    /* step through to begining of next
  1761.                      * dimension array */
  1762.     }
  1763.     max *= (*q);        /* max is total number of elements in the
  1764.                  * last pointer array */
  1765.     for (j = 1, s1 = r + 1, t = r[0]; j < max; j++)    /* same as previous
  1766.                              * loop, but different
  1767.                              * size factor */
  1768.         *s1++ = (t += s * *(q + 1));
  1769.     return tree;        /* return base pointer */
  1770. }
  1771.  
  1772. /*
  1773.  * freeup releases all memory that we have already declared analogous to
  1774.  * free() when using malloc() 
  1775.  */
  1776. freeup(r)
  1777. char *r;
  1778. {
  1779.     char **p;
  1780.  
  1781.     for (p = &r; p; p = (char **) *p)
  1782.         free(*p);
  1783. }
  1784. End of dynamem.c
  1785.  echo ffill.c 1>&2
  1786. cat >ffill.c <<'End of ffill.c'
  1787. #include <stdio.h>
  1788. #include "image.h"
  1789.  
  1790. IMAGE *image;
  1791.  
  1792. main(argc,argv)
  1793. char **argv;
  1794. {
  1795.     FILE *fp;
  1796.     int xpos = -1, ypos = -1;
  1797.     int boundary = 0;
  1798.     char *imagefile=NULL;
  1799.  
  1800.     stdopts(&argc,argv);
  1801.  
  1802.     for (argv++;*argv;*argv++)
  1803.         if (**argv=='-')
  1804.             switch ((*argv)[1]) {
  1805.             case 'b':
  1806.                 boundary=atoi(argv[0]+2);
  1807.                 break;
  1808.             }
  1809.         else if (xpos<0)
  1810.             xpos=atoi(*argv+2);
  1811.         else if (ypos<0)
  1812.             ypos=atoi(*argv+2);
  1813.         else
  1814.             imagefile = *argv;
  1815.  
  1816.     if (imagefile==NULL)
  1817.         fp=stdin;
  1818.     else if (!(fp=fopen(imagefile,"r"))) {
  1819.         fprintf(stderr,"Cannot open %s\n",imagefile);
  1820.         exit(-1);
  1821.         }
  1822.  
  1823.     image=readimage(fp);
  1824.  
  1825.     if (!newtitle)
  1826.         sprintf(image->title,"%s | ffill %d %d %d\n",image->title,xpos,ypos,boundary);
  1827.     else
  1828.         strcpy(image->title,newtitle);
  1829.     ffill(xpos,ypos,boundary);
  1830.  
  1831.     writeimage(stdout,image);
  1832.     
  1833. }
  1834.  
  1835. ffill(x,y,n)
  1836. {
  1837. int i,j,k;
  1838.  
  1839.     if (x<0 || x>=image->xsize || y<0 || y>=image->ysize|| ftest(x,y)==n)
  1840.         return;
  1841.     fset (x,y,n);
  1842.     for (i=x-1;i>=0;i--) {
  1843.         if (ftest(i,y)!=n)
  1844.             fset(i,y,n);
  1845.         else 
  1846.             break;
  1847.         }
  1848.     for (j=x+1;j<image->xsize;j++)
  1849.         if (ftest(j,y)!=n)
  1850.             fset(j,y,n);
  1851.         else 
  1852.             break;
  1853.     for (k=i+1;k<j;k++)
  1854.     {
  1855.         if (y>0 && ftest(k,y-1)!=n)
  1856.             ffill(k,y-1,n);
  1857.         if (y<image->ysize-1 && ftest(k,y+1)!=n)
  1858.             ffill(k,y+1,n);
  1859.     }
  1860. }
  1861.  
  1862. ftest(x,y)
  1863. {
  1864.     return image->image[y][x];
  1865. }
  1866.  
  1867. fset(x,y,n)
  1868. {
  1869.     image->image[y][x]=n;
  1870. }
  1871.  
  1872. End of ffill.c
  1873.  echo hist.c 1>&2
  1874. cat >hist.c <<'End of hist.c'
  1875. #include <suntool/sunview.h>
  1876. #include <suntool/canvas.h>
  1877. #include <stdio.h>
  1878. #include <math.h>
  1879. #include "image.h"
  1880.  
  1881. static short histicon[] = 
  1882. {
  1883. #include "hist.icon"
  1884. };
  1885. DEFINE_ICON_FROM_IMAGE(icon,histicon);
  1886.  
  1887. #define GREYLEVELS    256
  1888. #define HSIZE    128
  1889. #define HEADER    10
  1890. #define BOTTOM    20
  1891. #define BOXSIZE    3
  1892. #define MIN(a,b)    ((a) < (b) ? (a) : (b))
  1893. #define MAX(a,b)    ((a) > (b) ? (a) : (b))
  1894.  
  1895. IMAGE *image;
  1896. int vflag=1,
  1897.     lflag=0;
  1898. Frame frame;
  1899. Canvas canvas;
  1900. Menu menu;
  1901. Pixwin *pw;
  1902. int hist[GREYLEVELS],
  1903.     n=0;
  1904.  
  1905. main(argc,argv)
  1906. int argc;
  1907. char **argv;
  1908. {
  1909.     double mean(),
  1910.            lhist[GREYLEVELS],
  1911.            ldummy,
  1912.            lmaxh= -10000.0;
  1913.     register short i,j;
  1914.     int c,
  1915.         mo,
  1916.         len,
  1917.         dummy,
  1918.         maxh=0,
  1919.         maxc=0,
  1920.         minc=GREYLEVELS;
  1921.     Pixrect *pattern;
  1922.     char *imagefile=NULL;
  1923.     char message[BUFSIZ];
  1924.     FILE *fp;
  1925.  
  1926.     stdopts(&argc,argv);
  1927.     windopts(&argc,argv);
  1928.  
  1929.     for (argv++;*argv;*argv++)
  1930.         if (**argv=='-')
  1931.             switch ((*argv)[1]) {
  1932.             case 'l':
  1933.                 lflag=1;
  1934.                 break;
  1935.             case 'v':
  1936.                 vflag=0;
  1937.                 break;
  1938.             }
  1939.         else imagefile = *argv;
  1940.  
  1941.     if (imagefile==NULL)
  1942.         fp=stdin;
  1943.     else if (!(fp=fopen(imagefile,"r"))) {
  1944.         fprintf(stderr,"Cannot open %s\n",imagefile);
  1945.         exit(-1);
  1946.         }
  1947.  
  1948.     image=readimage(fp);
  1949.     
  1950.     for (i=0;i<GREYLEVELS;i++)
  1951.         hist[i]=0;
  1952.  
  1953.     for(j=0;j<image->ysize;j++) 
  1954.         for (i=0;i<image->xsize;i++) {
  1955.             c = MAX(image->image[j][i],0);
  1956.             c = MIN(c,GREYLEVELS);
  1957.             if (c>maxc) 
  1958.                 maxc = c;
  1959.             else if (c<minc) 
  1960.                 minc = c;
  1961.             hist[c]++;
  1962.             if (maxh<hist[c])
  1963.                 maxh=hist[c];
  1964.             n++;
  1965.         }
  1966.  
  1967.     fprintf(stderr,"mean pixel = %3g\n",mean());
  1968.     fprintf(stderr,"median pixel = %d\n",median());
  1969.     fprintf(stderr,"mode pixel = %d\n",mo=mode());
  1970.     fprintf(stderr,"max pixel = %d\nmin pixel = %d\n",maxc,minc);
  1971.  
  1972.     strcpy(message,(lflag==1)?"logarithmic histogram" : "histogram");
  1973.     strcat(message,": ");
  1974.     strcat(message,image->title);
  1975.  
  1976.        /* create frame and canvas */
  1977.        frame = window_create(NULL, FRAME,
  1978.              FRAME_LABEL, message, 
  1979.              WIN_X, winxoff,
  1980.              WIN_Y, winyoff,
  1981.              WIN_HEIGHT, (winxsize)?winxsize:HSIZE+28+HEADER+BOTTOM,
  1982.              WIN_WIDTH, (winysize)?winysize:(GREYLEVELS*BOXSIZE)+10,
  1983.              FRAME_ICON,&icon,
  1984.              0);
  1985.        canvas = window_create(frame, CANVAS,
  1986.               CANVAS_FAST_MONO, TRUE,
  1987.               CANVAS_HEIGHT, HSIZE+HEADER+BOTTOM,
  1988.               CANVAS_WIDTH, GREYLEVELS*BOXSIZE,
  1989.               0);
  1990.       
  1991.     /* get the cancas pixwin to draw into */
  1992.        pw = canvas_pixwin(canvas);
  1993.  
  1994.       /* Enable batching for efficiency */
  1995.        pw_batch_on(pw);
  1996.  
  1997.        if (!lflag) { 
  1998.            for (i = 0; i < GREYLEVELS; i++) {
  1999.             dummy = hist[i]*HSIZE/maxh;
  2000.             if (!dummy && hist[i]) 
  2001.                 dummy = 1;
  2002.              if (vflag) {
  2003.                 pw_vector(pw,i*BOXSIZE,HSIZE+HEADER-dummy,i*BOXSIZE,HSIZE+HEADER,PIX_SET,1);
  2004.                 pw_vector(pw,i*BOXSIZE+BOXSIZE,HSIZE+HEADER-dummy,i*BOXSIZE+BOXSIZE,HSIZE+HEADER,PIX_SET,1);
  2005.                 }
  2006.             pw_rop(pw,i*BOXSIZE,HSIZE+HEADER-dummy,BOXSIZE,1,PIX_SET,(Pixrect *)0,0,0);
  2007.                }    
  2008.         }
  2009.     else {
  2010.         for (i=0;i<GREYLEVELS;i++) {
  2011.             lhist[i] = log((double)hist[i]+1.0);        /* add 1 to avoid log(0) */
  2012.             if (lmaxh<lhist[i])
  2013.                 lmaxh=lhist[i];
  2014.             }
  2015.         for (i=0;i<GREYLEVELS;i++) {
  2016.             ldummy = lhist[i]*HSIZE /lmaxh; 
  2017.             if (dummy!=0.0 && lhist[i]==0.0)
  2018.                 ldummy = 1.0;
  2019.              if (vflag) {
  2020.                 pw_vector(pw,i*BOXSIZE,HSIZE+HEADER-(int)ldummy,i*BOXSIZE,HSIZE+HEADER,PIX_SET,1);
  2021.                 pw_vector(pw,i*BOXSIZE+BOXSIZE,HSIZE+HEADER-(int)ldummy,i*BOXSIZE+BOXSIZE,HSIZE+HEADER,PIX_SET,1);
  2022.                 }
  2023.             pw_rop(pw,i*BOXSIZE,HSIZE+HEADER-(int)ldummy,BOXSIZE,1,
  2024.             PIX_SET,(Pixrect *)0,0,0);
  2025.             }
  2026.         }
  2027.  
  2028.     /* print bottom axis */
  2029.     pw_vector(pw,0,HSIZE+HEADER,image->xsize*BOXSIZE,HSIZE+HEADER,PIX_SET,1);
  2030.     for(i=0;i<GREYLEVELS;i++) {
  2031.         len = (i%100==0) ? 10 :
  2032.               (i%50==0)  ? 8 :
  2033.               (i%10==0)  ? 6 :
  2034.               (i%2==0)   ? 5 : 0;
  2035.         if (len)
  2036.             pw_vector(pw,i*BOXSIZE,HSIZE+HEADER,i*BOXSIZE,HSIZE+HEADER+len,PIX_SET,1);
  2037.         }
  2038.  
  2039.     pw_batch_off(pw);
  2040.        window_main_loop(frame);
  2041.  
  2042.     exit(0);
  2043. }
  2044.  
  2045. double mean()
  2046. {
  2047.     int i;
  2048.     double m=0;
  2049.  
  2050.     for (i=0;i<GREYLEVELS;i++)  {
  2051.         m += hist[i]*i;    
  2052.         }
  2053.     return m/n;
  2054. }
  2055.     
  2056. median()
  2057. {
  2058.     int i=0,
  2059.         count=0;
  2060.     
  2061.     while (count<n/2) 
  2062.         count += hist[i++];
  2063.     return i-1;
  2064. }
  2065.  
  2066. mode()
  2067. {
  2068.     int i=0;
  2069.     int mo=0,
  2070.         m=0;
  2071.  
  2072.     for(i=0;i<GREYLEVELS;i++)
  2073.         if (hist[i]>m) {
  2074.             m=hist[i];
  2075.             mo=i;
  2076.             }
  2077.  
  2078.     return mo;
  2079. }
  2080.  
  2081. End of hist.c
  2082.  echo hist.icon 1>&2
  2083. cat >hist.icon <<'End of hist.icon'
  2084. /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
  2085.  */
  2086.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001,
  2087.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2088.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2089.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2090.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2091.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2092.     0x8000,0x0000,0x2000,0x0001,0x8000,0x0000,0x2000,0x0001,
  2093.     0x8000,0x0000,0x2000,0x0001,0x8000,0x0000,0x2000,0x0001,
  2094.     0x8002,0x0800,0x2008,0x0001,0x8002,0x0800,0x2008,0x0001,
  2095.     0x8002,0x0800,0x2008,0x0001,0x8002,0x0800,0x2008,0x0001,
  2096.     0x800A,0x0A00,0x2008,0x8081,0x800A,0x0A00,0x2008,0x8081,
  2097.     0x800A,0x0A00,0x2008,0x8081,0x800A,0x0A00,0x2008,0x8081,
  2098.     0x800A,0x0A00,0x2808,0x8081,0x800A,0x0A00,0x2808,0x8081,
  2099.     0x800A,0x0A00,0x2808,0x8081,0x800A,0x0A00,0x2808,0x8081,
  2100.     0x800A,0x8A00,0x2888,0x8281,0x800A,0x8A00,0x2888,0x8281,
  2101.     0x800A,0x8A00,0x2888,0x8281,0x800A,0x8A00,0x2888,0x8281,
  2102.     0x800A,0x8A00,0xA8A8,0x8281,0x800A,0x8A00,0xA8A8,0x8281,
  2103.     0x800A,0x8A00,0xA8A8,0x8281,0x800A,0x8A02,0xA8A8,0x8A81,
  2104.     0x802A,0x8A8A,0xAAAA,0x8A81,0x802A,0x8A8A,0xAAAA,0x8A81,
  2105.     0x802A,0x8A8A,0xAAAA,0x8A81,0x802A,0x8A8A,0xAAAA,0x8A81,
  2106.     0x80AA,0xAAAA,0xAAAA,0xAA81,0x80AA,0xAAAA,0xAAAA,0xAA81,
  2107.     0x80AA,0xAAAA,0xAAAA,0xAA81,0x80FF,0xFFFF,0xFFFF,0xFF81,
  2108.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2109.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2110.     0xA010,0x0040,0x0000,0x0001,0xA000,0x0040,0x0000,0x0001,
  2111.     0xAC70,0x71F1,0xC34B,0x0E35,0xB210,0x8842,0x24CC,0x912B,
  2112.     0xA210,0x8042,0x2448,0x012B,0xA210,0x7042,0x2448,0x0F2B,
  2113.     0xA210,0x0842,0x2448,0x112B,0xA210,0x8842,0x24C8,0x112B,
  2114.     0xA210,0x7031,0xC348,0x0F2B,0x8000,0x0000,0x0040,0x0001,
  2115.     0x8000,0x0000,0x0440,0x0001,0x8000,0x0000,0x0380,0x0001,
  2116.     0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  2117.     0x8000,0x0000,0x0000,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF
  2118. End of hist.icon
  2119.  echo image.h 1>&2
  2120. cat >image.h <<'End of image.h'
  2121. typedef struct img {
  2122.     unsigned char **image;
  2123.     short xsize, ysize;
  2124.     char title[252];
  2125. } IMAGE;
  2126.  
  2127. IMAGE *readimage(), *newimage();
  2128.  
  2129. extern int winxsize,winysize,
  2130.            winxoff, winyoff;
  2131. extern int helpflag;
  2132. extern char *newtitle;
  2133. End of image.h
  2134.  echo imagelw.c 1>&2
  2135. cat >imagelw.c <<'End of imagelw.c'
  2136. #include <stdio.h>
  2137. #include <ctype.h> 
  2138. #include "image.h"
  2139. #define MIDX        285             /* center of output page */
  2140. #define MIDY        396
  2141.  
  2142. IMAGE *image;
  2143.  
  2144. main (argc,argv)
  2145. int argc;
  2146. char **argv;
  2147. {
  2148.     int c,x=0,y=0,r=0;
  2149.     register int i,j;
  2150.     double sx=1.0,sy=1.0,atof();
  2151.     char *hex();
  2152.     char title[512],buf[512];
  2153.     FILE *fp,*p1;
  2154.     int sflag=0,mflag=0,oflag=0,cflag=0;
  2155.     char *imagefile=NULL;
  2156.     
  2157.     stdopts(&argc,argv);
  2158.     windopts(&argc,argv);
  2159.  
  2160.     for (argv++;*argv;*argv++)
  2161.         if (**argv=='-')
  2162.             switch ((*argv)[1]) {
  2163.             case 't':
  2164.                 sflag=1;
  2165.                 break;
  2166.             case 'm':
  2167.                 mflag=1;
  2168.                 break;
  2169.             case 'c':
  2170.                 cflag=1;
  2171.                 break;
  2172.             case '\0':
  2173.                 oflag=1;
  2174.                 break;
  2175.             }
  2176.         else
  2177.             imagefile = *argv;
  2178.  
  2179.     if (imagefile==NULL)
  2180.         fp=stdin;
  2181.     else if (!(fp=fopen(imagefile,"r"))) {
  2182.         fprintf(stderr,"Cannot open %s\n",imagefile);
  2183.         exit(-1);
  2184.         }
  2185.  
  2186.     image=readimage(fp);
  2187.     
  2188.     if (oflag || sflag)
  2189.         p1=stdout;
  2190.     else if((p1=popen(strcat("lpr -Plw -v",((mflag)?" -m":"")),"w"))==NULL) {
  2191.             fprintf(stderr,"Cannot open pipe to lpr\n");
  2192.             exit(-1);
  2193.             }
  2194.     
  2195.     fprintf(p1,"/picstr %d string def\n",image->xsize);
  2196.  
  2197.     if (image->title[0]) {
  2198.         fprintf(p1,"/Helvetica-Bold findfont\n");
  2199.         fprintf(p1,"12 scalefont setfont\n");
  2200.         fprintf(p1,"285 (%s) stringwidth pop 2 div sub 720 moveto\n",image->title);
  2201.         fprintf(p1,"(%s) show\n",image->title);
  2202.         }
  2203.     if (cflag) {
  2204.         sx=7.91*300/image->xsize;
  2205.         sy=8.5*300/image->ysize;                /* avoid title area */
  2206.         sx=sy=(sx>sy) ? sy:sx;
  2207.         x= -sx*image->xsize*72/300/2;
  2208.         y= -sy*image->ysize*72/300/2;
  2209.         }
  2210.     if (sflag) 
  2211.         fprintf(p1," 0 0 translate\n");
  2212.     else fprintf(p1,"%d %d translate\n",MIDX+x,MIDY-36+y);
  2213.  
  2214.     fprintf(p1,"%d %d scale\n",(int)(image->xsize/300.0*72.0*sx),(int)(image->ysize/300.0*72.0*sy));
  2215.     fprintf(p1,"%d %d 8\n",image->xsize,image->ysize);
  2216.     fprintf(p1,"[ %d 0 0 -%d 0 %d ]\n",image->xsize,image->ysize,image->ysize);
  2217.     fprintf(p1,"{currentfile\npicstr readhexstring pop}\nimage\n");
  2218.  
  2219.     for(j=0;j<image->ysize;j++)
  2220.         for(i=0;i<image->xsize;i++)
  2221.             fputs(hex(image->image[j][i]),p1);
  2222.  
  2223.     if (!sflag)
  2224.         fprintf(p1,"showpage\n");
  2225.     if (!(oflag || sflag))
  2226.         pclose(p1);
  2227. }
  2228.  
  2229. char *hex(d)
  2230. {
  2231.     static char a[10];
  2232.  
  2233.     sprintf(a,"%02x",d);
  2234.     return(a);
  2235. }
  2236. End of imagelw.c
  2237.  echo invert.c 1>&2
  2238. cat >invert.c <<'End of invert.c'
  2239. #include <stdio.h>
  2240. #include "image.h"
  2241.  
  2242. main(argc,argv)
  2243. char **argv;
  2244. {
  2245.     int c;
  2246.     register int i,j;
  2247.     char *imagefile=NULL;
  2248.     IMAGE *image;
  2249.     FILE *fp;
  2250.     
  2251.     stdopts(&argc,argv);
  2252.     if (argc-1>=1)
  2253.         imagefile= *++argv;
  2254.  
  2255.     if (imagefile==NULL)
  2256.         fp=stdin;
  2257.     else if (!(fp=fopen(imagefile,"r"))) {
  2258.         fprintf(stderr,"Cannot open %s\n",imagefile);
  2259.         exit(-1);
  2260.         }
  2261.  
  2262.     image=readimage(fp);
  2263.  
  2264.     if (!newtitle)
  2265.         strcat(image->title," | invert");
  2266.     else
  2267.         strcpy(image->title,newtitle);
  2268.  
  2269.     for(j=0;j<image->ysize;j++)
  2270.         for(i=0;i<image->xsize;i++)
  2271.             image->image[j][i]=abs(255 - image->image[j][i]);
  2272.  
  2273.  
  2274.     writeimage(stdout,image);
  2275.     fclose(fp);
  2276. }
  2277. End of invert.c
  2278.  echo lap1 1>&2
  2279. cat >lap1 <<'End of lap1'
  2280. 3 3
  2281.  
  2282.  0 -1  0
  2283. -1  4 -1
  2284.  0 -1  0
  2285. End of lap1
  2286.  echo normalise.c 1>&2
  2287. cat >normalise.c <<'End of normalise.c'
  2288. #include <stdio.h>
  2289. #include "image.h"
  2290.  
  2291. #define GREYLEVELS     256
  2292.  
  2293. IMAGE *image;
  2294.  
  2295. main(argc, argv)
  2296. char **argv;
  2297. {
  2298.  
  2299.     int c, low= -1, high= -1;
  2300.     char buff[BUFSIZ];
  2301.     register int i,j;
  2302.     char *imagefile = NULL;
  2303.     FILE *fp;
  2304.  
  2305.     stdopts(&argc, argv);
  2306.  
  2307.     imagefile = (*argv++)?*argv:NULL;
  2308.  
  2309.     if (imagefile == NULL)
  2310.         fp = stdin;
  2311.     else if (!(fp = fopen(imagefile, "r"))) {
  2312.         fprintf(stderr, "Cannot open %s\n", imagefile);
  2313.         exit(-1);
  2314.     }
  2315.  
  2316.     image = readimage(fp);
  2317.  
  2318.     if (!newtitle)
  2319.         strcat(image->title," | normalise");
  2320.     else
  2321.         strcpy(image->title,newtitle);
  2322.  
  2323.     norm(image);
  2324.  
  2325.     writeimage(stdout,image);
  2326. }
  2327.  
  2328. norm(image)
  2329. IMAGE *image;
  2330. {
  2331.     register int i,j;
  2332.     int x;
  2333.     int totpix=image->xsize * image->ysize;
  2334.     int hist[GREYLEVELS][2];
  2335.     int sum;
  2336.  
  2337.     for (i = 0; i < GREYLEVELS; i++) 
  2338.         hist[i][0] = hist[i][1] = 0;
  2339.  
  2340.     for (j=0;j<image->ysize;j++)
  2341.         for (i=0;i<image->xsize;i++) 
  2342.             hist[image->image[j][i]][0]++;
  2343.  
  2344.     sum = 0;
  2345.     for (i = 0; i < GREYLEVELS; i++) {
  2346.         sum += hist[i][0];
  2347.         x = sum * GREYLEVELS/ totpix;
  2348.         x = (x > 255) ? 255 : x;
  2349.         hist[i][1] = x;
  2350.     }
  2351.  
  2352.     for(j=0;j<image->ysize;j++)
  2353.         for(i=0;i<image->xsize;i++)
  2354.             image->image[j][i]=hist[image->image[j][i]][1];
  2355. }
  2356. End of normalise.c
  2357.  echo pattern3.h 1>&2
  2358. cat >pattern3.h <<'End of pattern3.h'
  2359. /* file pattern.h */
  2360. int pat[] = 
  2361. {    0,0,0,
  2362.     0,0,0,
  2363.     0,0,0,
  2364.         0,0,0,
  2365.         0,1,0,
  2366.         0,0,0,
  2367.     0,0,0,
  2368.     1,0,1,
  2369.     0,0,0,
  2370.         0,0,1,
  2371.         0,1,0,
  2372.         1,0,0,
  2373.     0,1,0,
  2374.     1,0,1,
  2375.     0,1,0,
  2376.         1,0,1,
  2377.         0,1,0,
  2378.         1,0,1,
  2379.     1,1,1,
  2380.     0,1,0,
  2381.     1,0,1,
  2382.         1,1,1,
  2383.         1,1,0,
  2384.         1,0,1,
  2385.     1,1,1,
  2386.     1,0,1,
  2387.     1,1,1,
  2388.         1,1,1,
  2389.         1,1,1,
  2390.         1,1,1};
  2391. End of pattern3.h
  2392.  echo pixval.c 1>&2
  2393. cat >pixval.c <<'End of pixval.c'
  2394. #include <stdio.h>
  2395. #include <string.h>
  2396. #include "image.h"
  2397.  
  2398. IMAGE *image,
  2399.       *image1;
  2400.  
  2401. main (argc,argv)
  2402. int argc;
  2403. char **argv;
  2404. {
  2405.     register int i,j;
  2406.     char *imagefile=NULL;
  2407.     FILE *fp;
  2408.  
  2409.     stdopts(&argc,argv);
  2410.     windopts(&argc,argv);
  2411.  
  2412.     if (argc>1)
  2413.         imagefile = argv[1];
  2414.  
  2415.     if (imagefile==NULL)
  2416.         fp=stdin;
  2417.     else if (!(fp=fopen(imagefile,"r"))) {
  2418.         fprintf(stderr,"Cannot open %s\n",imagefile);
  2419.         exit(-1);
  2420.         }
  2421.  
  2422.     image=readimage(fp);
  2423.     image1=newimage(winxsize,winysize,"");
  2424.  
  2425.     subarea(image,image1,winxoff,winyoff);
  2426.     
  2427.     for (j=0;j<image1->ysize;j++) {
  2428.         for(i=0;i<image1->xsize;i++)
  2429.             printf("%4d",image1->image[j][i]);
  2430.         putchar('\n');
  2431.         }
  2432. }
  2433. End of pixval.c
  2434.  echo range.c 1>&2
  2435. cat >range.c <<'End of range.c'
  2436. #include <stdio.h>
  2437. #include "image.h"
  2438.  
  2439. IMAGE *image;
  2440.  
  2441. main(argc, argv)
  2442. char **argv;
  2443. {
  2444.  
  2445.     int c, low= 0, high= 255;
  2446.     char buff[BUFSIZ];
  2447.     register int i,j;
  2448.     char *imagefile = NULL;
  2449.     FILE *fp;
  2450.  
  2451.     stdopts(&argc, argv);
  2452.  
  2453.     for (argv++; *argv; *argv++)
  2454.         if (**argv == '-')
  2455.             switch ((*argv)[1]) {
  2456.             case 'l':
  2457.                 low = atoi(argv[0] + 2);
  2458.                 break;
  2459.             case 'h':
  2460.                 high = atoi(argv[0] + 2);
  2461.                 break;
  2462.             }
  2463.         else
  2464.             imagefile = *argv;
  2465.  
  2466.     if (imagefile == NULL)
  2467.         fp = stdin;
  2468.     else if (!(fp = fopen(imagefile, "r"))) {
  2469.         fprintf(stderr, "Cannot open %s\n", imagefile);
  2470.         exit(-1);
  2471.     }
  2472.  
  2473.     image = readimage(fp);
  2474.  
  2475.     if (!newtitle)
  2476.     {
  2477.         strcat(image->title," | range");
  2478.         sprintf(buff," -l%d",low);
  2479.         strcat(image->title,buff);
  2480.         sprintf(buff," -h%d",high);
  2481.         strcat(image->title,buff);
  2482.     }
  2483.     else
  2484.         strcpy(image->title,newtitle);
  2485.  
  2486.     for(j=0;j<image->ysize;j++)
  2487.         for(i=0;i<image->xsize;i++) {
  2488.             c = (image->image[j][i] - low) * 255 / (high - low);
  2489.             c = (c < 0) ? 0 : c;
  2490.             image->image[j][i]= (c > 255) ? 255 : c;
  2491.             }
  2492.  
  2493.     writeimage(stdout,image);
  2494. }
  2495. End of range.c
  2496.  echo retitle.c 1>&2
  2497. cat >retitle.c <<'End of retitle.c'
  2498. #include <stdio.h>
  2499. #include "image.h"
  2500.  
  2501. main(argc,argv)
  2502. char **argv;
  2503. {
  2504. IMAGE *image1,*image2;
  2505. FILE *fp;
  2506.  
  2507.     stdopts(&argc,argv);
  2508.     if (helpflag)
  2509.     {
  2510.         help(*argv);
  2511.         exit(0);
  2512.     }
  2513.     if (argc>1)
  2514.     {
  2515.         if (!(fp=fopen(argv[1],"r")))
  2516.         {
  2517.             fprintf(stderr,"%s: cannot open %s\n",argv[0],argv[1]);
  2518.             exit(-1);
  2519.         }
  2520.         image1=readimage(fp);
  2521.     }
  2522.     else
  2523.         image1=readimage(stdin);
  2524.  
  2525.     if (newtitle)
  2526.     {
  2527.         image2=newimage(image1->xsize,image1->ysize,newtitle);
  2528.         image2->image=image1->image;
  2529.         writeimage(stdout,image2);
  2530.     }
  2531.     else
  2532.         writeimage(stdout,image1);
  2533. }
  2534.  
  2535. help(name)
  2536. char *name;
  2537. {
  2538.     printf("Retitling Filter\n");
  2539.     printf("----------------\n");
  2540.     printf("\nUsage: %s [file]\n",name);
  2541.     printf("\nOptions:\n");
  2542.     printf("  -h      help\n");
  2543.     printf("  -ttitle new title\n");
  2544. }
  2545. End of retitle.c
  2546.  echo sobel1 1>&2
  2547. cat >sobel1 <<'End of sobel1'
  2548. 5 5
  2549.  
  2550.  1  2  0 -2 -1
  2551.  2  4  0 -4 -2
  2552.  2  6  0 -6 -2
  2553.  2  4  0 -4 -2
  2554.  1  2  0 -2 -1
  2555.  
  2556.  
  2557. End of sobel1
  2558.  echo striphead.c 1>&2
  2559. cat >striphead.c <<'End of striphead.c'
  2560. #include <stdio.h>
  2561. #include "image.h"
  2562.  
  2563. IMAGE *image;
  2564.  
  2565. main(argc,argv)
  2566. int argc;
  2567. char **argv;
  2568. {
  2569.     int i,j;
  2570.     int xsize,ysize;
  2571.     unsigned char **pic;
  2572.     char *file, *title;
  2573.     FILE *fp;
  2574.  
  2575.     stdopts(&argc,argv);
  2576.  
  2577.     file = (*argv++)?*argv:NULL;
  2578.  
  2579.     if (file==NULL) {
  2580.         if (!(fp=fopen(file,"r"))) {
  2581.             fprintf(stderr,"Cannot open %s\n",file);
  2582.             exit(-1);
  2583.             }
  2584.         }
  2585.     else fp=stdin;
  2586.  
  2587.     image=readimage(fp);
  2588.  
  2589.     for (j=0;j<image->ysize;j++)
  2590.         for (i=0;i<image->xsize;i++)
  2591.             putchar(image->image[j][i]);
  2592.  
  2593.     fclose(fp);
  2594. }
  2595. End of striphead.c
  2596.  echo subarea.c 1>&2
  2597. cat >subarea.c <<'End of subarea.c'
  2598. #include <stdio.h>
  2599. #include "image.h"
  2600.  
  2601. main(argc,argv)
  2602. char **argv;
  2603. {
  2604. FILE *fp;
  2605.  
  2606.     stdopts(&argc,argv);
  2607.     windopts(&argc,argv);
  2608.  
  2609.     if (helpflag)
  2610.     {
  2611.         help(*argv);
  2612.         exit(0);
  2613.     }
  2614.     if (argc<1)
  2615.     {
  2616.         fprintf(stderr,"Usage: %s [filename]\n",argv[0]);
  2617.         exit(-1);
  2618.     }
  2619.     if (winxoff<0 || winyoff<0 || winxsize<0 || winysize<0)
  2620.     {
  2621.         fprintf(stderr,"Negative Values not permitted !!\n");
  2622.         exit(-1);
  2623.     }
  2624.     if (argc==1)
  2625.         subar(stdin);
  2626.     else
  2627.         if (!(fp=fopen(argv[1],"r")))
  2628.         {
  2629.             fprintf(stderr,"%s: cannot open %s\n",argv[0],argv[1]);
  2630.             exit(-1);
  2631.         }
  2632.         else
  2633.         {
  2634.             subar(fp);
  2635.             fclose(fp);
  2636.         }
  2637. }
  2638.  
  2639. subar(fp)
  2640. FILE *fp;
  2641. {
  2642. IMAGE *image1,*image2;
  2643.  
  2644.     image1=readimage(fp);
  2645.  
  2646.     if (newtitle)
  2647.         image2=newimage(winxsize,winysize,newtitle);
  2648.     else
  2649.     {
  2650.         image2=newimage(winxsize,winysize,image1->title);
  2651.         strcat(image2->title," | subarea");
  2652.     }
  2653.  
  2654.     subarea(image1,image2,winxoff,winyoff);
  2655.  
  2656.     writeimage(stdout,image2);
  2657. }
  2658.  
  2659. help(name)
  2660. char *name;
  2661. {
  2662.     printf("Subsample Filter\n");
  2663.     printf("----------------\n");
  2664.     printf("\nUsage: %s -xn -yn -Xn -Yn [file]\n",name);
  2665.     printf("\nOptions:\n");
  2666.     printf("  -h      help\n");
  2667.     printf("  -ttitle new title\n");
  2668. }
  2669. End of subarea.c
  2670.  echo subsample.c 1>&2
  2671. cat >subsample.c <<'End of subsample.c'
  2672. #include <stdio.h>
  2673. #include "image.h"
  2674.  
  2675. main(argc,argv)
  2676. char **argv;
  2677. {
  2678. int newx,newy;
  2679. FILE *fp;
  2680.  
  2681.     stdopts(&argc,argv);
  2682.     if (helpflag)
  2683.     {
  2684.         help(*argv);
  2685.         exit(0);
  2686.     }
  2687.     if (argc<3)
  2688.     {
  2689.         fprintf(stderr,"Usage: %s newx newy [filename]\n",argv[0]);
  2690.         exit(-1);
  2691.     }
  2692.     newx=atoi(argv[1]);
  2693.     newy=atoi(argv[2]);
  2694.     if (newx<=0 || newy<=0)
  2695.     {
  2696.         fprintf(stderr,"Negative Values not permitted !!\n");
  2697.         exit(-1);
  2698.     }
  2699.     if (argc==3)
  2700.         subsamp(stdin,newx,newy);
  2701.     else
  2702.         if (!(fp=fopen(argv[3],"r")))
  2703.         {
  2704.             fprintf(stderr,"%s: cannot open %s\n",argv[0],argv[3]);
  2705.             exit(-1);
  2706.         }
  2707.         else
  2708.         {
  2709.             subsamp(fp,newx,newy);
  2710.             fclose(fp);
  2711.         }
  2712. }
  2713.  
  2714. subsamp(fp,x,y)
  2715. FILE *fp;
  2716. {
  2717. IMAGE *image1,*image2;
  2718.  
  2719.     image1=readimage(fp);
  2720.  
  2721.     if (newtitle)
  2722.         image2=newimage(x,y,newtitle);
  2723.     else
  2724.     {
  2725.         image2=newimage(x,y,image1->title);
  2726.         strcat(image2->title," | subsample");
  2727.     }
  2728.  
  2729.     subsample(image1,image2);
  2730.  
  2731.     writeimage(stdout,image2);
  2732. }
  2733.  
  2734. help(name)
  2735. char *name;
  2736. {
  2737.     printf("Subsample Filter\n");
  2738.     printf("----------------\n");
  2739.     printf("\nUsage: %s xsize ysize [file]\n",name);
  2740.     printf("\nOptions:\n");
  2741.     printf("  -h      help\n");
  2742.     printf("  -ttitle new title\n");
  2743. }
  2744. End of subsample.c
  2745.  echo thresh.c 1>&2
  2746. cat >thresh.c <<'End of thresh.c'
  2747. #include <math.h>
  2748. #include <stdio.h>
  2749. #include "image.h"
  2750.  
  2751. #define MAX 255
  2752. #define MIN 0
  2753. main(argc, argv)
  2754. int argc;
  2755. char **argv;
  2756. {
  2757.     register int i,j;
  2758.     char buff[BUFSIZ];
  2759.     int thresh;
  2760.     FILE *fp;
  2761.     IMAGE *image, *image2;
  2762.  
  2763.     stdopts(&argc,argv);
  2764.  
  2765.     if (argc>1 && argv[1][0]=='-' && argv[1][1]=='t')
  2766.         thresh = atoi(argv[1]+2);
  2767.     else
  2768.         thresh = -1;
  2769.     
  2770.     for (*argv++;*argv;argv++)
  2771.         if (**argv!='-')
  2772.             break;
  2773.  
  2774.     if (*argv)
  2775.     {
  2776.         if (!(fp=fopen(*argv,"r")))
  2777.         {
  2778.             fprintf(stderr,"Cannot Open %s\n",*argv);
  2779.             exit(-1);
  2780.         }
  2781.     }
  2782.     else
  2783.         fp=stdin;
  2784.  
  2785.     image=readimage(fp);
  2786.     fclose(fp);
  2787.     image2=newimage(image->xsize,image->ysize,(newtitle)?newtitle:image->title);
  2788.  
  2789.     if (!newtitle)
  2790.     {
  2791.         strcat(image2->title," | thresh");
  2792.         if (thresh >= 0) {
  2793.             sprintf(buff," -t%d",thresh);
  2794.             strcat(image2->title,buff); 
  2795.         }
  2796.     }
  2797.     else strcpy(image2->title,newtitle);
  2798.     
  2799.     if (thresh == -1)
  2800.         thresh=autothresh(image);
  2801.  
  2802.     for (j=0;j<image->ysize;j++)
  2803.         for (i=0;i<image->xsize;i++)
  2804.             image2->image[j][i]=image->image[j][i]<thresh?MIN:MAX;
  2805.  
  2806.     writeimage(stdout,image2);
  2807. }
  2808.  
  2809. autothresh(image)
  2810. IMAGE *image;
  2811. {
  2812.     register int x, y;
  2813.     int mean, sumx = 0, sumxsqrd = 0;
  2814.     double sd, nsd = 1.5;
  2815.  
  2816.     for (y = 0; y < image->ysize; y++) 
  2817.         for (x = 0; x < image->xsize; x++) {
  2818.             sumx += image->image[y][x];
  2819.             sumxsqrd += image->image[y][x] * image->image[y][x];
  2820.         }
  2821.  
  2822.     mean = sumx / (image->xsize * image->ysize);
  2823.     sd = sqrt((double) sumxsqrd / (image->xsize * image->ysize) - (mean * mean));
  2824.     x=nsd*sd;
  2825.     fprintf(stderr,"Threshold = %d\n",(int)(mean + x /* (nsd * sd)*/));
  2826.     return (int)(mean + x /*(nsd * sd)*/);
  2827. }
  2828. End of thresh.c
  2829.  echo xdiff1 1>&2
  2830. cat >xdiff1 <<'End of xdiff1'
  2831. 7 7
  2832.  
  2833. 1 1 1 0 -1 -1 -1
  2834. 1 1 1 0 -1 -1 -1
  2835. 1 1 1 0 -1 -1 -1
  2836. 1 1 1 0 -1 -1 -1
  2837. 1 1 1 0 -1 -1 -1
  2838. 1 1 1 0 -1 -1 -1
  2839. 1 1 1 0 -1 -1 -1
  2840. End of xdiff1
  2841.