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