mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 03:55:46 -04:00
Initial community commit
This commit is contained in:
452
Src/Plugins/Input/in_mp3/graphics/filterWater.cpp
Normal file
452
Src/Plugins/Input/in_mp3/graphics/filterWater.cpp
Normal file
@ -0,0 +1,452 @@
|
||||
#include ".\filterwater.h"
|
||||
#include <math.h>
|
||||
|
||||
#define random( min, max ) (( rand() % (int)((( max ) + 1 ) - ( min ))) + ( min ))
|
||||
|
||||
MLImageFilterWater::MLImageFilterWater(void)
|
||||
{
|
||||
hField1 = NULL;
|
||||
hField2 = NULL;
|
||||
hHandle = NULL;
|
||||
|
||||
width = 0;
|
||||
height = 0;
|
||||
|
||||
drawWithLight = TRUE;
|
||||
lightModifier = 1;
|
||||
hPage = 0;
|
||||
density = 5;
|
||||
|
||||
}
|
||||
|
||||
MLImageFilterWater::~MLImageFilterWater(void)
|
||||
{
|
||||
ClearData();
|
||||
}
|
||||
|
||||
void MLImageFilterWater::ClearData(void)
|
||||
{
|
||||
if (hHandle)
|
||||
{
|
||||
if (hField1) HeapFree(hHandle, NULL, hField1);
|
||||
if (hField2) HeapFree(hHandle, NULL, hField2);
|
||||
HeapDestroy(hHandle);
|
||||
hField1 = NULL;
|
||||
hField2 = NULL;
|
||||
hHandle = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL MLImageFilterWater::CreateFor(const MLImage *image)
|
||||
{
|
||||
ClearData();
|
||||
width = image->GetWidth();
|
||||
height = image->GetHeight();
|
||||
hPage = 0;
|
||||
int len = height * width * sizeof(int);
|
||||
hHandle = HeapCreate(NULL, 3*len, 3*len);
|
||||
if (!hHandle)
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hField1 = (int*)HeapAlloc(hHandle, HEAP_ZERO_MEMORY, len);
|
||||
hField2 = (int*)HeapAlloc(hHandle, HEAP_ZERO_MEMORY, len);
|
||||
return hField1 && hField2;
|
||||
}
|
||||
|
||||
void MLImageFilterWater::Render(MLImage* destination, const MLImage* source)
|
||||
{
|
||||
if(!drawWithLight) DrawWaterNoLight(hPage, destination, source);
|
||||
else DrawWaterWithLight(destination, source);
|
||||
CalculateWater(hPage, density);
|
||||
// CalcWaterBigFilter(hPage, density);
|
||||
hPage ^= 1;
|
||||
}
|
||||
|
||||
void MLImageFilterWater::CalculateWater(int page, int density)
|
||||
{
|
||||
int newh;
|
||||
int count = width + 1;
|
||||
int *newptr;
|
||||
int *oldptr;
|
||||
|
||||
if(page == 0)
|
||||
{
|
||||
newptr = hField1;
|
||||
oldptr = hField2;
|
||||
}
|
||||
else
|
||||
{
|
||||
newptr = hField2;
|
||||
oldptr = hField1;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
for (y = (height - 1) * width; count < y; count += 2)
|
||||
{
|
||||
for (x = count + width - 2; count < x; count++)
|
||||
{
|
||||
// This does the eight-pixel method.
|
||||
|
||||
newh = ((oldptr[count + width]
|
||||
+ oldptr[count - width]
|
||||
+ oldptr[count + 1]
|
||||
+ oldptr[count - 1]
|
||||
+ oldptr[count - width - 1]
|
||||
+ oldptr[count - width + 1]
|
||||
+ oldptr[count + width - 1]
|
||||
+ oldptr[count + width + 1]
|
||||
) >> 2 )
|
||||
- newptr[count];
|
||||
newptr[count] = newh - (newh >> density);
|
||||
/*
|
||||
// This is the "sludge" method...
|
||||
newh = (oldptr[count]<<2)
|
||||
+ oldptr[count-1-m_iWidth]
|
||||
+ oldptr[count+1-m_iWidth]
|
||||
+ oldptr[count-1+m_iWidth]
|
||||
+ oldptr[count+1+m_iWidth]
|
||||
+ ((oldptr[count-1]
|
||||
+ oldptr[count+1]
|
||||
+ oldptr[count-m_iWidth]
|
||||
+ oldptr[count+m_iWidth])<<1);
|
||||
|
||||
newptr[count] = (newh-(newh>>6)) >> density;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilterWater::SmoothWater(int page)
|
||||
{
|
||||
int newh;
|
||||
int count = width + 1;
|
||||
|
||||
int *newptr;
|
||||
int *oldptr;
|
||||
|
||||
if(page == 0)
|
||||
{
|
||||
newptr = hField1;
|
||||
oldptr = hField2;
|
||||
}
|
||||
else
|
||||
{
|
||||
newptr = hField2;
|
||||
oldptr = hField1;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
|
||||
for(y = 1; y < height; y++, count += 2)
|
||||
{
|
||||
for( x = 1; x < width; x++, count++)
|
||||
{
|
||||
// This does the eight-pixel method.
|
||||
|
||||
newh = ((oldptr[count + width]
|
||||
+ oldptr[count - width]
|
||||
+ oldptr[count + 1]
|
||||
+ oldptr[count - 1]
|
||||
+ oldptr[count - width - 1]
|
||||
+ oldptr[count - width + 1]
|
||||
+ oldptr[count + width - 1]
|
||||
+ oldptr[count + width + 1]
|
||||
) >> 3 )
|
||||
+ newptr[count];
|
||||
newptr[count] = newh>>1;
|
||||
}
|
||||
}
|
||||
}
|
||||
void MLImageFilterWater::FlattenWater(void)
|
||||
{
|
||||
int len = width * height * sizeof(int);
|
||||
SecureZeroMemory(hField1, len);
|
||||
SecureZeroMemory(hField2, len);
|
||||
}
|
||||
void MLImageFilterWater::SineBlob(int x, int y, int radius, int height, int page)
|
||||
{
|
||||
int cx, cy;
|
||||
int left,top,right,bottom;
|
||||
double square, dist;
|
||||
double radsquare = radius * radius;
|
||||
double length = double((1024.0/(double)radius)*(1024.0/(double)radius));
|
||||
int *newptr;
|
||||
|
||||
if(page == 0)
|
||||
{
|
||||
newptr = hField1;
|
||||
}
|
||||
else
|
||||
{
|
||||
newptr = hField2;
|
||||
}
|
||||
|
||||
int t = (this->width - 2*radius - 1);
|
||||
if (t == 0) t = 1;
|
||||
if(x<0) x = 1 + radius + rand() % t;
|
||||
t = (this->height - 2*radius - 1);
|
||||
if (t == 0) t = 1;
|
||||
if(y<0) y = 1 + radius + rand() % t;
|
||||
|
||||
radsquare = (radius*radius);
|
||||
|
||||
left = -radius; right = radius;
|
||||
top = -radius; bottom = radius;
|
||||
|
||||
// Perform edge clipping...
|
||||
if(x - radius < 1) left -= (x-radius-1);
|
||||
if(y - radius < 1) top -= (y-radius-1);
|
||||
if(x + radius > this->width - 1) right -= (x + radius - this->width + 1);
|
||||
if(y + radius > this->height - 1) bottom -= (y + radius - this->height + 1);
|
||||
|
||||
for(cy = top; cy < bottom; cy++)
|
||||
{
|
||||
for(cx = left; cx < right; cx++)
|
||||
{
|
||||
square = cy*cy + cx*cx;
|
||||
if(square < radsquare)
|
||||
{
|
||||
dist = sqrt(square*length);
|
||||
newptr[this->width*(cy+y) + cx+x] += (int)((cos(dist)+0xffff)*(height)) >> 19;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilterWater::WarpBlob(int x, int y, int radius, int height, int page)
|
||||
{
|
||||
int cx, cy;
|
||||
int left,top,right,bottom;
|
||||
int square;
|
||||
int radsquare = radius * radius;
|
||||
int *newptr;
|
||||
|
||||
if(page == 0)
|
||||
{
|
||||
newptr = hField1;
|
||||
}
|
||||
else
|
||||
{
|
||||
newptr = hField2;
|
||||
}
|
||||
|
||||
radsquare = (radius*radius);
|
||||
|
||||
height /= 64;
|
||||
|
||||
left=-radius; right = radius;
|
||||
top=-radius; bottom = radius;
|
||||
|
||||
// Perform edge clipping...
|
||||
if(x - radius < 1) left -= (x-radius-1);
|
||||
if(y - radius < 1) top -= (y-radius-1);
|
||||
if(x + radius > this->width-1) right -= (x+ radius - this->width + 1);
|
||||
if(y + radius > this->height-1) bottom-= (y + radius - this->height + 1);
|
||||
|
||||
for(cy = top; cy < bottom; cy++)
|
||||
{
|
||||
for(cx = left; cx < right; cx++)
|
||||
{
|
||||
square = cy*cy + cx*cx;
|
||||
if(square < radsquare)
|
||||
{
|
||||
newptr[this->width*(cy+y) + cx+x] += int((radius-sqrt((float)square))*(float)(height));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void MLImageFilterWater::HeightBox (int x, int y, int radius, int height, int page)
|
||||
{
|
||||
int cx, cy;
|
||||
int left,top,right,bottom;
|
||||
int *newptr;
|
||||
|
||||
if(page == 0)
|
||||
{
|
||||
newptr = hField1;
|
||||
}
|
||||
else
|
||||
{
|
||||
newptr = hField2;
|
||||
}
|
||||
|
||||
int t = (this->width - 2*radius - 1);
|
||||
if (t == 0) t = 1;
|
||||
if(x<0) x = 1 + radius + rand() % t;
|
||||
t = (this->height - 2*radius - 1);
|
||||
if (t == 0) t = 1;
|
||||
if(y<0) y = 1 + radius + rand() % t;
|
||||
|
||||
left=-radius; right = radius;
|
||||
top=-radius; bottom = radius;
|
||||
|
||||
// Perform edge clipping...
|
||||
if(x - radius < 1) left -= (x-radius-1);
|
||||
if(y - radius < 1) top -= (y-radius-1);
|
||||
if(x + radius > this->width-1) right -= (x+ radius - this->width + 1);
|
||||
if(y + radius > this->height-1) bottom-= (y + radius - this->height + 1);
|
||||
|
||||
for(cy = top; cy < bottom; cy++)
|
||||
{
|
||||
for(cx = left; cx < right; cx++)
|
||||
{
|
||||
newptr[this->width*(cy+y) + cx+x] = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
void MLImageFilterWater::HeightBlob(int x, int y, int radius, int height, int page)
|
||||
{
|
||||
int rquad;
|
||||
int cx, cy;
|
||||
int left, top, right, bottom;
|
||||
|
||||
rquad = radius * radius;
|
||||
|
||||
// Make a randomly-placed blob...
|
||||
int t = (this->width - 2*radius - 1);
|
||||
if (t == 0) t = 1;
|
||||
if(x<0) x = 1 + radius + rand() % t;
|
||||
t = (this->height - 2*radius - 1);
|
||||
if (t == 0) t = 1;
|
||||
if(y<0) y = 1 + radius + rand() % t;
|
||||
|
||||
left = -radius; right = radius;
|
||||
top = -radius; bottom = radius;
|
||||
|
||||
// Perform edge clipping...
|
||||
if(x - radius < 1) left -= (x-radius-1);
|
||||
if(y - radius < 1) top -= (y-radius-1);
|
||||
if(x + radius > this->width-1) right -= (x+ radius - this->width + 1);
|
||||
if(y + radius > this->height-1) bottom-= (y + radius - this->height + 1);
|
||||
|
||||
for(cy = top; cy < bottom; cy++)
|
||||
{
|
||||
int cyq = cy*cy;
|
||||
for(cx = left; cx < right; cx++)
|
||||
{
|
||||
if(cx*cx + cyq < rquad) newptr[this->width * (cy+y) + (cx+x)] += height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilterWater::CalcWaterBigFilter(int page, int density)
|
||||
{
|
||||
int newh;
|
||||
int count = (2 * width) + 2;
|
||||
|
||||
int *newptr;
|
||||
int *oldptr;
|
||||
|
||||
// Set up the pointers
|
||||
if(page == 0)
|
||||
{
|
||||
newptr = hField1;
|
||||
oldptr = hField2;
|
||||
}
|
||||
else
|
||||
{
|
||||
newptr = hField2;
|
||||
oldptr = hField1;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
|
||||
for(y=2; y < height-2; y++, count += 4)
|
||||
{
|
||||
for(x=2; x < width-2; x++, count++)
|
||||
{
|
||||
// This does the 25-pixel method. It looks much okay.
|
||||
|
||||
newh = (
|
||||
(
|
||||
(
|
||||
(oldptr[count + width]
|
||||
+ oldptr[count - width]
|
||||
+ oldptr[count + 1]
|
||||
+ oldptr[count - 1]
|
||||
)<<1)
|
||||
+ ((oldptr[count - width - 1]
|
||||
+ oldptr[count - width + 1]
|
||||
+ oldptr[count + width - 1]
|
||||
+ oldptr[count + width + 1]))
|
||||
+ ( (
|
||||
oldptr[count - (width*2)]
|
||||
+ oldptr[count + (width*2)]
|
||||
+ oldptr[count - 2]
|
||||
+ oldptr[count + 2]
|
||||
) >> 1 )
|
||||
+ ( (
|
||||
oldptr[count - (width*2) - 1]
|
||||
+ oldptr[count - (width*2) + 1]
|
||||
+ oldptr[count + (width*2) - 1]
|
||||
+ oldptr[count + (width*2) + 1]
|
||||
+ oldptr[count - 2 - width]
|
||||
+ oldptr[count - 2 + width]
|
||||
+ oldptr[count + 2 - width]
|
||||
+ oldptr[count + 2 + width]
|
||||
) >> 2 )
|
||||
)
|
||||
>> 3)
|
||||
- (newptr[count]);
|
||||
|
||||
|
||||
newptr[count] = newh - (newh >> density);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilterWater::DrawWaterNoLight(int page, MLImage* destination, const MLImage* source)
|
||||
{
|
||||
unsigned int brk = width * height;
|
||||
|
||||
int *ptr = hField1;
|
||||
|
||||
DWORD *dataS = (DWORD*)source->GetData();
|
||||
DWORD *dataD = (DWORD*)destination->GetData();
|
||||
|
||||
for (unsigned int offset = 0; offset < brk; offset++)
|
||||
{
|
||||
int dx = ptr[offset] - ptr[offset + 1];
|
||||
int dy = ptr[offset] - ptr[offset + width];
|
||||
unsigned int index = offset + width * (dy>>3) + (dx>>3);
|
||||
dataD[offset] = (index < brk ) ? dataS[offset + width*(dy>>3) + (dx>>3)] : dataS[offset];
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilterWater::DrawWaterWithLight(MLImage* destination, const MLImage* source)
|
||||
{
|
||||
unsigned int brk = width * height;
|
||||
|
||||
int *ptr = hField1;
|
||||
|
||||
DWORD *dataS = (DWORD*)source->GetData();
|
||||
DWORD *dataD = (DWORD*)destination->GetData();
|
||||
|
||||
for (unsigned int offset = 0; offset < brk; offset++)
|
||||
{
|
||||
int dx = ptr[offset] - ptr[offset + 1];
|
||||
int dy = ptr[offset] - ptr[offset + width];
|
||||
unsigned int index = offset + width * (dy>>3) + (dx>>3);
|
||||
dataD[offset] = (index < brk ) ? GetShiftedColor(dataS[index], dx) : dataS[offset];
|
||||
}
|
||||
}
|
||||
COLORREF MLImageFilterWater::GetShiftedColor(COLORREF color,int shift)
|
||||
{
|
||||
int R,G, B;
|
||||
int r, g, b;
|
||||
|
||||
R = GetRValue(color)-shift;
|
||||
G = GetGValue(color)-shift;
|
||||
B = GetBValue(color)-shift;
|
||||
|
||||
r = (R < 0) ? 0 : (R > 255) ? 255 : R;
|
||||
g = (G < 0) ? 0 : (G > 255) ? 255 : G;
|
||||
b = (B < 0) ? 0 : (B > 255) ? 255 : B;
|
||||
|
||||
return RGB(r,g,b);
|
||||
}
|
47
Src/Plugins/Input/in_mp3/graphics/filterWater.h
Normal file
47
Src/Plugins/Input/in_mp3/graphics/filterWater.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef NULLSOFT_ML_IMAGE_FILTERWATER_HEADER
|
||||
#define NULLSOFT_ML_IMAGE_FILTERWATER_HEADER
|
||||
|
||||
#include <windows.h>
|
||||
#include ".\image.h"
|
||||
|
||||
class MLImageFilterWater
|
||||
{
|
||||
public:
|
||||
MLImageFilterWater(void);
|
||||
~MLImageFilterWater(void);
|
||||
|
||||
public:
|
||||
BOOL CreateFor(const MLImage *image);
|
||||
void Render(MLImage* destination, const MLImage* source);
|
||||
|
||||
void CalculateWater(int page, int density);
|
||||
void SmoothWater(int page);
|
||||
void FlattenWater(void);
|
||||
|
||||
void SineBlob(int x, int y, int radius, int height, int page);
|
||||
void WarpBlob(int x, int y, int radius, int height, int page);
|
||||
void HeightBox (int x, int y, int radius, int height, int page);
|
||||
void HeightBlob(int x, int y, int radius, int height, int page);
|
||||
|
||||
protected:
|
||||
void ClearData(void);
|
||||
void CalcWaterBigFilter(int page, int density);
|
||||
void DrawWaterNoLight(int page,MLImage* destination, const MLImage* source);
|
||||
void DrawWaterWithLight(MLImage* destination, const MLImage* source);
|
||||
COLORREF GetShiftedColor(COLORREF color,int shift);
|
||||
|
||||
private:
|
||||
HANDLE hHandle;
|
||||
int height;
|
||||
int width;
|
||||
|
||||
BOOL drawWithLight;
|
||||
int lightModifier;
|
||||
int hPage;
|
||||
int density;
|
||||
|
||||
int* hField1;
|
||||
int* hField2;
|
||||
};
|
||||
|
||||
#endif //#define NULLSOFT_ML_IMAGE_FILTERWATER_HEADER
|
209
Src/Plugins/Input/in_mp3/graphics/image.cpp
Normal file
209
Src/Plugins/Input/in_mp3/graphics/image.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
#include ".\image.h"
|
||||
|
||||
MLImage::MLImage(void)
|
||||
{
|
||||
loader = NULL;
|
||||
loaderDelete = TRUE;
|
||||
ResetData();
|
||||
}
|
||||
|
||||
MLImage::MLImage(IMGLOADFUNC loader, BOOL deleteDone)
|
||||
{
|
||||
ResetData();
|
||||
SetLoader(loader, deleteDone, FALSE);
|
||||
}
|
||||
|
||||
MLImage::MLImage(int width, int height)
|
||||
{
|
||||
loader = NULL;
|
||||
ResetData();
|
||||
Init(width,height);
|
||||
}
|
||||
|
||||
MLImage::~MLImage(void)
|
||||
{
|
||||
ResetData();
|
||||
}
|
||||
|
||||
INT_PTR MLImage::SetLoader(IMGLOADFUNC loader, BOOL deleteDone, BOOL forceLoad)
|
||||
{
|
||||
this->loader = loader;
|
||||
this->loaderDelete = deleteDone;
|
||||
if (loader && forceLoad) Load();
|
||||
return (loader != NULL) ? (INT_PTR) this : FALSE;
|
||||
}
|
||||
|
||||
BOOL MLImage::Load(void)
|
||||
{
|
||||
ResetData();
|
||||
|
||||
if (!loader) return FALSE;
|
||||
HBITMAP hbmpLoaded = loader((INT_PTR)this);
|
||||
if(hbmpLoaded == NULL) return FALSE;
|
||||
|
||||
BITMAP bi;
|
||||
if (GetObject(hbmpLoaded, sizeof(bi), &bi))
|
||||
{
|
||||
hbmp = ConvertTo32BppDIB(hbmpLoaded, bi.bmWidth, bi.bmHeight, &info, &data);
|
||||
}
|
||||
|
||||
if (loaderDelete) DeleteObject(hbmpLoaded);
|
||||
return (hbmp != NULL);
|
||||
}
|
||||
|
||||
void MLImage::ResetData(void)
|
||||
{
|
||||
if (hbmp) DeleteObject(hbmp);
|
||||
hbmp = NULL;
|
||||
SecureZeroMemory(&info, sizeof(BITMAPINFO));
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
BOOL MLImage::Draw(HDC hdcDest, int destX, int destY, int destWidth, int destHeight, int sourceX, int sourceY)
|
||||
{
|
||||
if (!hbmp) return FALSE;
|
||||
|
||||
int realheight = abs(info.bmiHeader.biHeight);
|
||||
int rsX = min(sourceX, info.bmiHeader.biWidth);
|
||||
int rsY = min(sourceY, info.bmiHeader.biWidth);
|
||||
int height = min(destHeight, realheight - rsY);
|
||||
|
||||
BOOL bResult = SetDIBitsToDevice( hdcDest, destX, destY,
|
||||
min(destWidth, info.bmiHeader.biWidth - rsX), height,
|
||||
rsX, realheight - height - rsY,
|
||||
0, height,
|
||||
data, &info, DIB_RGB_COLORS);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
BOOL MLImage::Draw(HDC hdcDest, int destX, int destY)
|
||||
{
|
||||
return (!hbmp) ? FALSE : SetDIBitsToDevice( hdcDest, destX, destY,
|
||||
info.bmiHeader.biWidth, abs(info.bmiHeader.biHeight),
|
||||
0, 0,
|
||||
0, abs(info.bmiHeader.biHeight),
|
||||
data, &info, DIB_RGB_COLORS);
|
||||
}
|
||||
|
||||
int MLImage::GetWidth(void) const
|
||||
{
|
||||
return (hbmp) ? info.bmiHeader.biWidth : 0;
|
||||
}
|
||||
|
||||
int MLImage::GetHeight(void) const
|
||||
{
|
||||
return (hbmp) ? abs(info.bmiHeader.biHeight) : 0;
|
||||
}
|
||||
|
||||
void* MLImage::GetData(void) const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
HBITMAP MLImage::ConvertTo32BppDIB(HBITMAP bmpHandle, int bmpWidth, int bmpHeight, LPBITMAPINFO bmpInfo, LPVOID *bmpData)
|
||||
{
|
||||
HBITMAP hbmpNew = NULL;
|
||||
|
||||
HDC hdc = GetWindowDC(NULL);
|
||||
HDC hdcTmp = CreateCompatibleDC(hdc);
|
||||
HBITMAP hbmpTmp = CreateCompatibleBitmap(hdc, bmpWidth, bmpHeight);
|
||||
HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcTmp, hbmpTmp);
|
||||
|
||||
// render original bitmap to the temp dc
|
||||
HDC hdcBmp = CreateCompatibleDC(hdc);
|
||||
SelectObject(hdcBmp, bmpHandle);
|
||||
BitBlt(hdcTmp, 0, 0, bmpWidth, bmpHeight, hdcBmp, 0,0, SRCCOPY);
|
||||
SelectObject(hdcBmp, NULL);
|
||||
DeleteDC(hdcBmp);
|
||||
|
||||
// Create a 32 bit bitmap
|
||||
BITMAPINFO bih;
|
||||
// create DIB Section
|
||||
bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bih.bmiHeader.biWidth = bmpWidth;
|
||||
bih.bmiHeader.biHeight = 0 - bmpHeight;
|
||||
bih.bmiHeader.biPlanes = 1;
|
||||
bih.bmiHeader.biBitCount = 32;
|
||||
bih.bmiHeader.biCompression = BI_RGB;
|
||||
bih.bmiHeader.biSizeImage = 0;
|
||||
bih.bmiHeader.biXPelsPerMeter = 0;
|
||||
bih.bmiHeader.biYPelsPerMeter = 0;
|
||||
bih.bmiHeader.biClrUsed = 0;
|
||||
bih.bmiHeader.biClrImportant = 0;
|
||||
|
||||
// Create a DC which will be used to get DIB, then create DIBsection
|
||||
hbmpNew = CreateDIBSection(hdc, (const BITMAPINFO*) &bih, DIB_RGB_COLORS, bmpData, NULL, 0);
|
||||
|
||||
|
||||
DWORD* line = (DWORD*)(*bmpData);
|
||||
// Copy the bits into our 32 bit dib..
|
||||
for(int i=0; i<bmpHeight; i++)
|
||||
{
|
||||
for(int j=0; j<bmpWidth; j++)
|
||||
{
|
||||
line[(i*bmpWidth) + j] = FIXCOLORREF(GetPixel(hdcTmp, j, i));
|
||||
}
|
||||
}
|
||||
|
||||
SelectObject(hdcTmp, hbmpOld);
|
||||
ReleaseDC(NULL, hdc);
|
||||
DeleteDC(hdcTmp);
|
||||
|
||||
memcpy(bmpInfo, &bih, sizeof(BITMAPINFO));
|
||||
|
||||
return hbmpNew;
|
||||
}
|
||||
|
||||
MLImage* MLImage::Copy(MLImage* destination, const MLImage* original)
|
||||
{
|
||||
if (!destination) return NULL;
|
||||
|
||||
destination->ResetData();
|
||||
|
||||
destination->loader = original->loader;
|
||||
destination->loaderDelete = original->loaderDelete;
|
||||
destination->info = original->info;
|
||||
HDC hdc = GetWindowDC(NULL);
|
||||
destination->hbmp = CreateDIBSection(hdc, (const BITMAPINFO*) &destination->info, DIB_RGB_COLORS, &destination->data, NULL, 0);
|
||||
|
||||
CopyMemory(destination->data, original->data, 4*destination->GetHeight() * destination->GetWidth());
|
||||
ReleaseDC(NULL, hdc);
|
||||
return destination;
|
||||
}
|
||||
|
||||
MLImage* MLImage::Init(int width, int height)
|
||||
{
|
||||
ResetData();
|
||||
|
||||
loader = NULL;
|
||||
loaderDelete = TRUE;
|
||||
|
||||
// create DIB Section
|
||||
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info.bmiHeader.biWidth = width;
|
||||
info.bmiHeader.biHeight = 0 - height;
|
||||
info.bmiHeader.biPlanes = 1;
|
||||
info.bmiHeader.biBitCount = 32;
|
||||
info.bmiHeader.biCompression = BI_RGB;
|
||||
info.bmiHeader.biSizeImage = 0;
|
||||
info.bmiHeader.biXPelsPerMeter = 0;
|
||||
info.bmiHeader.biYPelsPerMeter = 0;
|
||||
info.bmiHeader.biClrUsed = 0;
|
||||
info.bmiHeader.biClrImportant = 0;
|
||||
|
||||
HDC hdc = GetWindowDC(NULL);
|
||||
hbmp = CreateDIBSection(hdc, (const BITMAPINFO*) &info, DIB_RGB_COLORS, &data, NULL, 0);
|
||||
ReleaseDC(NULL, hdc);
|
||||
return this;
|
||||
}
|
||||
|
||||
MLImage* MLImage::Init(int width, int height, COLORREF color)
|
||||
{
|
||||
Init(width, height);
|
||||
|
||||
int rColor = FIXCOLORREF(color);
|
||||
DWORD *line = (DWORD*)(data);
|
||||
DWORD *end = line + GetHeight() * GetWidth();
|
||||
for(;line != end; line++) *line = rColor;
|
||||
return this;
|
||||
}
|
61
Src/Plugins/Input/in_mp3/graphics/image.h
Normal file
61
Src/Plugins/Input/in_mp3/graphics/image.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef NULLSOFT_ML_IMAGE_HEADER
|
||||
#define NULLSOFT_ML_IMAGE_HEADER
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define RGBA(r,g,b,a) ((COLORREF)(((BYTE)(r)|((WORD)(g)<<8))|(((DWORD)(BYTE)(b))<<16)|(((DWORD)(BYTE)(a))<<24)))
|
||||
#define FIXCOLORREF(clr) RGBA(GetBValue(clr),GetGValue(clr), GetRValue(clr),((DWORD)(clr)) >> 24)
|
||||
|
||||
// loader function will be called every time MLImage need to
|
||||
// reload picture. Input parameter - handle to the calling object
|
||||
// Output - loaded bitmap
|
||||
typedef HBITMAP (*IMGLOADFUNC)(INT_PTR handle);
|
||||
|
||||
class MLImage
|
||||
{
|
||||
public:
|
||||
MLImage(void);
|
||||
MLImage(IMGLOADFUNC loader, BOOL deleteDone);
|
||||
MLImage(int width, int height);
|
||||
~MLImage(void);
|
||||
|
||||
public:
|
||||
// sets the loader function and returns handle to the class or NULL if error
|
||||
// loader - pointer to the loader function
|
||||
// deleteDone - if TRUE MLImage will delete HBITMAP object from loader every time it is done loading
|
||||
// forceLoad - forcing to load bitamp immedialty by calling Load()
|
||||
INT_PTR SetLoader(IMGLOADFUNC loader, BOOL deleteDone, BOOL forceLoad);
|
||||
BOOL Load(void); // load image
|
||||
|
||||
MLImage* Init(int width, int height); // init image (allocates memory)
|
||||
MLImage* Init(int width, int height, COLORREF color); // init image (allocates memory) and set
|
||||
|
||||
BOOL Draw(HDC hdcDest, int destX, int destY, int destWidth, int destHeight, int sourceX, int sourceY); // draw image
|
||||
BOOL Draw(HDC hdcDest, int destX, int destY); // draw image
|
||||
|
||||
public:
|
||||
int GetWidth(void) const;
|
||||
int GetHeight(void) const;
|
||||
void* GetData(void) const;
|
||||
|
||||
|
||||
private:
|
||||
void ResetData(void);
|
||||
|
||||
public:
|
||||
static MLImage* Copy(MLImage* destination, const MLImage* original);// copy all data from the original object (including image data) to the destination
|
||||
|
||||
private:
|
||||
static HBITMAP ConvertTo32BppDIB(HBITMAP bmpHandle, int bmpWidth, int bmpHeight, LPBITMAPINFO bmpInfo, LPVOID *bmpData);
|
||||
|
||||
private:
|
||||
IMGLOADFUNC loader; // pointer to the loader function
|
||||
BOOL loaderDelete; // TRUE - delete HBITMAP from loader after load
|
||||
|
||||
HBITMAP hbmp; // my bitmap
|
||||
BITMAPINFO info;
|
||||
void *data;
|
||||
};
|
||||
|
||||
#endif // NULLSOFT_ML_IMAGE_HEADER
|
||||
|
91
Src/Plugins/Input/in_mp3/graphics/imageFilters.cpp
Normal file
91
Src/Plugins/Input/in_mp3/graphics/imageFilters.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include ".\imagefilters.h"
|
||||
|
||||
void MLImageFilter_GrayScale(MLImage *image)
|
||||
{
|
||||
DWORD *line = (DWORD*)(image->GetData());
|
||||
DWORD *end = line + image->GetHeight() * image->GetWidth();
|
||||
for(;line != end; line++)
|
||||
{
|
||||
BYTE y = (BYTE)(0.3f * GetBValue(*line) + 0.59f *GetGValue(*line) + 0.11f *GetRValue(*line));
|
||||
*line = RGB(y,y,y);
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilter_Invert(MLImage *image)
|
||||
{
|
||||
DWORD *line = (DWORD*)(image->GetData());
|
||||
DWORD *end = line + image->GetHeight() * image->GetWidth();
|
||||
for(;line != end; line++) *line = ((~*line) & 0x00FFFFFF) | (*line & 0xFF000000);
|
||||
}
|
||||
|
||||
void MLImageFilter_SetToColor(MLImage *image, COLORREF color)
|
||||
{
|
||||
COLORREF rColor = FIXCOLORREF(color);
|
||||
DWORD *line = (DWORD*)(image->GetData());
|
||||
DWORD *end = line + image->GetHeight() * image->GetWidth();
|
||||
for(;line != end; line++) *line = rColor;
|
||||
}
|
||||
|
||||
void MLImageFilter_Fader1(MLImage *dest, const MLImage* source, COLORREF color)
|
||||
{
|
||||
int len = dest->GetHeight() * dest->GetWidth();
|
||||
BYTE r = GetRValue(color), g = GetGValue(color), b = GetBValue(color);
|
||||
|
||||
DWORD *dataS = (DWORD*)(source->GetData());
|
||||
DWORD *dataD = (DWORD*)(dest->GetData());
|
||||
DWORD *end = dataD + len;
|
||||
for(;dataD != end; dataD++, dataS++)
|
||||
{
|
||||
*dataD = RGB( max(b, GetRValue(*dataS)), max(g, GetGValue(*dataS)), max(r, GetBValue(*dataS))) ;
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilter_Fader2(MLImage *dest, const MLImage* source, COLORREF color)
|
||||
{
|
||||
int len = dest->GetHeight() * dest->GetWidth();
|
||||
BYTE r = GetRValue(color), g = GetGValue(color), b = GetBValue(color);
|
||||
|
||||
DWORD *dataS = (DWORD*)(source->GetData());
|
||||
DWORD *dataD = (DWORD*)(dest->GetData());
|
||||
DWORD *end = dataD + len;
|
||||
for(;dataD != end; dataD++, dataS++)
|
||||
{
|
||||
*dataD = RGB( min(b, GetRValue(*dataS)), min(g, GetGValue(*dataS)), min(r, GetBValue(*dataS))) ;
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilter_Fader3(MLImage *dest, const MLImage* source, int koeff)
|
||||
{
|
||||
int len = dest->GetHeight() * dest->GetWidth();
|
||||
|
||||
DWORD *dataS = (DWORD*)(source->GetData());
|
||||
DWORD *dataD = (DWORD*)(dest->GetData());
|
||||
DWORD *end = dataD + len;
|
||||
for(;dataD != end; dataD++, dataS++)
|
||||
{
|
||||
*dataD = RGB(min(255,GetRValue(*dataS) + koeff), min(255,GetGValue(*dataS) + koeff), min(255, GetBValue(*dataS) + koeff));
|
||||
}
|
||||
}
|
||||
|
||||
void MLImageFilter_Blend1(MLImage *dest, MLImage *src1, int destX, int destY, int width, int height, const MLImage* src2, int srcX, int srcY, COLORREF color)
|
||||
{
|
||||
int widthS1 = src1->GetWidth();
|
||||
int widthS2 = src2->GetWidth();
|
||||
|
||||
DWORD *dataD = (DWORD*)(dest->GetData()) + destY * widthS1 + destX;
|
||||
DWORD *dataS1 = (DWORD*)(src1->GetData()) + destY * widthS1 + destX;
|
||||
DWORD *dataS2 = (DWORD*)(src2->GetData()) + srcY * widthS2 + srcX;
|
||||
|
||||
DWORD *curS1;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
DWORD *curD = dataD + y * widthS1;
|
||||
curS1 = dataS1 + y * widthS1;
|
||||
DWORD *curS2 = dataS2 + y * widthS2;
|
||||
for (DWORD *end = curS1 + width; end != curS1; curD++, curS1++, curS2++)
|
||||
{
|
||||
*curD = (*curS1 == color) ? *curS2 : *curS1;
|
||||
}
|
||||
}
|
||||
}
|
17
Src/Plugins/Input/in_mp3/graphics/imageFilters.h
Normal file
17
Src/Plugins/Input/in_mp3/graphics/imageFilters.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef NULLSOFT_ML_IMAGE_FILTER_HEADER
|
||||
#define NULLSOFT_ML_IMAGE_FILTER_HEADER
|
||||
|
||||
#include <windows.h>
|
||||
#include ".\image.h"
|
||||
#include ".\filterwater.h"
|
||||
|
||||
void MLImageFilter_GrayScale(MLImage *image);
|
||||
void MLImageFilter_Invert(MLImage *image);
|
||||
void MLImageFilter_SetToColor(MLImage *image, COLORREF color);
|
||||
void MLImageFilter_Fader1(MLImage *dest, const MLImage* source, COLORREF color);
|
||||
void MLImageFilter_Fader2(MLImage *dest, const MLImage* source, COLORREF color);
|
||||
void MLImageFilter_Fader3(MLImage *dest, const MLImage* source, int koeff);
|
||||
void MLImageFilter_Blend1(MLImage *dest, MLImage *src1, int destX, int destY, int width, int height, const MLImage* src2, int srcX, int srcY, COLORREF color);
|
||||
|
||||
|
||||
#endif //NULLSOFT_ML_IMAGE_FILTER_HEADER
|
Reference in New Issue
Block a user