#include #include #include #include "pic_private.h" #include "pic.h" // ---------------------------------------------------------------------------------------------------------------------------------- #pragma pack(1) typedef struct TGA_HEADER { unsigned char LengthID; unsigned char CMapType; unsigned char ImageType; unsigned short Origin; unsigned short Length; unsigned char Depth; unsigned short XOrg; unsigned short YOrg; unsigned short Width; unsigned short Height; unsigned char ImageDepth; unsigned char Desc; } TGA_HEADER; #pragma pack() // ---------------------------------------------------------------------------------------------------------------------------------- unsigned long Pic_TGA_Read( const char *FileName, char **ppPal, char **ppDatas, unsigned long *pWidth, unsigned long *pHeight, unsigned long *pDepth) { FILE *file; TGA_HEADER tgah; long w,h,d; unsigned long size; char *pDatas; char *pPal; long x,y; long slsize; unsigned char *scanline; unsigned char r,g,b; long i; int upSideDown; pDatas=NULL; pPal=NULL; file=fopen(FileName,"rb"); if (!file) { Pic_SetError("TGA_Read, unable to open %s",FileName); return(0); } fread(&tgah,1,sizeof(TGA_HEADER),file); if (tgah.ImageType>3) { Pic_SetError("TGA_Read, unsupported TGA format"); return(0); } *pWidth=w=tgah.Width; *pHeight=h=tgah.Height; *pDepth=d=tgah.ImageDepth; upSideDown = ((tgah.Desc & (1 << 5))==0); size=tgah.Width*tgah.Height*(tgah.ImageDepth/8); pDatas=(char*)Pic_malloc(size); if (!pDatas) { Pic_SetError("TGA_Read, not enough memory"); return(0); } if (*pDepth==8) { if (!ppPal) { Pic_free(pDatas); Pic_SetError("TGA_Read, need a pointer to palette"); return(0); } pPal=(char*)Pic_calloc(1,256*3); if (!pPal) { Pic_SetError("TGA_Read, not enough memory for palette"); return(0); } if (tgah.ImageType==1) { for(i=0 ; i<256*3 ; i+=3) { fread(&pPal[i+2],1,1,file); fread(&pPal[i+1],1,1,file); fread(&pPal[i+0],1,1,file); } } *ppPal=pPal; } slsize=w*d/8; scanline=(unsigned char*)Pic_calloc(1,slsize); if (!scanline) { if (pPal) { Pic_free(pPal); } Pic_free(pDatas); Pic_SetError("TGA_Read, not enough memory for scanline"); return(0); } for(y=0 ; y8) { tgah.CMapType=0; tgah.ImageType=2; tgah.Length=0; tgah.Depth=0; } else { tgah.CMapType=1; tgah.ImageType=1; tgah.Length=256; tgah.Depth=24; } tgah.Origin=0; tgah.XOrg=0; tgah.YOrg=0; tgah.Width=(unsigned short)w; tgah.Height=(unsigned short)h; tgah.ImageDepth=(unsigned char)d; tgah.Desc=0; fwrite(&tgah,1,sizeof(TGA_HEADER),file); if (d==8) { fwrite(pPal,1,256*3,file); } slsize=w*d/8; scanline=(unsigned char*)Pic_calloc(1,slsize); if (!scanline) { Pic_SetError("TGA_Write, not enough memory for scanline"); return(0); } 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++) { 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; } } fwrite(scanline,1,slsize,file); } Pic_free(scanline); fclose(file); return(1); }