From deb3f374a569a2d177bfae8c7fdb9d94679991f6 Mon Sep 17 00:00:00 2001 From: Sam Moore Date: Thu, 8 May 2014 17:26:43 +0800 Subject: [PATCH] Tests: MakeBitmap -> PointsToBitmap in its own header To use in other testers. --- src/tests/bezier.cpp | 97 +---------------------------------- src/tests/pointstobitmap.h | 102 +++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 95 deletions(-) create mode 100644 src/tests/pointstobitmap.h diff --git a/src/tests/bezier.cpp b/src/tests/bezier.cpp index 016fa5c..1e68ec2 100644 --- a/src/tests/bezier.cpp +++ b/src/tests/bezier.cpp @@ -9,6 +9,7 @@ #include #include "screen.h" #include +#include "pointstobitmap.h" using namespace std; using namespace IPDF; @@ -81,101 +82,7 @@ template vector > BezierCurve(const vector > & c return result; } -/** - * Map vector of points onto a Bitmap - * Because it was easier than working out the OpenGL stuff right now - * Points will be mapped according to the bounding rectangle. - * Should probably deal with possible aspect ratio difference... or just make sure to always use a square I guess - */ -template void MakeBitmap(const vector > & points, const T & scale = 1, uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, const char * filename = "bezier.bmp", bool overlay = false, uint64_t width = 400, uint64_t height = 400) -{ - - int ri = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 0 : 3; - int gi = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 1 : 2; - int bi = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 2 : 1; - //int ai = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 3 : 0; // No alpha in BMP - - // Pixel buffer - unsigned char * pixels = new unsigned char[width*height*4]; - - // Overlay indicates we should load the bitmap into the pixel buffer first - if (overlay) - { - SDL_Surface * bmp = SDL_LoadBMP(filename); - if (bmp == NULL) - { - overlay = false; // bmp (probably) doesn't exist -> not an error (we hope) - } - else - { - width = bmp->w; - height = bmp->h; - for (int i = 0; i < width*height*(bmp->format->BytesPerPixel); ++i) - { - // We're assuming the BMP was stored in the same Byteorder as we will save it - pixels[i] = *((unsigned char*)(bmp->pixels)+i); - } - } - } - if (!overlay) - { - for (int i = 0; i < width*height*4; ++i) - pixels[i] = 0xFF; // White pixels - } - - - typedef long double LD; // The temporary typedef, an underappreciated technique... - - // Named lambdas... this is getting worrying... - auto lessx = [](const pair & a, const pair & b){return (a.first < b.first);}; - auto lessy = [](const pair & a, const pair & b){return (a.second < b.second);}; - - // So I don't have to type as much here - pair left = *min_element(points.begin(), points.end(), lessx); - pair right = *max_element(points.begin(), points.end(), lessx); - pair bottom = *min_element(points.begin(), points.end(), lessy); - pair top = *max_element(points.begin(), points.end(),lessy); - - pair min(left.first, bottom.second); - pair max(right.first, top.second); - // Alternately, just do this: - /* - pair min(-scale, -scale); - pair max(scale, scale); - */ - - // Map each point to a pixel position - for (auto i = 0; i < points.size(); ++i) - { - // Do maths with long double; this way any artefacts are more likely due to the creation of the bezier itself than this mapping operation - uint64_t x = llround(((LD)(points[i].first) - (LD)(min.first)) * (LD)(width-1)/((LD)max.first - (LD)min.first)); - uint64_t y = llround(((LD)(points[i].second) - (LD)(min.second)) * (LD)(height-1)/((LD)max.second - (LD)min.second)); - int index = 4*(y*width + x); // Get index into pixel array - // Set colour - pixels[index+ri] = r; - pixels[index+gi] = g; - pixels[index+bi] = b; - } - - // Truly a thing of beauty - SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, width, height, 8*4, width*4, - #if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 - #else - 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff - #endif //SDL_BYTEORDER - ); - - if (surf == NULL) - Fatal("SDL_CreateRGBSurfaceFrom(pixels...) failed - %s", SDL_GetError()); - if (SDL_SaveBMP(surf, filename) != 0) - Fatal("SDL_SaveBMP failed - %s", SDL_GetError()); - - // Cleanup - SDL_FreeSurface(surf); - delete [] pixels; -} /** * Make a circle using Beziers @@ -241,7 +148,7 @@ void TestBeziers(long intervals = 50, long double start = 1e-38, long double end // Make bitmap(s) stringstream s; s << "bezier" << count << "_" << scale << ".bmp"; - MakeBitmap(f, scale, 5*(count++),0,0,s.str().c_str(),false); + PointsToBitmap(f, scale, 5*(count++),0,0,s.str().c_str(),false); #if REAL > REAL_LONG_DOUBLE auto r = TESTBEZIER(scale, intervals); diff --git a/src/tests/pointstobitmap.h b/src/tests/pointstobitmap.h new file mode 100644 index 0000000..90bfbdb --- /dev/null +++ b/src/tests/pointstobitmap.h @@ -0,0 +1,102 @@ +#ifndef _POINTSTOBITMAP_H +#define _POINTSTOBITMAP_H + +#include + +/** + * Map vector of points onto a Bitmap + * Because it was easier than working out the OpenGL stuff right now + * Points will be mapped according to the bounding rectangle. + * Should probably deal with possible aspect ratio difference... or just make sure to always use a square I guess + */ +template void PointsToBitmap(const vector > & points, const T & scale = 1, uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, const char * filename = "bezier.bmp", bool overlay = false, uint64_t width = 400, uint64_t height = 400) +{ + + int ri = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 0 : 3; + int gi = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 1 : 2; + int bi = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 2 : 1; + //int ai = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 3 : 0; // No alpha in BMP + + // Pixel buffer + unsigned char * pixels = new unsigned char[width*height*4]; + + // Overlay indicates we should load the bitmap into the pixel buffer first + if (overlay) + { + SDL_Surface * bmp = SDL_LoadBMP(filename); + if (bmp == NULL) + { + overlay = false; // bmp (probably) doesn't exist -> not an error (we hope) + } + else + { + width = bmp->w; + height = bmp->h; + for (int i = 0; i < width*height*(bmp->format->BytesPerPixel); ++i) + { + // We're assuming the BMP was stored in the same Byteorder as we will save it + pixels[i] = *((unsigned char*)(bmp->pixels)+i); + } + } + } + if (!overlay) + { + for (int i = 0; i < width*height*4; ++i) + pixels[i] = 0xFF; // White pixels + } + + + typedef long double LD; // The temporary typedef, an underappreciated technique... + + // Named lambdas... this is getting worrying... + auto lessx = [](const pair & a, const pair & b){return (a.first < b.first);}; + auto lessy = [](const pair & a, const pair & b){return (a.second < b.second);}; + + // So I don't have to type as much here + pair left = *min_element(points.begin(), points.end(), lessx); + pair right = *max_element(points.begin(), points.end(), lessx); + pair bottom = *min_element(points.begin(), points.end(), lessy); + pair top = *max_element(points.begin(), points.end(),lessy); + + pair min(left.first, bottom.second); + pair max(right.first, top.second); + + // Alternately, just do this: + /* + pair min(-scale, -scale); + pair max(scale, scale); + */ + + // Map each point to a pixel position + for (auto i = 0; i < points.size(); ++i) + { + // Do maths with long double; this way any artefacts are more likely due to the creation of the bezier itself than this mapping operation + uint64_t x = llround(((LD)(points[i].first) - (LD)(min.first)) * (LD)(width-1)/((LD)max.first - (LD)min.first)); + uint64_t y = llround(((LD)(points[i].second) - (LD)(min.second)) * (LD)(height-1)/((LD)max.second - (LD)min.second)); + int index = 4*(y*width + x); // Get index into pixel array + // Set colour + pixels[index+ri] = r; + pixels[index+gi] = g; + pixels[index+bi] = b; + } + + // Truly a thing of beauty + SDL_Surface * surf = SDL_CreateRGBSurfaceFrom(pixels, width, height, 8*4, width*4, + #if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 + #else + 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff + #endif //SDL_BYTEORDER + ); + + if (surf == NULL) + Fatal("SDL_CreateRGBSurfaceFrom(pixels...) failed - %s", SDL_GetError()); + if (SDL_SaveBMP(surf, filename) != 0) + Fatal("SDL_SaveBMP failed - %s", SDL_GetError()); + + // Cleanup + SDL_FreeSurface(surf); + delete [] pixels; +} + +#endif //_POINTSTOBITMAP_H -- 2.20.1