From 21391024b207f0b7bd5d86a02b45878ae1f26cab Mon Sep 17 00:00:00 2001 From: hyzboy Date: Mon, 6 Dec 2021 10:47:34 +0800 Subject: [PATCH] improved file header writing codes. --- CMakeLists.txt | 3 + ConvertImage.cpp | 7 ++- ILImage.h | 7 +-- ILImageSupport.cpp | 74 +++++++++++++++++------ Image2D.cpp | 134 ++++++++++++++++++++++++++++++++++++++++- Image2D.h | 17 +++--- TextureFileCreater.cpp | 33 +++++++++- TextureFileCreater.h | 15 ++++- main.cpp | 2 +- 9 files changed, 255 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba707cc..6317655 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/ConvertImage.cpp b/ConvertImage.cpp index b4d6731..bc67219 100644 --- a/ConvertImage.cpp +++ b/ConvertImage.cpp @@ -1,6 +1,7 @@ #include #include #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->formatWriteFileHeader(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(); diff --git a/ILImage.h b/ILImage.h index 0ef03e1..d3f0ddb 100644 --- a/ILImage.h +++ b/ILImage.h @@ -1,6 +1,7 @@ #pragma once #include #include +#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); diff --git a/ILImageSupport.cpp b/ILImageSupport.cpp index 94e8d2a..c9d3287 100644 --- a/ILImageSupport.cpp +++ b/ILImageSupport.cpp @@ -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 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) diff --git a/Image2D.cpp b/Image2D.cpp index 4a19137..8bd170d 100644 --- a/Image2D.cpp +++ b/Image2D.cpp @@ -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)); -} \ No newline at end of file +} + +class PixelStream +{ +public: + + virtual const double get()=0; + virtual void put(const double &)=0; +};// + +template class PISImple:public PixelStream +{ +protected: + + T *pointer; + +public: + + PISImple(void *ptr){pointer=(T *)ptr;} + + const double get() override; + void put(const double &) override; +}; + +template class PISFloat:public PISImple +{ +public: + + using PISImple::PISImple; + + const double get() override + { + double result=double(*pointer); + + ++pointer; + + return result; + } + + void put(const double &value) + { + *pointer=(T)value; + + ++pointer; + } +}; + +template class PISUinteger:public PISImple +{ +public: + + using PISImple::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; +using PISF64=PISFloat; +using PISU8 =PISUinteger; +using PISU16=PISUinteger; +using PISU32=PISUinteger; + +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; +} diff --git a/Image2D.h b/Image2D.h index 0d59e13..17f73f9 100644 --- a/Image2D.h +++ b/Image2D.h @@ -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 diff --git a/TextureFileCreater.cpp b/TextureFileCreater.cpp index f4752f3..4459ec3 100644 --- a/TextureFileCreater.cpp +++ b/TextureFileCreater.cpp @@ -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(pn,fn,old_filename); - filename=ReplaceExtName(old_filename,OS_TEXT(".Tex2D")); + if(!RangeCheck(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(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) { diff --git a/TextureFileCreater.h b/TextureFileCreater.h index b184f27..a9fd613 100644 --- a/TextureFileCreater.h +++ b/TextureFileCreater.h @@ -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; diff --git a/main.cpp b/main.cpp index fb4e9c6..3c175cf 100644 --- a/main.cpp +++ b/main.cpp @@ -111,7 +111,7 @@ int os_main(int argc,os_char **argv) ParseParamColorKey(cp); ParseParamFormat(cp); //检测推荐格式 - + ilInit(); CMP_RegisterHostPlugins();