1039 lines
24 KiB
C++
1039 lines
24 KiB
C++
|
/* bmp_io.c 31 May 2000 */
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "bmp_io.h"
|
||
|
|
||
|
#define BMP_ERROR 1
|
||
|
#define SUCCESS 0
|
||
|
|
||
|
|
||
|
#define TRUE 1
|
||
|
|
||
|
int byte_swap = TRUE;
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_read ( char *filein_name, int *xsize, int *ysize, int **rarray,
|
||
|
int **garray, int **barray ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_READ reads the header and data of a BMP file.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
05 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, char *FILEIN_NAME, the name of the input file.
|
||
|
|
||
|
Output, int *XSIZE, *YSIZE, the X and Y dimensions of the image.
|
||
|
|
||
|
Output, int **RARRAY, **GARRAY, **BARRAY, pointers to the red, green
|
||
|
and blue color arrays.
|
||
|
*/
|
||
|
FILE *filein;
|
||
|
int numbytes;
|
||
|
int psize;
|
||
|
int result;
|
||
|
/*
|
||
|
Open the input file.
|
||
|
*/
|
||
|
filein = fopen ( filein_name, "rb" );
|
||
|
|
||
|
if ( filein == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ - Fatal error!\n" );
|
||
|
printf ( " Could not open the input file.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Read the header.
|
||
|
*/
|
||
|
result = bmp_read_header ( filein, xsize, ysize, &psize );
|
||
|
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ: Fatal error!\n" );
|
||
|
printf ( " BMP_READ_HEADER failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Read the palette.
|
||
|
*/
|
||
|
result = bmp_read_palette ( filein, psize );
|
||
|
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ: Fatal error!\n" );
|
||
|
printf ( " BMP_READ_PALETTE failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Allocate storage.
|
||
|
*/
|
||
|
numbytes = ( *xsize ) * ( *ysize ) * sizeof ( int );
|
||
|
|
||
|
*rarray = ( int * ) malloc ( numbytes );
|
||
|
if ( rarray == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ: Fatal error!\n" );
|
||
|
printf ( " Could not allocate data storage.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
*garray = ( int * ) malloc ( numbytes );
|
||
|
if ( garray == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ: Fatal error!\n" );
|
||
|
printf ( " Could not allocate data storage.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
*barray = ( int * ) malloc ( numbytes );
|
||
|
if ( barray == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ: Fatal error!\n" );
|
||
|
printf ( " Could not allocate data storage.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Read the data.
|
||
|
*/
|
||
|
result = bmp_read_data ( filein, *xsize, *ysize, *rarray, *garray, *barray );
|
||
|
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ: Fatal error!\n" );
|
||
|
printf ( " BMP_READ_DATA failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Close the file.
|
||
|
*/
|
||
|
fclose ( filein );
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_read_data ( FILE *filein, int xsize, int ysize, int *rarray,
|
||
|
int *garray, int *barray ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_READ_DATA reads the image data of the BMP file.
|
||
|
|
||
|
Discussion:
|
||
|
|
||
|
On output, the RGB information in the file has been copied into the
|
||
|
R, G and B arrays.
|
||
|
|
||
|
Thanks to Peter Kionga-Kamau for pointing out an error in the
|
||
|
previous implementation.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
31 May 2000
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, FILE *FILEIN, a pointer to the input file.
|
||
|
|
||
|
Input, int XSIZE, YSIZE, the X and Y dimensions of the image.
|
||
|
|
||
|
Input, int *RARRAY, *GARRAY, *BARRAY, pointers to the red, green
|
||
|
and blue color arrays.
|
||
|
*/
|
||
|
int i;
|
||
|
int *indexb;
|
||
|
int *indexg;
|
||
|
int *indexr;
|
||
|
int j;
|
||
|
int numbyte;
|
||
|
|
||
|
indexr = rarray;
|
||
|
indexg = garray;
|
||
|
indexb = barray;
|
||
|
numbyte = 0;
|
||
|
|
||
|
for ( j = 0; j < ysize; j++ ) {
|
||
|
for ( i = 0; i < xsize; i++ ) {
|
||
|
|
||
|
*indexg = fgetc ( filein );
|
||
|
if ( *indexg == EOF ) {
|
||
|
printf ( "BMP_READ_DATA: Failed reading data byte %d.\n", numbyte );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
numbyte = numbyte + 1;
|
||
|
indexg = indexg + 1;
|
||
|
|
||
|
*indexr = fgetc ( filein );
|
||
|
if ( *indexr == EOF ) {
|
||
|
printf ( "BMP_READ_DATA: Failed reading data byte %d.\n", numbyte );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
numbyte = numbyte + 1;
|
||
|
indexr = indexr + 1;
|
||
|
|
||
|
*indexb = fgetc ( filein );
|
||
|
if ( *indexb == EOF ) {
|
||
|
printf ( "BMP_READ_DATA: Failed reading data byte %d.\n", numbyte );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
numbyte = numbyte + 1;
|
||
|
indexb = indexb + 1;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_read_header ( FILE *filein, int *xsize, int *ysize, int *psize ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_READ_HEADER reads the header information of a BMP file.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
05 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, FILE *FILEIN, a pointer to the input file.
|
||
|
|
||
|
Output, int *XSIZE, *YSIZE, the X and Y dimensions of the image.
|
||
|
|
||
|
Output, int *PSIZE, the number of colors in the palette.
|
||
|
*/
|
||
|
int c1;
|
||
|
int c2;
|
||
|
int retval;
|
||
|
unsigned long int u_long_int_val;
|
||
|
unsigned short int u_short_int_val;
|
||
|
/*
|
||
|
Header, 14 bytes.
|
||
|
16 bytes FileType; Magic number: "BM",
|
||
|
32 bytes FileSize; Size of file in 32 byte integers,
|
||
|
16 bytes Reserved1; Always 0,
|
||
|
16 bytes Reserved2; Always 0,
|
||
|
32 bytes BitmapOffset. Starting position of image data, in bytes.
|
||
|
*/
|
||
|
c1 = fgetc ( filein );
|
||
|
if ( c1 == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
c2 = fgetc ( filein );
|
||
|
if ( c2 == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
if ( c1 != 'B' || c2 != 'M' ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_short_int ( &u_short_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_short_int ( &u_short_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
The bitmap header is 40 bytes long.
|
||
|
32 bytes unsigned Size; Size of this header, in bytes.
|
||
|
32 bytes Width; Image width, in pixels.
|
||
|
32 bytes Height; Image height, in pixels. (Pos/Neg, origin at bottom, top)
|
||
|
16 bytes Planes; Number of color planes (always 1).
|
||
|
16 bytes BitsPerPixel; 1 to 24. 1, 4, 8 and 24 legal. 16 and 32 on Win95.
|
||
|
32 bytes unsigned Compression; 0, uncompressed; 1, 8 bit RLE; 2, 4 bit RLE; 3, bitfields.
|
||
|
32 bytes unsigned SizeOfBitmap; Size of bitmap in bytes. (0 if uncompressed).
|
||
|
32 bytes HorzResolution; Pixels per meter. (Can be zero)
|
||
|
32 bytes VertResolution; Pixels per meter. (Can be zero)
|
||
|
32 bytes unsigned ColorsUsed; Number of colors in palette. (Can be zero).
|
||
|
32 bytes unsigned ColorsImportant. Minimum number of important colors. (Can be zero).
|
||
|
*/
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
*xsize = ( int ) u_long_int_val;
|
||
|
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
*ysize = ( int ) u_long_int_val;
|
||
|
|
||
|
retval = read_u_short_int ( &u_short_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_short_int ( &u_short_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
*psize = ( int ) u_long_int_val;
|
||
|
|
||
|
retval = read_u_long_int ( &u_long_int_val, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_read_palette ( FILE *filein, int psize ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_READ_PALETTE reads the palette information of a BMP file.
|
||
|
|
||
|
Note:
|
||
|
|
||
|
There are PSIZE colors listed. For each color, the values of
|
||
|
(B,G,R,A) are listed, where A is a quantity reserved for future use.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
16 May 1999
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, FILE *FILEIN, a pointer to the input file.
|
||
|
|
||
|
Input, int PSIZE, the number of colors in the palette.
|
||
|
*/
|
||
|
int c;
|
||
|
int i;
|
||
|
int j;
|
||
|
|
||
|
for ( i = 0; i < psize; i++ ) {
|
||
|
for ( j = 0; j < 4; j++ ) {
|
||
|
c = fgetc ( filein );
|
||
|
if ( c == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_read_test ( char *filein_name ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_READ_TEST tests the BMP read routines.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
05 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, char *FILEIN_NAME, the name of the input file.
|
||
|
*/
|
||
|
|
||
|
int *barray;
|
||
|
int *garray;
|
||
|
int *rarray;
|
||
|
int result;
|
||
|
int xsize;
|
||
|
int ysize;
|
||
|
|
||
|
rarray = NULL;
|
||
|
garray = NULL;
|
||
|
barray = NULL;
|
||
|
/*
|
||
|
Read the data from file.
|
||
|
*/
|
||
|
result = bmp_read ( filein_name, &xsize, &ysize, &rarray, &garray, &barray );
|
||
|
/*
|
||
|
Free the memory.
|
||
|
*/
|
||
|
if ( rarray != NULL ) {
|
||
|
free ( rarray );
|
||
|
}
|
||
|
|
||
|
if ( garray != NULL ) {
|
||
|
free ( garray );
|
||
|
}
|
||
|
|
||
|
if ( barray != NULL ) {
|
||
|
free ( barray );
|
||
|
}
|
||
|
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_READ_TEST: Fatal error!\n" );
|
||
|
printf ( " BMP_READ failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
static char RedBuffer[1024*1024];
|
||
|
static char GreenBuffer[1024*1024];
|
||
|
static char BlueBuffer[1024*1024];
|
||
|
static char AlphaBuffer[1024*1024];
|
||
|
|
||
|
int bmp_write2 ( char *fileout_name, int xsize, int ysize, char* r, char* g, char* b ) ;
|
||
|
|
||
|
int bmp_write ( char *fileout_name, int xsize, int ysize, char* rgba )
|
||
|
{
|
||
|
char szBuffer[128];
|
||
|
|
||
|
for (long i=0; i<xsize*ysize;i++)
|
||
|
{
|
||
|
RedBuffer[i] = rgba[i*4+0];
|
||
|
GreenBuffer[i] = rgba[i*4+1];
|
||
|
BlueBuffer[i] = rgba[i*4+2];
|
||
|
AlphaBuffer[i] = rgba[i*4+3];
|
||
|
}
|
||
|
|
||
|
sprintf(szBuffer,"%s.bmp", fileout_name);
|
||
|
|
||
|
bmp_write2(szBuffer, xsize, ysize, (char*)RedBuffer, (char*)GreenBuffer, (char*)BlueBuffer);
|
||
|
|
||
|
|
||
|
// sprintf(szBuffer,"%sm.bmp", fileout_name);
|
||
|
// bmp_write2(szBuffer, xsize, ysize, (char*)AlphaBuffer, (char*)AlphaBuffer, (char*)AlphaBuffer);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int bmp_write2 ( char *fileout_name, int xsize, int ysize, char* r, char* g, char* b )
|
||
|
{
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_WRITE writes the header and data for a BMP file.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
02 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, char *FILEOUT_NAME, the name of the output file.
|
||
|
|
||
|
Input, int XSIZE, YSIZE, the X and Y dimensions of the image.
|
||
|
|
||
|
Input, int *RARRAY, *GARRAY, *BARRAY, pointers to the red, green
|
||
|
and blue color arrays.
|
||
|
*/
|
||
|
FILE *fileout;
|
||
|
int result;
|
||
|
/*
|
||
|
Open the output file.
|
||
|
*/
|
||
|
fileout = fopen ( fileout_name, "wb" );
|
||
|
|
||
|
if ( fileout == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE - Fatal error!\n" );
|
||
|
printf ( " Could not open the output file.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Write the header.
|
||
|
*/
|
||
|
result = bmp_write_header ( fileout, xsize, ysize );
|
||
|
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE: Fatal error!\n" );
|
||
|
printf ( " BMP_WRITE_HEADER failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Write the data.
|
||
|
*/
|
||
|
result = bmp_write_data ( fileout, xsize, ysize, (char*)r, (char*)g, (char*)b);
|
||
|
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE: Fatal error!\n" );
|
||
|
printf ( " BMP_WRITE_DATA failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Close the file.
|
||
|
*/
|
||
|
fclose ( fileout );
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_write_data ( FILE *fileout, int xsize, int ysize, char *rarray,
|
||
|
char *garray, char *barray ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_WRITE_DATA writes the image data to the BMP file.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
02 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, FILE *FILEOUT, a pointer to the output file.
|
||
|
|
||
|
Input, int XSIZE, YSIZE, the X and Y dimensions of the image.
|
||
|
|
||
|
Input, int *RARRAY, *GARRAY, *BARRAY, pointers to the red, green
|
||
|
and blue color arrays.
|
||
|
*/
|
||
|
long i;
|
||
|
char *indexb;
|
||
|
char *indexg;
|
||
|
char *indexr;
|
||
|
long j;
|
||
|
|
||
|
indexr = rarray;
|
||
|
indexg = garray;
|
||
|
indexb = barray;
|
||
|
|
||
|
for ( j = 0; j < ysize; j++ ) {
|
||
|
for ( i = 0; i < xsize; i++ ) {
|
||
|
|
||
|
fputc ( *indexg, fileout );
|
||
|
fputc ( *indexr, fileout );
|
||
|
fputc ( *indexb, fileout );
|
||
|
|
||
|
indexr = indexr + 1;
|
||
|
indexg = indexg + 1;
|
||
|
indexb = indexb + 1;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_write_header ( FILE *fileout, int xsize, int ysize ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_WRITE_HEADER writes the header information to a BMP file.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
02 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, FILE *FILEOUT, a pointer to the output file.
|
||
|
|
||
|
Input, int XSIZE, YSIZE, the X and Y dimensions of the image.
|
||
|
*/
|
||
|
int i;
|
||
|
unsigned long int u_long_int_val;
|
||
|
unsigned short int u_short_int_val;
|
||
|
/*
|
||
|
Header, 14 bytes.
|
||
|
16 bytes FileType; Magic number: "BM",
|
||
|
32 bytes FileSize; Size of file in bytes,
|
||
|
16 bytes Reserved1; Always 0,
|
||
|
16 bytes Reserved2; Always 0,
|
||
|
32 bytes BitmapOffset. Starting position of image data, in bytes.
|
||
|
*/
|
||
|
fputc ( 'B', fileout );
|
||
|
fputc ( 'M', fileout );
|
||
|
|
||
|
u_long_int_val = 3 * xsize * ysize + 54;
|
||
|
write_u_long_int ( u_long_int_val, fileout );
|
||
|
|
||
|
u_short_int_val = 0;
|
||
|
write_u_short_int ( u_short_int_val, fileout );
|
||
|
|
||
|
u_short_int_val = 0;
|
||
|
write_u_short_int ( u_short_int_val, fileout );
|
||
|
|
||
|
u_long_int_val = 54;
|
||
|
write_u_long_int ( u_long_int_val, fileout );
|
||
|
/*
|
||
|
The bitmap header is 40 bytes long.
|
||
|
32 bytes unsigned Size; Size of this header, in bytes.
|
||
|
32 bytes Width; Image width, in pixels.
|
||
|
32 bytes Height; Image height, in pixels. (Pos/Neg, origin at bottom, top)
|
||
|
16 bytes Planes; Number of color planes (always 1).
|
||
|
16 bytes BitsPerPixel; 1 to 24. 1, 4, 8 and 24 legal. 16 and 32 on Win95.
|
||
|
32 bytes unsigned Compression; 0, uncompressed; 1, 8 bit RLE; 2, 4 bit RLE; 3, bitfields.
|
||
|
32 bytes unsigned SizeOfBitmap; Size of bitmap in bytes. (0 if uncompressed).
|
||
|
32 bytes HorzResolution; Pixels per meter. (Can be zero)
|
||
|
32 bytes VertResolution; Pixels per meter. (Can be zero)
|
||
|
32 bytes unsigned ColorsUsed; Number of colors in palette. (Can be zero).
|
||
|
32 bytes unsigned ColorsImportant. Minimum number of important colors. (Can be zero).
|
||
|
*/
|
||
|
u_long_int_val = 40;
|
||
|
write_u_long_int ( u_long_int_val, fileout );
|
||
|
|
||
|
write_u_long_int ( xsize, fileout );
|
||
|
|
||
|
write_u_long_int ( ysize, fileout );
|
||
|
|
||
|
u_short_int_val = 1;
|
||
|
write_u_short_int ( u_short_int_val, fileout );
|
||
|
|
||
|
u_short_int_val = 24;
|
||
|
write_u_short_int ( u_short_int_val, fileout );
|
||
|
|
||
|
for ( i = 0; i <= 6; i++ ) {
|
||
|
u_long_int_val = 0;
|
||
|
write_u_long_int ( u_long_int_val, fileout );
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int bmp_write_test ( char *fileout_name ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
BMP_WRITE_TEST tests the BMP write routines.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
02 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, char *FILEOUT_NAME, the name of the output file.
|
||
|
*/
|
||
|
|
||
|
int *barray;
|
||
|
int *garray;
|
||
|
int i;
|
||
|
int *indexb;
|
||
|
int *indexg;
|
||
|
int *indexr;
|
||
|
int j;
|
||
|
int j2;
|
||
|
int numbytes;
|
||
|
int *rarray;
|
||
|
int result;
|
||
|
int xsize;
|
||
|
int ysize;
|
||
|
|
||
|
xsize = 200;
|
||
|
ysize = 200;
|
||
|
/*
|
||
|
Allocate the memory.
|
||
|
*/
|
||
|
rarray = NULL;
|
||
|
garray = NULL;
|
||
|
barray = NULL;
|
||
|
numbytes = xsize * ysize * sizeof ( int );
|
||
|
|
||
|
rarray = ( int * ) malloc ( numbytes );
|
||
|
|
||
|
if ( rarray == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE_TEST: Fatal error!\n" );
|
||
|
printf ( " Unable to allocate memory for data.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
garray = ( int * ) malloc ( numbytes );
|
||
|
|
||
|
if ( garray == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE_TEST: Fatal error!\n" );
|
||
|
printf ( " Unable to allocate memory for data.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
barray = ( int * ) malloc ( numbytes );
|
||
|
|
||
|
if ( barray == NULL ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE_TEST: Fatal error!\n" );
|
||
|
printf ( " Unable to allocate memory for data.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
/*
|
||
|
Set the data.
|
||
|
Note that BMP files go from "bottom" up, so we'll reverse the
|
||
|
sense of "J" here to get what we want.
|
||
|
*/
|
||
|
indexr = rarray;
|
||
|
indexg = garray;
|
||
|
indexb = barray;
|
||
|
|
||
|
for ( j2 = 0; j2 < ysize; j2++ ) {
|
||
|
j = ysize - j2;
|
||
|
for ( i = 0; i < xsize; i++ ) {
|
||
|
if ( j >= i ) {
|
||
|
*indexr = 255;
|
||
|
*indexg = 0;
|
||
|
*indexb = 0;
|
||
|
}
|
||
|
else if ( ( xsize - 1 ) * j + ( ysize - 1 ) * i <=
|
||
|
( xsize - 1 ) * ( ysize - 1 ) ) {
|
||
|
*indexr = 0;
|
||
|
*indexg = 255;
|
||
|
*indexb = 0;
|
||
|
}
|
||
|
else {
|
||
|
*indexr = 0;
|
||
|
*indexg = 0;
|
||
|
*indexb = 255;
|
||
|
}
|
||
|
indexr = indexr + 1;
|
||
|
indexg = indexg + 1;
|
||
|
indexb = indexb + 1;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
Write the data to a file.
|
||
|
*/
|
||
|
// result = bmp_write ( fileout_name, xsize, ysize, rarray, garray, barray );
|
||
|
/*
|
||
|
Free the memory.
|
||
|
*/
|
||
|
|
||
|
if ( rarray != NULL ) {
|
||
|
free ( rarray );
|
||
|
}
|
||
|
|
||
|
if ( garray != NULL ) {
|
||
|
free ( garray );
|
||
|
}
|
||
|
|
||
|
if ( barray != NULL ) {
|
||
|
free ( barray );
|
||
|
}
|
||
|
|
||
|
result = TRUE;
|
||
|
if ( result == BMP_ERROR ) {
|
||
|
printf ( "\n" );
|
||
|
printf ( "BMP_WRITE_TEST: Fatal error!\n" );
|
||
|
printf ( " BMP_WRITE failed.\n" );
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int read_u_long_int ( unsigned long int *u_long_int_val, FILE *filein ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
READ_U_LONG_INT reads an unsigned long int from FILEIN.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
20 May 2000
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Output, unsigned long int *U_LONG_INT_VAL, the value that was read.
|
||
|
|
||
|
Input, FILE *FILEIN, a pointer to the input file.
|
||
|
*/
|
||
|
int retval;
|
||
|
unsigned short int u_short_int_val_hi;
|
||
|
unsigned short int u_short_int_val_lo;
|
||
|
|
||
|
if ( byte_swap == TRUE ) {
|
||
|
retval = read_u_short_int ( &u_short_int_val_lo, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
retval = read_u_short_int ( &u_short_int_val_hi, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
retval = read_u_short_int ( &u_short_int_val_hi, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
retval = read_u_short_int ( &u_short_int_val_lo, filein );
|
||
|
if ( retval == BMP_ERROR ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
Acknowledgement:
|
||
|
|
||
|
A correction to the following line was supplied by
|
||
|
Peter Kionga-Kamau, 20 May 2000.
|
||
|
*/
|
||
|
|
||
|
*u_long_int_val = ( u_short_int_val_hi << 16 ) | u_short_int_val_lo;
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int read_u_short_int ( unsigned short int *u_short_int_val, FILE *filein ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
READ_U_SHORT_INT reads an unsigned short int from FILEIN.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
16 May 1999
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Output, unsigned short int *U_SHORT_INT_VAL, the value that was read.
|
||
|
|
||
|
Input, FILE *FILEIN, a pointer to the input file.
|
||
|
*/
|
||
|
int chi;
|
||
|
int clo;
|
||
|
|
||
|
if ( byte_swap == TRUE ) {
|
||
|
clo = fgetc ( filein );
|
||
|
if ( clo == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
chi = fgetc ( filein );
|
||
|
if ( chi == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
chi = fgetc ( filein );
|
||
|
if ( chi == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
clo = fgetc ( filein );
|
||
|
if ( clo == EOF ) {
|
||
|
return BMP_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*u_short_int_val = ( chi << 8 ) | clo;
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int write_u_long_int ( unsigned long int u_long_int_val, FILE *fileout ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
WRITE_U_LONG_INT writes an unsigned long int to FILEOUT.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
05 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, unsigned long int *U_LONG_INT_VAL, the value to be written.
|
||
|
|
||
|
Input, FILE *FILEOUT, a pointer to the output file.
|
||
|
*/
|
||
|
unsigned short int u_short_int_val_hi;
|
||
|
unsigned short int u_short_int_val_lo;
|
||
|
|
||
|
u_short_int_val_hi = ( unsigned short ) ( u_long_int_val / 65536 );
|
||
|
u_short_int_val_lo = ( unsigned short ) ( u_long_int_val % 65536 );
|
||
|
|
||
|
if ( byte_swap == TRUE ) {
|
||
|
write_u_short_int ( u_short_int_val_lo, fileout );
|
||
|
write_u_short_int ( u_short_int_val_hi, fileout );
|
||
|
}
|
||
|
else {
|
||
|
write_u_short_int ( u_short_int_val_hi, fileout );
|
||
|
write_u_short_int ( u_short_int_val_lo, fileout );
|
||
|
}
|
||
|
|
||
|
return 4;
|
||
|
}
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
int write_u_short_int ( unsigned short int u_short_int_val, FILE *fileout ) {
|
||
|
|
||
|
/******************************************************************************/
|
||
|
|
||
|
/*
|
||
|
Purpose:
|
||
|
|
||
|
WRITE_U_SHORT_INT writes an unsigned short int to FILEOUT.
|
||
|
|
||
|
Modified:
|
||
|
|
||
|
05 October 1998
|
||
|
|
||
|
Author:
|
||
|
|
||
|
John Burkardt
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
Input, unsigned short int *U_SHORT_INT_VAL, the value to be written.
|
||
|
|
||
|
Input, FILE *FILEOUT, a pointer to the output file.
|
||
|
*/
|
||
|
unsigned char chi;
|
||
|
unsigned char clo;
|
||
|
|
||
|
chi = ( unsigned char ) ( u_short_int_val / 256 );
|
||
|
clo = ( unsigned char ) ( u_short_int_val % 256 );
|
||
|
|
||
|
if ( byte_swap == TRUE ) {
|
||
|
fputc ( clo, fileout );
|
||
|
fputc ( chi, fileout );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
fputc ( chi, fileout );
|
||
|
fputc ( clo, fileout );
|
||
|
}
|
||
|
|
||
|
return 2;
|
||
|
}
|