#include "BImage.h"
#include <malloc.h>
unsigned long *sqrt_table = NULL;
BImage::BImage()
{
}
BImage::~BImage()
{
if (sqrt_table) delete sqrt_table;
}
void BImage::CreateGradientByRect(HDC hdc, RECT rect, int type, COLORREF colour1, COLORREF colour2, bool bInterlaced, int bevelStyle, int bevelPosition, int bevelWidth)
{
CreateBuffer(hdc, rect, colour1, colour2);
PaintGradient(type, bInterlaced, bevelStyle, bevelPosition, bevelWidth);
BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
DestroyBuffer();
}
void BImage::CreateBorder(HDC hdc, RECT rect, COLORREF borderColour, int borderWidth)
{
HPEN borderPen = CreatePen(PS_SOLID, 1, borderColour);
HPEN oldPen = (HPEN) SelectObject(hdc, borderPen);
for (int i = 0; i < borderWidth; i++)
{
int right = rect.right - i - 1;
int bottom = rect.bottom - i - 1;
MoveToEx(hdc, rect.left + i, rect.top + i, NULL);
LineTo(hdc, right, rect.top + i);
LineTo(hdc, right, bottom);
LineTo(hdc, rect.left + i, bottom);
LineTo(hdc, rect.left + i, rect.top + i);
}
SelectObject(hdc, oldPen);
DeleteObject(borderPen);
}
void BImage::CreateBuffer(HDC hdc, RECT rect, COLORREF colour1, COLORREF colour2)
{
width = rect.right - rect.left;
height = rect.bottom - rect.top;
buf = CreateCompatibleDC(NULL);
BITMAPINFOHEADER bv4info;
bv4info.biSize = sizeof(BITMAPINFOHEADER);
bv4info.biWidth = width;
bv4info.biHeight = height;
bv4info.biPlanes = 1;
bv4info.biBitCount = 32;
bv4info.biCompression = BI_RGB;
BITMAPINFO bminfo;
bminfo.bmiHeader = bv4info;
bufbmp = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS,(PVOID *) &pixels, NULL, 0);
oldbuf = (HBITMAP)SelectObject(buf, bufbmp);
from_red = GetRValue(colour1);
from_green = GetGValue(colour1);
from_blue = GetBValue(colour1);
to_red = GetRValue(colour2);
to_green = GetGValue(colour2);
to_blue = GetBValue(colour2);
xtable = new unsigned int[width * 3];
ytable = new unsigned int[height * 3];
}
void BImage::DestroyBuffer()
{
SelectObject(buf, oldbuf);
DeleteDC(buf);
DeleteObject(bufbmp);
DeleteObject(oldbuf);
if (xtable) delete [] xtable;
if (ytable) delete [] ytable;
}
void BImage::PaintGradient(int type, bool bInterlaced, int bevelStyle, int bevelPosition, int bevelWidth)
{
sunken = false;
interlaced = bInterlaced;
if (bevelStyle == BEVEL_SUNKEN)
{
if (type == B_PIPECROSS || type == B_ELLIPTIC || type == B_RECTANGLE || type == B_PYRAMID)
{
BYTE tempcolor;
tempcolor = from_red;
from_red = to_red;
to_red = tempcolor;
tempcolor = from_green;
from_green = to_green;
to_green = tempcolor;
tempcolor = from_blue;
from_blue = to_blue;
to_blue = tempcolor;
}
sunken = true;
}
if (type == B_SOLID)
{
to_red = from_red;
to_green = from_green;
to_blue = from_blue;
vgradient();
}
else if (type == B_VERTICAL) vgradient();
else if (type == B_DIAGONAL) dgradient();
else if (type == B_CROSSDIAGONAL) cdgradient();
else if (type == B_PIPECROSS) pcgradient();
else if (type == B_ELLIPTIC) egradient();
else if (type == B_RECTANGLE) rgradient();
else if (type == B_PYRAMID) pgradient();
else hgradient();
if (bevelStyle != BEVEL_FLAT)
{
if (bevelPosition == BEVEL1) bevel1(sunken);
else if (bevelPosition == BEVEL2) bevel2(sunken);
}
}
template <typename T> inline T lmax(T a, T b) { return ((a > b) ? a : b); }
template <typename T> inline T lmin(T a, T b) { return ((a < b) ? a : b); }
void BImage::bevel1(bool sunken)
{
if (width > 2 && height > 2)
{
unsigned int count, x, y;
unsigned int w = ((width * 4) - 4), h = (width * (height-1) * 4);
unsigned int nextpixel = 4, nextline = (width * 4);
count = 0;
for (x = 0; x < width; x++)
{
if (!sunken)
{
lightenpixel(count+h);
if (x) darkenpixel(count);
}
else
{
darkenpixel(count+h);
if (x) lightenpixel(count);
}
count += nextpixel;
}
count = 0;
for (y = 0; y < (height-1); y++)
{
if (!sunken)
{
lightenpixel(count);
if (y) darkenpixel(count+w);
}
else
{
darkenpixel(count);
if (y) lightenpixel(count+w);
}
count += nextline;
}
}
}
void BImage::bevel2(bool sunken)
{
if (width > 4 && height > 4)
{
unsigned int count, x, y, w = ((width * 4) - 12), h = (width * (height-3) * 4);
unsigned int nextpixel = 4, nextline = (width * 4);
count = nextline + nextpixel;
for (x = 0; x < (width-2); x++)
{
if (!sunken)
{
lightenpixel(count+h);
if (x) darkenpixel(count);
}
else
{
darkenpixel(count+h);
if (x) lightenpixel(count);
}
count += nextpixel;
}
count = nextline + nextpixel;
for (y = 0; y < (height-3); y++)
{
if (!sunken)
{
lightenpixel(count);
if (y) darkenpixel(count+w);
}
else
{
darkenpixel(count);
if (y) lightenpixel(count+w);
}
count += nextline;
}
}
}
void BImage::lightenpixel(unsigned int count)
{
r = pixels[count + 2];
rr = r + (r >> 1);
if (rr < r) rr = ~0;
g = pixels[count + 1];
gg = g + (g >> 1);
if (gg < g) gg = ~0;
b = pixels[count];
bb = b + (b >> 1);
if (bb < b) bb = ~0;
pixels[count + 2] = rr;
pixels[count + 1] = gg;
pixels[count] = bb;
}
void BImage::darkenpixel(unsigned int count)
{
r = pixels[count + 2];
rr = (r >> 2) + (r >> 1);
if (rr > r) rr = 0;
g = pixels[count + 1];
gg = (g >> 2) + (g >> 1);
if (gg > g) gg = 0;
b = pixels[count];
bb = (b >> 2) + (b >> 1);
if (bb > b) bb = 0;
pixels[count + 2] = rr;
pixels[count + 1] = gg;
pixels[count] = bb;
}
void BImage::dgradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
xr = (float) from_red,
xg = (float) from_green,
xb = (float) from_blue;
UINT w = width * 2, h = height * 2, *xt = xtable, *yt = ytable, x, y, count = 0;
dry = drx = (float) (to_red - from_red);
dgy = dgx = (float) (to_green - from_green);
dby = dbx = (float) (to_blue - from_blue);
drx /= w;
dgx /= w;
dbx /= w;
for (x = 0; x < width; x++)
{
*(xt++) = (unsigned char) (xr);
*(xt++) = (unsigned char) (xg);
*(xt++) = (unsigned char) (xb);
xr += drx;
xg += dgx;
xb += dbx;
}
dry /= h;
dgy /= h;
dby /= h;
for (yt = (ytable + (height * 3) - 1), y = 0; y < height; y++)
{
*(yt--) = ((unsigned char) yb);
*(yt--) = ((unsigned char) yg);
*(yt--) = ((unsigned char) yr);
yr += dry;
yg += dgy;
yb += dby;
}
if (!interlaced)
{
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
pixels[count + 2] = *(xt++) + *(yt);
pixels[count + 1] = *(xt++) + *(yt + 1);
pixels[count] = *(xt++) + *(yt + 2);
count += 4;
}
}
}
else
{
unsigned char channel, channel2;
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
if (y & 1)
{
channel = *(xt++) + *(yt);
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = *(xt++) + *(yt + 1);
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = *(xt++) + *(yt + 2);
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = *(xt++) + *(yt);
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = *(xt++) + *(yt + 1);
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = *(xt++) + *(yt + 2);
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
}
}
}
void BImage::hgradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float drx, dgx, dbx,
xr = (float) from_red,
xg = (float) from_green,
xb = (float) from_blue;
UINT x, y, count = 0, original = 0;
drx = (float) (to_red - from_red);
dgx = (float) (to_green - from_green);
dbx = (float) (to_blue - from_blue);
drx /= width;
dgx /= width;
dbx /= width;
if (interlaced && height > 2)
{
unsigned char channel, channel2;
for (x = 0; x < width; x++)
{
channel = (unsigned char) xr;
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = (unsigned char) xg;
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = (unsigned char) xb;
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
channel = (unsigned char) xr;
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2 + (width * 4)] = channel2;
channel = (unsigned char) xg;
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1 + (width * 4)] = channel2;
channel = (unsigned char) xb;
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + (width * 4)] = channel2;
xr += drx;
xg += dgx;
xb += dbx;
count += 4;
}
count += (width * 4);
int offset;
for (y = 2; y < height; y++)
{
if (y & 1) offset = (width * 4);
else offset = 0;
original = 0;
for (x =0; x < width; x++)
{
pixels[count + 2] = pixels[original + 2 + offset];
pixels[count + 1] = pixels[original + 1 + offset];
pixels[count] = pixels[original + offset];
count += 4;
original += 4;
}
}
}
else
{
for (x = 0; x < width; x++)
{
pixels[count + 2] = (unsigned char) (xr);
pixels[count + 1] = (unsigned char) (xg);
pixels[count] = (unsigned char) (xb);
xr += drx;
xg += dgx;
xb += dbx;
count += 4;
}
for (y = 1; y < height; y++)
{
original = 0;
for (x =0; x < width; x++)
{
pixels[count + 2] = pixels[original + 2];
pixels[count + 1] = pixels[original + 1];
pixels[count] = pixels[original];
count += 4;
original += 4;
}
}
}
}
void BImage::vgradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float dry, dgy, dby,
yr = (float) to_red,
yg = (float) to_green,
yb = (float) to_blue;
UINT x, y, count = 0;
dry = (float) (from_red - to_red);
dgy = (float) (from_green - to_green);
dby = (float) (from_blue - to_blue);
dry /= height;
dgy /= height;
dby /= height;
if (interlaced)
{
unsigned char channel, channel2;
for (y = 0; y < height; y++)
{
for (x =0; x < width; x++)
{
if (y & 1)
{
channel = (unsigned char) yr;
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = (unsigned char) yg;
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = (unsigned char) yb;
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = (unsigned char) yr;
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = (unsigned char) yg;
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = (unsigned char) yb;
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
yr += dry;
yg += dgy;
yb += dby;
}
}
else
{
for (y =0; y < height ; y++)
{
for (x =0; x < width; x++)
{
pixels[count + 2] = (unsigned char) yr;
pixels[count + 1] = (unsigned char) yg;
pixels[count] = (unsigned char) yb;
count += 4;
}
yr += dry;
yg += dgy;
yb += dby;
}
}
}
void BImage::pgradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float yr, yg, yb, drx, dgx, dbx, dry, dgy, dby, xr, xg, xb;
int rsign, gsign, bsign;
UINT tr = to_red, tg = to_green, tb = to_blue, *xt = xtable, *yt = ytable, x, y, count = 0;
dry = drx = (float) (to_red - from_red);
dgy = dgx = (float) (to_green - from_green);
dby = dbx = (float) (to_blue - from_blue);
rsign = (drx < 0) ? -1 : 1;
gsign = (dgx < 0) ? -1 : 1;
bsign = (dbx < 0) ? -1 : 1;
xr = yr = (drx / 2);
xg = yg = (dgx / 2);
xb = yb = (dbx / 2);
drx /= width;
dgx /= width;
dbx /= width;
for (x = 0; x < width; x++)
{
*(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
*(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
*(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
xr -= drx;
xg -= dgx;
xb -= dbx;
}
dry /= height;
dgy /= height;
dby /= height;
for (y = 0; y < height; y++)
{
*(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
*(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
*(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
yr -= dry;
yg -= dgy;
yb -= dby;
}
if (!interlaced)
{
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
pixels[count + 2] = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
pixels[count + 1] = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
pixels[count] = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
count += 4;
}
}
}
else
{
unsigned char channel, channel2;
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
if (y & 1)
{
channel = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
}
}
}
void BImage::rgradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
int rsign, gsign, bsign;
unsigned int tr = to_red, tg = to_green, tb = to_blue, *xt = xtable, *yt = ytable;
UINT x, y, count = 0;
dry = drx = (float) (to_red - from_red);
dgy = dgx = (float) (to_green - from_green);
dby = dbx = (float) (to_blue - from_blue);
rsign = (drx < 0) ? -2 : 2;
gsign = (dgx < 0) ? -2 : 2;
bsign = (dbx < 0) ? -2 : 2;
xr = yr = (drx / 2);
xg = yg = (dgx / 2);
xb = yb = (dbx / 2);
drx /= width;
dgx /= width;
dbx /= width;
for (x = 0; x < width; x++)
{
*(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
*(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
*(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
xr -= drx;
xg -= dgx;
xb -= dbx;
}
dry /= height;
dgy /= height;
dby /= height;
for (y = 0; y < height; y++)
{
*(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
*(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
*(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
yr -= dry;
yg -= dgy;
yb -= dby;
}
if (!interlaced)
{
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
pixels[count + 2] = (unsigned char) (tr - (rsign * lmax(*(xt++), *(yt))));
pixels[count + 1] = (unsigned char) (tg - (gsign * lmax(*(xt++), *(yt + 1))));
pixels[count] = (unsigned char) (tb - (bsign * lmax(*(xt++), *(yt + 2))));
count += 4;
}
}
}
else
{
unsigned char channel, channel2;
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
if (y & 1)
{
channel = (unsigned char) (tr - (rsign * lmax(*(xt++), *(yt))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = (unsigned char) (tg - (gsign * lmax(*(xt++), *(yt + 1))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = (unsigned char) (tb - (bsign * lmax(*(xt++), *(yt + 2))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = (unsigned char) (tr - (rsign * lmax(*(xt++), *(yt))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = (unsigned char) (tg - (gsign * lmax(*(xt++), *(yt + 1))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = (unsigned char) (tb - (bsign * lmax(*(xt++), *(yt + 2))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
}
}
}
void BImage::egradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float drx, dgx, dbx, dry, dgy, dby, yr, yg, yb, xr, xg, xb;
int rsign, gsign, bsign;
unsigned int *xt = xtable, *yt = ytable,
tr = (unsigned long) to_red,
tg = (unsigned long) to_green,
tb = (unsigned long) to_blue;
UINT x, y, count = 0;
dry = drx = (float) (to_red - from_red);
dgy = dgx = (float) (to_green - from_green);
dby = dbx = (float) (to_blue - from_blue);
rsign = (drx < 0) ? -1 : 1;
gsign = (dgx < 0) ? -1 : 1;
bsign = (dbx < 0) ? -1 : 1;
xr = yr = (drx / 2);
xg = yg = (dgx / 2);
xb = yb = (dbx / 2);
drx /= width;
dgx /= width;
dbx /= width;
for (x = 0; x < width; x++)
{
*(xt++) = (unsigned long) (xr * xr);
*(xt++) = (unsigned long) (xg * xg);
*(xt++) = (unsigned long) (xb * xb);
xr -= drx;
xg -= dgx;
xb -= dbx;
}
dry /= height;
dgy /= height;
dby /= height;
for (y = 0; y < height; y++)
{
*(yt++) = (unsigned long) (yr * yr);
*(yt++) = (unsigned long) (yg * yg);
*(yt++) = (unsigned long) (yb * yb);
yr -= dry;
yg -= dgy;
yb -= dby;
}
if (!interlaced)
{
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
pixels[count + 2] = (unsigned char)
(tr - (rsign * getSqrt(*(xt++) + *(yt))));
pixels[count + 1] = (unsigned char)
(tg - (gsign * getSqrt(*(xt++) + *(yt + 1))));
pixels[count] = (unsigned char)
(tb - (bsign * getSqrt(*(xt++) + *(yt + 2))));
count += 4;
}
}
}
else
{
unsigned char channel, channel2;
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
if (y & 1)
{
channel = (unsigned char)
(tr - (rsign * getSqrt(*(xt++) + *(yt))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = (unsigned char)
(tg - (gsign * getSqrt(*(xt++) + *(yt + 1))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = (unsigned char)
(tb - (bsign * getSqrt(*(xt++) + *(yt + 2))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = (unsigned char)
(tr - (rsign * getSqrt(*(xt++) + *(yt))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = (unsigned char)
(tg - (gsign * getSqrt(*(xt++) + *(yt + 1))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = (unsigned char)
(tb - (bsign * getSqrt(*(xt++) + *(yt + 2))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
}
}
}
void BImage::pcgradient(void)
{
if(!(height > 4) || !(width > 4))
return;
float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
int rsign, gsign, bsign;
unsigned int *xt = xtable, *yt = ytable, tr = to_red, tg = to_green, tb = to_blue;
UINT x, y, count = 0;
dry = drx = (float) (to_red - from_red);
dgy = dgx = (float) (to_green - from_green);
dby = dbx = (float) (to_blue - from_blue);
rsign = (drx < 0) ? -2 : 2;
gsign = (dgx < 0) ? -2 : 2;
bsign = (dbx < 0) ? -2 : 2;
xr = yr = (drx / 2);
xg = yg = (dgx / 2);
xb = yb = (dbx / 2);
drx /= width;
dgx /= width;
dbx /= width;
for (x = 0; x < width; x++)
{
*(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
*(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
*(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
xr -= drx;
xg -= dgx;
xb -= dbx;
}
dry /= height;
dgy /= height;
dby /= height;
for (y = 0; y < height; y++)
{
*(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
*(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
*(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
yr -= dry;
yg -= dgy;
yb -= dby;
}
if (!interlaced)
{
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
pixels[count + 2] = (unsigned char) (tr - (rsign * lmin(*(xt++), *(yt))));
pixels[count + 1] = (unsigned char) (tg - (gsign * lmin(*(xt++), *(yt + 1))));
pixels[count] = (unsigned char) (tb - (bsign * lmin(*(xt++), *(yt + 2))));
count += 4;
}
}
}
else
{
unsigned char channel, channel2;
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
if (y & 1)
{
channel = (unsigned char) (tr - (rsign * lmin(*(xt++), *(yt))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = (unsigned char) (tg - (bsign * lmin(*(xt++), *(yt + 1))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = (unsigned char) (tb - (gsign * lmin(*(xt++), *(yt + 2))));
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = (unsigned char) (tr - (rsign * lmin(*(xt++), *(yt))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = (unsigned char) (tg - (gsign * lmin(*(xt++), *(yt + 1))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = (unsigned char) (tb - (bsign * lmin(*(xt++), *(yt + 2))));
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
}
}
}
void BImage::cdgradient(void)
{
if (!(height > 2) || !(width > 2))
return;
float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
xr = (float) from_red,
xg = (float) from_green,
xb = (float) from_blue;
UINT w = width * 2, h = height * 2, *xt, *yt, x, y, count = 0;
dry = drx = (float) (to_red - from_red);
dgy = dgx = (float) (to_green - from_green);
dby = dbx = (float) (to_blue - from_blue);
drx /= w;
dgx /= w;
dbx /= w;
for (xt = (xtable + (width * 3) - 1), x = 0; x < width; x++)
{
*(xt--) = (unsigned char) xb;
*(xt--) = (unsigned char) xg;
*(xt--) = (unsigned char) xr;
xr += drx;
xg += dgx;
xb += dbx;
}
dry /= h;
dgy /= h;
dby /= h;
for (yt = (ytable + (height * 3) - 1), y = 0; y < height; y++)
{
*(yt--) = ((unsigned char) yb);
*(yt--) = ((unsigned char) yg);
*(yt--) = ((unsigned char) yr);
yr += dry;
yg += dgy;
yb += dby;
}
if (!interlaced)
{
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
pixels[count + 2] = *(xt++) + *(yt);
pixels[count + 1] = *(xt++) + *(yt + 1);
pixels[count] = *(xt++) + *(yt + 2);
count += 4;
}
}
}
else
{
unsigned char channel, channel2;
for (yt = ytable, y = 0; y < height; y++, yt += 3)
{
for (xt = xtable, x = 0; x < width; x++)
{
if (y & 1)
{
channel = *(xt++) + *(yt);
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 2] = channel2;
channel = *(xt++) + *(yt + 1);
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count + 1] = channel2;
channel = *(xt++) + *(yt + 2);
channel2 = (channel >> 1) + (channel >> 2);
if (channel2 > channel) channel2 = 0;
pixels[count] = channel2;
}
else
{
channel = *(xt++) + *(yt);
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 2] = channel2;
channel = *(xt++) + *(yt + 1);
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count + 1] = channel2;
channel = *(xt++) + *(yt + 2);
channel2 = channel + (channel >> 3);
if (channel2 < channel) channel2 = ~0;
pixels[count] = channel2;
}
count += 4;
}
}
}
}
static unsigned long bsqrt(unsigned long x)
{
if (x <= 0) return 0;
if (x == 1) return 1;
unsigned long r = x >> 1;
unsigned long q;
while (1)
{
q = x / r;
if (q >= r) return r;
r = (r + q) >> 1;
}
}
unsigned long getSqrt(unsigned int x)
{
if (!sqrt_table)
{
sqrt_table = new unsigned long[(256 * 256 * 2) + 1];
for (int i = 0; i < (256 * 256 * 2); i++)
*(sqrt_table + i) = bsqrt(i);
}
return (*(sqrt_table + x));
}
syntax highlighting by