new combo texture mode
This commit is contained in:
parent
b09db9ae35
commit
97f38a39dc
@ -53,11 +53,11 @@ target_link_libraries(TexConv PRIVATE CMCore CMPlatform CMUtil
|
||||
Qt5::Core Qt5::Gui Qt5::Widgets
|
||||
DevIL ILU)
|
||||
|
||||
add_executable(MicroPBR MicroPBR.cpp YUV.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE})
|
||||
target_link_libraries(MicroPBR PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib)
|
||||
add_executable(ComboTexture ComboTexture.cpp YUV.cpp ${ILIMAGE_SOURCE})
|
||||
target_link_libraries(ComboTexture PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib)
|
||||
|
||||
add_executable(YUVTest YUVTest.cpp YUV.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE})
|
||||
target_link_libraries(YUVTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib)
|
||||
#add_executable(YUVTest YUVTest.cpp YUV.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE})
|
||||
#target_link_libraries(YUVTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib)
|
||||
|
||||
add_executable(NormalTest NormalTest.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE})
|
||||
target_link_libraries(NormalTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib)
|
||||
#add_executable(NormalTest NormalTest.cpp SpheremapNormal.cpp ${ILIMAGE_SOURCE})
|
||||
#target_link_libraries(NormalTest PRIVATE CMCore CMPlatform CMUtil DevIL ILU MathGeoLib)
|
156
ComboTexture.cpp
Normal file
156
ComboTexture.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
#include<iostream>
|
||||
#include<iomanip>
|
||||
#include<ILImage.h>
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/util/cmd/CmdParse.h>
|
||||
#include<hgl/type/Smart.h>
|
||||
|
||||
using namespace hgl;
|
||||
using namespace hgl::util;
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
#define std_cout std::wcout
|
||||
#else
|
||||
#define std_cout std::cout
|
||||
#endif//
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint count);
|
||||
void normal_compress(uint8 *x,uint8 *y,const uint8 *rgb,const uint count);
|
||||
|
||||
template<typename T>
|
||||
void MixRGB(T *rgb,const T *r,const T *g,const T *b,const uint count)
|
||||
{
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*rgb=*r;++rgb;++r;
|
||||
*rgb=*g;++rgb;++g;
|
||||
*rgb=*b;++rgb;++b;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void MixRGBA(T *rgba,const T *r,const T *g,const T *b,const T *a,const uint count)
|
||||
{
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*rgba=*r;++rgba;++r;
|
||||
*rgba=*g;++rgba;++g;
|
||||
*rgba=*b;++rgba;++b;
|
||||
*rgba=*a;++rgba;++a;
|
||||
}
|
||||
}
|
||||
|
||||
bool SaveRGBAFile(const OSString &filename,const uint w,const uint h,const float scale,const uint8 *r,const uint8 *g,const uint8 *b,const uint8 *a,const OSString &flag)
|
||||
{
|
||||
const OSString out_filename=OSString(filename)+OS_TEXT("_")+flag+OS_TEXT(".png");
|
||||
|
||||
AutoDeleteArray<uint8> pixels=new uint8[w*h*4];
|
||||
|
||||
MixRGBA<uint8>(pixels,r,g,b,a,w*h);
|
||||
|
||||
if(SaveImageToFile(out_filename,w,h,scale,4,IL_UNSIGNED_BYTE,pixels))
|
||||
{
|
||||
std_cout<<OS_TEXT("Output ")<<flag.c_str()<<OS_TEXT(": ")<<out_filename.c_str()<<std::endl;
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
bool SaveRGBFile(const OSString &filename,const uint w,const uint h,const float scale,const uint8 *r,const uint8 *g,const uint8 *b,const OSString &flag)
|
||||
{
|
||||
const OSString out_filename=OSString(filename)+OS_TEXT("_")+flag+OS_TEXT(".png");
|
||||
|
||||
AutoDeleteArray<uint8> pixels=new uint8[w*h*3];
|
||||
|
||||
MixRGB<uint8>(pixels,r,g,b,w*h);
|
||||
|
||||
if(SaveImageToFile(out_filename,w,h,scale,3,IL_UNSIGNED_BYTE,pixels))
|
||||
{
|
||||
std_cout<<OS_TEXT("Output ")<<flag.c_str()<<OS_TEXT(": ")<<out_filename.c_str()<<std::endl;
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
}//namespace hgl
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
int wmain(int argc,wchar_t **argv)
|
||||
#else
|
||||
int main(int argc,char **argv)
|
||||
#endif//
|
||||
{
|
||||
std::cout<<"Combo Texture Compression"<<std::endl<<std::endl;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
// FullTexture: Y1+Y2+G
|
||||
// HalfTexture: U1+V1+U2+V2
|
||||
std::cout<<"Example1: ComboTexture <output name> C2G1 Color1.png Color2.png Grayscale.png"<<std::endl;
|
||||
|
||||
// FullTexture: Y+M+R
|
||||
// HalfTexture: U+V+G
|
||||
std::cout<<"Example2: ComboTexture <output name> MPBR6 Color.png Matallic.png Roughness.png Grayscale.png"<<std::endl;
|
||||
|
||||
// FullTexture: Y+G1+G2
|
||||
// HalfTexture: U+V+M+R
|
||||
std::cout<<"Example3: ComboTexture <output name> MPBR7 Color.png Matallic.png Roughness.png Grayscale1.png Grayscale2.png"<<std::endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
ilInit();
|
||||
|
||||
if(stricmp(argv[2],"C2G1")==0)
|
||||
{
|
||||
ILImage c1,c2,g;
|
||||
uint w,h;
|
||||
|
||||
if(!c1.LoadFile(argv[3]))return(1);
|
||||
if(!c2.LoadFile(argv[4]))return(2);
|
||||
if(!g.LoadFile(argv[5]))return(3);
|
||||
|
||||
c1.ToRGB();
|
||||
c2.ToRGB();
|
||||
g.ToGray();
|
||||
|
||||
if((c1.width()!=c2.width())||(c2.width()!=g.width())||(c1.width()!=g.width())
|
||||
||(c1.height()!=c2.height())||(c2.height()!=g.height())||(c1.width()!=g.height()))
|
||||
{
|
||||
w=hgl_min(c1.width(),hgl_min(c2.width(),g.width()));
|
||||
h=hgl_min(c1.height(),hgl_min(c2.height(),g.height()));
|
||||
|
||||
c1.Resize(w,h);
|
||||
c2.Resize(w,h);
|
||||
g.Resize(w,h);
|
||||
}
|
||||
|
||||
const uint pixel_total=w*h;
|
||||
const uint half_pixel_total=pixel_total>>2;
|
||||
|
||||
AutoDeleteArray<uint8> y1=new uint8[pixel_total];
|
||||
AutoDeleteArray<uint8> y2=new uint8[pixel_total];
|
||||
AutoDeleteArray<uint8> u1=new uint8[half_pixel_total];
|
||||
AutoDeleteArray<uint8> u2=new uint8[half_pixel_total];
|
||||
AutoDeleteArray<uint8> v1=new uint8[half_pixel_total];
|
||||
AutoDeleteArray<uint8> v2=new uint8[half_pixel_total];
|
||||
|
||||
RGB2YUV(y1,u1,v1,(uint8 *)c1.GetRGB(IL_UNSIGNED_BYTE),pixel_total);
|
||||
RGB2YUV(y2,u2,v2,(uint8 *)c2.GetRGB(IL_UNSIGNED_BYTE),pixel_total);
|
||||
|
||||
SaveRGBFile( argv[1],
|
||||
w,h,1.0,
|
||||
y1,y2,(uint8 *)g.GetLum(IL_UNSIGNED_BYTE),
|
||||
OS_TEXT("Y2G"));
|
||||
|
||||
SaveRGBAFile( argv[1],
|
||||
w,h,0.5,
|
||||
u1,v1,u2,v2,
|
||||
OS_TEXT("UV2"));
|
||||
}
|
||||
|
||||
ilShutDown();
|
||||
return 0;
|
||||
}
|
@ -44,8 +44,8 @@ public:
|
||||
|
||||
bool Resize(uint,uint);
|
||||
|
||||
void ToRGB(ILuint type=IL_UNSIGNED_BYTE);
|
||||
void ToGray(ILuint type=IL_UNSIGNED_BYTE);
|
||||
void *ToRGB(ILuint type=IL_UNSIGNED_BYTE);
|
||||
void *ToGray(ILuint type=IL_UNSIGNED_BYTE);
|
||||
|
||||
void *GetR(ILuint type);
|
||||
|
||||
@ -58,4 +58,4 @@ public:
|
||||
void *GetLum(ILuint type){return GetData(IL_LUMINANCE,type);}
|
||||
};//class ILImage
|
||||
|
||||
bool SaveImageToFile(const OSString &filename,ILuint w,ILuint h,ILuint c,ILuint t,void *data);
|
||||
bool SaveImageToFile(const OSString &filename,ILuint w,ILuint h,const float scale,ILuint c,ILuint t,void *data);
|
||||
|
@ -65,7 +65,7 @@ constexpr ILenum format_by_channel[]=
|
||||
IL_RGBA,
|
||||
};
|
||||
|
||||
bool SaveImageToFile(const OSString &filename,ILuint w,ILuint h,ILuint c,ILuint t,void *data)
|
||||
bool SaveImageToFile(const OSString &filename,ILuint w,ILuint h,const float scale,ILuint c,ILuint t,void *data)
|
||||
{
|
||||
if(filename.IsEmpty())return(false);
|
||||
if(w<=0||h<=1)return(false);
|
||||
@ -80,6 +80,8 @@ bool SaveImageToFile(const OSString &filename,ILuint w,ILuint h,ILuint c,ILuint
|
||||
if(!ilTexImage(w,h,1,c,format_by_channel[c-1],t,data))
|
||||
return(false);
|
||||
|
||||
iluScale(w*scale,h*scale,1);
|
||||
|
||||
iluFlipImage();
|
||||
ilEnable(IL_FILE_OVERWRITE);
|
||||
|
||||
@ -187,16 +189,20 @@ bool ILImage::LoadFile(const OSString &filename)
|
||||
return(true);
|
||||
}
|
||||
|
||||
void ILImage::ToRGB(ILuint type)
|
||||
void *ILImage::ToRGB(ILuint type)
|
||||
{
|
||||
if(il_format!=IL_RGB)
|
||||
Convert(IL_RGB,type);
|
||||
|
||||
return ilGetData();
|
||||
}
|
||||
|
||||
void ILImage::ToGray(ILuint type)
|
||||
void *ILImage::ToGray(ILuint type)
|
||||
{
|
||||
if(il_format!=IL_LUMINANCE)
|
||||
Convert(IL_LUMINANCE,type);
|
||||
|
||||
return ilGetData();
|
||||
}
|
||||
|
||||
void *ILImage::GetR(ILuint type)
|
||||
|
242
MicroPBR.cpp
242
MicroPBR.cpp
@ -1,242 +0,0 @@
|
||||
#include<iostream>
|
||||
#include<iomanip>
|
||||
#include<ILImage.h>
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/util/cmd/CmdParse.h>
|
||||
#include<hgl/type/Smart.h>
|
||||
|
||||
using namespace hgl;
|
||||
using namespace hgl::util;
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
#define std_cout std::wcout
|
||||
#else
|
||||
#define std_cout std::cout
|
||||
#endif//
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint w,const uint h);
|
||||
void normal_compress(uint8 *x,uint8 *y,const uint8 *rgb,const uint count);
|
||||
|
||||
template<typename T>
|
||||
void MixRGB(T *rgb,const T *r,const T *g,const T *b,const uint count)
|
||||
{
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*rgb=*r;++rgb;++r;
|
||||
*rgb=*g;++rgb;++g;
|
||||
*rgb=*b;++rgb;++b;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void MixRGBA(T *rgba,const T *r,const T *g,const T *b,const T *a,const uint count)
|
||||
{
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*rgba=*r;++rgba;++r;
|
||||
*rgba=*g;++rgba;++g;
|
||||
*rgba=*b;++rgba;++b;
|
||||
*rgba=*a;++rgba;++a;
|
||||
}
|
||||
}
|
||||
|
||||
class PBRComponent
|
||||
{
|
||||
OSString param_name;
|
||||
OSString name;
|
||||
OSString filename;
|
||||
|
||||
bool has;
|
||||
ILImage img;
|
||||
|
||||
public:
|
||||
|
||||
const uint width()const{return img.width();}
|
||||
const uint height()const{return img.height();}
|
||||
|
||||
public:
|
||||
|
||||
PBRComponent(const OSString &cn,const OSString &pn)
|
||||
{
|
||||
param_name=pn;
|
||||
name=cn;
|
||||
has=false;
|
||||
}
|
||||
|
||||
virtual ~PBRComponent()=default;
|
||||
|
||||
const bool isHas()const{return has;}
|
||||
|
||||
bool Parse(const CmdParse &cp)
|
||||
{
|
||||
has=cp.GetString(param_name,filename);
|
||||
if(!has)
|
||||
{
|
||||
std_cout<<OS_TEXT("no ")<<std::setw(10)<<name.c_str()<<std::endl;
|
||||
return(false);
|
||||
}
|
||||
|
||||
std_cout<<std::setw(10)<<name.c_str()<<": "<<filename.c_str()<<std::endl;
|
||||
|
||||
has=img.LoadFile(filename);
|
||||
|
||||
if(!has)
|
||||
std_cout<<OS_TEXT("Load file failed, filename: ")<<filename.c_str()<<std::endl;
|
||||
|
||||
return(has);
|
||||
}
|
||||
|
||||
void Resize(const uint w,const uint h){img.Resize(w,h);}
|
||||
void ToRGB(){img.ToRGB();}
|
||||
void ToGray(){img.ToGray();}
|
||||
|
||||
uint8 *GetRGB(){return (uint8 *)img.GetRGB(IL_UNSIGNED_BYTE);}
|
||||
uint8 *GetLum(){return (uint8 *)img.GetLum(IL_UNSIGNED_BYTE);}
|
||||
};//class PBRComponent
|
||||
|
||||
bool SaveRGBAFile(const OSString &filename,const uint w,const uint h,const uint8 *r,const uint8 *g,const uint8 *b,const uint8 *a,const OSString &flag)
|
||||
{
|
||||
const OSString out_filename=OSString(filename)+OS_TEXT("_")+flag+OS_TEXT(".png");
|
||||
|
||||
AutoDeleteArray<uint8> pixels=new uint8[w*h*3];
|
||||
|
||||
MixRGBA<uint8>(pixels,r,g,b,a,w*h);
|
||||
|
||||
if(SaveImageToFile(out_filename,w,h,4,IL_UNSIGNED_BYTE,pixels))
|
||||
{
|
||||
std_cout<<OS_TEXT("Output ")+flag+OS_TEXT(": ")<<out_filename.c_str()<<std::endl;
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
bool SaveRGBFile(const OSString &filename,const uint w,const uint h,const uint8 *r,const uint8 *g,const uint8 *b,const OSString &flag)
|
||||
{
|
||||
const OSString out_filename=OSString(filename)+OS_TEXT("_")+flag+OS_TEXT(".png");
|
||||
|
||||
AutoDeleteArray<uint8> pixels=new uint8[w*h*3];
|
||||
|
||||
MixRGB<uint8>(pixels,r,g,b,w*h);
|
||||
|
||||
if(SaveImageToFile(out_filename,w,h,3,IL_UNSIGNED_BYTE,pixels))
|
||||
{
|
||||
std_cout<<OS_TEXT("Output ")<<flag.c_str()<<OS_TEXT(": ")<<out_filename.c_str()<<std::endl;
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
}//namespace hgl
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
int wmain(int argc,wchar_t **argv)
|
||||
#else
|
||||
int main(int argc,char **argv)
|
||||
#endif//
|
||||
{
|
||||
std::cout<<"MicroPBR Texture Compression"<<std::endl<<std::endl;
|
||||
|
||||
if(argc<2)
|
||||
{
|
||||
std::cout<<"Example: MicroPBR <output name> /C:BaseColor.png /N:Normal.png /M:Metallic.png /R:Roughness.png"<<std::endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
CmdParse cp(argc,argv);
|
||||
|
||||
ilInit();
|
||||
|
||||
PBRComponent color (OS_TEXT("BaseColor"),OS_TEXT("/C:")),
|
||||
normal (OS_TEXT("Normal" ),OS_TEXT("/N:")),
|
||||
metallic (OS_TEXT("Metallic" ),OS_TEXT("/M:")),
|
||||
roughness (OS_TEXT("Roughness"),OS_TEXT("/R:"));
|
||||
|
||||
color.Parse(cp);
|
||||
normal.Parse(cp);
|
||||
metallic.Parse(cp);
|
||||
roughness.Parse(cp);
|
||||
|
||||
if(!color.isHas()||!normal.isHas())
|
||||
return(false);
|
||||
|
||||
color.ToRGB();
|
||||
normal.ToRGB();
|
||||
|
||||
if(color.width()!=normal.width()
|
||||
||color.height()!=normal.height())
|
||||
{
|
||||
uint nw=hgl_min(color.width(),normal.width());
|
||||
uint nh=hgl_max(color.height(),normal.height());
|
||||
|
||||
color.Resize(nw,nh);
|
||||
normal.Resize(nw,nh);
|
||||
}
|
||||
|
||||
const uint w=color.width();
|
||||
const uint h=color.height();
|
||||
const uint half_w=w>>1;
|
||||
const uint half_h=h>>1;
|
||||
const uint pixel_total=w*h;
|
||||
const uint half_pixel_total=half_w*half_h;
|
||||
|
||||
if(metallic.isHas())
|
||||
{
|
||||
metallic.ToGray();
|
||||
metallic.Resize(half_w,half_h);
|
||||
}
|
||||
|
||||
if(roughness.isHas())
|
||||
{
|
||||
roughness.ToGray();
|
||||
roughness.Resize(half_w,half_h);
|
||||
}
|
||||
|
||||
AutoDeleteArray<uint8> y,u,v,nx,ny;
|
||||
|
||||
y=new uint8[pixel_total];
|
||||
u=new uint8[half_pixel_total];
|
||||
v=new uint8[half_pixel_total];
|
||||
nx=new uint8[pixel_total];
|
||||
ny=new uint8[pixel_total];
|
||||
|
||||
// BaseColor Y + Normal XY
|
||||
{
|
||||
RGB2YUV(y,u,v,color.GetRGB(),w,h);
|
||||
normal_compress(nx,ny,normal.GetRGB(),w*h);
|
||||
|
||||
SaveRGBFile( argv[1],
|
||||
w,h,
|
||||
y,nx,ny,
|
||||
OS_TEXT("YN"));
|
||||
}
|
||||
|
||||
if(metallic.isHas()&&roughness.isHas())
|
||||
{
|
||||
SaveRGBAFile(argv[1],
|
||||
half_w,half_h,
|
||||
u,v,metallic.GetLum(),roughness.GetLum(),
|
||||
OS_TEXT("UVMR"));
|
||||
}
|
||||
else
|
||||
if(metallic.isHas())
|
||||
{
|
||||
SaveRGBFile( argv[1],
|
||||
half_w,half_h,
|
||||
u,v,metallic.GetLum(),
|
||||
OS_TEXT("UVM"));
|
||||
}
|
||||
else
|
||||
if(roughness.isHas())
|
||||
{
|
||||
SaveRGBFile( argv[1],
|
||||
half_w,half_h,
|
||||
u,v,roughness.GetLum(),
|
||||
OS_TEXT("UVR"));
|
||||
}
|
||||
|
||||
ilShutDown();
|
||||
return 0;
|
||||
}
|
87
YUV.cpp
87
YUV.cpp
@ -5,82 +5,39 @@ using namespace hgl;
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
void write_to_yuv_frame(uint w,uint h,uint8 *yuv,uint8 *yuv_y,uint8 *yuv_u,uint8 *yuv_v)
|
||||
{
|
||||
uint x;
|
||||
uint y;
|
||||
|
||||
uint yuv_h=((h+1)>>1)<<1;
|
||||
uint yuv_w=((w+1)>>1)<<1;
|
||||
|
||||
memset(yuv_y,0,yuv_h*yuv_w);
|
||||
memset(yuv_u,0,yuv_h*yuv_w/4);
|
||||
memset(yuv_v,0,yuv_h*yuv_w/4);
|
||||
|
||||
for(y = 0; y < h; y++)
|
||||
for(x = 0; x < w; x++)
|
||||
yuv_y[x + y * yuv_w] = yuv[3 * (x + y * w) + 0];
|
||||
|
||||
for(y = 0; y < h; y += 2)
|
||||
for(x = 0; x < w; x += 2)
|
||||
{
|
||||
yuv_u[(x >> 1) + (y >> 1) * (yuv_w >> 1)] = yuv[3 * (x + y * w) + 1];
|
||||
yuv_v[(x >> 1) + (y >> 1) * (yuv_w >> 1)] = yuv[3 * (x + y * w) + 2];
|
||||
}
|
||||
}
|
||||
|
||||
uint8 __inline clamp(double d)
|
||||
{
|
||||
if(d < 0 )return 0;
|
||||
if(d > 255 )return 255;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
const double clamp_u=0.436*255.0;
|
||||
const double clamp_v=0.615*255.0;
|
||||
|
||||
void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint w,const uint h)
|
||||
|
||||
void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint count)
|
||||
{
|
||||
const uint8 *sp=rgb;
|
||||
uint8 *tp,*temp=new uint8[w*h*3];
|
||||
uint8 r,g,b;
|
||||
|
||||
int size=w*h;
|
||||
|
||||
tp=temp;
|
||||
|
||||
while(size--)
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
uint8 r=*sp++;
|
||||
uint8 g=*sp++;
|
||||
uint8 b=*sp++;
|
||||
r=*rgb++;
|
||||
g=*rgb++;
|
||||
b=*rgb++;
|
||||
|
||||
*tp++=clamp( 0.299 * r + 0.587 * g + 0.114 * b);
|
||||
*tp++=clamp((clamp_u - 0.14713 * r - 0.28886 * g + 0.436 * b) / 0.872);
|
||||
*tp++=clamp((clamp_v + 0.615 * r - 0.51499 * g - 0.10001 * b) / 1.230);
|
||||
*y++= 0.299 * r + 0.587 * g + 0.114 * b;
|
||||
*u++=(clamp_u - 0.14713 * r - 0.28886 * g + 0.436 * b) / 0.872;
|
||||
*v++=(clamp_v + 0.615 * r - 0.51499 * g - 0.10001 * b) / 1.230;
|
||||
}
|
||||
|
||||
uint yuv_h=((h+1)>>1)<<1;
|
||||
uint yuv_w=((w+1)>>1)<<1;
|
||||
|
||||
write_to_yuv_frame(w,h,temp,y,u,v);
|
||||
|
||||
delete[] temp;
|
||||
}
|
||||
}//namespace hgl
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
static bool yuv2rgb=false;
|
||||
static int sAdjCrr[256];
|
||||
static int sAdjCrg[256];
|
||||
static int sAdjCbg[256];
|
||||
static int sAdjCbb[256];
|
||||
static int sAdjY[256];
|
||||
static uint8 sClampBuff[1024];
|
||||
static uint8 *sClamp = sClampBuff + 384;
|
||||
static unsigned char sClampBuff[1024];
|
||||
static unsigned char *sClamp = sClampBuff + 384;
|
||||
|
||||
static uint8 YV_R[256][256];
|
||||
static uint8 YU_B[256][256];
|
||||
static unsigned char YV_R[256][256];
|
||||
static unsigned char YU_B[256][256];
|
||||
|
||||
inline int getMin(int a, int b)
|
||||
{
|
||||
@ -119,28 +76,30 @@ namespace hgl
|
||||
YV_R[v][y]=sClamp[sAdjY[y]+sAdjCrr[v]];
|
||||
YU_B[v][y]=sClamp[sAdjY[y]+sAdjCbb[v]];
|
||||
}
|
||||
}
|
||||
|
||||
yuv2rgb=true;
|
||||
}
|
||||
|
||||
void YUV2RGB(uint8 *rgb,const uint8 *y,const uint8 *u,const uint8 *v,const uint w,const uint h)
|
||||
{
|
||||
const uint line_gap=w*3;
|
||||
|
||||
const uint y_stride=w;
|
||||
const uint uv_stride=w/2;
|
||||
const uint uv_stride=w>>1;
|
||||
|
||||
const uint8 *pY0, *pY1, *pU, *pV;
|
||||
|
||||
for(uint _y = 0; _y < h; _y += 2)
|
||||
for(int _y = 0; _y < h; _y += 2)
|
||||
{
|
||||
pY0 = y + _y * y_stride;
|
||||
pY1 = y + (_y | 1)* y_stride;
|
||||
pU = u + (( _y * uv_stride) >> 1);
|
||||
pV = v + (( _y * uv_stride) >> 1);
|
||||
|
||||
uint8 *dst0=rgb;
|
||||
uint8 *dst1=rgb+line_gap;
|
||||
unsigned __int8 *dst0=rgb;
|
||||
unsigned __int8 *dst1=rgb+line_gap;
|
||||
|
||||
for(uint _x = 0; _x < w; _x += 2)
|
||||
for(int _x = 0; _x < w; _x += 2)
|
||||
{
|
||||
const int G = sAdjCrg[*pV] + sAdjCbg[*pU];
|
||||
|
||||
|
23
YUVTest.cpp
23
YUVTest.cpp
@ -8,11 +8,10 @@ using namespace hgl::filesystem;
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint w,const uint h);
|
||||
void InitYUV2RGBDecode();
|
||||
void RGB2YUV(uint8 *y,uint8 *u,uint8 *v,const uint8 *rgb,const uint count);
|
||||
void YUV2RGB(uint8 *rgb,const uint8 *y,const uint8 *u,const uint8 *v,const uint w,const uint h);
|
||||
|
||||
void InitYUV2RGBDecode();
|
||||
|
||||
|
||||
void normal_compress(uint8 *x,uint8 *y,const uint8 *rgb,const uint count);
|
||||
void normal_decompress(uint8 *rgb,const uint8 *x,const uint8 *y,const uint count);
|
||||
}
|
||||
@ -29,9 +28,9 @@ int main(int argc,char **argv)
|
||||
{
|
||||
if(argc<1)
|
||||
return 0;
|
||||
|
||||
InitYUV2RGBDecode();
|
||||
|
||||
InitYUV2RGBDecode();
|
||||
|
||||
ilInit();
|
||||
|
||||
ILImage rgb_image;
|
||||
@ -44,13 +43,13 @@ int main(int argc,char **argv)
|
||||
|
||||
uint8 *rgb=(uint8 *)rgb_image.GetRGB(IL_UNSIGNED_BYTE);
|
||||
|
||||
const uint pixels=rgb_image.pixel_total();
|
||||
const uint pixel_total=rgb_image.pixel_total();
|
||||
|
||||
uint8 *y=new uint8[pixels];
|
||||
uint8 *u=new uint8[pixels/4];
|
||||
uint8 *v=new uint8[pixels/4];
|
||||
uint8 *y=new uint8[pixel_total];
|
||||
uint8 *u=new uint8[pixel_total>>2];
|
||||
uint8 *v=new uint8[pixel_total>>2];
|
||||
|
||||
RGB2YUV(y,u,v,rgb,rgb_image.width(),rgb_image.height());
|
||||
RGB2YUV(y,u,v,rgb,pixel_total);
|
||||
|
||||
YUV2RGB(rgb,y,u,v,rgb_image.width(),rgb_image.height());
|
||||
|
||||
@ -59,7 +58,7 @@ int main(int argc,char **argv)
|
||||
filename=ClipFileMainname<os_char>(argv[1]);
|
||||
filename+=OS_TEXT("_YUV.png");
|
||||
|
||||
if(SaveImageToFile(filename,rgb_image.width(),rgb_image.height(),3,IL_UNSIGNED_BYTE,rgb))
|
||||
if(SaveImageToFile(filename,rgb_image.width(),rgb_image.height(),1.0,3,IL_UNSIGNED_BYTE,rgb))
|
||||
std_cout<<OS_TEXT("Save To ")<<filename.c_str()<<OS_TEXT(" successed!")<<std::endl;
|
||||
|
||||
ilShutDown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user