1/* $Id: tiff-palette.c 276 2010-06-30 12:18:30Z nijtmans $ */
2
3/*
4 * tiff-palette.c -- create a Class P (palette) TIFF file
5 *
6 * Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
7 *
8 *                        All Rights Reserved
9 *
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation for any purpose and without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and that
13 * both that copyright notice and this permission notice appear in
14 * supporting documentation, and that the name of Digital not be
15 * used in advertising or publicity pertaining to distribution of the
16 * software without specific, written prior permission.
17 *
18 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24 * SOFTWARE.
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include "tiffio.h"
32
33#define WIDTH       512
34#define HEIGHT      WIDTH
35#define SCALE(x)    ((x) * 257L)
36
37char *              programName;
38void                Usage();
39
40int main(int argc, char **argv)
41{
42    int             bits_per_pixel = 8, cmsize, i, j, k,
43                    cmap_index, chunk_size = 32, nchunks = 16;
44    unsigned char * scan_line;
45    uint16          *red, *green, *blue;
46    TIFF *          tif;
47
48    programName = argv[0];
49
50    if (argc != 4)
51        Usage();
52
53    if (!strcmp(argv[1], "-depth"))
54         bits_per_pixel = atoi(argv[2]);
55    else
56         Usage();
57
58    switch (bits_per_pixel) {
59        case 8:
60            nchunks = 16;
61            chunk_size = 32;
62            break;
63        case 4:
64            nchunks = 4;
65            chunk_size = 128;
66            break;
67        case 2:
68            nchunks = 2;
69            chunk_size = 256;
70            break;
71	case 1:
72	    nchunks = 2;
73	    chunk_size = 256;
74	    break;
75        default:
76            Usage();
77    }
78
79    if (bits_per_pixel != 1) {
80	cmsize = nchunks * nchunks;
81    } else {
82	cmsize = 2;
83    }
84    red = (uint16 *) malloc(cmsize * sizeof(uint16));
85    green = (uint16 *) malloc(cmsize * sizeof(uint16));
86    blue = (uint16 *) malloc(cmsize * sizeof(uint16));
87
88    switch (bits_per_pixel) {
89    case 8:
90        for (i = 0; i < cmsize; i++) {
91            if (i < 32)
92                red[i] = 0;
93            else if (i < 64)
94                red[i] = SCALE(36);
95            else if (i < 96)
96                red[i] = SCALE(73);
97            else if (i < 128)
98                red[i] = SCALE(109);
99            else if (i < 160)
100                red[i] = SCALE(146);
101            else if (i < 192)
102                red[i] = SCALE(182);
103            else if (i < 224)
104                red[i] = SCALE(219);
105            else if (i < 256)
106                red[i] = SCALE(255);
107
108            if ((i % 32) < 4)
109                green[i] = 0;
110            else if (i < 8)
111                green[i] = SCALE(36);
112            else if ((i % 32) < 12)
113                green[i] = SCALE(73);
114            else if ((i % 32) < 16)
115                green[i] = SCALE(109);
116            else if ((i % 32) < 20)
117                green[i] = SCALE(146);
118            else if ((i % 32) < 24)
119                green[i] = SCALE(182);
120            else if ((i % 32) < 28)
121                green[i] = SCALE(219);
122            else if ((i % 32) < 32)
123                green[i] = SCALE(255);
124
125            if ((i % 4) == 0)
126                blue[i] = SCALE(0);
127            else if ((i % 4) == 1)
128                blue[i] = SCALE(85);
129            else if ((i % 4) == 2)
130                blue[i] = SCALE(170);
131            else if ((i % 4) == 3)
132                blue[i] = SCALE(255);
133        }
134        break;
135    case 4:
136        red[0] = SCALE(255);
137        green[0] = 0;
138        blue[0] = 0;
139
140        red[1] = 0;
141        green[1] = SCALE(255);
142        blue[1] = 0;
143
144        red[2] = 0;
145        green[2] = 0;
146        blue[2] = SCALE(255);
147
148        red[3] = SCALE(255);
149        green[3] = SCALE(255);
150        blue[3] = SCALE(255);
151
152        red[4] = 0;
153        green[4] = SCALE(255);
154        blue[4] = SCALE(255);
155
156        red[5] = SCALE(255);
157        green[5] = 0;
158        blue[5] = SCALE(255);
159
160        red[6] = SCALE(255);
161        green[6] = SCALE(255);
162        blue[6] = 0;
163
164        red[7] = 0;
165        green[7] = 0;
166        blue[7] = 0;
167
168        red[8] = SCALE(176);
169        green[8] = SCALE(224);
170        blue[8] = SCALE(230);
171        red[9] = SCALE(100);
172        green[9] = SCALE(149);
173        blue[9] = SCALE(237);
174        red[10] = SCALE(46);
175        green[10] = SCALE(139);
176        blue[10] = SCALE(87);
177        red[11] = SCALE(160);
178        green[11] = SCALE(82);
179        blue[11] = SCALE(45);
180        red[12] = SCALE(238);
181        green[12] = SCALE(130);
182        blue[12] = SCALE(238);
183        red[13] = SCALE(176);
184        green[13] = SCALE(48);
185        blue[13] = SCALE(96);
186        red[14] = SCALE(50);
187        green[14] = SCALE(205);
188        blue[14] = SCALE(50);
189        red[15] = SCALE(240);
190        green[15] = SCALE(152);
191        blue[15] = SCALE(35);
192        break;
193    case 2:
194        red[0] = SCALE(255);
195        green[0] = 0;
196        blue[0] = 0;
197
198        red[1] = 0;
199        green[1] = SCALE(255);
200        blue[1] = 0;
201
202        red[2] = 0;
203        green[2] = 0;
204        blue[2] = SCALE(255);
205        red[3] = SCALE(255);
206        green[3] = SCALE(255);
207        blue[3] = SCALE(255);
208        break;
209    case 1:
210        red[0] = 0;
211        green[0] = 0;
212        blue[0] = 0;
213
214        red[1] = SCALE(255);
215        green[1] = SCALE(255);
216        blue[1] = SCALE(255);
217        break;
218    }
219
220    if ((tif = TIFFOpen(argv[3], "w")) == NULL) {
221        fprintf(stderr, "can't open %s as a TIFF file\n", argv[3]);
222        return 0;
223    }
224
225    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH);
226    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT);
227    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_pixel);
228    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
229    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
230    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
231    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
232    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
233    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
234    TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
235
236    scan_line = (unsigned char *) malloc(WIDTH / (8 / bits_per_pixel));
237
238    for (i = 0; i < HEIGHT; i++) {
239        for (j = 0, k = 0; j < WIDTH;) {
240            cmap_index = (j / chunk_size) + ((i / chunk_size) * nchunks);
241
242            switch (bits_per_pixel) {
243            case 8:
244                scan_line[k++] = cmap_index;
245                j++;
246                break;
247            case 4:
248                scan_line[k++] = (cmap_index << 4) + cmap_index;
249                j += 2;
250                break;
251            case 2:
252                scan_line[k++] = (cmap_index << 6) + (cmap_index << 4)
253                    + (cmap_index << 2) + cmap_index;
254                j += 4;
255                break;
256	    case 1:
257		scan_line[k++] =
258			((j / chunk_size) == (i / chunk_size)) ? 0x00 : 0xff;
259		j += 8;
260		break;
261            }
262        }
263        TIFFWriteScanline(tif, scan_line, i, 0);
264    }
265
266    free(scan_line);
267    TIFFClose(tif);
268    return 0;
269}
270
271void
272Usage()
273{
274    fprintf(stderr, "Usage: %s -depth (8 | 4 | 2 | 1) tiff-image\n", programName);
275    exit(0);
276}
277/*
278 * Local Variables:
279 * mode: c
280 * c-basic-offset: 8
281 * fill-column: 78
282 * End:
283 */
284