 |
PGM Image
Format
PGM (Portable GrayMap) is a grayscale image. It has two versions. First
one is ASCII PGM which is just a text file as shown in Figure 1. Second one
is binary PGM. Binary format is easier to implement than ASCII format and runs
faster. Figure
2. shows the structure of the binary PGM format.
Click here to get some
binary PGM files.

Figure 1. ASCII PGM Format.

Figure 2. Binary PGM format.
Example for PGM ASCII Format (P2)P2
24 7
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Sample C Source Code for Binary PGM Format
PGM read/write functions use
dynamically allocated matrices.
/*
* Give a
reference to this site if you like to use this code.
*
* Written by Chasan Chouse, 2004
*/
/******************************/
/* ERROR MESSAGES */
/******************************/
void DispError(char Err[])
{
MessageBox(hDlg, Err, "Error", MB_OK | MB_ICONERROR);
// fprintf(stderr,Err);
}
int PGM_Read_Header(char FileName[],
long *width,
long *height,
long *max_color,
long *f_start)
{
FILE *fl;
char ch_width[6], ch_height[6], ch_max_color[6];
unsigned char ch;
long i;
if ( (fl = fopen(FileName,"rb")) == NULL )
{
DispError("\nERROR! Couldn't open image file\n");
return 1;
}
// only BINARY PGM is supported
if (fgetc(fl) == 'P' )
{
if (fgetc(fl) == '5')
{
fgetc(fl); // skips white space
ch = fgetc(fl);
if (ch == '#')
{
// skips the comment space
while( (fgetc(fl) != 10) && (ftell(fl) < filesize(fl)));
ch = fgetc(fl);
}
// get with
i=0;
while( 32 != ch) // between width and height there is a space character
{
ch_width[i] = ch;
ch = fgetc(fl);
i++;
}
ch_width[i] = 0;
*width = atol(ch_width);
// get height
i=0;
ch = fgetc(fl);
while( 10 != ch)
{
ch_height[i] = ch;
ch = fgetc(fl);
i++;
}
ch_height[i] = 0;
*height = atol(ch_height);
// get max_color
i=0;
ch = fgetc(fl);
while( 10 != ch)
{
ch_max_color[i] = ch;
ch = fgetc(fl);
i++;
}
ch_max_color[i] = 0;
*max_color = (short)atol(ch_max_color);
*f_start = ftell(fl);
}
else
{
DispError("\nERROR! File is not PGM binary format\n");
return 1;
}
}
else
{
DispError("\nERROR! File is not a PGM image\n");
return 1;
}
fclose(fl);
return true;
}
/************************************/
/* READS IMAGE DATA, INFORMATION */
/************************************/
int PGM_Get_Data(char FileName[],
long width,
long height,
long f_start,
UCHAR **img_data)
{
FILE *fl;
UCHAR ch;
long i, j;
if ( (fl = fopen(FileName,"rb")) == NULL )
{
DispError("\nERROR! Couldn't open image file\n");
return 1;
}
fseek(fl, f_start, SEEK_SET);
// READ DATA INTO MATRIX
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
ch = fgetc(fl);
img_data[i][j] = (UCHAR)ch;
//img_data[i*width + j] = ch;
}
}
fclose(fl);
return true;
}
/********************************************************/
/* WRITES IMAGE DATA and INFORMATION TO a GIVEN FILE */
/********************************************************/
int PGM_Put_Data(char FileName[],
long width,
long height,
long max_color,
UCHAR **img_data)
{
FILE *fl;
char str[128];
long i, j, pls;
if ( (fl = fopen(FileName,"wb")) == NULL )
{
DispError("\nERROR! Couldn't open image file\n");
return 1;
}
// Header
fputc('P', fl);
fputc('5', fl);
fputc( 10, fl); // white space
// comment will be written to file
strcpy(str, "# Created by Chasan Chouse");
pls = (long)strlen(str);
fwrite(str, pls, 1, fl);
fputc( 10, fl); // white space
// width will be written to file
ltoa(width, str, 10);
pls = (long)strlen(str);
fwrite(str, pls, 1, fl);
fputc( 32, fl); // space
// HEIGHT will be written to file
ltoa(height, str, 10);
pls = (long)strlen(str);
fwrite(str, pls, 1, fl);
fputc( 10, fl); // white space
// MAX_COLOR will be written to file
ltoa(max_color, str, 10);
pls = (long)strlen(str);
fwrite(str, pls, 1, fl);
fputc( 10, fl); // white space
// put with
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
fputc( img_data[i][j], fl);
}
}
fclose(fl);
return true;
}
|
 |