added Bitmap I/O in TGAFormat

This commit is contained in:
HuYingzhuo(hugo/hyzboy) 2023-09-15 18:20:46 +08:00
parent 04f182e78c
commit a5d8d578e7
4 changed files with 193 additions and 18 deletions

View File

@ -1,18 +0,0 @@
#pragma once
#include<hgl/type/DataType.h>
namespace hgl
{
/*
*
*/
class BitmapFont
{
uint bits;
uint width,height;
public:
};//class BitmapFont
}//namespace hgl

90
inc/hgl/2d/BitmapLoad.h Normal file
View File

@ -0,0 +1,90 @@
#pragma once
#include<hgl/2d/Bitmap.h>
#include<hgl/io/FileInputStream.h>
namespace hgl
{
namespace bitmap
{
struct BitmapLoader
{
virtual const uint OnChannels()const=0;
virtual const uint OnChannelBits()const=0;
const uint OnPixelBits()const
{
return OnChannelBits()*OnChannels();
}
virtual void *OnRecvBitmap(uint w,uint h)=0;
virtual void OnLoadFailed()=0;
virtual void OnFlip()=0;
};
template<typename T> struct BitmapLoaderImpl:public BitmapLoader
{
T *bmp;
public:
BitmapLoaderImpl()
{
bmp=nullptr;
}
const uint OnChannels()const override{return bmp->GetChannels();}
const uint OnChannelBits()const override{return bmp->GetChannelBits();}
void *OnRecvBitmap(uint w,uint h) override
{
if(!bmp)
bmp=new T;
bmp->Create(w,h);
return bmp->GetData();
}
void OnLoadFailed() override
{
SAFE_CLEAR(bmp);
}
void OnFlip() override
{
if(bmp)
bmp->Flip();
}
};
bool LoadBitmapFromTGAStream(io::InputStream *,BitmapLoader *);
template<typename T>
inline T *LoadBitmapFromTGA(io::InputStream *is)
{
BitmapLoaderImpl<T> bli;
if(LoadBitmapFromTGAStream(is,&bli))
return bli.bmp;
return(nullptr);
}
inline BitmapRGB8 *LoadBitmapRGB8FromTGA(io::InputStream *is){return LoadBitmapFromTGA<BitmapRGB8>(is);}
inline BitmapRGBA8 *LoadBitmapRGBA8FromTGA(io::InputStream *is){return LoadBitmapFromTGA<BitmapRGBA8>(is);}
template<typename T>
inline T *LoadBitmapFromTGA(const OSString &filename)
{
io::OpenFileInputStream fis(filename);
if(!fis)
return(false);
return LoadBitmapFromTGA<T>(&fis);
}
inline BitmapRGB8 *LoadBitmapRGB8FromTGA(const OSString &filename){return LoadBitmapFromTGA<BitmapRGB8>(filename);}
inline BitmapRGBA8 *LoadBitmapRGBA8FromTGA(const OSString &filename){return LoadBitmapFromTGA<BitmapRGBA8>(filename);}
}//namespace bitmap
}//namespace hgl

33
inc/hgl/2d/BitmapSave.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include<hgl/2d/Bitmap.h>
#include<hgl/io/FileOutputStream.h>
namespace hgl
{
namespace bitmap
{
bool SaveBitmapToTGA(io::OutputStream *os,void *data,uint width,uint height,uint channels,uint single_channel_bits);
template<typename T>
inline bool SaveBitmapToTGA(io::OutputStream *os,const T *bmp)
{
if(!os||!bmp)return(false);
return SaveBitmapToTGA(os,(void *)(bmp->GetData()),bmp->GetWidth(),bmp->GetHeight(),bmp->GetChannels(),bmp->GetChannelBits());
}
template<typename T>
inline bool SaveBitmapToTGA(const OSString &filename,T *bmp)
{
if(filename.IsEmpty()||!bmp)
return(false);
io::OpenFileOutputStream fos(filename,io::FileOpenMode::CreateTrunc);
if(!fos)
return(false);
return SaveBitmapToTGA(fos,bmp);
}
}//namespace bitmap
}//namespace hgl

View File

@ -0,0 +1,70 @@
#include<hgl/2d/BitmapLoad.h>
#include<hgl/2d/TGA.h>
#include<hgl/io/InputStream.h>
#include<hgl/io/OutputStream.h>
namespace hgl
{
using namespace io;
using namespace imgfmt;
namespace bitmap
{
bool LoadBitmapFromTGAStream(io::InputStream *is,BitmapLoader *bl)
{
if(!is||!bl)return(false);
TGAHeader tga_header;
TGAImageDesc tga_desc;
if(is->Read(&tga_header,TGAHeaderSize)!=TGAHeaderSize)
return(false);
if(tga_header.image_type!=TGA_IMAGE_TYPE_TRUE_COLOR)
return(false);
if(tga_header.bit!=bl->OnPixelBits())
return(false);
tga_desc.image_desc=tga_header.image_desc;
void *bmp=bl->OnRecvBitmap(tga_header.width,tga_header.height);
const uint total_bytes=(tga_header.width*tga_header.height*tga_header.bit)>>3;
if(is->Read(bmp,total_bytes)!=total_bytes)
{
bl->OnLoadFailed();
return(false);
}
if(tga_desc.direction==TGA_DIRECTION_LOWER_LEFT)
bl->OnFlip();
return(true);
}
/**
* ÒÔTGA¸ñʽ±£´æBitmapÊý¾Ýµ½Á÷
*/
bool SaveBitmapToTGA(io::OutputStream *os,void *data,uint width,uint height,uint channels,uint single_channel_bits)
{
if(!os||!data||width<=0||height<=0||channels<=0||single_channel_bits<=0)
return(false);
TGAHeader tga_header;
const uint total_bytes=(width*height*channels*single_channel_bits)>>3;
FillTGAHeader(&tga_header,width,height,channels,single_channel_bits);
if(os->Write(&tga_header,TGAHeaderSize)!=TGAHeaderSize)
return(false);
if(os->Write(data,total_bytes)!=total_bytes)
return(false);
return(true);
}
}//namespace bitmap
}//namespace hgl