Dib.cpp
上传用户:weiyeyoule
上传日期:2007-01-03
资源大小:21k
文件大小:29k
源码类别:

GDI/图象编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "DIB.h"
  3. #define PPM_EXT             ".PPM"
  4. BOOL CDIB::Create ( int Width, int Height )
  5. {
  6.     Destroy ();
  7.     ZeroMemory ( &m_Info, sizeof (BITMAPINFO) );
  8.     m_Info.bmiHeader.biSize=sizeof (BITMAPINFOHEADER);
  9.     m_Info.bmiHeader.biWidth=Width;
  10.     m_Info.bmiHeader.biHeight=Height;
  11.     m_Info.bmiHeader.biPlanes=1;
  12.     m_Info.bmiHeader.biBitCount=32; 
  13.     m_Info.bmiHeader.biCompression=BI_RGB;
  14.     m_Info.bmiHeader.biSizeImage=Width*Height*4;
  15.     
  16.     m_Bitmap=CreateDIBSection ( NULL, &m_Info, DIB_RGB_COLORS, (void **)&m_Bits, NULL, NULL ); 
  17.     if ( m_Bitmap )
  18.     {
  19.         m_Size=CSize ( Width, Height );
  20.         return TRUE;
  21.     }
  22.     else
  23.     {
  24.         m_Size=CSize ( 0, 0 );
  25.         return FALSE;
  26.     }
  27. }
  28. BOOL CDIB::Create (CDC *pDC, UINT uBitmapID)
  29. {   // Creates from a bitmap
  30.     CDC BufferDC;
  31.     CBitmap BufferBitmap, *OldBitmap;
  32.     if (!BufferBitmap.LoadBitmap (uBitmapID))
  33.         return FALSE;   // Can't load resource bitmap
  34.     BITMAP bmpData;
  35.     if (!BufferBitmap.GetBitmap (&bmpData))
  36.         return FALSE;   // Can't get bitmap info
  37.     if (!Create (bmpData.bmWidth, bmpData.bmHeight))
  38.         return FALSE;   // Can't create DIB buffer
  39.     BufferDC.CreateCompatibleDC (pDC);
  40.     OldBitmap=BufferDC.SelectObject (&BufferBitmap);
  41.     GetDIBits (BufferDC.m_hDC, HBITMAP(BufferBitmap), 0, m_Size.cy, m_Bits, &(m_Info), DIB_RGB_COLORS); 
  42.     BufferDC.SelectObject (OldBitmap);
  43.     BufferBitmap.DeleteObject();
  44.     return TRUE;
  45. }
  46. void CDIB::Destroy ()
  47. {
  48.     if ( m_Bitmap )
  49.         DeleteObject ( m_Bitmap );
  50.     m_Bitmap=NULL;
  51.     m_Size=CSize ( 0, 0 );
  52. }
  53. void CDIB::GetFromDC ( CDC *pDC, int x, int y, int w, int h )
  54. {
  55.     // If DibSize Wrong Re-Create Dib
  56.     if ( (m_Size.cx!=w) || (m_Size.cy!=h) )
  57.         Create ( w, h );
  58.     
  59.     CDC BufferDC;
  60.     CBitmap BufferBitmap, *OldBitmap;
  61.     BufferDC.CreateCompatibleDC ( pDC );
  62.     BufferBitmap.CreateCompatibleBitmap ( pDC, w, h );
  63.     OldBitmap=BufferDC.SelectObject ( &BufferBitmap );
  64.     BufferDC.FillSolidRect ( 0, 0, w, h, 0 );
  65.     BufferDC.BitBlt ( 0, 0, w, h, pDC, x, y, SRCCOPY );
  66.     BufferDC.SelectObject ( OldBitmap );
  67.     GetDIBits ( pDC->m_hDC, HBITMAP(BufferBitmap), 0, h, m_Bits, &(m_Info), DIB_RGB_COLORS ); 
  68. }
  69. DIBLoadResult 
  70. CDIB::Load (CString cstrFile)
  71. {
  72.     if ((4 < cstrFile.GetLength()) && 
  73.         (0 == (cstrFile.Right(4)).CompareNoCase(PPM_EXT)))
  74.     {   // The extension is suggesting it's a binary PPM (P6) file
  75.         return LoadPPM ( cstrFile );
  76.     } 
  77.     // Unsupported file type
  78.     return DIB_LOAD_NOFILE_OR_CORRUPT;
  79. }
  80. void CDIB::Fill ( int R, int G, int B )
  81. {
  82.     COLORREF Color=RGB ( B, G, R );
  83.     int Size=m_Size.cx*m_Size.cy;
  84.     for ( int i=0; i<Size; i++ )
  85.         m_Bits[i]=Color;
  86. }
  87. void CDIB::FillGlass ( int R, int G, int B, int A )
  88. {
  89.     BYTE *dst=(BYTE*)m_Bits;
  90.     int Size=m_Size.cx*m_Size.cy;
  91.         
  92.     while ( Size-- )
  93.     {
  94.         dst[0]=(BYTE)(((B-dst[0])*A+(dst[0]<<8))>>8);
  95.         dst[1]=(BYTE)(((G-dst[1])*A+(dst[1]<<8))>>8);
  96.         dst[2]=(BYTE)(((R-dst[2])*A+(dst[2]<<8))>>8);   
  97.         dst+=4;
  98.     }
  99. }
  100. void CDIB::FillStippledGlass ( int R, int G, int B )
  101. {   
  102.     COLORREF Color=RGB ( B, G, R );
  103.     int w=m_Size.cx;
  104.     int h=m_Size.cy;
  105.     for ( int j=0; j<w; j++ )
  106.     {
  107.         for ( int i=0; i<h; i++ )
  108.         {
  109.             m_Bits[j*w+i]=((i+j)&0x1) ? m_Bits[j*w+i] : Color;
  110.         }
  111.     }
  112. }
  113. void CDIB::CopyTransparentlyFrom ( CDIB *Dib, int R, int G, int B )
  114. {
  115.     if ( m_Size!=Dib->m_Size )
  116.         return;
  117.     COLORREF *src=Dib->m_Bits;
  118.     COLORREF *dst=m_Bits;
  119.     COLORREF ColorKey=RGB ( B, G, R );
  120.     int Size=m_Size.cx*m_Size.cy;
  121.         
  122.     while ( Size-- )
  123.     {
  124.         dst[0]=(src[0]==ColorKey) ? dst[0] : src[0];    
  125.         dst++;
  126.         src++;
  127.     }
  128. }
  129. void CDIB::Add ( CDIB *Dib )
  130. {
  131.     if ( m_Size!=Dib->m_Size )
  132.         return;
  133.     BYTE *src=(BYTE*)Dib->m_Bits;
  134.     BYTE *dst=(BYTE*)m_Bits;
  135.     int Size=m_Size.cx*m_Size.cy;
  136.     int Sum;
  137.         
  138.     while ( Size-- )
  139.     {
  140.         Sum=src[0]+dst[0];
  141.         dst[0]=(BYTE)((Sum>255) ? 255 : Sum);
  142.         Sum=src[1]+dst[1];
  143.         dst[1]=(BYTE)((Sum>255) ? 255 : Sum);
  144.         Sum=src[2]+dst[2];
  145.         dst[2]=(BYTE)((Sum>255) ? 255 : Sum);   
  146.         dst+=4;
  147.         src+=4;
  148.     }
  149. }
  150. void CDIB::Blend ( CDIB *Dib, int A )
  151. {
  152.     if ( m_Size!=Dib->m_Size )
  153.         return;
  154.     BYTE *src=(BYTE*)Dib->m_Bits;
  155.     BYTE *dst=(BYTE*)m_Bits;
  156.     int Size=m_Size.cx*m_Size.cy;
  157.         
  158.     while ( Size-- )
  159.     {
  160.         dst[0]=(BYTE)(((src[0]-dst[0])*A+(dst[0]<<8))>>8);
  161.         dst[1]=(BYTE)(((src[1]-dst[1])*A+(dst[1]<<8))>>8);
  162.         dst[2]=(BYTE)(((src[2]-dst[2])*A+(dst[2]<<8))>>8);  
  163.         dst+=4;
  164.         src+=4;
  165.     }
  166. }
  167. void CDIB::Darken ( CDIB *Dib )
  168. {
  169.     if ( m_Size!=Dib->m_Size )
  170.         return;
  171.     BYTE *src=(BYTE*)Dib->m_Bits;
  172.     BYTE *dst=(BYTE*)m_Bits;
  173.     int Size=m_Size.cx*m_Size.cy;
  174.         
  175.     while ( Size-- )
  176.     {
  177.         dst[0]=(BYTE)((src[0]<dst[0]) ? src[0] : dst[0]);
  178.         dst[1]=(BYTE)((src[1]<dst[1]) ? src[1] : dst[1]);
  179.         dst[2]=(BYTE)((src[2]<dst[2]) ? src[2] : dst[2]);   
  180.         dst+=4;
  181.         src+=4;
  182.     }
  183. }
  184. void CDIB::Difference ( CDIB *Dib )
  185. {
  186.     if ( m_Size!=Dib->m_Size )
  187.         return;
  188.     BYTE *src=(BYTE*)Dib->m_Bits;
  189.     BYTE *dst=(BYTE*)m_Bits;
  190.     int Size=m_Size.cx*m_Size.cy;
  191.     int Difference;
  192.     while ( Size-- )
  193.     {
  194.         Difference=src[0]-dst[0];
  195.         dst[0]=(BYTE)((Difference<0) ? -Difference : Difference);
  196.         Difference=src[1]-dst[1];
  197.         dst[1]=(BYTE)((Difference<0) ? -Difference : Difference);
  198.         Difference=src[2]-dst[2];
  199.         dst[2]=(BYTE)((Difference<0) ? -Difference : Difference);   
  200.         dst+=4;
  201.         src+=4;
  202.     }
  203. }
  204. void CDIB::Lighten ( CDIB *Dib )
  205. {
  206.     if ( m_Size!=Dib->m_Size )
  207.         return;
  208.     BYTE *src=(BYTE*)Dib->m_Bits;
  209.     BYTE *dst=(BYTE*)m_Bits;
  210.     int Size=m_Size.cx*m_Size.cy;
  211.         
  212.     while ( Size-- )
  213.     {
  214.         dst[0]=(BYTE)((src[0]>dst[0]) ? src[0] : dst[0]);
  215.         dst[1]=(BYTE)((src[1]>dst[1]) ? src[1] : dst[1]);
  216.         dst[2]=(BYTE)((src[2]>dst[2]) ? src[2] : dst[2]);   
  217.         dst+=4;
  218.         src+=4;
  219.     }
  220. }
  221. void CDIB::Multiply ( CDIB *Dib )
  222. {
  223.     if ( m_Size!=Dib->m_Size )
  224.         return;
  225.     BYTE *src=(BYTE*)Dib->m_Bits;
  226.     BYTE *dst=(BYTE*)m_Bits;
  227.     int Size=m_Size.cx*m_Size.cy;
  228.         
  229.     while ( Size-- )
  230.     {
  231.         dst[0]=(BYTE)(((src[0])*(dst[0]))>>8);
  232.         dst[1]=(BYTE)(((src[1])*(dst[1]))>>8);
  233.         dst[2]=(BYTE)(((src[2])*(dst[2]))>>8);  
  234.         dst+=4;
  235.         src+=4;
  236.     }
  237. }
  238. void CDIB::Screen ( CDIB *Dib )
  239. {
  240.     if ( m_Size!=Dib->m_Size )
  241.         return;
  242.     BYTE *src=(BYTE*)Dib->m_Bits;
  243.     BYTE *dst=(BYTE*)m_Bits;
  244.     int Size=m_Size.cx*m_Size.cy;
  245.         
  246.     while ( Size-- )
  247.     {
  248.         dst[0]=(BYTE)(255-(((255-src[0])*(255-dst[0]))>>8));
  249.         dst[1]=(BYTE)(255-(((255-src[1])*(255-dst[1]))>>8));
  250.         dst[2]=(BYTE)(255-(((255-src[2])*(255-dst[2]))>>8));    
  251.         dst+=4;
  252.         src+=4;
  253.     }
  254. }
  255. //////////////////////////////////////////////////////////////////////
  256. // Rectangle Functions
  257. //////////////////////////////////////////////////////////////////////
  258. void CDIB::CopyRect ( CDIB *Dib, int x, int y )
  259. {
  260.     // Clip Rect
  261.     int px=(x>=0) ? x : 0;
  262.     int py=(y>=0) ? y : 0;
  263.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  264.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  265.     dx=(x>=0) ? dx : dx + x;
  266.     dy=(y>=0) ? dy : dy + y;
  267.     // If Nothing to Copy return
  268.     if ( (dx<=0) || (dy<=0) )
  269.         return;
  270.     // If DibSize Wrong Re-Create Dib
  271.     if ( (dx!=Dib->m_Size.cx) || (dy!=Dib->m_Size.cy) )
  272.         Dib->Create ( dx, dy );
  273.     // Prepare Buffer Addresses
  274.     COLORREF *src=m_Bits+(py*m_Size.cx)+px;
  275.     COLORREF *dst=Dib->m_Bits;
  276.     // Do Copy
  277.     while ( dy-- )
  278.     {
  279.         for ( int i=0; i<dx; i++ )
  280.             dst[i]=src[i];
  281.         src+=m_Size.cx;
  282.         dst+=Dib->m_Size.cx;
  283.     }
  284. }
  285. void CDIB::PasteRect ( CDIB *Dib, int x, int y )
  286. {
  287.     // Clip Rect
  288.     int px=(x>=0) ? x : 0;
  289.     int py=(y>=0) ? y : 0;
  290.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  291.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  292.     dx=(x>=0) ? dx : dx + x;
  293.     dy=(y>=0) ? dy : dy + y;
  294.     // If Nothing to Paste return
  295.     if ( (dx<=0) || (dy<=0) )
  296.         return;
  297.     // Prepare Buffer Addresses
  298.     COLORREF *src=Dib->m_Bits+((py-y)*Dib->m_Size.cx)+px-x;
  299.     COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
  300.     // Do Paste
  301.     while ( dy-- )
  302.     {
  303.         for ( int i=0; i<dx; i++ )
  304.             dst[i]=src[i];
  305.         src+=Dib->m_Size.cx;
  306.         dst+=m_Size.cx;
  307.     }
  308. }
  309. void CDIB::PasteCKRect ( CDIB *Dib, int x, int y, int R, int G, int B )
  310. {
  311.     // Clip Rect
  312.     int px=(x>=0) ? x : 0;
  313.     int py=(y>=0) ? y : 0;
  314.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  315.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  316.     dx=(x>=0) ? dx : dx + x;
  317.     dy=(y>=0) ? dy : dy + y;
  318.     // If Nothing to Paste return
  319.     if ( (dx<=0) || (dy<=0) )
  320.         return;
  321.     // Prepare Buffer Addresses
  322.     COLORREF *src=Dib->m_Bits+((py-y)*Dib->m_Size.cx)+px-x;
  323.     COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
  324.     COLORREF ColorKey=RGB ( B, G, R );
  325.     // Do Paste
  326.     while ( dy-- )
  327.     {
  328.         for ( int i=0; i<dx; i++ )
  329.             dst[i]=(src[i]==ColorKey) ? dst[i] : src[i];
  330.         src+=Dib->m_Size.cx;
  331.         dst+=m_Size.cx;
  332.     }
  333. }
  334. void CDIB::FillRect ( int x, int y, int w, int h, int R, int G, int B )
  335. {
  336.     // Clip Rect
  337.     int px=(x>=0) ? x : 0;
  338.     int py=(y>=0) ? y : 0;
  339.     int dx=((x+w)<m_Size.cx) ? w : m_Size.cx-x;
  340.     int dy=((y+h)<m_Size.cy) ? h : m_Size.cy-y;
  341.     dx=(x>=0) ? dx : dx + x;
  342.     dy=(y>=0) ? dy : dy + y;
  343.     // If Nothing to Fill return
  344.     if ( (dx<=0) || (dy<=0) )
  345.         return;
  346.     // Prepare Buffer Address
  347.     COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
  348.     COLORREF Color=RGB ( B, G, R );
  349.     // Do Fill
  350.     while ( dy-- )
  351.     {
  352.         for ( int i=0; i<dx; i++ )
  353.         {
  354.             dst[i]=Color;   
  355.         }
  356.         dst+=m_Size.cx;
  357.     }
  358. }
  359. void CDIB::FillGlassRect ( int x, int y, int w, int h, int R, int G, int B, int A )
  360. {
  361.     // Clip Rect
  362.     int px=(x>=0) ? x : 0;
  363.     int py=(y>=0) ? y : 0;
  364.     int dx=((x+w)<m_Size.cx) ? w : m_Size.cx-x;
  365.     int dy=((y+h)<m_Size.cy) ? h : m_Size.cy-y;
  366.     dx=(x>=0) ? dx : dx + x;
  367.     dy=(y>=0) ? dy : dy + y;
  368.     // If Nothing to FillGlass return
  369.     if ( (dx<=0) || (dy<=0) )
  370.         return;
  371.     // Prepare Buffer Address
  372.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  373.     // Do FillGlass
  374.     while ( dy-- )
  375.     {
  376.         for ( int i=0; i<dx; i++ )
  377.         {
  378.             dst[0]=(BYTE)(((B-dst[0])*A+(dst[0]<<8))>>8);
  379.             dst[1]=(BYTE)(((G-dst[1])*A+(dst[1]<<8))>>8);
  380.             dst[2]=(BYTE)(((R-dst[2])*A+(dst[2]<<8))>>8);   
  381.             dst+=4;
  382.         }
  383.         dst+=(m_Size.cx-dx)<<2;
  384.     }
  385. }
  386. void CDIB::FillStippledGlassRect ( int x, int y, int w, int h, int R, int G, int B )
  387. {
  388.     // Clip Rect
  389.     int px=(x>=0) ? x : 0;
  390.     int py=(y>=0) ? y : 0;
  391.     int dx=((x+w)<m_Size.cx) ? w : m_Size.cx-x;
  392.     int dy=((y+h)<m_Size.cy) ? h : m_Size.cy-y;
  393.     dx=(x>=0) ? dx : dx + x;
  394.     dy=(y>=0) ? dy : dy + y;
  395.     // If Nothing to FillStippledGlass return
  396.     if ( (dx<=0) || (dy<=0) )
  397.         return;
  398.     // Prepare Buffer Address
  399.     COLORREF *dst=m_Bits+(py*m_Size.cx)+px;
  400.     COLORREF Color=RGB ( B, G, R );
  401.     // Do FillStippledGlass
  402.     for ( int j=0; j<dy; j++ )
  403.     {
  404.         for ( int i=0; i<dx; i++ )
  405.         {
  406.             dst[i]=((i+j)&0x1) ? dst[i] : Color;    
  407.         }
  408.         dst+=m_Size.cx;
  409.     }
  410. }
  411. void CDIB::AddRect ( CDIB *Dib, int x, int y )
  412. {
  413.     // Clip Rect
  414.     int px=(x>=0) ? x : 0;
  415.     int py=(y>=0) ? y : 0;
  416.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  417.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  418.     dx=(x>=0) ? dx : dx + x;
  419.     dy=(y>=0) ? dy : dy + y;
  420.     // If Nothing to Add return
  421.     if ( (dx<=0) || (dy<=0) )
  422.         return;
  423.     // Prepare Buffer Addresses
  424.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  425.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  426.     int Sum;
  427.     // Do Add
  428.     while ( dy-- )
  429.     {
  430.         for ( int i=0; i<dx; i++ )
  431.         {
  432.             Sum=src[0]+dst[0];
  433.             dst[0]=(BYTE)((Sum>255) ? 255 : Sum);
  434.             Sum=src[1]+dst[1];
  435.             dst[1]=(BYTE)((Sum>255) ? 255 : Sum);
  436.             Sum=src[2]+dst[2];
  437.             dst[2]=(BYTE)((Sum>255) ? 255 : Sum);   
  438.             dst+=4;
  439.             src+=4;
  440.         }
  441.         dst+=(m_Size.cx-dx)<<2;
  442.         src+=(Dib->m_Size.cx-dx)<<2;
  443.     }
  444. }
  445. void CDIB::BlendRect ( CDIB *Dib, int x, int y, int A )
  446. {
  447.     // Clip Rect
  448.     int px=(x>=0) ? x : 0;
  449.     int py=(y>=0) ? y : 0;
  450.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  451.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  452.     dx=(x>=0) ? dx : dx + x;
  453.     dy=(y>=0) ? dy : dy + y;
  454.     // If Nothing to Blend return
  455.     if ( (dx<=0) || (dy<=0) )
  456.         return;
  457.     // Prepare Buffer Addresses
  458.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  459.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  460.     // Do Blend
  461.     while ( dy-- )
  462.     {
  463.         for ( int i=0; i<dx; i++ )
  464.         {
  465.             dst[0]=(BYTE)(((src[0]-dst[0])*A+(dst[0]<<8))>>8);
  466.             dst[1]=(BYTE)(((src[1]-dst[1])*A+(dst[1]<<8))>>8);
  467.             dst[2]=(BYTE)(((src[2]-dst[2])*A+(dst[2]<<8))>>8);  
  468.             dst+=4;
  469.             src+=4;
  470.         }
  471.         dst+=(m_Size.cx-dx)<<2;
  472.         src+=(Dib->m_Size.cx-dx)<<2;
  473.     }
  474. }
  475. void CDIB::DarkenRect ( CDIB *Dib, int x, int y )
  476. {
  477.     // Clip Rect
  478.     int px=(x>=0) ? x : 0;
  479.     int py=(y>=0) ? y : 0;
  480.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  481.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  482.     dx=(x>=0) ? dx : dx + x;
  483.     dy=(y>=0) ? dy : dy + y;
  484.     // If Nothing to Darken return
  485.     if ( (dx<=0) || (dy<=0) )
  486.         return;
  487.     // Prepare Buffer Addresses
  488.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  489.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  490.     // Do Darken
  491.     while ( dy-- )
  492.     {
  493.         for ( int i=0; i<dx; i++ )
  494.         {
  495.             dst[0]=(BYTE)((src[0]<dst[0]) ? src[0] : dst[0]);
  496.             dst[1]=(BYTE)((src[1]<dst[1]) ? src[1] : dst[1]);
  497.             dst[2]=(BYTE)((src[2]<dst[2]) ? src[2] : dst[2]);   
  498.             dst+=4;
  499.             src+=4;
  500.         }
  501.         dst+=(m_Size.cx-dx)<<2;
  502.         src+=(Dib->m_Size.cx-dx)<<2;
  503.     }
  504. }
  505. void CDIB::DifferenceRect ( CDIB *Dib, int x, int y )
  506. {
  507.     // Clip Rect
  508.     int px=(x>=0) ? x : 0;
  509.     int py=(y>=0) ? y : 0;
  510.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  511.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  512.     dx=(x>=0) ? dx : dx + x;
  513.     dy=(y>=0) ? dy : dy + y;
  514.     // If Nothing to Difference return
  515.     if ( (dx<=0) || (dy<=0) )
  516.         return;
  517.     // Prepare Buffer Addresses
  518.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  519.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  520.     // Do Difference
  521.     while ( dy-- )
  522.     {
  523.         for ( int i=0; i<dx; i++ )
  524.         {
  525.             int Difference;
  526.             Difference=src[0]-dst[0];
  527.             dst[0]=(BYTE)((Difference<0) ? -Difference : Difference);
  528.             Difference=src[1]-dst[1];
  529.             dst[1]=(BYTE)((Difference<0) ? -Difference : Difference);
  530.             Difference=src[2]-dst[2];
  531.             dst[2]=(BYTE)((Difference<0) ? -Difference : Difference);   
  532.             dst+=4;
  533.             src+=4;
  534.         }
  535.         dst+=(m_Size.cx-dx)<<2;
  536.         src+=(Dib->m_Size.cx-dx)<<2;
  537.     }
  538. }
  539. void CDIB::LightenRect ( CDIB *Dib, int x, int y )
  540. {
  541.     // Clip Rect
  542.     int px=(x>=0) ? x : 0;
  543.     int py=(y>=0) ? y : 0;
  544.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  545.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  546.     dx=(x>=0) ? dx : dx + x;
  547.     dy=(y>=0) ? dy : dy + y;
  548.     // If Nothing to Lighten return
  549.     if ( (dx<=0) || (dy<=0) )
  550.         return;
  551.     // Prepare Buffer Addresses
  552.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  553.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  554.     // Do Lighten
  555.     while ( dy-- )
  556.     {
  557.         for ( int i=0; i<dx; i++ )
  558.         {
  559.             dst[0]=(BYTE)((src[0]>dst[0]) ? src[0] : dst[0]);
  560.             dst[1]=(BYTE)((src[1]>dst[1]) ? src[1] : dst[1]);
  561.             dst[2]=(BYTE)((src[2]>dst[2]) ? src[2] : dst[2]);
  562.             dst+=4;
  563.             src+=4;
  564.         }
  565.         dst+=(m_Size.cx-dx)<<2;
  566.         src+=(Dib->m_Size.cx-dx)<<2;
  567.     }
  568. }
  569. void CDIB::MultiplyRect ( CDIB *Dib, int x, int y )
  570. {
  571.     // Clip Rect
  572.     int px=(x>=0) ? x : 0;
  573.     int py=(y>=0) ? y : 0;
  574.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  575.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  576.     dx=(x>=0) ? dx : dx + x;
  577.     dy=(y>=0) ? dy : dy + y;
  578.     // If Nothing to Multiply return
  579.     if ( (dx<=0) || (dy<=0) )
  580.         return;
  581.     // Prepare Buffer Addresses
  582.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  583.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  584.     // Do Multiply
  585.     while ( dy-- )
  586.     {
  587.         for ( int i=0; i<dx; i++ )
  588.         {
  589.             dst[0]=(BYTE)(((src[0])*(dst[0]))>>8);
  590.             dst[1]=(BYTE)(((src[1])*(dst[1]))>>8);
  591.             dst[2]=(BYTE)(((src[2])*(dst[2]))>>8);
  592.             dst+=4;
  593.             src+=4;
  594.         }
  595.         dst+=(m_Size.cx-dx)<<2;
  596.         src+=(Dib->m_Size.cx-dx)<<2;
  597.     }
  598. }
  599. void CDIB::ScreenRect ( CDIB *Dib, int x, int y )
  600. {
  601.     // Clip Rect
  602.     int px=(x>=0) ? x : 0;
  603.     int py=(y>=0) ? y : 0;
  604.     int dx=((x+Dib->m_Size.cx)<m_Size.cx) ? Dib->m_Size.cx : m_Size.cx-x;
  605.     int dy=((y+Dib->m_Size.cy)<m_Size.cy) ? Dib->m_Size.cy : m_Size.cy-y;
  606.     dx=(x>=0) ? dx : dx + x;
  607.     dy=(y>=0) ? dy : dy + y;
  608.     // If Nothing to Screen return
  609.     if ( (dx<=0) || (dy<=0) )
  610.         return;
  611.     // Prepare Buffer Addresses
  612.     BYTE *src=(BYTE *)Dib->m_Bits+(((py-y)*Dib->m_Size.cx)+px-x)*4;
  613.     BYTE *dst=(BYTE *)m_Bits+((py*m_Size.cx)+px)*4;
  614.     // Do Screen
  615.     while ( dy-- )
  616.     {
  617.         for ( int i=0; i<dx; i++ )
  618.         {
  619.             dst[0]=(BYTE)(255-(((255-src[0])*(255-dst[0]))>>8));
  620.             dst[1]=(BYTE)(255-(((255-src[1])*(255-dst[1]))>>8));
  621.             dst[2]=(BYTE)(255-(((255-src[2])*(255-dst[2]))>>8));
  622.             dst+=4;
  623.             src+=4;
  624.         }
  625.         dst+=(m_Size.cx-dx)<<2;
  626.         src+=(Dib->m_Size.cx-dx)<<2;
  627.     }
  628. }
  629. //////////////////////////////////////////////////////////////////////
  630. // Line Functions
  631. //////////////////////////////////////////////////////////////////////
  632. #define CLIPCODE(x,y) (((x<0)?8:0)|((x>=m_Size.cx)?4:0)|((y<0)?2:0)|((y>=m_Size.cy)?1:0))
  633. void CDIB::ClippedLine ( int x1, int y1, int x2, int y2, int R, int G, int B )
  634. {
  635.     int c1=CLIPCODE(x1,y1), 
  636.         c2=CLIPCODE(x2,y2);
  637.     
  638.     int dx, dy;
  639.     while ( (c1|c2)!=0 )
  640.     {
  641.         if ( (c1&c2)!=0 )
  642.             return;
  643.         dx=x2-x1;
  644.         dy=y2-y1;
  645.         if ( c1!=0 )
  646.         {  
  647.             if ( (c1&8)==8)
  648.             {
  649.                 y1+=(0-x1)*dy/dx;
  650.                 x1=0;
  651.             }  
  652.             else if ( (c1&4)==4)
  653.             {
  654.                 y1+=(m_Size.cx-1-x1)*dy/dx;
  655.                 x1=m_Size.cx-1;
  656.             }  
  657.             else if ((c1&2) == 2)
  658.             {
  659.                 x1+=(0-y1)*dx/dy;
  660.                 y1=0;
  661.             }  
  662.             else
  663.             if ( (c1&1)==1)
  664.             {
  665.                 x1+=(m_Size.cy-1-y1)*dx/dy;
  666.                 y1=m_Size.cy-1;
  667.             }  
  668.             c1=CLIPCODE(x1,y1);
  669.          }  
  670.          else if ( c2!=0 )
  671.          {
  672.             if ( (c2&8)==8 )
  673.             {
  674.                 y2+=(0-x2)*dy/dx;
  675.                 x2=0;
  676.             }  
  677.             else if ( (c2&4)==4 )
  678.             {
  679.                 y2+=(m_Size.cx-1-x2)*dy/dx;
  680.                 x2=m_Size.cx-1;
  681.             }  
  682.             else if ( (c2&2)==2 )
  683.             {
  684.                 x2+=(0-y2)*dx/dy;
  685.                 y2=0;
  686.             }  
  687.             else if ( (c2&1)==1 )
  688.             {
  689.                 x2+=(m_Size.cy-1-y2)*dx/dy;
  690.                 y2=m_Size.cy-1;
  691.             }  
  692.             c2=CLIPCODE(x2,y2);
  693.         }  
  694.     }
  695.     
  696.     int d, x, y, ax, ay, sx, sy;
  697.     COLORREF Color=RGB ( B, G, R );
  698.     
  699.     dx=x2-x1;
  700.     ax=abs ( dx )<<1;
  701.     sx=(dx<0) ? -1 : 1;
  702.     dy=y2-y1;
  703.     ay=abs ( dy )<<1;
  704.     sy=(dy<0) ? -1 : 1;
  705.     x=x1;
  706.     y=y1;
  707.     
  708.     if ( ax>ay )
  709.     {
  710.         d=ay-(ax>>1);
  711.         while ( x!=x2 )
  712.         {
  713.             m_Bits[y*m_Size.cx+x]=Color;
  714.             if ( d>=0 )
  715.             {
  716.                 y+=sy;
  717.                 d-=ax;
  718.             }
  719.             x+=sx;
  720.             d+=ay;
  721.         }
  722.     }
  723.     else
  724.     {
  725.         d=ax-(ay>>1);
  726.         while ( y!=y2 )
  727.         {
  728.             m_Bits[y*m_Size.cx+x]=Color;
  729.             if ( d>=0 )
  730.             {
  731.                 x+=sx;
  732.                 d-=ay;
  733.             }
  734.             y+=sy;
  735.             d+=ax;
  736.         }
  737.     }
  738. }
  739. void CDIB::Line ( int x1, int y1, int x2, int y2, int R, int G, int B )
  740. {
  741.     int d, x, y, ax, ay, sx, sy, dx, dy;
  742.     COLORREF Color=RGB ( B, G, R );
  743.     
  744.     dx=x2-x1;
  745.     ax=abs ( dx )<<1;
  746.     sx=(dx<0) ? -1 : 1;
  747.     dy=y2-y1;
  748.     ay=abs ( dy )<<1;
  749.     sy=(dy<0) ? -1 : 1;
  750.     x=x1;
  751.     y=y1;
  752.     
  753.     if ( ax>ay )
  754.     {
  755.         d=ay-(ax>>1);
  756.         while ( x!=x2 )
  757.         {
  758.             m_Bits[y*m_Size.cx+x]=Color;
  759.             if ( d>=0 )
  760.             {
  761.                 y+=sy;
  762.                 d-=ax;
  763.             }
  764.             x+=sx;
  765.             d+=ay;
  766.         }
  767.     }
  768.     else
  769.     {
  770.         d=ax-(ay>>1);
  771.         while ( y!=y2 )
  772.         {
  773.             m_Bits[y*m_Size.cx+x]=Color;
  774.             if ( d>=0 )
  775.             {
  776.                 x+=sx;
  777.                 d-=ay;
  778.             }
  779.             y+=sy;
  780.             d+=ax;
  781.         }
  782.     }
  783. }
  784. void CDIB::LineGlass ( int x1, int y1, int x2, int y2, int R, int G, int B, int A )
  785. {
  786.     int d, x, y, ax, ay, sx, sy, dx, dy;
  787.     BYTE *dst=(BYTE *)m_Bits;
  788.     
  789.     dx=x2-x1;
  790.     ax=abs ( dx )<<1;
  791.     sx=(dx<0) ? -1 : 1;
  792.     dy=y2-y1;
  793.     ay=abs ( dy )<<1;
  794.     sy=(dy<0) ? -1 : 1;
  795.     x=x1;
  796.     y=y1;
  797.     
  798.     if ( ax>ay )
  799.     {
  800.         d=ay-(ax>>1);
  801.         while ( x!=x2 )
  802.         {
  803.             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);
  804.             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);
  805.             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);
  806.             if ( d>=0 )
  807.             {
  808.                 y+=sy;
  809.                 d-=ax;
  810.             }
  811.             x+=sx;
  812.             d+=ay;
  813.         }
  814.     }
  815.     else
  816.     {
  817.         d=ax-(ay>>1);
  818.         while ( y!=y2 )
  819.         {
  820.             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);
  821.             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);
  822.             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);
  823.             if ( d>=0 )
  824.             {
  825.                 x+=sx;
  826.                 d-=ay;
  827.             }
  828.             y+=sy;
  829.             d+=ax;
  830.         }
  831.     }
  832. }
  833. BOOL 
  834. CDIB::operator == (const CDIB &dib) const
  835. {
  836.     if (m_Size != dib.m_Size)
  837.         return FALSE;
  838.     if ((NULL == m_Bits) || (NULL == dib.m_Bits))
  839.         return FALSE;
  840.     if (0 != memcmp (&m_Info, &dib.m_Info, sizeof (BITMAPINFO)))
  841.         return FALSE;
  842.     if (0 != memcmp (m_Bits, dib.m_Bits, m_Info.bmiHeader.biSizeImage))
  843.         return FALSE;
  844.     return TRUE;
  845. }
  846. CDIB &
  847. CDIB::operator = (const CDIB &dib)
  848. {
  849.     CopyFrom (&dib); 
  850.     return *this;
  851. }
  852. DIBSaveResult 
  853. CDIB::SavePPM (CString cstrFileName, UINT uDescID)
  854. {
  855.     FILE *fp;
  856.     fp = fopen (cstrFileName,"wb");
  857.     if (NULL == fp)
  858.     {
  859.         return DIB_SAVE_CANT_WRITE;
  860.     }
  861.     fprintf (fp,"P6n");
  862.     CString cstrDesc;
  863.     if (uDescID && cstrDesc.LoadString(uDescID))
  864.     {   // Description string ID specified and loaded successfully
  865.         fprintf (fp,"# %sn", cstrDesc);
  866.     }
  867.     fprintf (fp, "%d %dn",
  868.              m_Size.cx,
  869.              m_Size.cy);
  870.     fprintf (fp,"255n");
  871.     for (int y=m_Size.cy - 1; y>=0; y--)
  872.         for (int x=0; x<m_Size.cx; x++)
  873.         {
  874.             COLORREF c = m_Bits[x + y * m_Size.cx];
  875.             if (3 != fprintf (fp, "%c%c%c", GetBValue(c), GetGValue(c), GetRValue(c)))
  876.             {
  877.                 fclose (fp);
  878.                 return DIB_SAVE_CANT_WRITE;
  879.             }
  880.         }
  881.     fclose (fp);
  882.     return DIB_SAVE_OK;
  883. }
  884. DIBSaveResult 
  885. CDIB::SaveBMP (CString cstrFileName)
  886. {
  887.     BITMAPFILEHEADER    hdr;
  888.     CFile file;
  889.     if( !file.Open( cstrFileName, CFile::modeWrite |CFile::modeCreate) )
  890.         return DIB_SAVE_CANT_WRITE;
  891.     // Fill in the fields of the file header 
  892.     hdr.bfType      = ((WORD) ('M' << 8) | 'B');    // is always "BM"
  893.     hdr.bfSize      = m_Info.bmiHeader.biSize + m_Info.bmiHeader.biSizeImage + sizeof( hdr );
  894.     hdr.bfReserved1 = 0;
  895.     hdr.bfReserved2 = 0;
  896.     hdr.bfOffBits   = (DWORD) (sizeof( hdr ) + m_Info.bmiHeader.biSize);
  897.     // Write the file header 
  898.     file.Write( &hdr, sizeof(hdr) );
  899.     // Write BITMAPINFO header
  900.     file.Write (&m_Info, m_Info.bmiHeader.biSize);
  901.     // Write the DIB header and the bits 
  902.     file.Write( m_Bits, m_Info.bmiHeader.biSizeImage );
  903.     return DIB_SAVE_OK;
  904. }
  905. DIBLoadResult 
  906. CDIB::LoadPPM (CString cstrFile)
  907. {
  908.     FILE *fp = NULL;
  909.     int i,j;
  910.     DIBLoadResult res = DIB_LOAD_OK;
  911.     BOOL bPPM3;
  912.     if ((cstrFile.GetLength() < int(strlen (PPM_EXT))) ||
  913.         stricmp (PPM_EXT, cstrFile.Right(strlen(PPM_EXT))))
  914.     {
  915.         /* No extension, create one */
  916.         cstrFile += PPM_EXT;
  917.     }
  918.     if ((fp = fopen (cstrFile,"rb"))==NULL)
  919.     {
  920.         res = DIB_LOAD_NOFILE_OR_CORRUPT;
  921.         goto cleanup;
  922.     }
  923.     char tmp[1024];
  924.     fgets (tmp,1024,fp); /* Get header */
  925.     if (!strcmp (tmp,"P6n"))   /* Test header */
  926.         bPPM3 = FALSE;  /* PPM6 - binary */
  927.     else if (!strcmp (tmp,"P3n"))
  928.         bPPM3 = TRUE;  /* PPM3 - ASCII */
  929.     else
  930.     {   /* Bad PPM header */
  931.         res = DIB_LOAD_NOFILE_OR_CORRUPT;
  932.         goto cleanup;
  933.     }
  934.     do    /* Read remarks (starting with '#' char) */
  935.         fgets (tmp,1024,fp);
  936.     while ('#' == tmp[0]); 
  937.     int Width,Height;
  938.     if (!strlen(tmp) || (2 != sscanf (tmp,"%d %d",&Width,&Height)))   /* Obtain width and height */
  939.     {
  940.         res = DIB_LOAD_NOFILE_OR_CORRUPT;
  941.         goto cleanup;
  942.     }
  943.     fgets (tmp,1024,fp); 
  944.     int MaxColor;
  945.     if (!strlen(tmp) || (1 != sscanf (tmp,"%d",&MaxColor)))  /* Get max color used */
  946.     {
  947.         res = DIB_LOAD_NOFILE_OR_CORRUPT;
  948.         goto cleanup;
  949.     }
  950.     if (!Create (Width, Height))
  951.     {
  952.         res = DIB_LOAD_NO_MEM;
  953.         goto cleanup;
  954.     }
  955.     for (i=Height - 1; i >= 0; i--)      /* Read each row (reverse) */
  956.         for (j=0; j < Width; j++)   /* Read each column */
  957.             if (!bPPM3)
  958.             {   // PPM 6
  959.                 BYTE rgb[3];
  960.                 if (fread (rgb, 3, 1, fp) != 1)
  961.                 {   // Can't read pixel
  962.                     res = DIB_LOAD_NOFILE_OR_CORRUPT;
  963.                     goto cleanup;
  964.                 }
  965.                 else
  966.                 {
  967.                     ColorAt(j,i) = RGB(rgb[2],rgb[1],rgb[0]);
  968.                 }
  969.             }
  970.             else
  971.             {   // PPM 3
  972.                 int r, g, b;
  973.                 if (3 != fscanf(fp, "%d %d %d", &b, &g, &r))
  974.                 {   // Can't read pixel
  975.                     res = DIB_LOAD_NOFILE_OR_CORRUPT;
  976.                     goto cleanup;
  977.                 }
  978.                 else
  979.                 {
  980.                     ColorAt(j,i) = RGB((BYTE)r, (BYTE)g, (BYTE)b);
  981.                 }
  982.             }
  983. cleanup:
  984.     if (NULL != fp)
  985.     {
  986.         fclose (fp);
  987.     }
  988.     return res;
  989. }