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