Update to v093r03 release.

byuu says:

Updated to support latest phoenix changes.
Converted Settings and Tools to TabFrame views.

Errata:
- phoenix/Windows ComboButton wasn't calling parent
  pWidget::setGeometry() [fixed locally]
- TRACKBAR_CLASS draws COLOR_3DFACE for the background even when its
  parent is a WC_TABCONTROL
This commit is contained in:
Tim Allen
2013-11-28 21:29:01 +11:00
parent 8c0b0fa4ad
commit 68eaf53691
210 changed files with 5319 additions and 1977 deletions

View File

@@ -41,7 +41,7 @@ ifeq ($(compiler),)
flags :=
link :=
else ifeq ($(platform),macosx)
compiler := clang
compiler := clang++
flags := -w -stdlib=libc++
link := -lc++ -lobjc
else ifeq ($(platform),bsd)

View File

@@ -8,7 +8,7 @@
#include <nall/string.hpp>
#include <nall/utility.hpp>
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
#if defined(PLATFORM_X) || defined(PLATFORM_MACOSX)
#include <dlfcn.h>
#elif defined(PLATFORM_WINDOWS)
#include <windows.h>
@@ -59,7 +59,7 @@ inline void library::close() {
dlclose((void*)handle);
handle = 0;
}
#elif defined(PLATFORM_OSX)
#elif defined(PLATFORM_MACOSX)
inline bool library::open(const string& name, const string& path) {
if(handle) close();
handle = (uintptr_t)dlopen(string(path, !path.empty() && !path.endswith("/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);

View File

@@ -11,13 +11,14 @@
namespace nall {
struct image {
uint8_t* data = nullptr;
unsigned width = 0;
uint8_t* data = nullptr;
unsigned width = 0;
unsigned height = 0;
unsigned pitch = 0;
unsigned pitch = 0;
unsigned size = 0;
bool endian = 0;
unsigned depth = 32;
bool endian = 0; //0 = lsb, 1 = msb
unsigned depth = 32;
unsigned stride = 4;
struct Channel {
@@ -34,10 +35,18 @@ struct image {
}
};
Channel alpha = {255u << 24, 8u, 24};
Channel red = {255u << 16, 8u, 16};
Channel green = {255u << 8, 8u, 8};
Channel blue = {255u << 0, 8u, 0};
enum class blend : unsigned {
add,
sourceAlpha, //color = sourceColor * sourceAlpha + targetColor * (1 - sourceAlpha)
sourceColor, //color = sourceColor
targetAlpha, //color = targetColor * targetAlpha + sourceColor * (1 - targetAlpha)
targetColor, //color = targetColor
};
Channel alpha = {255u << 24, 8u, 24u};
Channel red = {255u << 16, 8u, 16u};
Channel green = {255u << 8, 8u, 8u};
Channel blue = {255u << 0, 8u, 0u};
typedef double (*interpolation)(double, double, double, double, double);
static inline unsigned bitDepth(uint64_t color);
@@ -63,18 +72,27 @@ struct image {
inline void free();
inline bool empty() const;
inline void allocate(unsigned width, unsigned height);
inline void clear(uint64_t color);
inline bool crop(unsigned x, unsigned y, unsigned width, unsigned height);
inline void impose(blend mode, unsigned targetX, unsigned targetY, image source, unsigned x, unsigned y, unsigned width, unsigned height);
inline void fill(uint64_t color = 0);
inline void gradient(uint64_t a, uint64_t b, uint64_t c, uint64_t d);
inline void horizontalGradient(uint64_t a, uint64_t b);
inline void verticalGradient(uint64_t a, uint64_t b);
inline bool load(const string& filename);
//inline bool loadBMP(const uint8_t* data, unsigned size);
inline bool loadPNG(const uint8_t* data, unsigned size);
inline void scale(unsigned width, unsigned height, interpolation op);
inline void scale(unsigned width, unsigned height, bool linear = true);
inline void transform(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
inline void alphaBlend(uint64_t alphaColor);
protected:
inline uint64_t interpolate(double mu, const uint64_t* s, interpolation op);
inline void scaleX(unsigned width, interpolation op);
inline void scaleY(unsigned height, interpolation op);
inline uint8_t* allocate(unsigned width, unsigned height, unsigned stride);
alwaysinline uint64_t interpolate1D(int64_t a, int64_t b, uint32_t x);
alwaysinline uint64_t interpolate2D(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y);
inline void scaleLinearWidth(unsigned width);
inline void scaleLinearHeight(unsigned height);
inline void scaleLinear(unsigned width, unsigned height);
inline void scaleNearest(unsigned width, unsigned height);
inline bool loadBMP(const string& filename);
inline bool loadPNG(const string& filename);
};
@@ -131,6 +149,7 @@ image& image::operator=(const image& source) {
width = source.width;
height = source.height;
pitch = source.pitch;
size = source.size;
endian = source.endian;
stride = source.stride;
@@ -140,8 +159,8 @@ image& image::operator=(const image& source) {
green = source.green;
blue = source.blue;
data = new uint8_t[width * height * stride];
memcpy(data, source.data, width * height * stride);
data = allocate(width, height, stride);
memcpy(data, source.data, source.size);
return *this;
}
@@ -151,6 +170,7 @@ image& image::operator=(image&& source) {
width = source.width;
height = source.height;
pitch = source.pitch;
size = source.size;
endian = source.endian;
stride = source.stride;
@@ -175,13 +195,13 @@ image::image(image&& source) {
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) {
this->endian = endian;
this->depth = depth;
this->depth = depth;
this->stride = (depth / 8) + ((depth & 7) > 0);
alpha = {alphaMask, bitDepth(alphaMask), bitShift(alphaMask)};
red = {redMask, bitDepth(redMask), bitShift(redMask)};
red = {redMask, bitDepth(redMask), bitShift(redMask )};
green = {greenMask, bitDepth(greenMask), bitShift(greenMask)};
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask)};
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask )};
}
image::image(const string& filename) {
@@ -231,39 +251,175 @@ bool image::empty() const {
void image::allocate(unsigned width, unsigned height) {
if(data != nullptr && this->width == width && this->height == height) return;
free();
data = new uint8_t[width * height * stride]();
data = allocate(width, height, stride);
pitch = width * stride;
size = height * pitch;
this->width = width;
this->height = height;
}
void image::clear(uint64_t color) {
uint8_t *dp = data;
void image::fill(uint64_t color) {
uint8_t* dp = data;
for(unsigned n = 0; n < width * height; n++) {
write(dp, color);
dp += stride;
}
}
void image::gradient(uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
//create gradient by scaling 2x2 image using linear interpolation
//replace data with gradient data to prevent extra copy
delete[] data;
nall::image gradient;
gradient.endian = endian, gradient.depth = depth, gradient.stride = stride;
gradient.alpha = alpha, gradient.red = red, gradient.green = green, gradient.blue = blue;
gradient.allocate(2, 2);
uint8_t* dp = gradient.data;
gradient.write(dp, a); dp += stride;
gradient.write(dp, b); dp += stride;
gradient.write(dp, c); dp += stride;
gradient.write(dp, d); dp += stride;
gradient.scale(width, height);
data = gradient.data;
gradient.data = nullptr;
}
void image::horizontalGradient(uint64_t a, uint64_t b) {
gradient(a, b, a, b);
}
void image::verticalGradient(uint64_t a, uint64_t b) {
gradient(a, a, b, b);
}
bool image::load(const string& filename) {
if(loadBMP(filename) == true) return true;
if(loadPNG(filename) == true) return true;
return false;
}
void image::scale(unsigned outputWidth, unsigned outputHeight, interpolation op) {
if(width != outputWidth) scaleX(outputWidth, op);
if(height != outputHeight) scaleY(outputHeight, op);
bool image::crop(unsigned outputX, unsigned outputY, unsigned outputWidth, unsigned outputHeight) {
if(outputX + outputWidth > width) return false;
if(outputY + outputHeight > height) return false;
uint8_t* outputData = allocate(outputWidth, outputHeight, stride);
unsigned outputPitch = outputWidth * stride;
#pragma omp parallel for
for(unsigned y = 0; y < outputHeight; y++) {
const uint8_t* sp = data + pitch * (outputY + y) + stride * outputX;
uint8_t* dp = outputData + outputPitch * y;
for(unsigned x = 0; x < outputWidth; x++) {
write(dp, read(sp));
sp += stride;
dp += stride;
}
}
delete[] data;
data = outputData;
width = outputWidth;
height = outputHeight;
pitch = outputPitch;
size = width * pitch;
return true;
}
void image::impose(blend mode, unsigned targetX, unsigned targetY, image source, unsigned sourceX, unsigned sourceY, unsigned sourceWidth, unsigned sourceHeight) {
source.transform(endian, depth, alpha.mask, red.mask, green.mask, blue.mask);
for(unsigned y = 0; y < sourceHeight; y++) {
const uint8_t* sp = source.data + source.pitch * (sourceY + y) + source.stride * sourceX;
uint8_t* dp = data + pitch * (targetY + y) + stride * targetX;
for(unsigned x = 0; x < sourceWidth; x++) {
uint64_t sourceColor = source.read(sp);
uint64_t targetColor = read(dp);
int64_t sa = (sourceColor & alpha.mask) >> alpha.shift;
int64_t sr = (sourceColor & red.mask ) >> red.shift;
int64_t sg = (sourceColor & green.mask) >> green.shift;
int64_t sb = (sourceColor & blue.mask ) >> blue.shift;
int64_t da = (targetColor & alpha.mask) >> alpha.shift;
int64_t dr = (targetColor & red.mask ) >> red.shift;
int64_t dg = (targetColor & green.mask) >> green.shift;
int64_t db = (targetColor & blue.mask ) >> blue.shift;
uint64_t a, r, g, b;
switch(mode) {
case blend::add:
a = max(sa, da);
r = min(red.mask >> red.shift, ((sr * sa) >> alpha.depth) + ((dr * da) >> alpha.depth));
g = min(green.mask >> green.shift, ((sg * sa) >> alpha.depth) + ((dg * da) >> alpha.depth));
b = min(blue.mask >> blue.shift, ((sb * sa) >> alpha.depth) + ((db * da) >> alpha.depth));
break;
case blend::sourceAlpha:
a = max(sa, da);
r = dr + (((sr - dr) * sa) >> alpha.depth);
g = dg + (((sg - dg) * sa) >> alpha.depth);
b = db + (((sb - db) * sa) >> alpha.depth);
break;
case blend::sourceColor:
a = sa;
r = sr;
g = sg;
b = sb;
break;
case blend::targetAlpha:
a = max(sa, da);
r = sr + (((dr - sr) * da) >> alpha.depth);
g = sg + (((dg - sg) * da) >> alpha.depth);
b = sb + (((db - sb) * da) >> alpha.depth);
break;
case blend::targetColor:
a = da;
r = dr;
g = dg;
b = db;
break;
}
write(dp, (a << alpha.shift) | (r << red.shift) | (g << green.shift) | (b << blue.shift));
sp += source.stride;
dp += stride;
}
}
}
void image::scale(unsigned outputWidth, unsigned outputHeight, bool linear) {
if(width == outputWidth && height == outputHeight) return; //no scaling necessary
if(linear == false) return scaleNearest(outputWidth, outputHeight);
if(width == outputWidth ) return scaleLinearHeight(outputHeight);
if(height == outputHeight) return scaleLinearWidth(outputWidth);
//find fastest scaling method, based on number of interpolation operations required
//magnification usually benefits from two-pass linear interpolation
//minification usually benefits from one-pass bilinear interpolation
unsigned d1wh = ((width * outputWidth ) + (outputWidth * outputHeight)) * 1;
unsigned d1hw = ((height * outputHeight) + (outputWidth * outputHeight)) * 1;
unsigned d2wh = (outputWidth * outputHeight) * 3;
if(d1wh <= d1hw && d1wh <= d2wh) return scaleLinearWidth(outputWidth), scaleLinearHeight(outputHeight);
if(d1hw <= d2wh) return scaleLinearHeight(outputHeight), scaleLinearWidth(outputWidth);
return scaleLinear(outputWidth, outputHeight);
}
void image::transform(bool outputEndian, unsigned outputDepth, uint64_t outputAlphaMask, uint64_t outputRedMask, uint64_t outputGreenMask, uint64_t outputBlueMask) {
if(endian == outputEndian && depth == outputDepth && alpha.mask == outputAlphaMask && red.mask == outputRedMask && green.mask == outputGreenMask && blue.mask == outputBlueMask) return;
image output(outputEndian, outputDepth, outputAlphaMask, outputRedMask, outputGreenMask, outputBlueMask);
output.allocate(width, height);
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
const uint8_t* sp = data + pitch * y;
uint8_t* dp = output.data + output.pitch * y;
uint8_t* sp = data + pitch * y;
for(unsigned x = 0; x < width; x++) {
uint64_t color = read(sp);
sp += stride;
@@ -287,9 +443,9 @@ void image::transform(bool outputEndian, unsigned outputDepth, uint64_t outputAl
}
void image::alphaBlend(uint64_t alphaColor) {
uint64_t alphaR = (alphaColor & red.mask) >> red.shift;
uint64_t alphaR = (alphaColor & red.mask ) >> red.shift;
uint64_t alphaG = (alphaColor & green.mask) >> green.shift;
uint64_t alphaB = (alphaColor & blue.mask) >> blue.shift;
uint64_t alphaB = (alphaColor & blue.mask ) >> blue.shift;
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
@@ -298,9 +454,9 @@ void image::alphaBlend(uint64_t alphaColor) {
uint64_t color = read(dp);
uint64_t colorA = (color & alpha.mask) >> alpha.shift;
uint64_t colorR = (color & red.mask) >> red.shift;
uint64_t colorR = (color & red.mask ) >> red.shift;
uint64_t colorG = (color & green.mask) >> green.shift;
uint64_t colorB = (color & blue.mask) >> blue.shift;
uint64_t colorB = (color & blue.mask ) >> blue.shift;
double alphaScale = (double)colorA / (double)((1 << alpha.depth) - 1);
colorA = (1 << alpha.depth) - 1;
@@ -316,99 +472,199 @@ void image::alphaBlend(uint64_t alphaColor) {
//protected
uint64_t image::interpolate(double mu, const uint64_t* s, double (*op)(double, double, double, double, double)) {
uint64_t aa = (s[0] & alpha.mask) >> alpha.shift, ar = (s[0] & red.mask) >> red.shift,
ag = (s[0] & green.mask) >> green.shift, ab = (s[0] & blue.mask) >> blue.shift;
uint64_t ba = (s[1] & alpha.mask) >> alpha.shift, br = (s[1] & red.mask) >> red.shift,
bg = (s[1] & green.mask) >> green.shift, bb = (s[1] & blue.mask) >> blue.shift;
uint64_t ca = (s[2] & alpha.mask) >> alpha.shift, cr = (s[2] & red.mask) >> red.shift,
cg = (s[2] & green.mask) >> green.shift, cb = (s[2] & blue.mask) >> blue.shift;
uint64_t da = (s[3] & alpha.mask) >> alpha.shift, dr = (s[3] & red.mask) >> red.shift,
dg = (s[3] & green.mask) >> green.shift, db = (s[3] & blue.mask) >> blue.shift;
int64_t A = op(mu, aa, ba, ca, da);
int64_t R = op(mu, ar, br, cr, dr);
int64_t G = op(mu, ag, bg, cg, dg);
int64_t B = op(mu, ab, bb, cb, db);
A = max(0, min(A, (1 << alpha.depth) - 1));
R = max(0, min(R, (1 << red.depth) - 1));
G = max(0, min(G, (1 << green.depth) - 1));
B = max(0, min(B, (1 << blue.depth) - 1));
return (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift);
uint8_t* image::allocate(unsigned width, unsigned height, unsigned stride) {
//allocate 1x1 larger than requested; so that linear interpolation does not require bounds-checking
unsigned size = width * height * stride;
unsigned padding = width * stride + stride;
uint8_t* data = new uint8_t[size + padding];
memset(data + size, 0x00, padding);
return data;
}
void image::scaleX(unsigned outputWidth, interpolation op) {
uint8_t* outputData = new uint8_t[outputWidth * height * stride];
//fixed-point reduction of: a * (1 - x) + b * x
uint64_t image::interpolate1D(int64_t a, int64_t b, uint32_t x) {
return a + (((b - a) * x) >> 32); //a + (b - a) * x
}
//fixed-point reduction of: a * (1 - x) * (1 - y) + b * x * (1 - y) + c * (1 - x) * y + d * x * y
uint64_t image::interpolate2D(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y) {
a = a + (((b - a) * x) >> 32); //a + (b - a) * x
c = c + (((d - c) * x) >> 32); //c + (d - c) * x
return a + (((c - a) * y) >> 32); //a + (c - a) * y
}
void image::scaleLinearWidth(unsigned outputWidth) {
uint8_t* outputData = allocate(outputWidth, height, stride);
unsigned outputPitch = outputWidth * stride;
double step = (double)width / (double)outputWidth;
const uint8_t* terminal = data + pitch * height;
uint64_t xstride = ((uint64_t)(width - 1) << 32) / max(1u, outputWidth - 1);
#pragma omp parallel for
for(unsigned y = 0; y < height; y++) {
uint64_t xfraction = 0;
const uint8_t* sp = data + pitch * y;
uint8_t* dp = outputData + outputPitch * y;
uint8_t* sp = data + pitch * y;
double fraction = 0.0;
uint64_t s[4] = {sp < terminal ? read(sp) : 0}; //B,C (0,1) = center of kernel { 0, 0, 1, 2 }
s[1] = s[0];
s[2] = sp + stride < terminal ? read(sp += stride) : s[1];
s[3] = sp + stride < terminal ? read(sp += stride) : s[2];
uint64_t a = read(sp);
uint64_t b = read(sp + stride);
sp += stride;
for(unsigned x = 0; x < width; x++) {
while(fraction <= 1.0) {
if(dp >= outputData + outputPitch * height) break;
write(dp, interpolate(fraction, (const uint64_t*)&s, op));
unsigned x = 0;
while(x < outputWidth) {
while(xfraction < 0x100000000 && x++ < outputWidth) {
uint64_t A = interpolate1D((a & alpha.mask) >> alpha.shift, (b & alpha.mask) >> alpha.shift, xfraction);
uint64_t R = interpolate1D((a & red.mask ) >> red.shift , (b & red.mask ) >> red.shift, xfraction);
uint64_t G = interpolate1D((a & green.mask) >> green.shift, (b & green.mask) >> green.shift, xfraction);
uint64_t B = interpolate1D((a & blue.mask ) >> blue.shift , (b & blue.mask ) >> blue.shift, xfraction);
write(dp, (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift));
dp += stride;
fraction += step;
xfraction += xstride;
}
s[0] = s[1]; s[1] = s[2]; s[2] = s[3];
if(sp + stride < terminal) s[3] = read(sp += stride);
fraction -= 1.0;
sp += stride;
a = b;
b = read(sp);
xfraction -= 0x100000000;
}
}
free();
data = outputData;
width = outputWidth;
pitch = width * stride;
pitch = outputPitch;
size = height * pitch;
}
void image::scaleY(unsigned outputHeight, interpolation op) {
uint8_t* outputData = new uint8_t[width * outputHeight * stride];
double step = (double)height / (double)outputHeight;
const uint8_t* terminal = data + pitch * height;
void image::scaleLinearHeight(unsigned outputHeight) {
uint8_t* outputData = allocate(width, outputHeight, stride);
uint64_t ystride = ((uint64_t)(height - 1) << 32) / max(1u, outputHeight - 1);
#pragma omp parallel for
for(unsigned x = 0; x < width; x++) {
uint64_t yfraction = 0;
const uint8_t* sp = data + stride * x;
uint8_t* dp = outputData + stride * x;
uint8_t* sp = data + stride * x;
double fraction = 0.0;
uint64_t s[4] = {sp < terminal ? read(sp) : 0};
s[1] = s[0];
s[2] = sp + pitch < terminal ? read(sp += pitch) : s[1];
s[3] = sp + pitch < terminal ? read(sp += pitch) : s[2];
uint64_t a = read(sp);
uint64_t b = read(sp + pitch);
sp += pitch;
for(unsigned y = 0; y < height; y++) {
while(fraction <= 1.0) {
if(dp >= outputData + pitch * outputHeight) break;
write(dp, interpolate(fraction, (const uint64_t*)&s, op));
unsigned y = 0;
while(y < outputHeight) {
while(yfraction < 0x100000000 && y++ < outputHeight) {
uint64_t A = interpolate1D((a & alpha.mask) >> alpha.shift, (b & alpha.mask) >> alpha.shift, yfraction);
uint64_t R = interpolate1D((a & red.mask ) >> red.shift, (b & red.mask ) >> red.shift, yfraction);
uint64_t G = interpolate1D((a & green.mask) >> green.shift, (b & green.mask) >> green.shift, yfraction);
uint64_t B = interpolate1D((a & blue.mask ) >> blue.shift, (b & blue.mask ) >> blue.shift, yfraction);
write(dp, (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift));
dp += pitch;
fraction += step;
yfraction += ystride;
}
s[0] = s[1]; s[1] = s[2]; s[2] = s[3];
if(sp + pitch < terminal) s[3] = read(sp += pitch);
fraction -= 1.0;
sp += pitch;
a = b;
b = read(sp);
yfraction -= 0x100000000;
}
}
free();
data = outputData;
height = outputHeight;
size = height * pitch;
}
void image::scaleLinear(unsigned outputWidth, unsigned outputHeight) {
uint8_t* outputData = allocate(outputWidth, outputHeight, stride);
unsigned outputPitch = outputWidth * stride;
uint64_t xstride = ((uint64_t)(width - 1) << 32) / max(1u, outputWidth - 1);
uint64_t ystride = ((uint64_t)(height - 1) << 32) / max(1u, outputHeight - 1);
#pragma omp parallel for
for(unsigned y = 0; y < outputHeight; y++) {
uint64_t yfraction = ystride * y;
uint64_t xfraction = 0;
const uint8_t* sp = data + pitch * (yfraction >> 32);
uint8_t* dp = outputData + outputPitch * y;
uint64_t a = read(sp);
uint64_t b = read(sp + stride);
uint64_t c = read(sp + pitch);
uint64_t d = read(sp + pitch + stride);
sp += stride;
unsigned x = 0;
while(x < outputWidth) {
while(xfraction < 0x100000000 && x++ < outputWidth) {
uint64_t A = interpolate2D((a & alpha.mask) >> alpha.shift, (b & alpha.mask) >> alpha.shift, (c & alpha.mask) >> alpha.shift, (d & alpha.mask) >> alpha.shift, xfraction, yfraction);
uint64_t R = interpolate2D((a & red.mask ) >> red.shift, (b & red.mask ) >> red.shift, (c & red.mask ) >> red.shift, (d & red.mask ) >> red.shift, xfraction, yfraction);
uint64_t G = interpolate2D((a & green.mask) >> green.shift, (b & green.mask) >> green.shift, (c & green.mask) >> green.shift, (d & green.mask) >> green.shift, xfraction, yfraction);
uint64_t B = interpolate2D((a & blue.mask ) >> blue.shift, (b & blue.mask ) >> blue.shift, (c & blue.mask ) >> blue.shift, (d & blue.mask ) >> blue.shift, xfraction, yfraction);
write(dp, (A << alpha.shift) | (R << red.shift) | (G << green.shift) | (B << blue.shift));
dp += stride;
xfraction += xstride;
}
sp += stride;
a = b;
c = d;
b = read(sp);
d = read(sp + pitch);
xfraction -= 0x100000000;
}
}
free();
data = outputData;
width = outputWidth;
height = outputHeight;
pitch = outputPitch;
size = height * pitch;
}
void image::scaleNearest(unsigned outputWidth, unsigned outputHeight) {
uint8_t* outputData = allocate(outputWidth, outputHeight, stride);
unsigned outputPitch = outputWidth * stride;
uint64_t xstride = ((uint64_t)width << 32) / outputWidth;
uint64_t ystride = ((uint64_t)height << 32) / outputHeight;
#pragma omp parallel for
for(unsigned y = 0; y < outputHeight; y++) {
uint64_t yfraction = ystride * y;
uint64_t xfraction = 0;
const uint8_t* sp = data + pitch * (yfraction >> 32);
uint8_t* dp = outputData + outputPitch * y;
uint64_t a = read(sp);
unsigned x = 0;
while(x < outputWidth) {
while(xfraction < 0x100000000 && x++ < outputWidth) {
write(dp, a);
dp += stride;
xfraction += xstride;
}
sp += stride;
a = read(sp);
xfraction -= 0x100000000;
}
}
free();
data = outputData;
width = outputWidth;
height = outputHeight;
pitch = outputPitch;
size = height * pitch;
}
bool image::loadBMP(const string& filename) {

View File

@@ -21,6 +21,7 @@ namespace Math {
#include <utility>
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>

View File

@@ -5,7 +5,7 @@
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#if !defined(PLATFORM_X) && !defined(PLATFORM_OSX)
#if !defined(PLATFORM_X) && !defined(PLATFORM_MACOSX)
#error "nall/serial: unsupported platform"
#endif

View File

@@ -49,7 +49,7 @@ string configpath() {
SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#elif defined(PLATFORM_OSX)
#elif defined(PLATFORM_MACOSX)
result = {userpath(), "Library/Application Support/"};
#else
result = {userpath(), ".config/"};
@@ -66,7 +66,7 @@ string sharedpath() {
SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, nullptr, 0, path);
result = (const char*)utf8_t(path);
result.transform("\\", "/");
#elif defined(PLATFORM_OSX)
#elif defined(PLATFORM_MACOSX)
result = "/Library/Application Support/";
#else
result = "/usr/share/";

View File

@@ -5,7 +5,7 @@
#include <nall/function.hpp>
#include <nall/intrinsics.hpp>
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
#if defined(PLATFORM_X) || defined(PLATFORM_MACOSX)
#include <pthread.h>
namespace nall {
@@ -64,7 +64,7 @@ void* thread_entry_point(void* parameter) {
}
}
#elif defined(PLATFORM_WIN)
#elif defined(PLATFORM_WINDOWS)
namespace nall {
inline DWORD WINAPI thread_entry_point(LPVOID);