1#ifndef lint 2static char id[] = "$Id: tif2ras.c 276 2010-06-30 12:18:30Z nijtmans $"; 3#endif 4/*- 5 * tif2ras.c - Converts from a Tagged Image File Format image to a Sun Raster. 6 * 7 * Copyright (c) 1990 by Sun Microsystems, Inc. 8 * 9 * Author: Patrick J. Naughton 10 * naughton@wind.sun.com 11 * 12 * Permission to use, copy, modify, and distribute this software and its 13 * documentation for any purpose and without fee is hereby granted, 14 * provided that the above copyright notice appear in all copies and that 15 * both that copyright notice and this permission notice appear in 16 * supporting documentation. 17 * 18 * This file is provided AS IS with no warranties of any kind. The author 19 * shall have no liability with respect to the infringement of copyrights, 20 * trade secrets or any patents by this file or any part thereof. In no 21 * event will the author be liable for any lost revenue or profits or 22 * other special, indirect and consequential damages. 23 * 24 * Comments and additions should be sent to the author: 25 * 26 * Patrick J. Naughton 27 * Sun Microsystems 28 * 2550 Garcia Ave, MS 14-40 29 * Mountain View, CA 94043 30 * (415) 336-1080 31 * 32 * Revision History: 33 * 10-Jan-89: Created. 34 * 06-Mar-90: Change to byte encoded rasterfiles. 35 * fix bug in call to ReadScanline(). 36 * fix bug in CVT() macro. 37 * fix assignment of td, (missing &). 38 * 39 * Description: 40 * This program takes a MicroSoft/Aldus "Tagged Image File Format" image or 41 * "TIFF" file as input and writes a Sun Rasterfile [see rasterfile(5)]. The 42 * output file may be standard output, but the input TIFF file must be a real 43 * file since seek(2) is used. 44 */ 45 46#include <stdio.h> 47#include <pixrect/pixrect_hs.h> 48#include "tiffio.h" 49 50typedef int boolean; 51#define True (1) 52#define False (0) 53#define CVT(x) (((x) * 255) / ((1L<<16)-1)) 54 55boolean Verbose = False; 56char *pname; /* program name (used for error messages) */ 57 58void 59error(s1, s2) 60 char *s1, 61 *s2; 62{ 63 fprintf(stderr, s1, pname, s2); 64 exit(1); 65} 66 67void 68usage() 69{ 70 error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL); 71} 72 73 74main(argc, argv) 75 int argc; 76 char *argv[]; 77{ 78 char *inf = NULL; 79 char *outf = NULL; 80 FILE *fp; 81 long width, 82 height; 83 int depth, 84 numcolors; 85 register TIFF *tif; 86 TIFFDirectory *td; 87 register u_char *inp, 88 *outp; 89 register int col, 90 i; 91 register long row; 92 u_char *Map = NULL; 93 u_char *buf; 94 short bitspersample; 95 short samplesperpixel; 96 short photometric; 97 u_short *redcolormap, 98 *bluecolormap, 99 *greencolormap; 100 101 Pixrect *pix; /* The Sun Pixrect */ 102 colormap_t Colormap; /* The Pixrect Colormap */ 103 u_char red[256], 104 green[256], 105 blue[256]; 106 107 setbuf(stderr, NULL); 108 pname = argv[0]; 109 110 while (--argc) { 111 if ((++argv)[0][0] == '-') 112 switch (argv[0][1]) { 113 case 'v': 114 Verbose = True; 115 break; 116 case 'q': 117 usage(); 118 break; 119 default: 120 fprintf(stderr, "%s: illegal option -%c.\n", pname, 121 argv[0][1]); 122 exit(1); 123 } 124 else if (inf == NULL) 125 inf = argv[0]; 126 else if (outf == NULL) 127 outf = argv[0]; 128 else 129 usage(); 130 131 } 132 133 if (inf == NULL) 134 error("%s: can't read input file from a stream.\n", NULL); 135 136 if (Verbose) 137 fprintf(stderr, "Reading %s...", inf); 138 139 tif = TIFFOpen(inf, "r"); 140 141 if (tif == NULL) 142 error("%s: error opening TIFF file %s", inf); 143 144 if (Verbose) 145 TIFFPrintDirectory(tif, stderr, True, False, False); 146 TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); 147 if (bitspersample > 8) 148 error("%s: can't handle more than 8-bits per sample\n", NULL); 149 150 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); 151 switch (samplesperpixel) { 152 case 1: 153 if (bitspersample == 1) 154 depth = 1; 155 else 156 depth = 8; 157 break; 158 case 3: 159 case 4: 160 depth = 24; 161 break; 162 default: 163 error("%s: only handle 1-channel gray scale or 3-channel color\n"); 164 } 165 166 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); 167 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); 168 169 if (Verbose) 170 fprintf(stderr, "%dx%dx%d image, ", width, height, depth); 171 if (Verbose) 172 fprintf(stderr, "%d bits/sample, %d samples/pixel, ", 173 bitspersample, samplesperpixel); 174 175 pix = mem_create(width, height, depth); 176 if (pix == (Pixrect *) NULL) 177 error("%s: can't allocate memory for output pixrect...\n", NULL); 178 179 numcolors = (1 << bitspersample); 180 181 TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric); 182 if (numcolors == 2) { 183 if (Verbose) 184 fprintf(stderr, "monochrome "); 185 Colormap.type = RMT_NONE; 186 Colormap.length = 0; 187 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL; 188 } else { 189 switch (photometric) { 190 case PHOTOMETRIC_MINISBLACK: 191 if (Verbose) 192 fprintf(stderr, "%d graylevels (min=black), ", numcolors); 193 Map = (u_char *) malloc(numcolors * sizeof(u_char)); 194 for (i = 0; i < numcolors; i++) 195 Map[i] = (255 * i) / numcolors; 196 Colormap.type = RMT_EQUAL_RGB; 197 Colormap.length = numcolors; 198 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map; 199 break; 200 case PHOTOMETRIC_MINISWHITE: 201 if (Verbose) 202 fprintf(stderr, "%d graylevels (min=white), ", numcolors); 203 Map = (u_char *) malloc(numcolors * sizeof(u_char)); 204 for (i = 0; i < numcolors; i++) 205 Map[i] = 255 - ((255 * i) / numcolors); 206 Colormap.type = RMT_EQUAL_RGB; 207 Colormap.length = numcolors; 208 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map; 209 break; 210 case PHOTOMETRIC_RGB: 211 if (Verbose) 212 fprintf(stderr, "truecolor "); 213 Colormap.type = RMT_NONE; 214 Colormap.length = 0; 215 Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL; 216 break; 217 case PHOTOMETRIC_PALETTE: 218 if (Verbose) 219 fprintf(stderr, "colormapped "); 220 Colormap.type = RMT_EQUAL_RGB; 221 Colormap.length = numcolors; 222 memset(red, 0, sizeof(red)); 223 memset(green, 0, sizeof(green)); 224 memset(blue, 0, sizeof(blue)); 225 TIFFGetField(tif, TIFFTAG_COLORMAP, 226 &redcolormap, &greencolormap, &bluecolormap); 227 for (i = 0; i < numcolors; i++) { 228 red[i] = (u_char) CVT(redcolormap[i]); 229 green[i] = (u_char) CVT(greencolormap[i]); 230 blue[i] = (u_char) CVT(bluecolormap[i]); 231 } 232 Colormap.map[0] = red; 233 Colormap.map[1] = green; 234 Colormap.map[2] = blue; 235 break; 236 case PHOTOMETRIC_MASK: 237 error("%s: Don't know how to handle PHOTOMETRIC_MASK\n"); 238 break; 239 case PHOTOMETRIC_DEPTH: 240 error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n"); 241 break; 242 default: 243 error("%s: unknown photometric (cmap): %d\n", photometric); 244 } 245 } 246 247 buf = (u_char *) malloc(TIFFScanlineSize(tif)); 248 if (buf == NULL) 249 error("%s: can't allocate memory for scanline buffer...\n", NULL); 250 251 for (row = 0; row < height; row++) { 252 if (TIFFReadScanline(tif, buf, row, 0) < 0) 253 error("%s: bad data read on line: %d\n", row); 254 inp = buf; 255 outp = (u_char *) mprd_addr(mpr_d(pix), 0, row); 256 switch (photometric) { 257 case PHOTOMETRIC_RGB: 258 if (samplesperpixel == 4) 259 for (col = 0; col < width; col++) { 260 *outp++ = *inp++; /* Blue */ 261 *outp++ = *inp++; /* Green */ 262 *outp++ = *inp++; /* Red */ 263 inp++; /* skip alpha channel */ 264 } 265 else 266 for (col = 0; col < width; col++) { 267 *outp++ = *inp++; /* Blue */ 268 *outp++ = *inp++; /* Green */ 269 *outp++ = *inp++; /* Red */ 270 } 271 break; 272 case PHOTOMETRIC_MINISWHITE: 273 case PHOTOMETRIC_MINISBLACK: 274 switch (bitspersample) { 275 case 1: 276 for (col = 0; col < ((width + 7) / 8); col++) 277 *outp++ = *inp++; 278 break; 279 case 2: 280 for (col = 0; col < ((width + 3) / 4); col++) { 281 *outp++ = (*inp >> 6) & 3; 282 *outp++ = (*inp >> 4) & 3; 283 *outp++ = (*inp >> 2) & 3; 284 *outp++ = *inp++ & 3; 285 } 286 break; 287 case 4: 288 for (col = 0; col < width / 2; col++) { 289 *outp++ = *inp >> 4; 290 *outp++ = *inp++ & 0xf; 291 } 292 break; 293 case 8: 294 for (col = 0; col < width; col++) 295 *outp++ = *inp++; 296 break; 297 default: 298 error("%s: bad bits/sample: %d\n", bitspersample); 299 } 300 break; 301 case PHOTOMETRIC_PALETTE: 302 memcpy(outp, inp, width); 303 break; 304 default: 305 error("%s: unknown photometric (write): %d\n", photometric); 306 } 307 } 308 309 free((char *) buf); 310 311 if (Verbose) 312 fprintf(stderr, "done.\n"); 313 314 if (outf == NULL || strcmp(outf, "Standard Output") == 0) { 315 outf = "Standard Output"; 316 fp = stdout; 317 } else { 318 if (!(fp = fopen(outf, "w"))) 319 error("%s: %s couldn't be opened for writing.\n", outf); 320 } 321 322 if (Verbose) 323 fprintf(stderr, "Writing rasterfile in %s...", outf); 324 325 if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR) 326 error("%s: error writing Sun Rasterfile: %s\n", outf); 327 328 if (Verbose) 329 fprintf(stderr, "done.\n"); 330 331 pr_destroy(pix); 332 333 if (fp != stdout) 334 fclose(fp); 335 336 exit(0); 337} 338/* 339 * Local Variables: 340 * mode: c 341 * c-basic-offset: 8 342 * fill-column: 78 343 * End: 344 */ 345