tif2ras.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. #ifndef lint
  2. static char id[] = "$Id: tif2ras.c,v 1.3 2010-06-08 18:55:15 bfriesen Exp $";
  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. #include <stdio.h>
  46. #include <pixrect/pixrect_hs.h>
  47. #include "tiffio.h"
  48. typedef int boolean;
  49. #define True (1)
  50. #define False (0)
  51. #define CVT(x) (((x) * 255) / ((1L<<16)-1))
  52. boolean Verbose = False;
  53. char *pname; /* program name (used for error messages) */
  54. void
  55. error(s1, s2)
  56. char *s1,
  57. *s2;
  58. {
  59. fprintf(stderr, s1, pname, s2);
  60. exit(1);
  61. }
  62. void
  63. usage()
  64. {
  65. error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL);
  66. }
  67. main(argc, argv)
  68. int argc;
  69. char *argv[];
  70. {
  71. char *inf = NULL;
  72. char *outf = NULL;
  73. FILE *fp;
  74. long width,
  75. height;
  76. int depth,
  77. numcolors;
  78. register TIFF *tif;
  79. TIFFDirectory *td;
  80. register u_char *inp,
  81. *outp;
  82. register int col,
  83. i;
  84. register long row;
  85. u_char *Map = NULL;
  86. u_char *buf;
  87. short bitspersample;
  88. short samplesperpixel;
  89. short photometric;
  90. u_short *redcolormap,
  91. *bluecolormap,
  92. *greencolormap;
  93. Pixrect *pix; /* The Sun Pixrect */
  94. colormap_t Colormap; /* The Pixrect Colormap */
  95. u_char red[256],
  96. green[256],
  97. blue[256];
  98. setbuf(stderr, NULL);
  99. pname = argv[0];
  100. while (--argc) {
  101. if ((++argv)[0][0] == '-')
  102. switch (argv[0][1]) {
  103. case 'v':
  104. Verbose = True;
  105. break;
  106. case 'q':
  107. usage();
  108. break;
  109. default:
  110. fprintf(stderr, "%s: illegal option -%c.\n", pname,
  111. argv[0][1]);
  112. exit(1);
  113. }
  114. else if (inf == NULL)
  115. inf = argv[0];
  116. else if (outf == NULL)
  117. outf = argv[0];
  118. else
  119. usage();
  120. }
  121. if (inf == NULL)
  122. error("%s: can't read input file from a stream.\n", NULL);
  123. if (Verbose)
  124. fprintf(stderr, "Reading %s...", inf);
  125. tif = TIFFOpen(inf, "r");
  126. if (tif == NULL)
  127. error("%s: error opening TIFF file %s", inf);
  128. if (Verbose)
  129. TIFFPrintDirectory(tif, stderr, True, False, False);
  130. TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  131. if (bitspersample > 8)
  132. error("%s: can't handle more than 8-bits per sample\n", NULL);
  133. TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  134. switch (samplesperpixel) {
  135. case 1:
  136. if (bitspersample == 1)
  137. depth = 1;
  138. else
  139. depth = 8;
  140. break;
  141. case 3:
  142. case 4:
  143. depth = 24;
  144. break;
  145. default:
  146. error("%s: only handle 1-channel gray scale or 3-channel color\n");
  147. }
  148. TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  149. TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  150. if (Verbose)
  151. fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
  152. if (Verbose)
  153. fprintf(stderr, "%d bits/sample, %d samples/pixel, ",
  154. bitspersample, samplesperpixel);
  155. pix = mem_create(width, height, depth);
  156. if (pix == (Pixrect *) NULL)
  157. error("%s: can't allocate memory for output pixrect...\n", NULL);
  158. numcolors = (1 << bitspersample);
  159. TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
  160. if (numcolors == 2) {
  161. if (Verbose)
  162. fprintf(stderr, "monochrome ");
  163. Colormap.type = RMT_NONE;
  164. Colormap.length = 0;
  165. Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
  166. } else {
  167. switch (photometric) {
  168. case PHOTOMETRIC_MINISBLACK:
  169. if (Verbose)
  170. fprintf(stderr, "%d graylevels (min=black), ", numcolors);
  171. Map = (u_char *) malloc(numcolors * sizeof(u_char));
  172. for (i = 0; i < numcolors; i++)
  173. Map[i] = (255 * i) / numcolors;
  174. Colormap.type = RMT_EQUAL_RGB;
  175. Colormap.length = numcolors;
  176. Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
  177. break;
  178. case PHOTOMETRIC_MINISWHITE:
  179. if (Verbose)
  180. fprintf(stderr, "%d graylevels (min=white), ", numcolors);
  181. Map = (u_char *) malloc(numcolors * sizeof(u_char));
  182. for (i = 0; i < numcolors; i++)
  183. Map[i] = 255 - ((255 * i) / numcolors);
  184. Colormap.type = RMT_EQUAL_RGB;
  185. Colormap.length = numcolors;
  186. Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
  187. break;
  188. case PHOTOMETRIC_RGB:
  189. if (Verbose)
  190. fprintf(stderr, "truecolor ");
  191. Colormap.type = RMT_NONE;
  192. Colormap.length = 0;
  193. Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
  194. break;
  195. case PHOTOMETRIC_PALETTE:
  196. if (Verbose)
  197. fprintf(stderr, "colormapped ");
  198. Colormap.type = RMT_EQUAL_RGB;
  199. Colormap.length = numcolors;
  200. memset(red, 0, sizeof(red));
  201. memset(green, 0, sizeof(green));
  202. memset(blue, 0, sizeof(blue));
  203. TIFFGetField(tif, TIFFTAG_COLORMAP,
  204. &redcolormap, &greencolormap, &bluecolormap);
  205. for (i = 0; i < numcolors; i++) {
  206. red[i] = (u_char) CVT(redcolormap[i]);
  207. green[i] = (u_char) CVT(greencolormap[i]);
  208. blue[i] = (u_char) CVT(bluecolormap[i]);
  209. }
  210. Colormap.map[0] = red;
  211. Colormap.map[1] = green;
  212. Colormap.map[2] = blue;
  213. break;
  214. case PHOTOMETRIC_MASK:
  215. error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
  216. break;
  217. case PHOTOMETRIC_DEPTH:
  218. error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
  219. break;
  220. default:
  221. error("%s: unknown photometric (cmap): %d\n", photometric);
  222. }
  223. }
  224. buf = (u_char *) malloc(TIFFScanlineSize(tif));
  225. if (buf == NULL)
  226. error("%s: can't allocate memory for scanline buffer...\n", NULL);
  227. for (row = 0; row < height; row++) {
  228. if (TIFFReadScanline(tif, buf, row, 0) < 0)
  229. error("%s: bad data read on line: %d\n", row);
  230. inp = buf;
  231. outp = (u_char *) mprd_addr(mpr_d(pix), 0, row);
  232. switch (photometric) {
  233. case PHOTOMETRIC_RGB:
  234. if (samplesperpixel == 4)
  235. for (col = 0; col < width; col++) {
  236. *outp++ = *inp++; /* Blue */
  237. *outp++ = *inp++; /* Green */
  238. *outp++ = *inp++; /* Red */
  239. inp++; /* skip alpha channel */
  240. }
  241. else
  242. for (col = 0; col < width; col++) {
  243. *outp++ = *inp++; /* Blue */
  244. *outp++ = *inp++; /* Green */
  245. *outp++ = *inp++; /* Red */
  246. }
  247. break;
  248. case PHOTOMETRIC_MINISWHITE:
  249. case PHOTOMETRIC_MINISBLACK:
  250. switch (bitspersample) {
  251. case 1:
  252. for (col = 0; col < ((width + 7) / 8); col++)
  253. *outp++ = *inp++;
  254. break;
  255. case 2:
  256. for (col = 0; col < ((width + 3) / 4); col++) {
  257. *outp++ = (*inp >> 6) & 3;
  258. *outp++ = (*inp >> 4) & 3;
  259. *outp++ = (*inp >> 2) & 3;
  260. *outp++ = *inp++ & 3;
  261. }
  262. break;
  263. case 4:
  264. for (col = 0; col < width / 2; col++) {
  265. *outp++ = *inp >> 4;
  266. *outp++ = *inp++ & 0xf;
  267. }
  268. break;
  269. case 8:
  270. for (col = 0; col < width; col++)
  271. *outp++ = *inp++;
  272. break;
  273. default:
  274. error("%s: bad bits/sample: %d\n", bitspersample);
  275. }
  276. break;
  277. case PHOTOMETRIC_PALETTE:
  278. memcpy(outp, inp, width);
  279. break;
  280. default:
  281. error("%s: unknown photometric (write): %d\n", photometric);
  282. }
  283. }
  284. free((char *) buf);
  285. if (Verbose)
  286. fprintf(stderr, "done.\n");
  287. if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
  288. outf = "Standard Output";
  289. fp = stdout;
  290. } else {
  291. if (!(fp = fopen(outf, "w")))
  292. error("%s: %s couldn't be opened for writing.\n", outf);
  293. }
  294. if (Verbose)
  295. fprintf(stderr, "Writing rasterfile in %s...", outf);
  296. if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR)
  297. error("%s: error writing Sun Rasterfile: %s\n", outf);
  298. if (Verbose)
  299. fprintf(stderr, "done.\n");
  300. pr_destroy(pix);
  301. if (fp != stdout)
  302. fclose(fp);
  303. exit(0);
  304. }
  305. /*
  306. * Local Variables:
  307. * mode: c
  308. * c-basic-offset: 8
  309. * fill-column: 78
  310. * End:
  311. */