You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.6 KiB
108 lines
2.6 KiB
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//===========================================================================//
|
|
|
|
#include <tier0/platform.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include "bitmap/float_bm.h"
|
|
#include "vstdlib/vstdlib.h"
|
|
#include "vstdlib/random.h"
|
|
#include "tier1/strtools.h"
|
|
|
|
void FloatBitMap_t::InitializeWithRandomPixelsFromAnotherFloatBM(FloatBitMap_t const &other)
|
|
{
|
|
for(int y=0;y<Height;y++)
|
|
for(int x=0;x<Width;x++)
|
|
{
|
|
float x1=RandomInt(0,other.Width-1);
|
|
float y1=RandomInt(0,other.Height-1);
|
|
for(int c=0;c<4;c++)
|
|
{
|
|
Pixel(x,y,c)=other.Pixel(x1,y1,c);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
FloatBitMap_t *FloatBitMap_t::QuarterSizeWithGaussian(void) const
|
|
{
|
|
// generate a new bitmap half on each axis, using a separable gaussian.
|
|
static float kernel[]={.05,.25,.4,.25,.05};
|
|
FloatBitMap_t *newbm=new FloatBitMap_t(Width/2,Height/2);
|
|
|
|
for(int y=0;y<Height/2;y++)
|
|
for(int x=0;x<Width/2;x++)
|
|
{
|
|
for(int c=0;c<4;c++)
|
|
{
|
|
float sum=0;
|
|
float sumweights=0; // for versatility in handling the
|
|
// offscreen case
|
|
for(int xofs=-2;xofs<=2;xofs++)
|
|
{
|
|
int orig_x=max(0,min(Width-1,x*2+xofs));
|
|
for(int yofs=-2;yofs<=2;yofs++)
|
|
{
|
|
int orig_y=max(0,min(Height-1,y*2+yofs));
|
|
float coeff=kernel[xofs+2]*kernel[yofs+2];
|
|
sum+=Pixel(orig_x,orig_y,c)*coeff;
|
|
sumweights+=coeff;
|
|
}
|
|
}
|
|
newbm->Pixel(x,y,c)=sum/sumweights;
|
|
}
|
|
}
|
|
return newbm;
|
|
}
|
|
|
|
FloatImagePyramid_t::FloatImagePyramid_t(FloatBitMap_t const &src, ImagePyramidMode_t mode)
|
|
{
|
|
memset(m_pLevels,0,sizeof(m_pLevels));
|
|
m_nLevels=1;
|
|
m_pLevels[0]=new FloatBitMap_t(&src);
|
|
ReconstructLowerResolutionLevels(0);
|
|
}
|
|
|
|
void FloatImagePyramid_t::ReconstructLowerResolutionLevels(int start_level)
|
|
{
|
|
while( (m_pLevels[start_level]->Width>1) && (m_pLevels[start_level]->Height>1) )
|
|
{
|
|
if (m_pLevels[start_level+1])
|
|
delete m_pLevels[start_level+1];
|
|
m_pLevels[start_level+1]=m_pLevels[start_level]->QuarterSizeWithGaussian();
|
|
start_level++;
|
|
}
|
|
m_nLevels=start_level+1;
|
|
}
|
|
|
|
float & FloatImagePyramid_t::Pixel(int x, int y, int component, int level) const
|
|
{
|
|
assert(level<m_nLevels);
|
|
x<<=level;
|
|
y<<=level;
|
|
return m_pLevels[level]->Pixel(x,y,component);
|
|
}
|
|
|
|
void FloatImagePyramid_t::WriteTGAs(char const *basename) const
|
|
{
|
|
for(int l=0;l<m_nLevels;l++)
|
|
{
|
|
char bname_out[1024];
|
|
Q_snprintf(bname_out,sizeof(bname_out),"%s_%02d.tga",basename,l);
|
|
m_pLevels[l]->WriteTGAFile(bname_out);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
FloatImagePyramid_t::~FloatImagePyramid_t(void)
|
|
{
|
|
for(int l=0;l<m_nLevels;l++)
|
|
if (m_pLevels[l])
|
|
delete m_pLevels[l];
|
|
}
|