📄 pnmsource.cc
字号:
/*************************************************************** * C++ source * * File : PnmSource.cc // used to be called PgmSource in the past * * Module : PnmSource * * Author : A M Baumberg (CoMIR) * * Creation Date : Wed Jun 29 20:25:25 1994 * ***************************************************************/#include <math.h>#include <ctype.h> // for isspace() etc#include "PnmSource.h"#include "Grey8Image.h"#include "RGB32Image.h"#include "text_output.h"namespace ReadingPeopleTracker{// utility function to read a pnm file header; returns 5 for P5 etc, 0 for error.// NOTE: does not open or close file. Leaves file pointer at first data byte.PnmFileType PnmSource::read_pnm_header(FILE *infile, unsigned int *width, unsigned int *height){ unsigned char c1; unsigned char c2; unsigned char aline[255]; fscanf(infile,"%c%c", &c1, &c2); if ((c1 != 'P') || ((c2 != '5') && (c2 != '6'))) return PNM_INVALID; // nts: new parser which is compliant with the pnm standard (see p{g,p}m(5)) // FIXME: we assume that there is no end of file at the wrong place etc... unsigned char byte; // skip whitespace and comments until first dimension parameter, width... for (byte = (unsigned char) fgetc(infile); (byte == '#') || (isspace(byte)); byte = (unsigned char) fgetc(infile)) if (byte == '#') // ignore comments (to end of line) while ((byte = (unsigned char) fgetc(infile)) != '\n') ; // skip chars unsigned int length = 0; // length of character line we are reading into "aline" buffer for ( ; (isdigit(byte) && (length < 255)); byte = (unsigned char) fgetc(infile)) aline[length++] = byte; // append character to aline if (length == 0) return PNM_INVALID; aline [length] = '\0'; sscanf((char *) aline,"%ui",width); // skip whitespace and comments until second dimension parameter, height... for ( ; (byte == '#') || (isspace(byte)); byte = (unsigned char) fgetc(infile)) if (byte == '#') // ignore comments (to end of line) while ((byte = (unsigned char) fgetc(infile)) != '\n') ; // skip chars to eol length = 0; for ( ; (isdigit(byte) && (length < 255)); byte = (unsigned char) fgetc(infile)) aline[length++] = byte; // append character to aline if (length == 0) return PNM_INVALID; aline [length] = '\0'; sscanf((char *) aline,"%u", height); // skip whitespace and comments until 3rd and last size parameter, maxval... for ( ; (byte == '#') || (isspace(byte)); byte = (unsigned char) fgetc(infile)) if (byte == '#') // ignore comments (to end of line) while ((byte = (unsigned char) fgetc(infile)) != '\n') ; // skip chars to eol unsigned int maxval; // maxval (maximum value allowed in data fields, expect 255 or less) length = 0; for ( ; (isdigit(byte) && (length < 255)); byte = (unsigned char) fgetc(infile)) aline[length++] = byte; // append character to aline if (length == 0) return PNM_INVALID; // We assume RAW PPM here: only one whitespace (usually newline) is allowed at // this point in file (see ppm(5)) if (!(isspace(byte))) return PNM_INVALID; aline [length] = '\0'; sscanf((char *) aline,"%u", &maxval); if (maxval > 255) // more than 255 possible values for input components? return PNM_INVALID; // these cannot be no single bytes per colour channel! switch (c2) { case '5': return PNM_GREY_COMPRESSED; case '6': return PNM_COLOUR_COMPRESSED; /* NOTREACHED */ default : return PNM_INVALID; } /* NOTREACHED */}Image *PnmSource::read_pnm(FILE *infile, Image *res){ unsigned int width; unsigned int height; PnmFileType file_type = read_pnm_header(infile, &width, &height); switch (file_type) { case PNM_COLOUR_COMPRESSED: // marker "P6" --- PPM (24-bit RGB) raw (RAWBITS) { bool created_new_image = false; if (res == NULL) { res = new RGB32Image(width,height); created_new_image = true; } if ((res->get_image_type() != RGB32) || (res->get_width() != width) || (res->get_height() != height)) { cerror << " PnmSource::read_pnm(): Unexpected image dimensions/format (expected " << res->get_width() << "x" << res->get_height(); if (res->get_image_type() == GREY8) cerror << " PGM). " << endl; else if (res->get_image_type() == RGB32) cerror << " PPM)." << endl; else cerror << " PNM)." << endl; if (created_new_image) delete res; return NULL; } RGB32pixel *dat1; unsigned int x; unsigned int y; for (y = height; y > 0; y--) { dat1 = (RGB32pixel *) res->get_pixel(0, y-1); for (x = 0; x < width; x++) { fscanf(infile, "%c%c%c", &(dat1->red),&(dat1->green),&(dat1->blue)); dat1->alpha = 0; dat1++; } } // fread does not distinguish between end-of-file and error, // we use use ferror(3) to determine which one occurred. if (ferror(infile) != 0) { cerror << " PnmSource::read_pnm: error reading PPM image file (file truncated?) " << endl; // ignore error, hoping for the best } break; } case PNM_GREY_COMPRESSED: // marker "P5" --- PGM (256 grey levels) raw (RAWBITS) { bool created_new_image = false; if (res == NULL) { res = new Grey8Image(width, height); created_new_image = true; } if ((res->get_image_type() != GREY8) || (res->get_width() != width) || (res->get_height() != height)) { cerror << " PnmSource::read_pnm(): Unexpected image dimensions/format (expected " << res->get_width() << "x" << res->get_height(); if (res->get_image_type() == GREY8) cerror << " PGM). " << endl; else if (res->get_image_type() == RGB32) cerror << " PPM)." << endl; else cerror << " PNM)." << endl; if (created_new_image) delete res; return NULL; } // PNM images are stored top to bottom. if (Image::image_storage_mode == IA_TOP_TO_BOTTOM) { // no flipping of the image while reading: read all data in one go fread(res->get_data(), 1, width*height, infile); } else { // flip the image, but we use get_pixel which in turn depends on // both Image::image_storage_mode and Image::image_addressing_mode if (Image::image_addressing_mode == IA_TOP_TO_BOTTOM) { // no conversion of the address get_pixel gives us unsigned int y; for (y = 0; y < height; y++) fread(res->get_pixel(0,y), 1, width, infile); } else { // convert get_pixel addresses unsigned int y; for (y = height; y > 0; y--) fread(res->get_pixel(0, y-1), 1, width, infile); } } // fread does not distinguish between end-of-file and error, // we use use ferror(3) to determine which one occurred. if (ferror(infile) != 0) { cerror << " PnmSource::read_pnm: error reading PGM image file (file truncated?) " << endl; // ignore error, hoping for the best } break; } PNM_INVALID: default: { cerror << " PnmSource::read_pnm: Sorry --- Error in or unsupported pgm/ppm image format. " << endl; return NULL; } } return res;}Image *PnmSource::read_pnm(char *filename, Image *res){ FILE *fhandle = fopen(filename, "rb"); // `b' may be important on non-UNIX if (fhandle == NULL) { cerror << "PnmSource::read_pnm: cannot open image file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -