1 /*
2  * tiff-grayscale.c -- create a Class G (grayscale) TIFF file
3  *      with a gray response curve in linear optical density
4  *
5  * Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
6  *
7  *                        All Rights Reserved
8  *
9  * Permission to use, copy, modify, and distribute this software and its
10  * documentation for any purpose and without fee is hereby granted,
11  * provided that the above copyright notice appear in all copies and that
12  * both that copyright notice and this permission notice appear in
13  * supporting documentation, and that the name of Digital not be
14  * used in advertising or publicity pertaining to distribution of the
15  * software without specific, written prior permission.
16  *
17  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23  * SOFTWARE.
24  */
25 
26 #include <math.h>
27 #include <stdio.h>
28 #include <tiffio.h>
29 
30 #define WIDTH       512
31 #define HEIGHT      WIDTH
32 
33 typedef	unsigned char u_char;
34 typedef	unsigned short u_short;
35 typedef	unsigned long u_long;
36 
37 char *              programName;
38 void                Usage();
39 
40 void
main(argc,argv)41 main(argc, argv)
42     int             argc;
43     char **         argv;
44 {
45     int             bits_per_pixel, cmsize, i, j, k,
46                     gray_index, chunk_size, nchunks;
47     u_char *        scan_line;
48     u_short *       gray;
49     u_long	    refblackwhite[2*1];
50     TIFF *          tif;
51 
52     programName = argv[0];
53 
54     if (argc != 4)
55         Usage();
56 
57     if (!strcmp(argv[1], "-depth"))
58          bits_per_pixel = atoi(argv[2]);
59     else
60          Usage();
61 
62     switch (bits_per_pixel) {
63         case 8:
64             nchunks = 16;
65             chunk_size = 32;
66             break;
67         case 4:
68             nchunks = 4;
69             chunk_size = 128;
70             break;
71         case 2:
72             nchunks = 2;
73             chunk_size = 256;
74             break;
75         default:
76             Usage();
77     }
78 
79     cmsize = nchunks * nchunks;
80     gray = (u_short *) malloc(cmsize * sizeof(u_short));
81 
82     gray[0] = 3000;
83     for (i = 1; i < cmsize; i++)
84         gray[i] = (u_short) (-log10((double) i / (cmsize - 1)) * 1000);
85 
86     refblackwhite[0] = 0;
87     refblackwhite[0] = (1L<<bits_per_pixel) - 1;
88 
89     if ((tif = TIFFOpen(argv[3], "w")) == NULL) {
90         fprintf(stderr, "can't open %s as a TIFF file\n", argv[3]);
91         exit(0);
92     }
93 
94     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH);
95     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT);
96     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_pixel);
97     TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
98     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
99     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
100     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
101     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
102     TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refblackwhite);
103     TIFFSetField(tif, TIFFTAG_TRANSFERFUNCTION, gray);
104     TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
105 
106     scan_line = (u_char *) malloc(WIDTH / (8 / bits_per_pixel));
107 
108     for (i = 0; i < HEIGHT; i++) {
109         for (j = 0, k = 0; j < WIDTH;) {
110             gray_index = (j / chunk_size) + ((i / chunk_size) * nchunks);
111 
112             switch (bits_per_pixel) {
113             case 8:
114                 scan_line[k++] = gray_index;
115                 j++;
116                 break;
117             case 4:
118                 scan_line[k++] = (gray_index << 4) + gray_index;
119                 j += 2;
120                 break;
121             case 2:
122                 scan_line[k++] = (gray_index << 6) + (gray_index << 4)
123                     + (gray_index << 2) + gray_index;
124                 j += 4;
125                 break;
126             }
127         }
128         TIFFWriteScanline(tif, scan_line, i, 0);
129     }
130 
131     free(scan_line);
132     TIFFClose(tif);
133     exit(0);
134 }
135 
136 void
Usage()137 Usage()
138 {
139     fprintf(stderr, "Usage: %s -depth (8 | 4 | 2) tiff-image\n", programName);
140     exit(0);
141 }
142