Reputation: 163
I am trying to read PGM Images using the following function:
typedef struct PGMImage{
int w;
int h;
unsigned char* data;
}GrayImage;
void ReadPGMImage(char* filename,GrayImage* image)
{
int width,height,size,binary,i,j;
FILE *fp = fopen(filename, "r");
if(!fp){
fprintf(stderr,"Unable to open file in 'r' mode");
exit(errno);
}
readPNMHeader(fp, &width, &height,&binary);
size = width * height;
*image = CreateGrayImage(width,height);
if (!(image->data)){
fprintf(stderr,"Memory not allocated");
exit(errno);
}
fread((void *)image->data, sizeof(unsigned char), (size_t) size, fp);
fclose(fp);
return;
}
The image I am trying to read has these headers: P2 640 480 255
When I print out the values of certain pixels(rows:400-410,columns:300-310),'205' gets printed for all the pixels whereas the actual values as per Matlab are:
>248 255 255 250 254 254 254 252 252 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>255 255 255 255 255 255 255 255 255 255
>248 247 249 245 251 252 253 252 245 251
>241 240 243 237 240 244 239 242 243 244
>235 238 238 237 239 238 239 238 240 242
>236 233 241 235 236 234 236 239 235 237
>231 239 231 239 234 234 230 233 233 234
Similar code works when I read PPM images. Could someone tell me where I am going wrong?
EDIT: Final code that works:
void ReadPGMImage(char * fileName, GrayImage* image) {
FILE * fp = NULL;
char version[100];
int levels = 0;
unsigned int w = 0, h = 0;
unsigned int i = 0;
int pixdat = 0;
if( fileName == NULL ) {
fprintf(stderr,"Bad file name=%s\n", fileName );
return;
}
fp = fopen(fileName,"rb");
if( fp == NULL ) {
fprintf(stderr,"Cannot open file = %s\n", fileName );
return;
}
fscanf(fp,"%s",version);
SkipComments(fp);
fscanf(fp, "%d", &w);
SkipComments(fp);
fscanf(fp, "%d", &h);
SkipComments(fp);
fscanf(fp, "%d", &levels);
CreateGrayImage(image,w,h);
image->w = w;
image->h = h;
for(i=0;i<w*h;i++) {
fscanf(fp, "%d", &pixdat);
image->data[i] = pixdat;
}
fclose(fp);
return;
}
Upvotes: 0
Views: 3412
Reputation: 396
PGM has a decimal representation of the data values, so use fscanf to read the values in:
int offset=0;
while(! feof(fp) ){
fscanf(fp, "%hu", &value);
image->data[offset++] = value;
}
The %hu gives you unsigned short values (i.e. 0..65535 value), since PGM values can be shorts as well as bytes. On this basis, when you allocate the memory for the data, make sure to use:
x->data = (unsigned short*)malloc( width * height * sizeof(unsigned short))
Upvotes: 1
Reputation: 31
The code so far seems to be fine with one little exception.
I think the following code line is the cause of the problem
*image = CreateGrayImage(width,height);
Here you assign the pointer returned by CreateGrayImage() to *image which overwrites the content of the structure.
I assume you want to pass the pointer returned by CreateGrayImage() to the caller of CreateGrayImage(). In this case you need to change the function declaration of ReadPGMImage() to the following:
void ReadPGMImage(char* filename,GrayImage** image)
Then it should work as you expect.
Upvotes: 0