ulf.schroeter Posted February 28, 2011 Share Posted February 28, 2011 Problem PPM/PGM image header data read might fail in case of # character only comment line before data line P5 # Next line will cause invalid image dimensions because width and height line will be skipped # 752 480 65535 @@€ Cause Image.cpp int Image::load_ppm(const char *name) { .... while(file.eof() == 0 && num_colors == -1) { file.readToken(buf,sizeof(buf)); if(buf[0] == '#') { file.readLine(); // THIS WILL SKIP WIDTH HEIGHT LINE IN PREVIOUS EXAMPLE continue; } if(width == -1) width = atoi(buf); else if(height == -1) height = atoi(buf); else if(num_colors == -1) num_colors = atoi(buf); } Temporary Workaround In case of problems users can remove single # comment line by hand. Link to comment
ulf.schroeter Posted February 28, 2011 Author Share Posted February 28, 2011 Proposal Additional support for PPM/PGM ASCII P2/P3 formats as outputted by GlobalMapper tool. Image.cpp /******************************************************************************\ * * PPM format * \******************************************************************************/ static void ppm_read_pixel_tokens(unsigned char *data,const File &file,size_t size,int num_colors) { char buf[1024]; for(size_t i = 0; i < size; i++) { if( file.readToken(buf,sizeof(buf)) == 0 ) break; int pixel = atoi(buf); if( num_colors <= 255 ) { *((unsigned char*) data) = (unsigned char) pixel; data += 1; } else { *((unsigned short*) data) = (unsigned short) pixel; data += 2; } } } /* */ int Image::load_ppm(const char *name) { ... if(strcmp(header,"P2") && strcmp(header,"P3") && strcmp(header,"P5") && strcmp(header,"P6")) { .... .... if(num_colors <= 255) { if(!strcmp(header,"P5")) { create2D(width,height,FORMAT_R8,1,0); file.read(data,sizeof(unsigned char),width * height); } else if(!strcmp(header,"P6")) { create2D(width,height,FORMAT_RGB8,1,0); file.read(data,sizeof(unsigned char),width * height * 3); } else if(!strcmp(header,"P2")) { create2D(width,height,FORMAT_R8,1,0); ppm_read_pixel_tokens(data,file,width * height,num_colors); } else if(!strcmp(header,"P3")) { create2D(width,height,FORMAT_RGB8,1,0); ppm_read_pixel_tokens(data,file,width * height * 3,num_colors); } else { assert(0 && "Image::load_ppm(): unknown image format"); } } else if(num_colors <= 65535) { if(!strcmp(header,"P5")) { create2D(width,height,FORMAT_R16,1,0); file.readUShortArrayBig((unsigned short*)data,width * height); } else if(!strcmp(header,"P6")) { create2D(width,height,FORMAT_RGB16,1,0); file.readUShortArrayBig((unsigned short*)data,width * height * 3); } else if(!strcmp(header,"P2")) { create2D(width,height,FORMAT_R16,1,0); ppm_read_pixel_tokens(data,file,width * height,num_colors); } else if(!strcmp(header,"P3")) { create2D(width,height,FORMAT_RGB16,1,0); ppm_read_pixel_tokens(data,file,width * height * 3,num_colors); } else { assert(0 && "Image::load_ppm(): unknown image format"); } .... } Link to comment
frustum Posted March 1, 2011 Share Posted March 1, 2011 Thanks. This is a fix for single symbol comments: char buf[1024]; int width = -1; int height = -1; int num_colors = -1; while(file.eof() == 0 && num_colors == -1) { int offset = file.tell(); file.readToken(buf,sizeof(buf)); if(buf[0] == '#') { file.seekSet(offset); file.readLine(); continue; } if(width == -1) width = atoi(buf); else if(height == -1) height = atoi(buf); else if(num_colors == -1) num_colors = atoi(buf); } Support of P2 and P3 is also added. Link to comment
ulf.schroeter Posted March 1, 2011 Author Share Posted March 1, 2011 This is a fix for single symbol comments: Support of P2 and P3 is also added. perfect Link to comment
Recommended Posts