improved file header writing codes.

This commit is contained in:
hyzboy 2021-12-06 10:47:34 +08:00
parent e173b88097
commit 21391024b2
9 changed files with 255 additions and 37 deletions

View File

@ -34,6 +34,8 @@ SOURCE_GROUP("Intel Texture Compression" FILES ${INTEL_TC_SOURCE})
SET(ILIMAGE_SOURCE ILImage.h
ILImageSupport.cpp)
# Image2D.h
# Image2D.cpp)
SET(PIXEL_FORMAT_SOURCE pixel_format.cpp
pixel_format.h)
@ -86,3 +88,4 @@ texture_tool_project(TexConv)
texture_tool_project(CubeMapConv)
texture_tool_project(ComboTexture)
texture_tool_project(DFGen)
#texture_tool_project(IMTest)

View File

@ -1,6 +1,7 @@
#include<hgl/log/LogInfo.h>
#include<IL/ilu.h>
#include"ILImage.h"
#include"Image2D.h"
#include"TextureFileCreater.h"
TextureFileCreater *CreateTextureFileCreaterR(const PixelFormat *,ILImage *);
@ -37,18 +38,22 @@ bool ConvertImage(const OSString &filename,const PixelFormat **pf,const bool mip
TextureFileCreater *tex_file_creater;
const PixelFormat *fmt=pf[channels-1];
Image2D *origin_img=nullptr;
if(fmt->format<ColorFormat::COMPRESS)
tex_file_creater=CreateTFC[channels-1](fmt,&image);
else
tex_file_creater=CreateTextureFileCreaterCompress(fmt,&image);
if(!tex_file_creater->WriteFileHeader(filename,miplevel))
if(!tex_file_creater->WriteFileHeader(filename,TextureFileType::Tex2D,miplevel))
{
tex_file_creater->Delete();
LOG_ERROR(OS_TEXT("Write file header failed."));
return(false);
}
// origin_img=tex_file_creater->CreateImage2D();
tex_file_creater->InitFormat();
uint width=image.width();

View File

@ -1,6 +1,7 @@
#pragma once
#include<IL/il.h>
#include<hgl/type/String.h>
#include"Image2D.h"
using namespace hgl;
@ -46,11 +47,9 @@ public:
void Bind();
void Copy(ILImage *);
bool Resize(uint,uint);
// Image2D *CreateImage2D();
bool GenMipmaps();
int GetMipLevel();
bool ActiveMipmap(ILuint mip);
bool Resize(uint,uint);
void *ToRGB(ILuint type=IL_UNSIGNED_BYTE);
void *ToGray(ILuint type=IL_UNSIGNED_BYTE);

View File

@ -163,7 +163,7 @@ bool ILImage::Resize(uint nw,uint nh)
if(nw==il_width&&nh==il_height)return(true);
if(nw==0||nh==0)return(false);
iluImageParameter(ILU_FILTER,ILU_SCALE_LANCZOS3);
iluImageParameter(ILU_FILTER,ILU_LINEAR);
if(!iluScale(nw,nh,il_depth))
return(false);
@ -174,21 +174,6 @@ bool ILImage::Resize(uint nw,uint nh)
return(true);
}
bool ILImage::GenMipmaps()
{
return iluBuildMipmaps();
}
bool ILImage::ActiveMipmap(ILuint mip)
{
return ilActiveMipmap(mip);
}
int ILImage::GetMipLevel()
{
return ilGetInteger(IL_NUM_MIPMAPS);
}
bool ILImage::Convert(ILuint format,ILuint type)
{
if(il_format==format
@ -197,8 +182,9 @@ bool ILImage::Convert(ILuint format,ILuint type)
if(!ilConvertImage(format,type))
return(false);
il_format=format;
il_type=type;
il_format =format;
il_type =type;
il_bit =ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
return(true);
}
@ -229,6 +215,58 @@ bool ILImage::LoadFile(const OSString &filename)
return(true);
}
const PixelDataType GetPixelDataType(ILuint type)
{
if(type==IL_UNSIGNED_BYTE )return PixelDataType::U8; else
if(type==IL_UNSIGNED_SHORT )return PixelDataType::U16;else
if(type==IL_UNSIGNED_INT )return PixelDataType::U32;else
if(type==IL_FLOAT )return PixelDataType::F32;else
if(type==IL_DOUBLE )return PixelDataType::F64;else
return(PixelDataType::Unknow);
}
template<typename T> void MixRG(T *tar,T *src,T *alpha,const uint count)
{
}
//Image2D *ILImage::CreateImage2D()
//{
// const PixelDataType pdt=GetPixelDataType(il_type);
// void *src=nullptr;
// const uint pixel_count=il_width*il_height;
//
// if(channel_count==1)
// {
// if(il_format==IL_ALPHA )src=ilGetAlpha(il_type);else
// if(il_format==IL_LUMINANCE )src=ilGetData();else
// return(nullptr);
// }
// else
// if(channel_count==2)
// {
// src=GetRG(il_type);
// }
// else
// if(channel_count==3)
// {
// src=GetRGB(il_type);
// }
// else
// if(channel_count==4)
// {
// src=GetRGBA(il_type);
// }
//
// const uint pixel_byte=(il_bit>>3);
// const uint total_bytes=pixel_count*pixel_byte;
//
// void *img_data=new uint8[total_bytes];
//
// memcpy(img_data,src,total_bytes);
//
// return(new Image2D(il_width,il_height,channel_count,pdt,img_data));
//}
void *ILImage::ToRGB(ILuint type)
{
if(il_format!=IL_RGB)

View File

@ -1,4 +1,21 @@
#include"Image2D.h"
const uint GetStride(const enum class PixelDataType type)
{
const uint stride[]={0,1,2,4,4,8};
return stride[(size_t)type];
}
Image2D::Image2D(const uint w,const uint h,const uint c,const PixelDataType &pdt,void *ptr)
{
width=w;
height=h;
channels=c;
type=pdt;
data=ptr;
}
struct HalfImage
{
virtual void Process(void *,void *,const uint,const uint,const uint)=0;
@ -68,4 +85,119 @@ Image2D *Image2D::CreateHalfImage()
delete hi;
return(new Image2D(hw,hh,channels,type,new_data));
}
}
class PixelStream
{
public:
virtual const double get()=0;
virtual void put(const double &)=0;
};//
template<typename T> class PISImple:public PixelStream
{
protected:
T *pointer;
public:
PISImple(void *ptr){pointer=(T *)ptr;}
const double get() override;
void put(const double &) override;
};
template<typename T> class PISFloat:public PISImple<T>
{
public:
using PISImple<T>::PISImple;
const double get() override
{
double result=double(*pointer);
++pointer;
return result;
}
void put(const double &value)
{
*pointer=(T)value;
++pointer;
}
};
template<typename T,const T max_value> class PISUinteger:public PISImple<T>
{
public:
using PISImple<T>::PISImple;
const double get() override
{
double result=double(*pointer)/double(max_value);
++pointer;
return result;
}
void put(const double &value)
{
*pointer=T(value*max_value);
++pointer;
}
};
using PISF32=PISFloat<float>;
using PISF64=PISFloat<double>;
using PISU8 =PISUinteger<uint8,HGL_U8_MAX>;
using PISU16=PISUinteger<uint16,HGL_U16_MAX>;
using PISU32=PISUinteger<uint32,HGL_U32_MAX>;
PixelStream *CreatePIS(const PixelDataType &type,void *data)
{
if(type==PixelDataType::F32)return(new PISF32(data));else
if(type==PixelDataType::F64)return(new PISF64(data));else
if(type==PixelDataType::U8 )return(new PISU8 (data));else
if(type==PixelDataType::U16)return(new PISU16(data));else
if(type==PixelDataType::U32)return(new PISU32(data));else
return(nullptr);
}
void *CreateData(const PixelDataType &type,const uint total)
{
if(type==PixelDataType::F32)return(new float [total]);else
if(type==PixelDataType::F64)return(new double[total]);else
if(type==PixelDataType::U8 )return(new uint8 [total]);else
if(type==PixelDataType::U16)return(new uint16[total]);else
if(type==PixelDataType::U32)return(new uint32[total]);else
return(nullptr);
}
void Image2D::TypeConvert(const PixelDataType &new_type)
{
if(new_type==type)return;
uint total=GetPixelsTotal()*channels;
void *new_data=CreateData(new_type,total);
PixelStream *src=CreatePIS(type,data);
PixelStream *tar=CreatePIS(new_type,new_data);
while(total--)
tar->put(src->get());
delete src;
delete[] data;
data=new_data;
type=new_type;
}

View File

@ -5,6 +5,8 @@ using namespace hgl;
enum class PixelDataType
{
Unknow=0,
U8,
U16,
U32,
@ -12,6 +14,8 @@ enum class PixelDataType
F64
};
const uint GetStride(const enum class PixelDataType);
class Image2D
{
uint width;
@ -26,7 +30,9 @@ public:
const uint GetWidth()const{return width;}
const uint GetHeight()const{return height;}
const uint GetPixelsTotal()const{return width*height;}
const uint GetChannels()const{return channels;}
const PixelDataType GetType()const{return type;}
void *GetData()const{return data;}
@ -37,14 +43,7 @@ public:
width=height=channels=0;
}
Image2D(const uint w,const uint h,const uint c,const PixelDataType &pdt,void *ptr)
{
width=w;
height=h;
channels=c;
type=pdt;
data=ptr;
}
Image2D(const uint w,const uint h,const uint c,const PixelDataType &pdt,void *ptr);
~Image2D()
{
@ -52,4 +51,6 @@ public:
}
Image2D *CreateHalfImage();
void TypeConvert(const PixelDataType &);
};//class Image2D

View File

@ -74,24 +74,51 @@ TextureFileCreater::~TextureFileCreater()
SAFE_CLEAR(dos);
}
bool TextureFileCreater::WriteFileHeader(const OSString &old_filename,const uint mip_level)
const char texture_file_type_name[uint(TextureFileType::RANGE_SIZE)][16]=
{
"Tex1D",
"Tex2D",
"Tex3D",
"TexCubemap",
"Tex1DArray",
"Tex2DArray",
"TexCubemapArray"
};
bool TextureFileCreater::WriteFileHeader(const OSString &old_filename,const TextureFileType &type,const uint mip_level)
{
OSString pn,fn;
SplitFilename<os_char>(pn,fn,old_filename);
filename=ReplaceExtName<os_char>(old_filename,OS_TEXT(".Tex2D"));
if(!RangeCheck<TextureFileType>(type))
{
LOG_ERROR(OS_TEXT("TextureFileCreater::WriteFileHeader(")+old_filename+OS_TEXT(") texture type error that it's ")+OSString::valueOf(int(type)));
return(false);
}
AnsiString file_type_name=texture_file_type_name[uint(type)];
OSString file_ext_name=OS_TEXT(".")+ToOSString(file_type_name);
filename=ReplaceExtName<os_char>(old_filename,file_ext_name);
if(!fos.CreateTrunc(filename))
return(false);
dos=new io::LEDataOutputStream(&fos);
dos->Write("Tex2D\x1A",6);
dos->Write(file_type_name.c_str(),file_type_name.Length());
dos->WriteUint8(0x1A);
dos->WriteUint8(3); //版本
dos->WriteUint8(mip_level); //mipmaps级数
dos->WriteUint32(image->width());
if(type!=TextureFileType::Tex1D
||type!=TextureFileType::Tex1DArray)
dos->WriteUint32(image->height());
if(type==TextureFileType::Tex3D)
dos->WriteUint32(image->depth());
if(pixel_format->format>ColorFormat::COMPRESS)
{

View File

@ -9,6 +9,19 @@ using namespace hgl;
bool ToILType(ILuint &type,const uint8 bits,const ColorDataType cdt);
enum class TextureFileType
{
Tex1D=0,
Tex2D,
Tex3D,
TexCubemap,
Tex1DArray,
Tex2DArray,
TexCubemapArray,
ENUM_CLASS_RANGE(Tex1D,TexCubemapArray)
};//
class TextureFileCreater
{
protected:
@ -31,7 +44,7 @@ public:
TextureFileCreater(const PixelFormat *pf,ILImage *);
virtual ~TextureFileCreater();
virtual bool WriteFileHeader(const OSString &,const uint);
virtual bool WriteFileHeader(const OSString &,const TextureFileType &,const uint);
virtual bool InitFormat()=0;
virtual uint32 Write()=0;

View File

@ -111,7 +111,7 @@ int os_main(int argc,os_char **argv)
ParseParamColorKey(cp);
ParseParamFormat(cp); //检测推荐格式
ilInit();
CMP_RegisterHostPlugins();