00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005 #include "pic_private.h"
00006 #include "pic.h"
00007
00008
00009
00010 #pragma pack(1)
00011 typedef struct BMP_HEADER
00012 {
00013 unsigned short bfType;
00014 unsigned long bfSize;
00015 unsigned short Res1;
00016 unsigned short Res2;
00017 unsigned long bfOffBits;
00018 unsigned long biSize;
00019 unsigned long biWidth;
00020 unsigned long biHeight;
00021 unsigned short biPlanes;
00022 unsigned short biBitCount;
00023 unsigned long biCompression;
00024 unsigned long biSizeImage;
00025 unsigned long biXPelsPerMeter;
00026 unsigned long biYPelsPerMeter;
00027 unsigned long biClrUsed;
00028 unsigned long biClrImportant;
00029 } BMP_HEADER;
00030 #pragma pack()
00031
00032
00033
00034 unsigned long Pic_BMP_Write( unsigned char *FileName,
00035 unsigned char *pPal,unsigned char *pDatas,
00036 unsigned long w, unsigned long h, unsigned long d)
00037
00038 {
00039 FILE *file;
00040 BMP_HEADER bmph;
00041 unsigned long slsize;
00042 unsigned char *scanline;
00043 unsigned long i;
00044 long x,y,rest;
00045 unsigned char r,g,b;
00046
00047 file=fopen(FileName,"wb");
00048 if (!file)
00049 {
00050 return(0);
00051 }
00052 memset(&bmph,0,sizeof(BMP_HEADER));
00053 bmph.bfType=19778;
00054 bmph.bfSize=sizeof(BMP_HEADER);
00055 bmph.bfSize+=w*h*d/8;
00056 if (pPal)
00057 {
00058 bmph.bfSize+=(256*4);
00059 }
00060 bmph.bfOffBits=sizeof(BMP_HEADER);
00061 if (pPal)
00062 {
00063 bmph.bfOffBits+=(256*4);
00064 }
00065 bmph.biSize=40;
00066 bmph.biWidth=w;
00067 bmph.biHeight=h;
00068 bmph.biPlanes=1;
00069 bmph.biBitCount=(unsigned short)d;
00070 bmph.biCompression=0;
00071 bmph.biSizeImage=w*h*d/8;
00072
00073 fwrite(&bmph,1,sizeof(BMP_HEADER),file);
00074 if (pPal)
00075 {
00076 for(i=0 ; i<256 ; i++)
00077 {
00078 fwrite(&pPal[i*3+0],1,1,file);
00079 fwrite(&pPal[i*3+1],1,1,file);
00080 fwrite(&pPal[i*3+2],1,1,file);
00081 fwrite(&pPal[i*3+2],1,1,file);
00082 }
00083 }
00084 slsize=w*d/8;
00085 scanline=Pic_calloc(1,slsize);
00086 if (!scanline)
00087 {
00088 Pic_SetError("BMP_Write, not enough memory for scanline");
00089 return(0);
00090 }
00091 for(rest=0 ; ((w*d/8)+rest)%4!=0 ; rest++);
00092 for(y=0 ; y<(long)h ; y++)
00093 {
00094 memcpy(scanline,&pDatas[(h-y-1)*slsize],slsize);
00095 if (d==24)
00096 {
00097 for(x=0 ; x<(long)w ; x++)
00098 {
00099 b=scanline[x*3+0];
00100 g=scanline[x*3+1];
00101 r=scanline[x*3+2];
00102 scanline[x*3+0]=b;
00103 scanline[x*3+1]=g;
00104 scanline[x*3+2]=r;
00105 }
00106 }
00107 fwrite(scanline,1,slsize,file);
00108 if (rest)
00109 {
00110 fwrite(scanline,1,rest,file);
00111 }
00112 }
00113 Pic_free(scanline);
00114 fclose(file);
00115 return(1);
00116 }
00117
00118
00119
00120 unsigned long Pic_BMP_Read( unsigned char *FileName,
00121 unsigned char **ppPal, unsigned char **ppDatas,
00122 unsigned long *pWidth, unsigned long *pHeight,
00123 unsigned long *pDepth)
00124 {
00125 FILE *file;
00126 BMP_HEADER bmph;
00127 unsigned char *pPal;
00128 unsigned char *pDatas;
00129 unsigned char *scanline;
00130 long w,h,d;
00131 long i,x,y,rest;
00132 unsigned char r,g,b;
00133 unsigned char pad[4];
00134
00135 pPal=NULL;
00136 pDatas=NULL;
00137 file=fopen(FileName,"rb");
00138 if (!file)
00139 {
00140 Pic_SetError("BMP_Read, unable to open %s",FileName);
00141 return(0);
00142 }
00143 fread(&bmph,1,sizeof(BMP_HEADER),file);
00144 *pWidth=w=bmph.biWidth;
00145 *pHeight=h=bmph.biHeight;
00146 *pDepth=d=bmph.biBitCount;
00147 if (d!=8 && d!=24)
00148 {
00149 Pic_SetError("BMP_Read, number of bits per pixel unsupported");
00150 return(0);
00151 }
00152 if (*pDepth==8)
00153 {
00154 pPal=Pic_calloc(1,256*3);
00155 if (!pPal)
00156 {
00157 Pic_SetError("BMP_Read, not enough memory for palette");
00158 return(0);
00159 }
00160 for(i=0 ; i<256 ; i++)
00161 {
00162 fread(&pPal[i*3+2],1,1,file);
00163 fread(&pPal[i*3+1],1,1,file);
00164 fread(&pPal[i*3+0],1,1,file);
00165 fread(&pad[0],1,1,file);
00166 }
00167 }
00168 pDatas=Pic_calloc(1,w*h*d/8);
00169 if (!pDatas)
00170 {
00171 if (pPal)
00172 {
00173 Pic_free(pPal);
00174 }
00175 Pic_SetError("BMP_Read, not enough memory for datas");
00176 return(0);
00177 }
00178 scanline=Pic_calloc(1,w*h*d/8);
00179 if (!scanline)
00180 {
00181 if (pPal)
00182 {
00183 Pic_free(pPal);
00184 }
00185 Pic_free(pDatas);
00186 Pic_SetError("BMP_Read, not enough memory for scanline");
00187 return(0);
00188 }
00189 for(rest=0 ; (w+rest)%4!=0 ; rest++);
00190 for(y=0 ; y<h ; y++)
00191 {
00192 fread(scanline,w,d/8,file);
00193 if (d==24)
00194 {
00195 for(x=0 ; x<w ; x++)
00196 {
00197 r=scanline[x*3+0];
00198 g=scanline[x*3+1];
00199 b=scanline[x*3+2];
00200 scanline[x*3+0]=b;
00201 scanline[x*3+1]=g;
00202 scanline[x*3+2]=r;
00203 }
00204 }
00205 memcpy(&pDatas[(h-y-1)*w*d/8],scanline,w*d/8);
00206 fread(pad,rest,d/8,file);
00207 }
00208 fclose(file);
00209 Pic_free(scanline);
00210 *ppPal=pPal;
00211 *ppDatas=pDatas;
00212 return(1);
00213 }
00214
00215