JDib.cpp
上传用户:milkenxj
上传日期:2007-01-18
资源大小:21k
文件大小:10k
源码类别:

图形图象

开发平台:

WINDOWS

  1. //*****************************************************************************
  2. //
  3. // JDib.cpp
  4. //
  5. //=============================================================================
  6. //
  7. // Copyright:
  8. //
  9. // Author:      老魏
  10. //
  11. // Date:        1999.04.06
  12. //
  13. // Description: CJDib 类实现文件
  14. //
  15. // Side Effects:
  16. //
  17. // Class:
  18. //
  19. // Function:
  20. //
  21. // Notes:
  22. //
  23. // Update:
  24. //
  25. // Date     Name     Description
  26. //
  27. // ======== ===================================================================
  28. // Known restrictions:
  29. //
  30. // Known bugs:
  31. //
  32. //*****************************************************************************
  33. #include "stdafx.h"
  34. #include "JDib.h"
  35. #ifdef _DEBUG
  36. #define new DEBUG_NEW
  37. #undef THIS_FILE
  38. static char THIS_FILE[] = __FILE__;
  39. #endif
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CJDib
  42. //**************************************************************
  43. // Name:        CJDib()
  44. //
  45. // Author:      老魏
  46. //
  47. // Date:        1999.04.06
  48. //
  49. // Description: 构造函数, 初始化成员变量
  50. //
  51. // Arguments:   无
  52. //
  53. // Return:      无
  54. //
  55. // Side Effects: no
  56. //               
  57. // Notes:       
  58. //
  59. // Known restrictions:  
  60. //
  61. // Err NO. Date     Name         Description
  62. //
  63. // Update:
  64. // Date     Name         Description
  65. // ======== ============ =============================
  66. //
  67. //****************************************************
  68. CJDib::CJDib()
  69. {
  70.     m_bSetPalette = TRUE;
  71.     m_lpBMFileHeader = NULL;
  72.     m_lpBMInfoHeader = NULL;
  73.     m_lpLogPalette = NULL;
  74.     m_nBytesPerLine = 0;
  75.     m_pData = NULL;
  76.     m_pFileBuffer = NULL;
  77. }
  78. //**************************************************************
  79. // Name:        ~CJDib()
  80. //
  81. // Author:      老魏
  82. //
  83. // Date:        1999.04.06
  84. //
  85. // Description: 析构函数, 释放不为空的数据和调色盘内存空间
  86. //
  87. // Arguments:   无
  88. //
  89. // Return:      无
  90. //
  91. // Side Effects: no
  92. //               
  93. // Notes:       
  94. //
  95. // Known restrictions:  
  96. //
  97. // Err NO. Date     Name         Description
  98. //
  99. // Update:
  100. // Date     Name         Description
  101. // ======== ============ =============================
  102. //
  103. //****************************************************
  104. CJDib::~CJDib()
  105. {
  106.     if (m_lpLogPalette)
  107.     {
  108.         LocalFree(m_lpLogPalette);
  109.     }
  110.     if (m_pFileBuffer)
  111.     {
  112.         LocalFree(m_pFileBuffer);
  113.     }
  114. }
  115. //**************************************************************
  116. // Name:        Read(CString strBMPName)
  117. //
  118. // Author:      老魏
  119. //
  120. // Date:        1999.04.06
  121. //
  122. // Description: 读取 BMP文件数据, 各种指针赋值和计算逻辑调色盘
  123. //              不支持 JPEG 或 PNG格式
  124. //
  125. // Arguments:
  126. //              CString strBMPName: BMP文件名
  127. //
  128. // Return:      
  129. //              TRUE: 成功
  130. //              FALSE: 失败
  131. //
  132. // Side Effects: no
  133. //               
  134. // Notes:       
  135. //
  136. // Known restrictions:  
  137. //
  138. // Err NO. Date     Name         Description
  139. //
  140. // Update:
  141. // Date     Name         Description
  142. // ======== ============ =============================
  143. //
  144. //****************************************************
  145. BOOL CJDib::Read(CString strBMPName)
  146. {
  147.     CFile File;
  148.     //按只读方式打开文件
  149.     BOOL bResult = File.Open(strBMPName, CFile::modeRead);
  150. if (!bResult)
  151. {
  152. CString strErrorMessage;
  153. strErrorMessage = "打开文件:" + strBMPName + "失败 !";
  154. AfxMessageBox(strErrorMessage);
  155. return FALSE;
  156. }
  157.     //取得文件长度
  158.     int nFileLength = File.GetLength();
  159.     //按文件长度申请空间
  160.     m_pFileBuffer = (char *)LocalAlloc(LPTR, nFileLength);
  161.     if (!m_pFileBuffer)
  162.     {
  163. AfxMessageBox("申请必须的内存空间失败 !");
  164.         return FALSE;
  165.     }
  166.     //读取文件所有数据
  167.     int nBytesRead = File.Read(m_pFileBuffer, nFileLength);
  168.     if (nBytesRead != nFileLength)
  169.     {
  170. AfxMessageBox("读取文件内容失败 !");
  171.         return FALSE;
  172.     }
  173.     //文件头指针赋值
  174.     m_lpBMFileHeader = (LPBITMAPFILEHEADER)m_pFileBuffer;
  175.     //判断文件类型
  176.     if (m_lpBMFileHeader->bfType != 0x4d42) // 'BM'
  177.     {
  178. CString strErrorMessage;
  179. strErrorMessage = "文件:" + strBMPName + "不是有效的 BMP文件 !";
  180. AfxMessageBox(strErrorMessage);
  181.         return FALSE;
  182.     }
  183.     //信息头指针赋值
  184.     m_lpBMInfoHeader = (LPBITMAPINFOHEADER)(m_pFileBuffer + sizeof(BITMAPFILEHEADER));
  185.     
  186.     //计算每行占用的字节数 (m_lpBMInfoHeader的biSizeImage成员有时为空不可用)
  187.     //m_nBytesPerLine = m_lpBMInfoHeader->biSizeImage / m_lpBMInfoHeader->biHeight;
  188.     m_nBytesPerLine = m_lpBMInfoHeader->biWidth * m_lpBMInfoHeader->biBitCount / 8;
  189.     if (m_nBytesPerLine % 4 != 0)
  190.         m_nBytesPerLine = (m_nBytesPerLine / 4 + 1) * 4;
  191.     //数据指针赋值
  192.     m_pData = m_pFileBuffer + m_lpBMFileHeader->bfOffBits;
  193.     //为调色盘申请空间
  194.     m_lpLogPalette = (LPLOGPALETTE)LocalAlloc(LPTR, sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY));
  195.     m_lpLogPalette->palVersion = 0x300;
  196.     //判断是否需使用调色盘
  197.     switch (m_lpBMInfoHeader->biBitCount)
  198.     {
  199.     case 0: //JPEG 或 PNG 格式
  200.         m_bSetPalette = FALSE;
  201.         break;
  202.         
  203.     case 1:
  204.         m_lpLogPalette->palNumEntries = 2;
  205.         m_bSetPalette = TRUE;
  206.         break;
  207.         
  208.     case 4:
  209.         m_lpLogPalette->palNumEntries = 16;
  210.         m_bSetPalette = TRUE;
  211.         break;
  212.         
  213.     case 8:
  214.         m_lpLogPalette->palNumEntries = 256;
  215.         m_bSetPalette = TRUE;
  216.         break;
  217.         
  218.     case 16:
  219.     case 24:
  220.     case 32:
  221.         m_bSetPalette = FALSE;
  222.         break;
  223.         
  224.     default:
  225. AfxMessageBox("文件色彩数不可识别 !");
  226.         return FALSE;
  227.     }
  228.     //申请临时空间以处理调色盘
  229.     char *pPalette = m_pFileBuffer + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  230.     if (!pPalette)
  231. {
  232. AfxMessageBox("申请必须的内存空间失败 !");
  233.         return FALSE;
  234. }
  235.     RGBQUAD rgbQuad[256];
  236.     //调色盘赋值
  237.     memcpy(rgbQuad, pPalette, sizeof(PALETTEENTRY) * m_lpLogPalette->palNumEntries);
  238.     for (int i = 0; i < m_lpLogPalette->palNumEntries; i ++)
  239.     {                                               
  240.         m_lpLogPalette->palPalEntry[i].peBlue = rgbQuad[i].rgbBlue;
  241.         m_lpLogPalette->palPalEntry[i].peGreen = rgbQuad[i].rgbGreen;
  242.         m_lpLogPalette->palPalEntry[i].peRed = rgbQuad[i].rgbRed;
  243.         m_lpLogPalette->palPalEntry[i].peFlags = rgbQuad[i].rgbReserved;
  244.     }
  245.     return TRUE;
  246. }
  247. //**************************************************************
  248. // Name:        ConvertToText(CString strBMPName)
  249. //
  250. // Author:      老魏
  251. //
  252. // Date:        1999.04.06
  253. //
  254. // Description: 将给定 BMP文件转换为文本文件, 仅支持 256色格式和真彩格式
  255. //
  256. // Arguments:
  257. //              CString strBMPName: BMP文件名
  258. //
  259. // Return:
  260. //              TRUE: 成功
  261. //              FALSE: 失败
  262. //
  263. // Side Effects: no
  264. //               
  265. // Notes:       
  266. //
  267. // Known restrictions:  
  268. //
  269. // Err NO. Date     Name         Description
  270. //
  271. // Update:
  272. // Date     Name         Description
  273. // ======== ============ =============================
  274. //
  275. //****************************************************
  276. BOOL CJDib::ConvertToText(CString strBMPName)
  277. {
  278.     //字符调色盘
  279. //后面将会根据像素的不同
  280. //灰度选择相应的字符
  281.     BYTE CharPalette[16];
  282.     CharPalette[0] = '#';
  283.     CharPalette[1] = 'M';
  284.     CharPalette[2] = '@';
  285.     CharPalette[3] = 'H';
  286.     CharPalette[4] = 'X';
  287.     CharPalette[5] = '$';
  288.     CharPalette[6] = '%';
  289.     CharPalette[7] = '+';
  290.     CharPalette[8] = '/';
  291.     CharPalette[9] = ';';
  292.     CharPalette[10] = ':';
  293.     CharPalette[11] = '=';
  294.     CharPalette[12] = '-';
  295.     CharPalette[13] = ',';
  296.     CharPalette[14] = '.';
  297.     CharPalette[15] = ' ';
  298.     
  299.     CString strTxtName = strBMPName;
  300.     //计算文本文件名
  301.     strTxtName = strTxtName.Left(strTxtName.Find('.'));
  302.     strTxtName += ".txt";
  303.     CStdioFile TxtFile;
  304.     //创建文本文件
  305.     if (!TxtFile.Open(strTxtName, CFile::modeCreate | CFile::modeWrite | CFile::typeText))
  306.     {
  307. CString strErrorMessage;
  308. strErrorMessage = "创建文本文件:" + strTxtName + "失败 !";
  309. AfxMessageBox(strErrorMessage);
  310.         return FALSE;
  311.     }
  312.     //读取 BMP文件数据
  313.     if (!Read(strBMPName))
  314.     {
  315.         return FALSE;
  316.     }
  317.     TxtFile.WriteString("Generated by 老魏!n");
  318.     //取得 BMP数据指针
  319.     BYTE *pData = (BYTE *)m_pData;
  320.     BYTE *pLine = pData;
  321.     for (int i = m_lpBMInfoHeader->biHeight - 1; i >= 0; i--)
  322.     {
  323.         //计算每行的数据指针
  324.         pLine = pData + i * m_nBytesPerLine;
  325.         CString strLineText;
  326.         for (int j = 0; j < m_lpBMInfoHeader->biWidth; j++)
  327.         {
  328.             int nRed, nGreen, nBlue, nValue;
  329.             //计算当前象素的 RGB三分量的值
  330.             switch (m_lpBMInfoHeader->biBitCount)
  331.             {
  332.             case 24:
  333.                 nRed = *pLine++;
  334.                 nGreen = *pLine++;
  335.                 nBlue = *pLine++;
  336.                 break;
  337.             case 8:
  338.                 nRed = m_lpLogPalette->palPalEntry[*pLine].peRed;
  339.                 nGreen = m_lpLogPalette->palPalEntry[*pLine].peGreen;
  340.                 nBlue = m_lpLogPalette->palPalEntry[*pLine].peBlue;
  341.                 pLine++;
  342.                 break;
  343.             default:
  344. AfxMessageBox("抱歉, 当前版本仅支持 8bit和24bit文件 !");
  345.                 return FALSE;
  346.             }
  347.             //计算灰度值
  348.             nValue = (nRed * 30 + nGreen * 59 + nBlue * 11) / 100;
  349.             //转换到文本
  350.             strLineText += CharPalette[nValue / 16];
  351.         }
  352.         //写入文本文件
  353.         TxtFile.WriteString(strLineText);
  354.         TxtFile.WriteString("n");
  355.     }
  356.     TxtFile.Close();
  357.     return TRUE;
  358. }