summaryrefslogtreecommitdiff
path: root/src/graphics
diff options
context:
space:
mode:
authorSimon 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)
commitb4475ae96f29a0ae64263b010d66c04e9bc5d02d (patch)
tree00fb0313d5dde91a0182950c1bad3e03672420b5 /src/graphics
parenta1af662b8fad2cc654fdcfda2aeedec24659c908 (diff)
downloadpowder-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.cpp91
-rw-r--r--src/graphics/Graphics.h18
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)