|
|
PoV-Ray can't read some valid PPM files containing comments,
most notable those created by The GIMP, starting with
something like
P6
# CREATOR: The GIMP's PNM Filter Version 1.0
320 240
255
Here I include PPM spec for reference (well, the part about
nonlinear sampling is quite controversal, since nowadays
most tools use what is called ``common variation'' there,
i.e. linear sampling)
A PPM file consists of a sequence of one or more PPM
images. There are no data, delimiters, or padding before,
after, or between images.
Each PPM image consists of the following:
- A "magic number" for identifying the file type. A ppm
image's magic number is the two characters "P6".
- Whitespace (blanks, TABs, CRs, LFs).
- A width, formatted as ASCII characters in decimal.
- Whitespace.
- A height, again in ASCII decimal.
- Whitespace.
- The maximum color value (Maxval), again in ASCII deci-
mal. Must be less than 65536.
- Newline or other single whitespace character.
- A raster of Width * Height pixels, proceeding through
the image in normal English reading order. Each pixel
is a triplet of red, green, and blue samples, in that
order. Each sample is represented in pure binary by
either 1 or 2 bytes. If the Maxval is less than 256, it
is 1 byte. Otherwise, it is 2 bytes. The most signifi-
cant byte is first.
- In the raster, the sample values are "nonlinear." They
are proportional to the intensity of the CIE Rec. 709
red, green, and blue in the pixel, adjusted by the CIE
Rec. 709 gamma transfer function. (That transfer func-
tion specifies a gamma number of 2.2 and has a linear
section for small intensities). A value of Maxval for
all three samples represents CIE D65 white and the most
intense color in the color universe of which the image
is part (the color universe is all the colors in all
images to which this image might be compared).
- Note that a common variation on the PPM format is to
have the sample values be "linear," i.e. as specified
above except without the gamma adjustment. pnmgamma
takes such a PPM variant as input and produces a true
PPM as output.
- Characters from a "#" to the next end-of-line, before
the maxval line, are comments and are ignored.
A patch is also included (I don't send it here, not to
unofficial-patches, because it's a bugfix, not a new
feature)
Yeti
--- povray-3.50a.orig/src/ppm.cpp Wed Aug 21 18:53:45 2002
+++ povray-3.50a/src/ppm.cpp Wed Aug 21 20:01:12 2002
@@ -56,6 +56,8 @@
#include "ppm.h"
#include "file_pov.h"
+#include <cctype>
+
/*****************************************************************************
* Local preprocessor defines
******************************************************************************/
@@ -434,21 +436,58 @@
if((type != '3') && (type != '6'))
Error ("File is not in PPM format.");
+ /* Eat up all whitespace */
+ do {
+ data = infile->Read_Byte ();
+ } while (std::isspace (data));
+ infile->UnRead_Byte (data) ;
+
/* Ignore any comments */
while ((data = infile->Read_Byte ()) == '#')
infile->getline(junk,512);
infile->UnRead_Byte (data) ;
- if ((data = infile->Read_Byte ()) != ' ')
- infile->UnRead_Byte (data) ;
- for (i = 0, s = junk ; (i < 8) && ((data = infile->Read_Byte ()) != ' ') ; i++,
s++)
+ /* Eat up all whitespace */
+ do {
+ data = infile->Read_Byte ();
+ } while (std::isspace (data));
+ infile->UnRead_Byte (data) ;
+
+ /* Read width */
+ for (i = 0, s = junk ; i < 8 ; i++, s++) {
+ data = infile->Read_Byte ();
+ if (std::isspace (data))
+ break ;
*s = (char) data ;
+ }
*s = '\0' ;
if (*infile)
width = atoi (junk) ;
- for (i = 0, s = junk ; (i < 8) && ((data = infile->Read_Byte ()) != ' ') ; i++,
s++)
+ /* Eat up all whitespace */
+ do {
+ data = infile->Read_Byte ();
+ } while (std::isspace (data));
+ infile->UnRead_Byte (data) ;
+
+ /* Ignore any comments */
+ while ((data = infile->Read_Byte ()) == '#')
+ infile->getline(junk,512);
+ infile->UnRead_Byte (data) ;
+
+ /* Eat up all whitespace */
+ do {
+ data = infile->Read_Byte ();
+ } while (std::isspace (data));
+ infile->UnRead_Byte (data) ;
+
+ /* Read height */
+ for (i = 0, s = junk ; i < 8 ; i++, s++) {
+ data = infile->Read_Byte ();
+ if (std::isspace (data))
+ break ;
*s = (char) data ;
+ }
*s = '\0' ;
if (*infile)
height = atoi (junk) ;
@@ -456,14 +495,35 @@
if (width == 0 || height == 0)
Error ("Invalid width or height read from PPM image.");
+ /* Eat up all whitespace */
+ do {
+ data = infile->Read_Byte ();
+ } while (std::isspace (data));
+ infile->UnRead_Byte (data) ;
+
/* Ignore any comments */
while ((data = infile->Read_Byte ()) == '#')
infile->getline(junk,512);
infile->UnRead_Byte (data) ;
- infile->getline(junk,512);
- depth = atoi(junk);
- if((depth > 255) || (depth < 1))
+ /* Eat up all whitespace */
+ do {
+ data = infile->Read_Byte ();
+ } while (std::isspace (data));
+ infile->UnRead_Byte (data) ;
+
+ /* Read depth, must end with _exactly_ one whitespace */
+ for (i = 0, s = junk ; i < 5 ; i++, s++) {
+ data = infile->Read_Byte ();
+ if (std::isspace (data))
+ break ;
+ *s = (char) data ;
+ }
+ *s = '\0' ;
+ if (*infile)
+ depth = atoi (junk) ;
+
+ if ((depth > 255) || (depth < 1))
Error ("Unsupported number of colors (%d) in PPM image.", depth);
Image->width = (DBL)(Image->iwidth = width);
Post a reply to this message
|
|