PGM.C 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /****************************************************************************
  2. * pgm.c
  3. *
  4. * This module contains the code to read the PGM file format.
  5. *
  6. * from Persistence of Vision(tm) Ray Tracer
  7. * Copyright 1996,1999 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. * NOTICE: This source code file is provided so that users may experiment
  10. * with enhancements to POV-Ray and to port the software to platforms other
  11. * than those supported by the POV-Ray Team. There are strict rules under
  12. * which you are permitted to use this file. The rules are in the file
  13. * named POVLEGAL.DOC which should be distributed with this file.
  14. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  16. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. * Original patch copyright 1994 Tim Rowley
  23. * Updated for POV 3.0 by Chris Cason, Jan '95.
  24. *
  25. * Modifications by Hans-Detlev Fink, January 1999, used with permission
  26. *
  27. *****************************************************************************/
  28. /****************************************************************************
  29. * The format is as follows:
  30. *
  31. * (header:)
  32. * P2 - ASCII data in file OR
  33. * P5 - binary data in file
  34. * # hello - comment (optional, may be multiple)
  35. * wwww hhhh - Width, Height (ASCII text)
  36. * # world - comment (optional, may be multiple)
  37. * nnn - maximum color (nnn = white, 0 = black)
  38. *
  39. * (each pixel: one of the following)
  40. * xx - Intensity 0-nnn (binary byte)
  41. * AAA - Intensity 0-nnn (ASCII number)
  42. *
  43. *****************************************************************************/
  44. #include "frame.h"
  45. #include "povproto.h"
  46. #include "povray.h"
  47. #include "pgm.h"
  48. #include "ppm.h"
  49. /*****************************************************************************
  50. *
  51. * FUNCTION
  52. *
  53. * Read_PGM_Image
  54. *
  55. * INPUT
  56. *
  57. * OUTPUT
  58. *
  59. * RETURNS
  60. *
  61. * AUTHOR
  62. *
  63. * DESCRIPTION
  64. *
  65. * CHANGES
  66. * Modified to support ASCII files, comments, and arbitrary bit depth [AED]
  67. *
  68. ******************************************************************************/
  69. void Read_PGM_Image(IMAGE *Image, char *name)
  70. {
  71. char type;
  72. int width, height;
  73. int depth;
  74. char input;
  75. char junk[512];
  76. int x, y;
  77. int data;
  78. FILE *infile;
  79. if ((infile = Locate_File(name,READ_BINFILE_STRING,".pgm",".PGM",NULL,TRUE)) == NULL)
  80. {
  81. Error ("Cannot open PGM image %s.\n", name);
  82. return; /* -hdf99- */
  83. }
  84. if (fscanf(infile,"P%c\n",&type) != 1 || (type != '2' && type != '5'))
  85. {
  86. Error ("File is not in PGM format.\n");
  87. return; /* -hdf99- */
  88. }
  89. /* Ignore any comments */
  90. while ((input = fgetc(infile)) == '#')
  91. {
  92. fgets(junk,512,infile);
  93. }
  94. ungetc(input,infile);
  95. if (fscanf(infile,"%d %d\n",&width,&height) != 2)
  96. {
  97. Error ("Error reading width or height from PGM image.\n");
  98. }
  99. /* Ignore any comments */
  100. while ((input = fgetc(infile)) == '#')
  101. {
  102. fgets(junk,512,infile);
  103. }
  104. ungetc(input,infile);
  105. if (fscanf(infile,"%d\n",&depth) != 1 ||
  106. (depth > 255 && type == '5') ||
  107. depth > 65535 || depth < 1)
  108. {
  109. Error ("Unsupported number of colors (%d) in PGM image.\n", depth);
  110. }
  111. Image->width = (DBL)(Image->iwidth = width);
  112. Image->height = (DBL)(Image->iheight = height);
  113. if (depth < 256)
  114. {
  115. Image->Colour_Map_Size = depth;
  116. Image->Colour_Map = (IMAGE_COLOUR *)POV_MALLOC(depth*sizeof(IMAGE_COLOUR), "PGM color map");
  117. for (x = 0; x < depth; x++)
  118. {
  119. Image->Colour_Map[x].Red =
  120. Image->Colour_Map[x].Green =
  121. Image->Colour_Map[x].Blue = x*255/depth;
  122. Image->Colour_Map[x].Filter =0;
  123. Image->Colour_Map[x].Transmit =0;
  124. }
  125. Image->data.map_lines = (unsigned char **)POV_MALLOC(height*sizeof(unsigned char *), "PGM image");
  126. for (y = 0; y < height; y++)
  127. {
  128. Image->data.map_lines[y] = (unsigned char *)POV_MALLOC(width,"PGM image line");
  129. if (type == '2') /* ASCII data to be input */
  130. {
  131. for (x = 0; x < width; x++)
  132. {
  133. if (fscanf(infile,"%d",&data) != 1)
  134. {
  135. Error ("Error reading data from PGM image.\n");
  136. }
  137. Image->data.map_lines[y][x] = data;
  138. }
  139. }
  140. else /* (type == '5') Raw binary data to be input */
  141. {
  142. for (x = 0; x < width; x++)
  143. {
  144. if ((data = getc(infile)) == EOF)
  145. {
  146. Error ("Error reading data from PGM image.\n");
  147. }
  148. Image->data.map_lines[y][x] = data;
  149. }
  150. }
  151. }
  152. }
  153. else /* if(depth < 65536) the data MUST be in ASCII format */
  154. {
  155. IMAGE_LINE *line_data;
  156. Image->Colour_Map_Size = 0;
  157. Image->Colour_Map = (IMAGE_COLOUR *)NULL;
  158. Image->data.rgb_lines = (IMAGE_LINE *)POV_MALLOC(height * sizeof(IMAGE_LINE), "PGM image");
  159. for (y = 0; y < height; y++)
  160. {
  161. line_data = &Image->data.rgb_lines[y];
  162. line_data->red = (unsigned char *)POV_MALLOC(width, "PGM image line");
  163. line_data->green = (unsigned char *)POV_MALLOC(width, "PGM image line");
  164. line_data->blue = (unsigned char *)POV_MALLOC(width, "PGM image line");
  165. line_data->transm = (unsigned char *)NULL;
  166. for (x = 0; x < width; x++)
  167. {
  168. if (fscanf(infile,"%d",&data) != 1)
  169. {
  170. Error("Error reading data from PGM image.\n");
  171. }
  172. data = (int)((DBL)data*65535/depth);
  173. line_data->red[x] = (data >> 8) & 0xFF;
  174. line_data->green[x] = data & 0xFF;
  175. line_data->blue[x] = 0;
  176. }
  177. }
  178. }
  179. fclose(infile);
  180. }