www.pudn.com > RotateByShear_demo.zip > Dib.cpp
#include "stdafx.h"
#include "DIB.h"
#define PPM_EXT ".PPM"
BOOL CDIB::Create ( int Width, int Height )
{
Destroy ();
ZeroMemory ( &m_Info, sizeof (BITMAPINFO) );
m_Info.bmiHeader.biSize=sizeof (BITMAPINFOHEADER);
m_Info.bmiHeader.biWidth=Width;
m_Info.bmiHeader.biHeight=Height;
m_Info.bmiHeader.biPlanes=1;
m_Info.bmiHeader.biBitCount=32;
m_Info.bmiHeader.biCompression=BI_RGB;
m_Info.bmiHeader.biSizeImage=Width*Height*4;
m_Bitmap=CreateDIBSection ( NULL, &m_Info, DIB_RGB_COLORS, (void **)&m_Bits, NULL, NULL );
if ( m_Bitmap )
{
m_Size=CSize ( Width, Height );
return TRUE;
}
else
{
m_Size=CSize ( 0, 0 );
return FALSE;
}
}
BOOL CDIB::Create (CDC *pDC, UINT uBitmapID)
{ // Creates from a bitmap
CDC BufferDC;
CBitmap BufferBitmap, *OldBitmap;
if (!BufferBitmap.LoadBitmap (uBitmapID))
return FALSE; // Can't load resource bitmap
BITMAP bmpData;
if (!BufferBitmap.GetBitmap (&bmpData))
return FALSE; // Can't get bitmap info
if (!Create (bmpData.bmWidth, bmpData.bmHeight))
return FALSE; // Can't create DIB buffer
BufferDC.CreateCompatibleDC (pDC);
OldBitmap=BufferDC.SelectObject (&BufferBitmap);
GetDIBits (BufferDC.m_hDC, HBITMAP(BufferBitmap), 0, m_Size.cy, m_Bits, &(m_Info), DIB_RGB_COLORS);
BufferDC.SelectObject (OldBitmap);
BufferBitmap.DeleteObject();
return TRUE;
}
void CDIB::Destroy ()
{
if ( m_Bitmap )
DeleteObject ( m_Bitmap );
m_Bitmap=NULL;
m_Size=CSize ( 0, 0 );
}
void CDIB::GetFromDC ( CDC *pDC, int x, int y, int w, int h )
{
// If DibSize Wrong Re-Create Dib
if ( (m_Size.cx!=w) || (m_Size.cy!=h) )
Create ( w, h );
CDC BufferDC;
CBitmap BufferBitmap, *OldBitmap;
BufferDC.CreateCompatibleDC ( pDC );
BufferBitmap.CreateCompatibleBitmap ( pDC, w, h );
OldBitmap=BufferDC.SelectObject ( &BufferBitmap );
BufferDC.FillSolidRect ( 0, 0, w, h, 0 );
BufferDC.BitBlt ( 0, 0, w, h, pDC, x, y, SRCCOPY );
BufferDC.SelectObject ( OldBitmap );
GetDIBits ( pDC->m_hDC, HBITMAP(BufferBitmap), 0, h, m_Bits, &(m_Info), DIB_RGB_COLORS );
}
DIBLoadResult
CDIB::Load (CString cstrFile)
{
if ((4 < cstrFile.GetLength()) &&
(0 == (cstrFile.Right(4)).CompareNoCase(PPM_EXT)))
{ // The extension is suggesting it's a binary PPM (P6) file
return LoadPPM ( cstrFile );
}
// Unsupported file type
return DIB_LOAD_NOFILE_OR_CORRUPT;
}
void CDIB::Fill ( int R, int G, int B )
{
COLORREF Color=RGB ( B, G, R );
int Size=m_Size.cx*m_Size.cy;
for ( int i=0; i>8);
dst[1]=(BYTE)(((G-dst[1])*A+(dst[1]<<8))>>8);
dst[2]=(BYTE)(((R-dst[2])*A+(dst[2]<<8))>>8);
dst+=4;
}
}
void CDIB::FillStippledGlass ( int R, int G, int B )
{
COLORREF Color=RGB ( B, G, R );
int w=m_Size.cx;
int h=m_Size.cy;
for ( int j=0; jm_Size )
return;
COLORREF *src=Dib->m_Bits;
COLORREF *dst=m_Bits;
COLORREF ColorKey=RGB ( B, G, R );
int Size=m_Size.cx*m_Size.cy;
while ( Size-- )
{
dst[0]=(src[0]==ColorKey) ? dst[0] : src[0];
dst++;
src++;
}
}
void CDIB::Add ( CDIB *Dib )
{
if ( m_Size!=Dib->m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
int Sum;
while ( Size-- )
{
Sum=src[0]+dst[0];
dst[0]=(BYTE)((Sum>255) ? 255 : Sum);
Sum=src[1]+dst[1];
dst[1]=(BYTE)((Sum>255) ? 255 : Sum);
Sum=src[2]+dst[2];
dst[2]=(BYTE)((Sum>255) ? 255 : Sum);
dst+=4;
src+=4;
}
}
void CDIB::Blend ( CDIB *Dib, int A )
{
if ( m_Size!=Dib->m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
while ( Size-- )
{
dst[0]=(BYTE)(((src[0]-dst[0])*A+(dst[0]<<8))>>8);
dst[1]=(BYTE)(((src[1]-dst[1])*A+(dst[1]<<8))>>8);
dst[2]=(BYTE)(((src[2]-dst[2])*A+(dst[2]<<8))>>8);
dst+=4;
src+=4;
}
}
void CDIB::Darken ( CDIB *Dib )
{
if ( m_Size!=Dib->m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
while ( Size-- )
{
dst[0]=(BYTE)((src[0]m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
int Difference;
while ( Size-- )
{
Difference=src[0]-dst[0];
dst[0]=(BYTE)((Difference<0) ? -Difference : Difference);
Difference=src[1]-dst[1];
dst[1]=(BYTE)((Difference<0) ? -Difference : Difference);
Difference=src[2]-dst[2];
dst[2]=(BYTE)((Difference<0) ? -Difference : Difference);
dst+=4;
src+=4;
}
}
void CDIB::Lighten ( CDIB *Dib )
{
if ( m_Size!=Dib->m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
while ( Size-- )
{
dst[0]=(BYTE)((src[0]>dst[0]) ? src[0] : dst[0]);
dst[1]=(BYTE)((src[1]>dst[1]) ? src[1] : dst[1]);
dst[2]=(BYTE)((src[2]>dst[2]) ? src[2] : dst[2]);
dst+=4;
src+=4;
}
}
void CDIB::Multiply ( CDIB *Dib )
{
if ( m_Size!=Dib->m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
while ( Size-- )
{
dst[0]=(BYTE)(((src[0])*(dst[0]))>>8);
dst[1]=(BYTE)(((src[1])*(dst[1]))>>8);
dst[2]=(BYTE)(((src[2])*(dst[2]))>>8);
dst+=4;
src+=4;
}
}
void CDIB::Screen ( CDIB *Dib )
{
if ( m_Size!=Dib->m_Size )
return;
BYTE *src=(BYTE*)Dib->m_Bits;
BYTE *dst=(BYTE*)m_Bits;
int Size=m_Size.cx*m_Size.cy;
while ( Size-- )
{
dst[0]=(BYTE)(255-(((255-src[0])*(255-dst[0]))>>8));
dst[1]=(BYTE)(255-(((255-src[1])*(255-dst[1]))>>8));
dst[2]=(BYTE)(255-(((255-src[2])*(255-dst[2]))>>8));
dst+=4;
src+=4;
}
}
//////////////////////////////////////////////////////////////////////
// Rectangle Functions
//////////////////////////////////////////////////////////////////////
void CDIB::CopyRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Copy return
if ( (dx<=0) || (dy<=0) )
return;
// If DibSize Wrong Re-Create Dib
if ( (dx!=Dib->m_Size.cx) || (dy!=Dib->m_Size.cy) )
Dib->Create ( dx, dy );
// Prepare Buffer Addresses
COLORREF *src=m_Bits+(py*m_Size.cx)+px;
COLORREF *dst=Dib->m_Bits;
// Do Copy
while ( dy-- )
{
for ( int i=0; im_Size.cx;
}
}
void CDIB::PasteRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Paste return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
COLORREF *src=Dib->m_Bits+((py-y)*Dib->m_Size.cx)+px-x;
COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
// Do Paste
while ( dy-- )
{
for ( int i=0; im_Size.cx;
dst+=m_Size.cx;
}
}
void CDIB::PasteCKRect ( CDIB *Dib, int x, int y, int R, int G, int B )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Paste return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
COLORREF *src=Dib->m_Bits+((py-y)*Dib->m_Size.cx)+px-x;
COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
COLORREF ColorKey=RGB ( B, G, R );
// Do Paste
while ( dy-- )
{
for ( int i=0; im_Size.cx;
dst+=m_Size.cx;
}
}
void CDIB::FillRect ( int x, int y, int w, int h, int R, int G, int B )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+w)=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Fill return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Address
COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
COLORREF Color=RGB ( B, G, R );
// Do Fill
while ( dy-- )
{
for ( int i=0; i=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+w)=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to FillGlass return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Address
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do FillGlass
while ( dy-- )
{
for ( int i=0; i>8);
dst[1]=(BYTE)(((G-dst[1])*A+(dst[1]<<8))>>8);
dst[2]=(BYTE)(((R-dst[2])*A+(dst[2]<<8))>>8);
dst+=4;
}
dst+=(m_Size.cx-dx)<<2;
}
}
void CDIB::FillStippledGlassRect ( int x, int y, int w, int h, int R, int G, int B )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+w)=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to FillStippledGlass return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Address
COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
COLORREF Color=RGB ( B, G, R );
// Do FillStippledGlass
for ( int j=0; j=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Add return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
int Sum;
// Do Add
while ( dy-- )
{
for ( int i=0; i255) ? 255 : Sum);
Sum=src[1]+dst[1];
dst[1]=(BYTE)((Sum>255) ? 255 : Sum);
Sum=src[2]+dst[2];
dst[2]=(BYTE)((Sum>255) ? 255 : Sum);
dst+=4;
src+=4;
}
dst+=(m_Size.cx-dx)<<2;
src+=(Dib->m_Size.cx-dx)<<2;
}
}
void CDIB::BlendRect ( CDIB *Dib, int x, int y, int A )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Blend return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do Blend
while ( dy-- )
{
for ( int i=0; i>8);
dst[1]=(BYTE)(((src[1]-dst[1])*A+(dst[1]<<8))>>8);
dst[2]=(BYTE)(((src[2]-dst[2])*A+(dst[2]<<8))>>8);
dst+=4;
src+=4;
}
dst+=(m_Size.cx-dx)<<2;
src+=(Dib->m_Size.cx-dx)<<2;
}
}
void CDIB::DarkenRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Darken return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do Darken
while ( dy-- )
{
for ( int i=0; im_Size.cx-dx)<<2;
}
}
void CDIB::DifferenceRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Difference return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do Difference
while ( dy-- )
{
for ( int i=0; im_Size.cx-dx)<<2;
}
}
void CDIB::LightenRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Lighten return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do Lighten
while ( dy-- )
{
for ( int i=0; idst[0]) ? src[0] : dst[0]);
dst[1]=(BYTE)((src[1]>dst[1]) ? src[1] : dst[1]);
dst[2]=(BYTE)((src[2]>dst[2]) ? src[2] : dst[2]);
dst+=4;
src+=4;
}
dst+=(m_Size.cx-dx)<<2;
src+=(Dib->m_Size.cx-dx)<<2;
}
}
void CDIB::MultiplyRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Multiply return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do Multiply
while ( dy-- )
{
for ( int i=0; i>8);
dst[1]=(BYTE)(((src[1])*(dst[1]))>>8);
dst[2]=(BYTE)(((src[2])*(dst[2]))>>8);
dst+=4;
src+=4;
}
dst+=(m_Size.cx-dx)<<2;
src+=(Dib->m_Size.cx-dx)<<2;
}
}
void CDIB::ScreenRect ( CDIB *Dib, int x, int y )
{
// Clip Rect
int px=(x>=0) ? x : 0;
int py=(y>=0) ? y : 0;
int dx=((x+Dib->m_Size.cx)m_Size.cx : m_Size.cx-x;
int dy=((y+Dib->m_Size.cy)m_Size.cy : m_Size.cy-y;
dx=(x>=0) ? dx : dx + x;
dy=(y>=0) ? dy : dy + y;
// If Nothing to Screen return
if ( (dx<=0) || (dy<=0) )
return;
// Prepare Buffer Addresses
BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
// Do Screen
while ( dy-- )
{
for ( int i=0; i>8));
dst[1]=(BYTE)(255-(((255-src[1])*(255-dst[1]))>>8));
dst[2]=(BYTE)(255-(((255-src[2])*(255-dst[2]))>>8));
dst+=4;
src+=4;
}
dst+=(m_Size.cx-dx)<<2;
src+=(Dib->m_Size.cx-dx)<<2;
}
}
//////////////////////////////////////////////////////////////////////
// Line Functions
//////////////////////////////////////////////////////////////////////
#define CLIPCODE(x,y) (((x<0)?8:0)|((x>=m_Size.cx)?4:0)|((y<0)?2:0)|((y>=m_Size.cy)?1:0))
void CDIB::ClippedLine ( int x1, int y1, int x2, int y2, int R, int G, int B )
{
int c1=CLIPCODE(x1,y1),
c2=CLIPCODE(x2,y2);
int dx, dy;
while ( (c1|c2)!=0 )
{
if ( (c1&c2)!=0 )
return;
dx=x2-x1;
dy=y2-y1;
if ( c1!=0 )
{
if ( (c1&8)==8)
{
y1+=(0-x1)*dy/dx;
x1=0;
}
else if ( (c1&4)==4)
{
y1+=(m_Size.cx-1-x1)*dy/dx;
x1=m_Size.cx-1;
}
else if ((c1&2) == 2)
{
x1+=(0-y1)*dx/dy;
y1=0;
}
else
if ( (c1&1)==1)
{
x1+=(m_Size.cy-1-y1)*dx/dy;
y1=m_Size.cy-1;
}
c1=CLIPCODE(x1,y1);
}
else if ( c2!=0 )
{
if ( (c2&8)==8 )
{
y2+=(0-x2)*dy/dx;
x2=0;
}
else if ( (c2&4)==4 )
{
y2+=(m_Size.cx-1-x2)*dy/dx;
x2=m_Size.cx-1;
}
else if ( (c2&2)==2 )
{
x2+=(0-y2)*dx/dy;
y2=0;
}
else if ( (c2&1)==1 )
{
x2+=(m_Size.cy-1-y2)*dx/dy;
y2=m_Size.cy-1;
}
c2=CLIPCODE(x2,y2);
}
}
int d, x, y, ax, ay, sx, sy;
COLORREF Color=RGB ( B, G, R );
dx=x2-x1;
ax=abs ( dx )<<1;
sx=(dx<0) ? -1 : 1;
dy=y2-y1;
ay=abs ( dy )<<1;
sy=(dy<0) ? -1 : 1;
x=x1;
y=y1;
if ( ax>ay )
{
d=ay-(ax>>1);
while ( x!=x2 )
{
m_Bits[y*m_Size.cx+x]=Color;
if ( d>=0 )
{
y+=sy;
d-=ax;
}
x+=sx;
d+=ay;
}
}
else
{
d=ax-(ay>>1);
while ( y!=y2 )
{
m_Bits[y*m_Size.cx+x]=Color;
if ( d>=0 )
{
x+=sx;
d-=ay;
}
y+=sy;
d+=ax;
}
}
}
void CDIB::Line ( int x1, int y1, int x2, int y2, int R, int G, int B )
{
int d, x, y, ax, ay, sx, sy, dx, dy;
COLORREF Color=RGB ( B, G, R );
dx=x2-x1;
ax=abs ( dx )<<1;
sx=(dx<0) ? -1 : 1;
dy=y2-y1;
ay=abs ( dy )<<1;
sy=(dy<0) ? -1 : 1;
x=x1;
y=y1;
if ( ax>ay )
{
d=ay-(ax>>1);
while ( x!=x2 )
{
m_Bits[y*m_Size.cx+x]=Color;
if ( d>=0 )
{
y+=sy;
d-=ax;
}
x+=sx;
d+=ay;
}
}
else
{
d=ax-(ay>>1);
while ( y!=y2 )
{
m_Bits[y*m_Size.cx+x]=Color;
if ( d>=0 )
{
x+=sx;
d-=ay;
}
y+=sy;
d+=ax;
}
}
}
void CDIB::LineGlass ( int x1, int y1, int x2, int y2, int R, int G, int B, int A )
{
int d, x, y, ax, ay, sx, sy, dx, dy;
BYTE *dst=(BYTE *)m_Bits;
dx=x2-x1;
ax=abs ( dx )<<1;
sx=(dx<0) ? -1 : 1;
dy=y2-y1;
ay=abs ( dy )<<1;
sy=(dy<0) ? -1 : 1;
x=x1;
y=y1;
if ( ax>ay )
{
d=ay-(ax>>1);
while ( x!=x2 )
{
dst[(y*m_Size.cx+x)<<2]=(BYTE)(((B-dst[(y*m_Size.cx+x)<<2])*A+(dst[(y*m_Size.cx+x)<<2]<<8))>>8);
dst[((y*m_Size.cx+x)<<2)+1]=(BYTE)(((G-dst[((y*m_Size.cx+x)<<2)+1])*A+(dst[((y*m_Size.cx+x)<<2)+1]<<8))>>8);
dst[((y*m_Size.cx+x)<<2)+2]=(BYTE)(((R-dst[((y*m_Size.cx+x)<<2)+2])*A+(dst[((y*m_Size.cx+x)<<2)+2]<<8))>>8);
if ( d>=0 )
{
y+=sy;
d-=ax;
}
x+=sx;
d+=ay;
}
}
else
{
d=ax-(ay>>1);
while ( y!=y2 )
{
dst[(y*m_Size.cx+x)<<2]=(BYTE)(((B-dst[(y*m_Size.cx+x)<<2])*A+(dst[(y*m_Size.cx+x)<<2]<<8))>>8);
dst[((y*m_Size.cx+x)<<2)+1]=(BYTE)(((G-dst[((y*m_Size.cx+x)<<2)+1])*A+(dst[((y*m_Size.cx+x)<<2)+1]<<8))>>8);
dst[((y*m_Size.cx+x)<<2)+2]=(BYTE)(((R-dst[((y*m_Size.cx+x)<<2)+2])*A+(dst[((y*m_Size.cx+x)<<2)+2]<<8))>>8);
if ( d>=0 )
{
x+=sx;
d-=ay;
}
y+=sy;
d+=ax;
}
}
}
BOOL
CDIB::operator == (const CDIB &dib) const
{
if (m_Size != dib.m_Size)
return FALSE;
if ((NULL == m_Bits) || (NULL == dib.m_Bits))
return FALSE;
if (0 != memcmp (&m_Info, &dib.m_Info, sizeof (BITMAPINFO)))
return FALSE;
if (0 != memcmp (m_Bits, dib.m_Bits, m_Info.bmiHeader.biSizeImage))
return FALSE;
return TRUE;
}
CDIB &
CDIB::operator = (const CDIB &dib)
{
CopyFrom (&dib);
return *this;
}
DIBSaveResult
CDIB::SavePPM (CString cstrFileName, UINT uDescID)
{
FILE *fp;
fp = fopen (cstrFileName,"wb");
if (NULL == fp)
{
return DIB_SAVE_CANT_WRITE;
}
fprintf (fp,"P6\n");
CString cstrDesc;
if (uDescID && cstrDesc.LoadString(uDescID))
{ // Description string ID specified and loaded successfully
fprintf (fp,"# %s\n", cstrDesc);
}
fprintf (fp, "%d %d\n",
m_Size.cx,
m_Size.cy);
fprintf (fp,"255\n");
for (int y=m_Size.cy - 1; y>=0; y--)
for (int x=0; x= 0; i--) /* Read each row (reverse) */
for (j=0; j < Width; j++) /* Read each column */
if (!bPPM3)
{ // PPM 6
BYTE rgb[3];
if (fread (rgb, 3, 1, fp) != 1)
{ // Can't read pixel
res = DIB_LOAD_NOFILE_OR_CORRUPT;
goto cleanup;
}
else
{
ColorAt(j,i) = RGB(rgb[2],rgb[1],rgb[0]);
}
}
else
{ // PPM 3
int r, g, b;
if (3 != fscanf(fp, "%d %d %d", &b, &g, &r))
{ // Can't read pixel
res = DIB_LOAD_NOFILE_OR_CORRUPT;
goto cleanup;
}
else
{
ColorAt(j,i) = RGB((BYTE)r, (BYTE)g, (BYTE)b);
}
}
cleanup:
if (NULL != fp)
{
fclose (fp);
}
return res;
}