diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-12-15 01:04:17 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-12-15 01:04:17 (GMT) |
| commit | b4475ae96f29a0ae64263b010d66c04e9bc5d02d (patch) | |
| tree | 00fb0313d5dde91a0182950c1bad3e03672420b5 /src/graphics | |
| parent | a1af662b8fad2cc654fdcfda2aeedec24659c908 (diff) | |
| download | powder-b4475ae96f29a0ae64263b010d66c04e9bc5d02d.zip powder-b4475ae96f29a0ae64263b010d66c04e9bc5d02d.tar.gz | |
Very high quality image resampling code curtesy of imageresampler (http://code.google.com/p/imageresampler/), will replace current shitty linear interpolation for SSE2 and renderer builds.
Diffstat (limited to 'src/graphics')
| -rw-r--r-- | src/graphics/Graphics.cpp | 91 | ||||
| -rw-r--r-- | src/graphics/Graphics.h | 18 |
2 files changed, 101 insertions, 8 deletions
diff --git a/src/graphics/Graphics.cpp b/src/graphics/Graphics.cpp index 11dcac3..c3a5aca 100644 --- a/src/graphics/Graphics.cpp +++ b/src/graphics/Graphics.cpp @@ -7,6 +7,9 @@ #include "Graphics.h" #define INCLUDE_FONTDATA #include "font.h" +#ifdef HIGH_QUALITY_RESAMPLE +#include "resampler/resampler.h" +#endif VideoBuffer::VideoBuffer(int width, int height): Width(width), @@ -291,6 +294,93 @@ pixel *Graphics::resample_img_nn(pixel * src, int sw, int sh, int rw, int rh) pixel *Graphics::resample_img(pixel *src, int sw, int sh, int rw, int rh) { +#ifdef HIGH_QUALITY_RESAMPLE + + unsigned char * source = (unsigned char*)src; + int sourceWidth = sw, sourceHeight = sh; + int resultWidth = rw, resultHeight = rh; + int sourcePitch = sourceWidth*PIXELSIZE, resultPitch = resultWidth*PIXELSIZE; + // Filter scale - values < 1.0 cause aliasing, but create sharper looking mips. + const float filter_scale = 0.75f; + const char* pFilter = "lanczos12"; + + + Resampler * resamplers[PIXELCHANNELS]; + float * samples[PIXELCHANNELS]; + + //Resampler for each colour channel + resamplers[0] = new Resampler(sourceWidth, sourceHeight, resultWidth, resultHeight, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, NULL, NULL, filter_scale, filter_scale); + samples[0] = new float[sourceWidth]; + for (int i = 1; i < PIXELCHANNELS; i++) + { + resamplers[i] = new Resampler(sourceWidth, sourceHeight, resultWidth, resultHeight, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, resamplers[0]->get_clist_x(), resamplers[0]->get_clist_y(), filter_scale, filter_scale); + samples[i] = new float[sourceWidth]; + } + + unsigned char * resultImage = new unsigned char[resultHeight * resultPitch]; + std::fill(resultImage, resultImage + (resultHeight*resultPitch), 0); + + //Resample time + int resultY = 0; + for (int sourceY = 0; sourceY < sourceHeight; sourceY++) + { + unsigned char * sourcePixel = &source[sourceY * sourcePitch]; + + //Move pixel components into channel samples + for (int c = 0; c < PIXELCHANNELS; c++) + { + for (int x = 0; x < sourceWidth; x++) + { + samples[c][x] = sourcePixel[(x*PIXELSIZE)+c] * (1.0f/255.0f); + } + } + + //Put channel sample data into resampler + for (int c = 0; c < PIXELCHANNELS; c++) + { + if (!resamplers[c]->put_line(&samples[c][0])) + { + printf("Out of memory!\n"); + return NULL; + } + } + + //Perform resample and Copy components from resampler result samples to image buffer + for ( ; ; ) + { + int comp_index; + for (comp_index = 0; comp_index < PIXELCHANNELS; comp_index++) + { + const float* resultSamples = resamplers[comp_index]->get_line(); + if (!resultSamples) + break; + + unsigned char * resultPixel = &resultImage[(resultY * resultPitch) + comp_index]; + + for (int x = 0; x < resultWidth; x++) + { + int c = (int)(255.0f * resultSamples[x] + .5f); + if (c < 0) c = 0; else if (c > 255) c = 255; + *resultPixel = (unsigned char)c; + resultPixel += PIXELSIZE; + } + } + if (comp_index < PIXELCHANNELS) + break; + + resultY++; + } + } + + //Clean up + for(int i = 0; i < PIXELCHANNELS; i++) + { + delete resamplers[i]; + delete[] samples[i]; + } + + return (pixel*)resultImage; +#else #ifdef DEBUG std::cout << "Resampling " << sw << "x" << sh << " to " << rw << "x" << rh << std::endl; #endif @@ -402,6 +492,7 @@ pixel *Graphics::resample_img(pixel *src, int sw, int sh, int rw, int rh) } } return q; +#endif } pixel *Graphics::rescale_img(pixel *src, int sw, int sh, int *qw, int *qh, int f) diff --git a/src/graphics/Graphics.h b/src/graphics/Graphics.h index 53d3ee7..2c90074 100644 --- a/src/graphics/Graphics.h +++ b/src/graphics/Graphics.h @@ -11,38 +11,40 @@ #include "Config.h" //#include "powder.h" +#define PIXELCHANNELS 3 #ifdef PIX16 #define PIXELSIZE 2 -#define PIXPACK(x) ((((x)>>8)&0xF800)|(((x)>>5)&0x07E0)|(((x)>>3)&0x001F)) +#define PIXPACK(x) ((((x)>>8)&0xF800)|(((x)>>5)&0x07E0)|(((x)>>3)&0x001F)) //16bit RGB in 16bit int: ???? #define PIXRGB(r,g,b) ((((r)<<8)&0xF800)|(((g)<<3)&0x07E0)|(((b)>>3)&0x001F)) #define PIXR(x) (((x)>>8)&0xF8) #define PIXG(x) (((x)>>3)&0xFC) #define PIXB(x) (((x)<<3)&0xF8) #else #define PIXELSIZE 4 -#ifdef PIX32BGR -#define PIXPACK(x) ((((x)>>16)&0x0000FF)|((x)&0x00FF00)|(((x)<<16)&0xFF0000)) +#ifdef PIX32BGRA +#define PIXPACK(x) ((((x)>>16)&0x0000FF)|((x)&0x00FF00)|(((x)<<16)&0xFF0000)) //24bit BGR in 32bit int: 00BBGGRR #define PIXRGB(r,g,b) (((b)<<16)|((g)<<8)|((r)))// (((b)<<16)|((g)<<8)|(r)) #define PIXR(x) ((x)&0xFF) #define PIXG(x) (((x)>>8)&0xFF) #define PIXB(x) ((x)>>16) #else #ifdef PIX32BGRA -#define PIXPACK(x) ((((x)>>8)&0x0000FF00)|(((x)<<8)&0x00FF0000)|(((x)<<24)&0xFF000000)) +#define PIXPACK(x) ((((x)>>8)&0x0000FF00)|(((x)<<8)&0x00FF0000)|(((x)<<24)&0xFF000000)) //32bit BGRA in 32bit int: BBGGRRAA #define PIXRGB(r,g,b) (((b)<<24)|((g)<<16)|((r)<<8)) #define PIXR(x) (((x)>>8)&0xFF) #define PIXG(x) (((x)>>16)&0xFF) #define PIXB(x) (((x)>>24)) #elif defined(PIX32OGL) -#define PIXPACK(x) (0xFF000000|((x)&0xFFFFFF)) -#define PIXRGB(r,g,b) (0xFF000000|((r)<<16)|((g)<<8)|((b)))// (((b)<<16)|((g)<<8)|(r)) -#define PIXRGBA(r,g,b,a) (((a)<<24)|((r)<<16)|((g)<<8)|((b)))// (((b)<<16)|((g)<<8)|(r)) +#define PIXELCHANNELS 4 +#define PIXPACK(x) (0xFF000000|((x)&0xFFFFFF)) //32bit ARGB in 32bit int: AARRGGBB +#define PIXRGB(r,g,b) (0xFF000000|((r)<<16)|((g)<<8)|((b))) +#define PIXRGBA(r,g,b,a) (((a)<<24)|((r)<<16)|((g)<<8)|((b))) #define PIXA(x) (((x)>>24)&0xFF) #define PIXR(x) (((x)>>16)&0xFF) #define PIXG(x) (((x)>>8)&0xFF) #define PIXB(x) ((x)&0xFF) #else -#define PIXPACK(x) (x) +#define PIXPACK(x) (x) //24bit RGB in 32bit int: 00RRGGBB. #define PIXRGB(r,g,b) (((r)<<16)|((g)<<8)|(b)) #define PIXR(x) ((x)>>16) #define PIXG(x) (((x)>>8)&0xFF) |
