久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

3

 啟蒙彩魂 2011-02-27
// dibapi.h////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _INC_DIBAPI
#define _INC_DIBAPI
// DIB句柄
DECLARE_HANDLE(HDIB);
// DIB常量
#define PALVERSION   0x300
/* DIB宏 */
// 判斷是否是Win 3.0的DIB
#define IS_WIN30_DIB(lpbi)  ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
// 計(jì)算矩形區(qū)域的寬度
#define RECTWIDTH(lpRect)     ((lpRect)->right - (lpRect)->left)
// 計(jì)算矩形區(qū)域的高度
#define RECTHEIGHT(lpRect)    ((lpRect)->bottom - (lpRect)->top)
// 在計(jì)算圖像大小時(shí),,采用公式:biSizeImage = biWidth' × biHeight,。
// 是biWidth',而不是biWidth,,這里的biWidth'必須是4的整倍數(shù),,表示
// 大于或等于biWidth的,離4最近的整倍數(shù),。WIDTHBYTES就是用來計(jì)算
// biWidth'
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)
// PCX文件頭結(jié)構(gòu)
typedef struct{
   BYTE bManufacturer;
   BYTE bVersion;
   BYTE bEncoding;
   BYTE bBpp;
   WORD wLeft;
   WORD wTop;
   WORD wRight;
   WORD wBottom;
   WORD wXResolution;
   WORD wYResolution;
   BYTE bPalette[48];
   BYTE bReserved;
   BYTE bPlanes;
   WORD wLineBytes;
   WORD wPaletteType;
   WORD wSrcWidth;
   WORD wSrcDepth;
   BYTE bFiller[54];
} PCXHEADER;
// 函數(shù)原型
BOOL      WINAPI  PaintDIB (HDC, LPRECT, HDIB, LPRECT, CPalette* pPal);
BOOL      WINAPI  CreateDIBPalette(HDIB hDIB, CPalette* cPal);
LPSTR     WINAPI  FindDIBBits (LPSTR lpbi);
DWORD     WINAPI  DIBWidth (LPSTR lpDIB);
DWORD     WINAPI  DIBHeight (LPSTR lpDIB);
WORD      WINAPI  PaletteSize (LPSTR lpbi);
WORD      WINAPI  DIBNumColors (LPSTR lpbi);
WORD   WINAPI  DIBBitCount(LPSTR lpbi);
HGLOBAL   WINAPI  CopyHandle (HGLOBAL h);
BOOL      WINAPI  SaveDIB (HDIB hDib, CFile& file);
HDIB      WINAPI  ReadDIBFile(CFile& file);
BOOL      WINAPI  DIBToPCX256(LPSTR lpDIB, CFile& file);
HDIB      WINAPI  ReadPCX256(CFile& file);
#endif //!_INC_DIBAPI
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************************************************
//  文件名:dibapi.cpp
//
//  DIB(Independent Bitmap) API函數(shù)庫(kù):
//
//  PaintDIB()          - 繪制DIB對(duì)象
//  CreateDIBPalette()  - 創(chuàng)建DIB對(duì)象調(diào)色板
//  FindDIBBits()       - 返回DIB圖像象素起始位置
//  DIBWidth()          - 返回DIB寬度
//  DIBHeight()         - 返回DIB高度
//  PaletteSize()       - 返回DIB調(diào)色板大小
//  DIBNumColors()      - 計(jì)算DIB調(diào)色板顏色數(shù)目
//  CopyHandle()        - 拷貝內(nèi)存塊
//
//  SaveDIB()           - 將DIB保存到指定文件中
//  ReadDIBFile()       - 重指定文件中讀取DIB對(duì)象
//
//  DIBToPCX256()  - 將指定的256色DIB對(duì)象保存為256色PCX文件
//  ReadPCX256()  - 讀取256色PCX文件
//
// ************************************************************************
#include "stdafx.h"
#include "dibapi.h"
#include <io.h>
#include <errno.h>
#include <math.h>
#include <direct.h>
/*
 * Dib文件頭標(biāo)志(字符串"BM",,寫DIB時(shí)用到該常數(shù))
 */
#define DIB_HEADER_MARKER   ((WORD) ('M' << 8) | 'B')
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   PaintDIB()
 *
 * 參數(shù):
 *   HDC hDC            - 輸出設(shè)備DC
 *   LPRECT lpDCRect    - 繪制矩形區(qū)域
 *   HDIB hDIB          - 指向DIB對(duì)象的指針
 *   LPRECT lpDIBRect   - 要輸出的DIB區(qū)域
 *   CPalette* pPal     - 指向DIB對(duì)象調(diào)色板的指針
 *
 * 返回值:
 *   BOOL               - 繪制成功返回TRUE,否則返回FALSE,。
 *
 * 說明:
 *   該函數(shù)主要用來繪制DIB對(duì)象,。其中調(diào)用了StretchDIBits()或者
 * SetDIBitsToDevice()來繪制DIB對(duì)象。輸出的設(shè)備由由參數(shù)hDC指
 * 定,;繪制的矩形區(qū)域由參數(shù)lpDCRect指定,;輸出DIB的區(qū)域由參數(shù)
 * lpDIBRect指定。
 *
 ************************************************************************/
BOOL WINAPI PaintDIB(HDC     hDC,
     LPRECT  lpDCRect,
     HDIB    hDIB,
     LPRECT  lpDIBRect,
     CPalette* pPal)
{
 LPSTR    lpDIBHdr;            // BITMAPINFOHEADER指針
 LPSTR    lpDIBBits;           // DIB象素指針
 BOOL     bSuccess=FALSE;      // 成功標(biāo)志
 HPALETTE hPal=NULL;           // DIB調(diào)色板
 HPALETTE hOldPal=NULL;        // 以前的調(diào)色板
 // 判斷DIB對(duì)象是否為空
 if (hDIB == NULL)
 {
  // 返回
  return FALSE;
 }
 // 鎖定DIB
 lpDIBHdr  = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
 // 找到DIB圖像象素起始位置
 lpDIBBits = ::FindDIBBits(lpDIBHdr);
 // 獲取DIB調(diào)色板,,并選中它
 if (pPal != NULL)
 {
  hPal = (HPALETTE) pPal->m_hObject;
  // 選中調(diào)色板
  hOldPal = ::SelectPalette(hDC, hPal, TRUE);
 }
 // 設(shè)置顯示模式
 ::SetStretchBltMode(hDC, COLORONCOLOR);
 // 判斷是調(diào)用StretchDIBits()還是SetDIBitsToDevice()來繪制DIB對(duì)象
 if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDIBRect)) &&
    (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
 {
  // 原始大小,,不用拉伸。
  bSuccess = ::SetDIBitsToDevice(hDC,                    // hDC
           lpDCRect->left,             // DestX
           lpDCRect->top,              // DestY
           RECTWIDTH(lpDCRect),        // nDestWidth
           RECTHEIGHT(lpDCRect),       // nDestHeight
           lpDIBRect->left,            // SrcX
           (int)DIBHeight(lpDIBHdr) -
           lpDIBRect->top -
           RECTHEIGHT(lpDIBRect),   // SrcY
           0,                          // nStartScan
           (WORD)DIBHeight(lpDIBHdr),  // nNumScans
           lpDIBBits,                  // lpBits
           (LPBITMAPINFO)lpDIBHdr,     // lpBitsInfo
           DIB_RGB_COLORS);            // wUsage
 }
    else
 {
  // 非原始大小,,拉伸,。
  bSuccess = ::StretchDIBits(hDC,                          // hDC
          lpDCRect->left,                 // DestX
          lpDCRect->top,                  // DestY
          RECTWIDTH(lpDCRect),            // nDestWidth
          RECTHEIGHT(lpDCRect),           // nDestHeight
          lpDIBRect->left,                // SrcX
          lpDIBRect->top,                 // SrcY
          RECTWIDTH(lpDIBRect),           // wSrcWidth
          RECTHEIGHT(lpDIBRect),          // wSrcHeight
          lpDIBBits,                      // lpBits
          (LPBITMAPINFO)lpDIBHdr,         // lpBitsInfo
          DIB_RGB_COLORS,                 // wUsage
          SRCCOPY);                       // dwROP
 }
 
    // 解除鎖定
 ::GlobalUnlock((HGLOBAL) hDIB);
 
 // 恢復(fù)以前的調(diào)色板
 if (hOldPal != NULL)
 {
  ::SelectPalette(hDC, hOldPal, TRUE);
 }
 
 // 返回
 return bSuccess;
}
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   CreateDIBPalette()
 *
 * 參數(shù):
 *   HDIB hDIB          - 指向DIB對(duì)象的指針
 *   CPalette* pPal     - 指向DIB對(duì)象調(diào)色板的指針
 *
 * 返回值:
 *   BOOL               - 創(chuàng)建成功返回TRUE,否則返回FALSE,。
 *
 * 說明:
 *   該函數(shù)按照DIB創(chuàng)建一個(gè)邏輯調(diào)色板,,從DIB中讀取顏色表并存到調(diào)色板中,
 * 最后按照該邏輯調(diào)色板創(chuàng)建一個(gè)新的調(diào)色板,,并返回該調(diào)色板的句柄,。這樣
 * 可以用最好的顏色來顯示DIB圖像。
 *
 ************************************************************************/

BOOL WINAPI CreateDIBPalette(HDIB hDIB, CPalette* pPal)
{
 // 指向邏輯調(diào)色板的指針
 LPLOGPALETTE lpPal;
 
 // 邏輯調(diào)色板的句柄
 HANDLE hLogPal;
 
 // 調(diào)色板的句柄
 HPALETTE hPal = NULL;
 
 // 循環(huán)變量
 int i;
 
 // 顏色表中的顏色數(shù)目
 WORD wNumColors;
 
 // 指向DIB的指針
 LPSTR lpbi;
 
 // 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
 LPBITMAPINFO lpbmi;
 
 // 指向BITMAPCOREINFO結(jié)構(gòu)的指針
 LPBITMAPCOREINFO lpbmc;
 
 // 表明是否是Win3.0 DIB的標(biāo)記
 BOOL bWinStyleDIB;
 
 // 創(chuàng)建結(jié)果
 BOOL bResult = FALSE;
 
 // 判斷DIB是否為空
 if (hDIB == NULL)
 {
  // 返回FALSE
  return FALSE;
 }
 
 // 鎖定DIB
 lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
 
 // 獲取指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
 lpbmi = (LPBITMAPINFO)lpbi;
 
 // 獲取指向BITMAPCOREINFO結(jié)構(gòu)的指針
 lpbmc = (LPBITMAPCOREINFO)lpbi;
 
 // 獲取DIB中顏色表中的顏色數(shù)目
 wNumColors = ::DIBNumColors(lpbi);
 
 if (wNumColors != 0)
 {
  // 分配為邏輯調(diào)色板內(nèi)存
  hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
         + sizeof(PALETTEENTRY)
         * wNumColors);
  
  // 如果內(nèi)存不足,,退出
  if (hLogPal == 0)
  {
   // 解除鎖定
   ::GlobalUnlock((HGLOBAL) hDIB);
   
   // 返回FALSE
   return FALSE;
  }
  
  lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
  
  // 設(shè)置版本號(hào)
  lpPal->palVersion = PALVERSION;
  
  // 設(shè)置顏色數(shù)目
  lpPal->palNumEntries = (WORD)wNumColors;
  
  // 判斷是否是WIN3.0的DIB
  bWinStyleDIB = IS_WIN30_DIB(lpbi);
  // 讀取調(diào)色板
  for (i = 0; i < (int)wNumColors; i++)
  {
   if (bWinStyleDIB)
   {
    // 讀取紅色分量
    lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
    
    // 讀取綠色分量
    lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
    
    // 讀取藍(lán)色分量
    lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
    
    // 保留位
    lpPal->palPalEntry[i].peFlags = 0;
   }
   else
   {
    // 讀取紅色分量
    lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
    
    // 讀取綠色分量
    lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
    
    // 讀取紅色分量
    lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
    
    // 保留位
    lpPal->palPalEntry[i].peFlags = 0;
   }
  }
  
  // 按照邏輯調(diào)色板創(chuàng)建調(diào)色板,,并返回指針
  bResult = pPal->CreatePalette(lpPal);
  
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hLogPal);
  
  // 釋放邏輯調(diào)色板
  ::GlobalFree((HGLOBAL) hLogPal);
 }
 
 // 解除鎖定
 ::GlobalUnlock((HGLOBAL) hDIB);
 
 // 返回結(jié)果
 return bResult;
}
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   FindDIBBits()
 *
 * 參數(shù):
 *   LPSTR lpbi         - 指向DIB對(duì)象的指針
 *
 * 返回值:
 *   LPSTR              - 指向DIB圖像象素起始位置
 *
 * 說明:
 *   該函數(shù)計(jì)算DIB中圖像象素的起始位置,并返回指向它的指針,。
 *
 ************************************************************************/

LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
 return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi));
}

/*************************************************************************
 *
 * 函數(shù)名稱:
 *   DIBWidth()
 *
 * 參數(shù):
 *   LPSTR lpbi         - 指向DIB對(duì)象的指針
 *
 * 返回值:
 *   DWORD              - DIB中圖像的寬度
 *
 * 說明:
 *   該函數(shù)返回DIB中圖像的寬度,。對(duì)于Windows 3.0 DIB,返回BITMAPINFOHEADER
 * 中的biWidth值,;對(duì)于其它返回BITMAPCOREHEADER中的bcWidth值,。
 *
 ************************************************************************/

DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
 // 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
 LPBITMAPINFOHEADER lpbmi;
 
 // 指向BITMAPCOREINFO結(jié)構(gòu)的指針
 LPBITMAPCOREHEADER lpbmc;
 // 獲取指針
 lpbmi = (LPBITMAPINFOHEADER)lpDIB;
 lpbmc = (LPBITMAPCOREHEADER)lpDIB;
 // 返回DIB中圖像的寬度
 if (IS_WIN30_DIB(lpDIB))
 {
  // 對(duì)于Windows 3.0 DIB,返回lpbmi->biWidth
  return lpbmi->biWidth;
 }
 else
 {
  // 對(duì)于其它格式的DIB,,返回lpbmc->bcWidth
  return (DWORD)lpbmc->bcWidth;
 }
}

/*************************************************************************
 *
 * 函數(shù)名稱:
 *   DIBHeight()
 *
 * 參數(shù):
 *   LPSTR lpDIB        - 指向DIB對(duì)象的指針
 *
 * 返回值:
 *   DWORD              - DIB中圖像的高度
 *
 * 說明:
 *   該函數(shù)返回DIB中圖像的高度,。對(duì)于Windows 3.0 DIB,,返回BITMAPINFOHEADER
 * 中的biHeight值;對(duì)于其它返回BITMAPCOREHEADER中的bcHeight值,。
 *
 ************************************************************************/

DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
 // 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
 LPBITMAPINFOHEADER lpbmi;
 
 // 指向BITMAPCOREINFO結(jié)構(gòu)的指針
 LPBITMAPCOREHEADER lpbmc;
 // 獲取指針
 lpbmi = (LPBITMAPINFOHEADER)lpDIB;
 lpbmc = (LPBITMAPCOREHEADER)lpDIB;
 // 返回DIB中圖像的寬度
 if (IS_WIN30_DIB(lpDIB))
 {
  // 對(duì)于Windows 3.0 DIB,,返回lpbmi->biHeight
  return lpbmi->biHeight;
 }
 else
 {
  // 對(duì)于其它格式的DIB,返回lpbmc->bcHeight
  return (DWORD)lpbmc->bcHeight;
 }
}

/*************************************************************************
 *
 * 函數(shù)名稱:
 *   PaletteSize()
 *
 * 參數(shù):
 *   LPSTR lpbi         - 指向DIB對(duì)象的指針
 *
 * 返回值:
 *   WORD               - DIB中調(diào)色板的大小
 *
 * 說明:
 *   該函數(shù)返回DIB中調(diào)色板的大小,。對(duì)于Windows 3.0 DIB,,返回顏色數(shù)目×
 * RGBQUAD的大小,;對(duì)于其它返回顏色數(shù)目×RGBTRIPLE的大小,。
 *
 ************************************************************************/

WORD WINAPI PaletteSize(LPSTR lpbi)
{
 // 計(jì)算DIB中調(diào)色板的大小
 if (IS_WIN30_DIB (lpbi))
 {
  //返回顏色數(shù)目×RGBQUAD的大小
  return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
 }
 else
 {
  //返回顏色數(shù)目×RGBTRIPLE的大小
  return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
 }
}

/*************************************************************************
 *
 * 函數(shù)名稱:
 *   DIBNumColors()
 *
 * 參數(shù):
 *   LPSTR lpbi         - 指向DIB對(duì)象的指針
 *
 * 返回值:
 *   WORD               - 返回調(diào)色板中顏色的種數(shù)
 *
 * 說明:
 *   該函數(shù)返回DIB中調(diào)色板的顏色的種數(shù)。對(duì)于單色位圖,,返回2,,
 * 對(duì)于16色位圖,返回16,,對(duì)于256色位圖,,返回256;對(duì)于真彩色
 * 位圖(24位),,沒有調(diào)色板,返回0,。
 *
 ************************************************************************/
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
 WORD wBitCount;
 // 對(duì)于Windows的DIB, 實(shí)際顏色的數(shù)目可以比象素的位數(shù)要少,。
 // 對(duì)于這種情況,則返回一個(gè)近似的數(shù)值,。
 
 // 判斷是否是WIN3.0 DIB
 if (IS_WIN30_DIB(lpbi))
 {
  DWORD dwClrUsed;
  
  // 讀取dwClrUsed值
  dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
  
  if (dwClrUsed != 0)
  {
   // 如果dwClrUsed(實(shí)際用到的顏色數(shù))不為0,,直接返回該值
   return (WORD)dwClrUsed;
  }
 }
 // 讀取象素的位數(shù)
 if (IS_WIN30_DIB(lpbi))
 {
  // 讀取biBitCount值
  wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
 }
 else
 {
  // 讀取biBitCount值
  wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
 }
 
 // 按照象素的位數(shù)計(jì)算顏色數(shù)目
 switch (wBitCount)
 {
  case 1:
   return 2;
  case 4:
   return 16;
  case 8:
   return 256;
  default:
   return 0;
 }
}

/*************************************************************************
 *
 * 函數(shù)名稱:
 *   DIBBitCount()
 *
 * 參數(shù):
 *   LPSTR lpbi         - 指向DIB對(duì)象的指針
 *
 * 返回值:
 *   WORD               - 返回調(diào)色板中顏色的種數(shù)
 *
 * 說明:
 *   該函數(shù)返回DIBBitCount。
 *
 ************************************************************************/
WORD WINAPI DIBBitCount(LPSTR lpbi)
{
 WORD wBitCount;
 // 讀取象素的位數(shù)
 if (IS_WIN30_DIB(lpbi))
 {
  // 讀取biBitCount值
  wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
 }
 else
 {
  // 讀取biBitCount值
  wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
 }
 
 // 返回wBitCount
 return wBitCount;
}
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   CopyHandle()
 *
 * 參數(shù):
 *   HGLOBAL h          - 要復(fù)制的內(nèi)存區(qū)域
 *
 * 返回值:
 *   HGLOBAL            - 復(fù)制后的新內(nèi)存區(qū)域
 *
 * 說明:
 *   該函數(shù)復(fù)制指定的內(nèi)存區(qū)域,。返回復(fù)制后的新內(nèi)存區(qū)域,,出錯(cuò)時(shí)返回0。
 *
 ************************************************************************/
HGLOBAL WINAPI CopyHandle (HGLOBAL h)
{
 if (h == NULL)
  return NULL;
 // 獲取指定內(nèi)存區(qū)域大小
 DWORD dwLen = ::GlobalSize((HGLOBAL) h);
 
 // 分配新內(nèi)存空間
 HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
 
 // 判斷分配是否成功
 if (hCopy != NULL)
 {
  // 鎖定
  void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
  void* lp     = ::GlobalLock((HGLOBAL) h);
  
  // 復(fù)制
  memcpy(lpCopy, lp, dwLen);
  
  // 解除鎖定
  ::GlobalUnlock(hCopy);
  ::GlobalUnlock(h);
 }
 return hCopy;
}
 
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   SaveDIB()
 *
 * 參數(shù):
 *   HDIB hDib          - 要保存的DIB
 *   CFile& file        - 保存文件CFile
 *
 * 返回值:
 *   BOOL               - 成功返回TRUE,,否則返回FALSE或者CFileException
 *
 * 說明:
 *   該函數(shù)將指定的DIB對(duì)象保存到指定的CFile中,。該CFile由調(diào)用程序打開和關(guān)閉。
 *
 *************************************************************************/

BOOL WINAPI SaveDIB(HDIB hDib, CFile& file)
{
 // Bitmap文件頭
 BITMAPFILEHEADER bmfHdr;
 
 // 指向BITMAPINFOHEADER的指針
 LPBITMAPINFOHEADER lpBI;
 
 // DIB大小
 DWORD dwDIBSize;
 if (hDib == NULL)
 {
  // 如果DIB為空,,返回FALSE
  return FALSE;
 }
 // 讀取BITMAPINFO結(jié)構(gòu),,并鎖定
 lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
 
 if (lpBI == NULL)
 {
  // 為空,返回FALSE
  return FALSE;
 }
 
 // 判斷是否是WIN3.0 DIB
 if (!IS_WIN30_DIB(lpBI))
 {
  // 不支持其它類型的DIB保存
  
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hDib);
  
  // 返回FALSE
  return FALSE;
 }
 // 填充文件頭
 // 文件類型"BM"
 bmfHdr.bfType = DIB_HEADER_MARKER;
 // 計(jì)算DIB大小時(shí),,最簡(jiǎn)單的方法是調(diào)用GlobalSize()函數(shù),。但是全局內(nèi)存大小并
 // 不是DIB真正的大小,它總是多幾個(gè)字節(jié),。這樣就需要計(jì)算一下DIB的真實(shí)大小,。
 
 // 文件頭大小+顏色表大小
 // (BITMAPINFOHEADER和BITMAPCOREHEADER結(jié)構(gòu)的第一個(gè)DWORD都是該結(jié)構(gòu)的大小)
 dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI);
 
 // 計(jì)算圖像大小
 if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
 {
  // 對(duì)于RLE位圖,,沒法計(jì)算大小,,只能信任biSizeImage內(nèi)的值
  dwDIBSize += lpBI->biSizeImage;
 }
 else
 {
  // 象素的大小
  DWORD dwBmBitsSize;
  // 大小為Width * Height
  dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight;
  
  // 計(jì)算出DIB真正的大小
  dwDIBSize += dwBmBitsSize;
  // 更新biSizeImage(很多BMP文件頭中biSizeImage的值是錯(cuò)誤的)
  lpBI->biSizeImage = dwBmBitsSize;
 }

 // 計(jì)算文件大小:DIB大?。獴ITMAPFILEHEADER結(jié)構(gòu)大小
 bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
 
 // 兩個(gè)保留字
 bmfHdr.bfReserved1 = 0;
 bmfHdr.bfReserved2 = 0;
 // 計(jì)算偏移量bfOffBits,,它的大小為Bitmap文件頭大小+DIB頭大?。伾泶笮?br> bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
             + PaletteSize((LPSTR)lpBI);
 // 嘗試寫文件
 TRY
 {
  // 寫文件頭
  file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
  
  // 寫DIB頭和象素
  file.WriteHuge(lpBI, dwDIBSize);
 }
 CATCH (CFileException, e)
 {
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hDib);
  
  // 拋出異常
  THROW_LAST();
 }
 END_CATCH
 
 // 解除鎖定
 ::GlobalUnlock((HGLOBAL) hDib);
 
 // 返回TRUE
 return TRUE;
}

/*************************************************************************
 *
 * 函數(shù)名稱:
 *   ReadDIBFile()
 *
 * 參數(shù):
 *   CFile& file        - 要讀取得文件文件CFile
 *
 * 返回值:
 *   HDIB               - 成功返回DIB的句柄,,否則返回NULL。
 *
 * 說明:
 *   該函數(shù)將指定的文件中的DIB對(duì)象讀到指定的內(nèi)存區(qū)域中,。除BITMAPFILEHEADER
 * 外的內(nèi)容都將被讀入內(nèi)存,。
 *
 *************************************************************************/
HDIB WINAPI ReadDIBFile(CFile& file)
{
 BITMAPFILEHEADER bmfHeader;
 DWORD dwBitsSize;
 HDIB hDIB;
 LPSTR pDIB;
 // 獲取DIB(文件)長(zhǎng)度(字節(jié))
 dwBitsSize = file.GetLength();
 // 嘗試讀取DIB文件頭
 if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
 {
  // 大小不對(duì),返回NULL,。
  return NULL;
 }
 // 判斷是否是DIB對(duì)象,,檢查頭兩個(gè)字節(jié)是否是"BM"
 if (bmfHeader.bfType != DIB_HEADER_MARKER)
 {
  // 非DIB對(duì)象,返回NULL,。
  return NULL;
 }
 // 為DIB分配內(nèi)存
 hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
 if (hDIB == 0)
 {
  // 內(nèi)存分配失敗,,返回NULL。
  return NULL;
 }
 
 // 鎖定
 pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
 // 讀象素
 if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
  dwBitsSize - sizeof(BITMAPFILEHEADER) )
 {
  // 大小不對(duì),。
  
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hDIB);
  
  // 釋放內(nèi)存
  ::GlobalFree((HGLOBAL) hDIB);
  
  // 返回NULL,。
  return NULL;
 }
 
 // 解除鎖定
 ::GlobalUnlock((HGLOBAL) hDIB);
 
 // 返回DIB句柄
 return hDIB;
}
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   DIBToPCX256()
 *
 * 參數(shù):
 *   LPSTR lpDIB        - 指向DIB對(duì)象的指針
 *   CFile& file        - 要保存的文件
 *
 * 返回值:
 *   BOOL               - 成功返回True,否則返回False,。
 *
 * 說明:
 *   該函數(shù)將指定的256色DIB對(duì)象保存為256色PCX文件,。
 *
 *************************************************************************/
BOOL WINAPI DIBToPCX256(LPSTR lpDIB, CFile& file)
{
 // 循環(huán)變量
 LONG i;
 LONG j;
 
 // DIB高度
 WORD wHeight;
 
 // DIB寬度
 WORD wWidth;
 
 // 中間變量
 BYTE bChar1;
 BYTE bChar2;
 
 // 指向源圖像象素的指針
 BYTE * lpSrc;
 
 // 指向編碼后圖像數(shù)據(jù)的指針
 BYTE * lpDst;
 
 // 圖像每行的字節(jié)數(shù)
 LONG lLineBytes;
 
 // 重復(fù)像素計(jì)數(shù)
 int  iCount;
 
 // 緩沖區(qū)已使用的字節(jié)數(shù)
 DWORD dwBuffUsed;
 
 // 指向DIB象素指針
 LPSTR   lpDIBBits;
 
 // 獲取DIB高度
 wHeight = (WORD) DIBHeight(lpDIB);
 
 // 獲取DIB寬度
 wWidth  = (WORD) DIBWidth(lpDIB);
 
 // 找到DIB圖像象素起始位置
 lpDIBBits = FindDIBBits(lpDIB);
 
 // 計(jì)算圖像每行的字節(jié)數(shù)
 lLineBytes = WIDTHBYTES(wWidth * 8);
 
 
 //*************************************************************************
 // PCX文件頭
 PCXHEADER pcxHdr;
 
 // 給文件頭賦值
 
 // PCX標(biāo)識(shí)碼
 pcxHdr.bManufacturer = 0x0A;
 
 // PCX版本號(hào)
 pcxHdr.bVersion = 5;
 
 // PCX編碼方式(1表示RLE編碼)
 pcxHdr.bEncoding = 1;
 
 // 像素位數(shù)(256色為8位)
 pcxHdr.bBpp = 8;
 
 // 圖像相對(duì)于屏幕的左上角X坐標(biāo)(以像素為單位)
 pcxHdr.wLeft = 0;
 
 // 圖像相對(duì)于屏幕的左上角Y坐標(biāo)(以像素為單位)
 pcxHdr.wTop = 0;
 
 // 圖像相對(duì)于屏幕的右下角X坐標(biāo)(以像素為單位)
 pcxHdr.wRight = wWidth - 1;
 
 // 圖像相對(duì)于屏幕的右下角Y坐標(biāo)(以像素為單位)
 pcxHdr.wBottom = wHeight - 1;
 
 // 圖像的水平分辨率
 pcxHdr.wXResolution = wWidth;
 
 // 圖像的垂直分辨率
 pcxHdr.wYResolution = wHeight;
 
 // 調(diào)色板數(shù)據(jù)(對(duì)于256色PCX無意義,直接賦值為0)
 for (i = 0; i < 48; i ++)
 {
  pcxHdr.bPalette[i] = 0;
 }
 
 // 保留域,,設(shè)定為0,。
 pcxHdr.bReserved = 0;
 
 // 圖像色彩平面數(shù)目(對(duì)于256色PCX設(shè)定為1)。
 pcxHdr.bPlanes = 1;
 
 // 圖像的寬度(字節(jié)為單位),,必須為偶數(shù),。
// if ((wWidth & 1) == 0)
// {
  pcxHdr.wLineBytes = wWidth;
// }
// else
// {
//  pcxHdr.wLineBytes = wWidth + 1;
// }
 
 // 圖像調(diào)色板的類型,1表示彩色或者單色圖像,,2表示圖像是灰度圖,。
 pcxHdr.wPaletteType = 1;
 
 // 制作該圖像的屏幕寬度(像素為單位)
 pcxHdr.wSrcWidth = 0;
 
 // 制作該圖像的屏幕高度(像素為單位)
 pcxHdr.wSrcDepth = 0;
 
 // 保留域,取值設(shè)定為0,。
 for (i = 0; i < 54; i ++)
 {
  pcxHdr.bFiller[i] = 0;
 }
 
 // 寫入文件頭
 file.Write((LPSTR)&pcxHdr, sizeof(PCXHEADER));
 
 //*******************************************************************************
 // 開始編碼
 
 // 開辟一片緩沖區(qū)(2被原始圖像大小)以保存編碼結(jié)果
 lpDst = new BYTE[wHeight * wWidth * 2];
 
 // 指明當(dāng)前已經(jīng)用了多少緩沖區(qū)(字節(jié)數(shù))
 dwBuffUsed = 0;
 
 // 每行
 for (i = 0; i < wHeight; i++)
 {
  // 指向DIB第i行,,第0個(gè)象素的指針
  lpSrc = (BYTE *)lpDIBBits + lLineBytes * (wHeight - 1 - i);
  
  // 給bChar1賦值
  bChar1 = *lpSrc;
  
  // 設(shè)置iCount為1
  iCount = 1;
  
  // 剩余列
  for (j = 1; j < wWidth; j ++)
  {
   // 指向DIB第i行,第j個(gè)象素的指針
   lpSrc++;
   
   // 讀取下一個(gè)像素
   bChar2 = *lpSrc;
   
   // 判斷是否和bChar1相同并且iCount < 63
   if ((bChar1 == bChar2) && (iCount < 63))
   {
    // 相同,,計(jì)數(shù)加1
    iCount ++;
    
    // 繼續(xù)讀下一個(gè)
   }
   else
   {
    // 不同,,或者iCount = 63
    
    // 寫入緩沖區(qū)
    if ((iCount > 1) || (bChar1 >= 0xC0))
    {
     // 保存碼長(zhǎng)信息
     lpDst[dwBuffUsed] = iCount | 0xC0;
     
     // 保存bChar1
     lpDst[dwBuffUsed + 1] = bChar1;
     
     // 更新dwBuffUsed
     dwBuffUsed += 2;
    }
    else
    {
     // 直接保存該值
     lpDst[dwBuffUsed] = bChar1;
     
     // 更新dwBuffUsed
     dwBuffUsed ++;
    }
    
    // 重新給bChar1賦值
    bChar1 = bChar2;
    
    // 設(shè)置iCount為1
    iCount = 1;
   }
  }
  
  // 保存每行最后一部分編碼
  if ((iCount > 1) || (bChar1 >= 0xC0))
  {
   // 保存碼長(zhǎng)信息
   lpDst[dwBuffUsed] = iCount | 0xC0;
   
   // 保存bChar1
   lpDst[dwBuffUsed + 1] = bChar1;
   
   // 更新dwBuffUsed
   dwBuffUsed += 2;
  }
  else
  {
   // 直接保存該值
   lpDst[dwBuffUsed] = bChar1;
   
   // 更新dwBuffUsed
   dwBuffUsed ++;
  }
 }
 
 // 寫入編碼結(jié)果
 file.WriteHuge((LPSTR)lpDst, dwBuffUsed);
 
 // 釋放內(nèi)存
 delete lpDst;
 
 //**************************************************************************
 // 寫入調(diào)色板信息
 
 // 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
 LPBITMAPINFO lpbmi;
 
 // 指向BITMAPCOREINFO結(jié)構(gòu)的指針
 LPBITMAPCOREINFO lpbmc;
 
 // 表明是否是Win3.0 DIB的標(biāo)記
 BOOL bWinStyleDIB;
 
 // 開辟一片緩沖區(qū)以保存調(diào)色板
 lpDst = new BYTE[769];
 
 // 調(diào)色板起始字節(jié)
 * lpDst = 0x0C;
 
 // 獲取指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)
 lpbmi = (LPBITMAPINFO)lpDIB;
 
 // 獲取指向BITMAPCOREINFO結(jié)構(gòu)的指針
 lpbmc = (LPBITMAPCOREINFO)lpDIB;
 
 // 判斷是否是WIN3.0的DIB
 bWinStyleDIB = IS_WIN30_DIB(lpDIB);
 
 // 讀取當(dāng)前DIB調(diào)色板
 for (i = 0; i < 256; i ++)
 {
  if (bWinStyleDIB)
  {
   // 讀取DIB調(diào)色板紅色分量
   lpDst[i * 3 + 1] = lpbmi->bmiColors[i].rgbRed;
   
   // 讀取DIB調(diào)色板綠色分量
   lpDst[i * 3 + 2] = lpbmi->bmiColors[i].rgbGreen;
   
   // 讀取DIB調(diào)色板藍(lán)色分量
   lpDst[i * 3 + 3] = lpbmi->bmiColors[i].rgbBlue;
  }
  else
  {
   // 讀取DIB調(diào)色板紅色分量
   lpDst[i * 3 + 1] = lpbmc->bmciColors[i].rgbtRed;
   
   // 讀取DIB調(diào)色板綠色分量
   lpDst[i * 3 + 2] = lpbmc->bmciColors[i].rgbtGreen;
   
   // 讀取DIB調(diào)色板藍(lán)色分量
   lpDst[i * 3 + 3] = lpbmc->bmciColors[i].rgbtBlue;
  }
 }
 
 // 寫入調(diào)色板信息
 file.Write((LPSTR)lpDst, 769);
 
 // 返回
 return TRUE;
}
/*************************************************************************
 *
 * 函數(shù)名稱:
 *   ReadPCX256()
 *
 * 參數(shù):
 *   CFile& file        - 要讀取的文件
 *
 * 返回值:
 *   HDIB               - 成功返回DIB的句柄,,否則返回NULL。
 *
 * 說明:
 *   該函數(shù)將讀取指定的256色PCX文件,。將讀取的結(jié)果保存在一個(gè)未壓縮
 * 編碼的DIB對(duì)象中,。
 *
 *************************************************************************/
HDIB WINAPI ReadPCX256(CFile& file)
{
 // PCX文件頭
 PCXHEADER pcxHdr;
 
 // DIB大小(字節(jié)數(shù))
 DWORD dwDIBSize;
 
 // DIB句柄
 HDIB hDIB;
 
 // DIB指針
 LPSTR pDIB;
 
 // 循環(huán)變量
 LONG i;
 LONG j;
 
 // 重復(fù)像素計(jì)數(shù)
 int  iCount;
 
 // DIB高度
 WORD wHeight;
 
 // DIB寬度
 WORD wWidth;
 
 // 圖像每行的字節(jié)數(shù)
 LONG lLineBytes;
 
 // 中間變量
 BYTE bChar;
 
 // 指向源圖像象素的指針
 BYTE * lpSrc;
 
 // 指向編碼后圖像數(shù)據(jù)的指針
 BYTE * lpDst;
 
 // 臨時(shí)指針
 BYTE * lpTemp;
 
 // 嘗試讀取PCX文件頭
 if (file.Read((LPSTR)&pcxHdr, sizeof(PCXHEADER)) != sizeof(PCXHEADER))
 {
  // 大小不對(duì),,返回NULL,。
  return NULL;
 }
 
 // 判斷是否是256色PCX文件,檢查第一個(gè)字節(jié)是否是0x0A,,
 if ((pcxHdr.bManufacturer != 0x0A) || (pcxHdr.bBpp != 8) || (pcxHdr.bPlanes != 1))
 {
  // 非256色PCX文件,,返回NULL。
  return NULL;
 }
 
 // 獲取圖像高度
 wHeight = pcxHdr.wBottom - pcxHdr.wTop + 1;
 
 // 獲取圖像寬度
 wWidth  = pcxHdr.wRight - pcxHdr.wLeft + 1;
 
 // 計(jì)算圖像每行的字節(jié)數(shù)
 lLineBytes = WIDTHBYTES(wWidth * 8);
 
 // 計(jì)算DIB長(zhǎng)度(字節(jié))
 dwDIBSize = sizeof(BITMAPINFOHEADER) + 1024 + wHeight * lLineBytes;
 
 // 為DIB分配內(nèi)存
 hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize);
 if (hDIB == 0)
 {
  // 內(nèi)存分配失敗,,返回NULL,。
  return NULL;
 }
 
 // 鎖定
 pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
 
 // 指向BITMAPINFOHEADER的指針
 LPBITMAPINFOHEADER lpBI;
 
 // 賦值
 lpBI = (LPBITMAPINFOHEADER) pDIB;
 
 // 給lpBI成員賦值
 lpBI->biSize = 40;
 lpBI->biWidth = wWidth;
 lpBI->biHeight = wHeight;
 lpBI->biPlanes = 1;
 lpBI->biBitCount = 8;
 lpBI->biCompression = BI_RGB;
 lpBI->biSizeImage = wHeight * lLineBytes;
 lpBI->biXPelsPerMeter = pcxHdr.wXResolution;
 lpBI->biYPelsPerMeter = pcxHdr.wYResolution;
 lpBI->biClrUsed = 0;
 lpBI->biClrImportant = 0;
 
 // 分配內(nèi)存以讀取編碼后的象素
 lpSrc = new BYTE[file.GetLength() - sizeof(PCXHEADER) - 769];
 lpTemp = lpSrc;
 
 // 讀取編碼后的象素
 if (file.ReadHuge(lpSrc, file.GetLength() - sizeof(PCXHEADER) - 769) !=
  file.GetLength() - sizeof(PCXHEADER) - 769 )
 {
  // 大小不對(duì)。
  
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hDIB);
  
  // 釋放內(nèi)存
  ::GlobalFree((HGLOBAL) hDIB);
  
  // 返回NULL,。
  return NULL;
 }
 
 // 計(jì)算DIB中像素位置
 lpDst = (BYTE *) FindDIBBits(pDIB);
 
 // 一行一行解碼
 for (j = 0; j <wHeight; j++)
 {
  i = 0;
  while (i < wWidth)
  {
   // 讀取一個(gè)字節(jié)
   bChar = *lpTemp;
   lpTemp++;
   
   if ((bChar & 0xC0) == 0xC0)
   {
    // 行程
    iCount = bChar & 0x3F;
    
    // 讀取下一個(gè)字節(jié)
    bChar = *lpTemp;
    lpTemp++;
    
    // bChar重復(fù)iCount次保存
    memset(&lpDst[(wHeight - j - 1) * lLineBytes + i], bChar, iCount);
    // 已經(jīng)讀取像素的個(gè)數(shù)加iCount
    i += iCount;
   }
   else
   {
    // 保存當(dāng)前字節(jié)
    lpDst[(wHeight - j - 1) * lLineBytes + i] = bChar;
    
    // 已經(jīng)讀取像素的個(gè)數(shù)加1
    i += 1;
   }
  }
 }
 
 // 釋放內(nèi)存
 delete lpSrc;
 
 //*************************************************************
 // 調(diào)色板
 
 // 讀調(diào)色板標(biāo)志位
 file.Read(&bChar, 1);
 if (bChar != 0x0C)
 {
  // 出錯(cuò)
  
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hDIB);
  
  // 釋放內(nèi)存
  ::GlobalFree((HGLOBAL) hDIB);
  
  // 返回NULL,。
  return NULL;
 }
 
 // 分配內(nèi)存以讀取編碼后的象素
 lpSrc = new BYTE[768];
 
 // 計(jì)算DIB中調(diào)色板的位置
 lpDst = (BYTE *) pDIB + sizeof(BITMAPINFOHEADER);
 
 // 讀取調(diào)色板
 if (file.Read(lpSrc, 768) != 768)
 {
  // 大小不對(duì)。
  
  // 解除鎖定
  ::GlobalUnlock((HGLOBAL) hDIB);
  
  // 釋放內(nèi)存
  ::GlobalFree((HGLOBAL) hDIB);
  
  // 返回NULL,。
  return NULL;
 }
 
 // 給調(diào)色板賦值
 for (i = 0; i < 256; i++)
 {
  lpDst[i * 4] = lpSrc[i * 3 + 2];
  lpDst[i * 4 + 1] = lpSrc[i * 3 + 1];
  lpDst[i * 4 + 2] = lpSrc[i * 3];
  lpDst[i * 4 + 3] = 0;
 }
 
 // 釋放內(nèi)存
 delete lpSrc;
 
 // 解除鎖定
 ::GlobalUnlock((HGLOBAL) hDIB);
 
 // 返回DIB句柄
 return hDIB;
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多