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