215 lines
4.5 KiB
C++
215 lines
4.5 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "pic_private.h"
|
|
#include "pic.h"
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
#pragma pack(1)
|
|
typedef struct BMP_HEADER
|
|
{
|
|
unsigned short bfType;
|
|
unsigned long bfSize;
|
|
unsigned short Res1;
|
|
unsigned short Res2;
|
|
unsigned long bfOffBits;
|
|
unsigned long biSize;
|
|
unsigned long biWidth;
|
|
unsigned long biHeight;
|
|
unsigned short biPlanes;
|
|
unsigned short biBitCount;
|
|
unsigned long biCompression;
|
|
unsigned long biSizeImage;
|
|
unsigned long biXPelsPerMeter;
|
|
unsigned long biYPelsPerMeter;
|
|
unsigned long biClrUsed;
|
|
unsigned long biClrImportant;
|
|
} BMP_HEADER;
|
|
#pragma pack()
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned long Pic_BMP_Write( const char *FileName,
|
|
char *pPal, char *pDatas,
|
|
unsigned long w, unsigned long h, unsigned long d)
|
|
|
|
{
|
|
FILE *file;
|
|
BMP_HEADER bmph;
|
|
unsigned long slsize;
|
|
unsigned char *scanline;
|
|
unsigned long i;
|
|
long x,y,rest;
|
|
unsigned char r,g,b;
|
|
|
|
file=fopen(FileName,"wb");
|
|
if (!file)
|
|
{
|
|
return(0);
|
|
}
|
|
memset(&bmph,0,sizeof(BMP_HEADER));
|
|
bmph.bfType=19778;
|
|
bmph.bfSize=sizeof(BMP_HEADER);
|
|
bmph.bfSize+=w*h*d/8;
|
|
if (pPal)
|
|
{
|
|
bmph.bfSize+=(256*4);
|
|
}
|
|
bmph.bfOffBits=sizeof(BMP_HEADER);
|
|
if (pPal)
|
|
{
|
|
bmph.bfOffBits+=(256*4);
|
|
}
|
|
bmph.biSize=40;//sizeof(BMP_HEADER);
|
|
bmph.biWidth=w;
|
|
bmph.biHeight=h;
|
|
bmph.biPlanes=1;
|
|
bmph.biBitCount=(unsigned short)d;
|
|
bmph.biCompression=0;
|
|
bmph.biSizeImage=w*h*d/8;
|
|
|
|
fwrite(&bmph,1,sizeof(BMP_HEADER),file);
|
|
if (pPal)
|
|
{
|
|
for(i=0 ; i<256 ; i++)
|
|
{
|
|
fwrite(&pPal[i*3+0],1,1,file);
|
|
fwrite(&pPal[i*3+1],1,1,file);
|
|
fwrite(&pPal[i*3+2],1,1,file);
|
|
fwrite(&pPal[i*3+2],1,1,file);
|
|
}
|
|
}
|
|
slsize=w*d/8;
|
|
scanline=(unsigned char*)Pic_calloc(1,slsize);
|
|
if (!scanline)
|
|
{
|
|
Pic_SetError("BMP_Write, not enough memory for scanline");
|
|
return(0);
|
|
}
|
|
for(rest=0 ; ((w*d/8)+rest)%4!=0 ; rest++);
|
|
for(y=0 ; y<(long)h ; y++)
|
|
{
|
|
memcpy(scanline,&pDatas[(h-y-1)*slsize],slsize);
|
|
if (d==24)
|
|
{
|
|
for(x=0 ; x<(long)w ; x++)
|
|
{
|
|
b=scanline[x*3+0];
|
|
g=scanline[x*3+1];
|
|
r=scanline[x*3+2];
|
|
scanline[x*3+0]=b;
|
|
scanline[x*3+1]=g;
|
|
scanline[x*3+2]=r;
|
|
}
|
|
}
|
|
fwrite(scanline,1,slsize,file);
|
|
if (rest)
|
|
{
|
|
fwrite(scanline,1,rest,file);
|
|
}
|
|
}
|
|
Pic_free(scanline);
|
|
fclose(file);
|
|
return(1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
unsigned long Pic_BMP_Read( const char *FileName,
|
|
char **ppPal, char **ppDatas,
|
|
unsigned long *pWidth, unsigned long *pHeight,
|
|
unsigned long *pDepth)
|
|
{
|
|
FILE *file;
|
|
BMP_HEADER bmph;
|
|
char *pPal;
|
|
char *pDatas;
|
|
unsigned char *scanline;
|
|
long w,h,d;
|
|
long i,x,y,rest;
|
|
unsigned char r,g,b;
|
|
unsigned char pad[4];
|
|
|
|
pPal=NULL;
|
|
pDatas=NULL;
|
|
file=fopen(FileName,"rb");
|
|
if (!file)
|
|
{
|
|
Pic_SetError("BMP_Read, unable to open %s",FileName);
|
|
return(0);
|
|
}
|
|
fread(&bmph,1,sizeof(BMP_HEADER),file);
|
|
*pWidth=w=bmph.biWidth;
|
|
*pHeight=h=bmph.biHeight;
|
|
*pDepth=d=bmph.biBitCount;
|
|
if (d!=8 && d!=24)
|
|
{
|
|
Pic_SetError("BMP_Read, number of bits per pixel unsupported");
|
|
return(0);
|
|
}
|
|
if (*pDepth==8)
|
|
{
|
|
pPal=(char*)Pic_calloc(1,256*3);
|
|
if (!pPal)
|
|
{
|
|
Pic_SetError("BMP_Read, not enough memory for palette");
|
|
return(0);
|
|
}
|
|
for(i=0 ; i<256 ; i++)
|
|
{
|
|
fread(&pPal[i*3+2],1,1,file);
|
|
fread(&pPal[i*3+1],1,1,file);
|
|
fread(&pPal[i*3+0],1,1,file);
|
|
fread(&pad[0],1,1,file);
|
|
}
|
|
}
|
|
pDatas=(char*)Pic_calloc(1,w*h*d/8);
|
|
if (!pDatas)
|
|
{
|
|
if (pPal)
|
|
{
|
|
Pic_free(pPal);
|
|
}
|
|
Pic_SetError("BMP_Read, not enough memory for datas");
|
|
return(0);
|
|
}
|
|
scanline=(unsigned char*)Pic_calloc(1,w*h*d/8);
|
|
if (!scanline)
|
|
{
|
|
if (pPal)
|
|
{
|
|
Pic_free(pPal);
|
|
}
|
|
Pic_free(pDatas);
|
|
Pic_SetError("BMP_Read, not enough memory for scanline");
|
|
return(0);
|
|
}
|
|
for(rest=0 ; (w+rest)%4!=0 ; rest++);
|
|
for(y=0 ; y<h ; y++)
|
|
{
|
|
fread(scanline,w,d/8,file);
|
|
if (d==24)
|
|
{
|
|
for(x=0 ; x<w ; x++)
|
|
{
|
|
r=scanline[x*3+0];
|
|
g=scanline[x*3+1];
|
|
b=scanline[x*3+2];
|
|
scanline[x*3+0]=b;
|
|
scanline[x*3+1]=g;
|
|
scanline[x*3+2]=r;
|
|
}
|
|
}
|
|
memcpy(&pDatas[(h-y-1)*w*d/8],scanline,w*d/8);
|
|
fread(pad,rest,d/8,file);
|
|
}
|
|
fclose(file);
|
|
Pic_free(scanline);
|
|
*ppPal=pPal;
|
|
*ppDatas=pDatas;
|
|
return(1);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------------------------------------------------
|