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]; |
|
}
|
|
|