IMAGEAREAPROCESSES.CPP
上传用户:alisonmail
上传日期:2013-02-28
资源大小:500k
文件大小:56k
源码类别:

图片显示

开发平台:

Visual C++

  1. // ImageAreaProcesses.cpp
  2. #include "stdafx.h"
  3. #include "ImageAreaProcesses.h"
  4. #define MAX( a, b ) ( a > b ? a : b )
  5. /**************************************************************************
  6. *                                                                         *
  7. *                                Area Processes                           *
  8. *                                                                         *
  9. **************************************************************************/
  10. CImageAreaProcesses::CImageAreaProcesses()
  11. {
  12. }
  13. CImageAreaProcesses::CImageAreaProcesses( CImageObject *pImageObject )
  14. {
  15. m_pImageObject = pImageObject;
  16. }
  17. BOOL CImageAreaProcesses::MedianFilter( int nX1, int nY1, int nX2, int nY2, CImageObject *pImageObject )
  18. {
  19. if( pImageObject != NULL ) m_pImageObject = pImageObject;
  20. if( m_pImageObject == NULL ) return( FALSE );
  21. if( m_pImageObject->GetNumBits() == 1 ) return( FALSE );
  22. m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
  23. int nWidth = m_pImageObject->GetWidth();
  24. int nHeight = m_pImageObject->GetHeight();
  25. if( nX1 < 2 ) nX1 = 2;
  26. if( nY1 < 2 ) nY1 = 2;
  27. if( nX2 >= nWidth - 2 ) nX2 = nWidth - 2;
  28. if( nY2 >= nHeight - 2 ) nY2 = nHeight - 2;
  29. DWORD dwMedianList[9];
  30. int nLoc[9];
  31. unsigned char Data;
  32. unsigned char *pOldBuffer, *pNewBuffer, *pOldBits, *pNewBits, *pOldTemp, *pNewTemp;
  33. BITMAPFILEHEADER *pOldBFH, *pNewBFH;
  34. BITMAPINFOHEADER *pOldBIH, *pNewBIH;
  35. RGBQUAD *pOldPalette, *pNewPalette;
  36. int nWidthBytes, nNumColors, x, y, i, j, k, l;
  37. pOldBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() );
  38. if( pOldBuffer == NULL ) return( FALSE );
  39. pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
  40. pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
  41. nNumColors = m_pImageObject->GetNumColors();
  42. pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  43. pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  44. DWORD dwNewSize;
  45. HGLOBAL hNewDib;
  46. dwNewSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumColors * sizeof( RGBQUAD ) + nWidthBytes * m_pImageObject->GetHeight();
  47. hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
  48. if( hNewDib == NULL ){
  49. m_pImageObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
  50. ::GlobalUnlock( m_pImageObject->GetDib() );
  51. return( FALSE );
  52. }
  53. pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
  54. if( pNewBuffer == NULL ){
  55. ::GlobalFree( hNewDib );
  56. m_pImageObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
  57. ::GlobalUnlock( m_pImageObject->GetDib() );
  58. return( FALSE );
  59. }
  60. pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
  61. pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
  62. pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  63. pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  64. *pNewBFH = *pOldBFH;
  65. *pNewBIH = *pOldBIH;
  66. for( i=0; i<nNumColors; i++ ) pNewPalette[i] = pOldPalette[i];
  67. memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );
  68. unsigned char ucRed, ucGreen, ucBlue;
  69. switch( m_pImageObject->GetNumBits() ){
  70. case 8:
  71. for( y=nY1; y<=nY2; y++ ){
  72. pOldTemp = pOldBits;
  73. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  74. pOldTemp += ( nX1 - 1 );
  75. pNewTemp = pNewBits;
  76. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  77. pNewTemp += nX1;
  78. l = 0;
  79. for( x=nX1; x<=nX2; x++ ){
  80. // List all pixel gray values in the 3x3 area
  81. for( i=0; i<3; i++ ){
  82. Data = pOldTemp[i+l];
  83. dwMedianList[i] = ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  84. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  85. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100;
  86. nLoc[i] = ( i + l );
  87. }
  88. for( i=0; i<3; i++ ){
  89. Data = pOldTemp[i+l+nWidthBytes];
  90. dwMedianList[i+3] = ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  91. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  92. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100;
  93. nLoc[i+3] = ( i + l ) + nWidthBytes;
  94. }
  95. for( i=0; i<3; i++ ){
  96. Data = pOldTemp[i+l+nWidthBytes*2];
  97. dwMedianList[i+6] = ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  98. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  99. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100;
  100. nLoc[i+6] = ( i + l ) + nWidthBytes * 2;
  101. }
  102. // Sort the list;
  103. for( i=1; i<9; i++ ){
  104. for( j=0; j<i; j++ ){
  105. if( dwMedianList[i] < dwMedianList[j] ){
  106. DWORD dwTmp;
  107. int nTmp;
  108. dwTmp = dwMedianList[i];
  109. nTmp = nLoc[i];
  110. for( k=i; k>j; k-- ){
  111. dwMedianList[k] = dwMedianList[k-1];
  112. nLoc[k] = nLoc[k-1];
  113. }
  114. dwMedianList[j] = dwTmp;
  115. nLoc[j] = nTmp;
  116. break;
  117. }
  118. }
  119. }
  120. // Get the median RGB values and store them
  121. Data = pOldTemp[nLoc[4]];
  122. *pNewTemp++ = (unsigned char) m_pImageObject->GetNearestIndex( pNewPalette[Data].rgbRed, pNewPalette[Data].rgbGreen, pNewPalette[Data].rgbBlue, pNewPalette, nNumColors );
  123. l++;
  124. }
  125. }
  126. break;
  127. case 16:
  128. for( y=nY1; y<=nY2; y++ ){
  129. pOldTemp = pOldBits;
  130. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  131. pOldTemp += ( ( nX1 - 1 ) * 2 );
  132. pNewTemp = pNewBits;
  133. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  134. pNewTemp += ( nX1 * 2 );
  135. l = 0;
  136. for( x=nX1; x<=nX2; x++ ){
  137. // List all pixel gray values in the 3x3 area
  138. for( i=0; i<3; i++ ){
  139. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[(i+l)*2] ); 
  140. dwMedianList[i] = ( (DWORD) ucRed * 30 +
  141. (DWORD) ucGreen * 59 +
  142. (DWORD) ucBlue * 11 ) / 100;
  143. nLoc[i] = ( i + l ) * 2;
  144. }
  145. for( i=0; i<3; i++ ){
  146. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(i+l)*2] );
  147. dwMedianList[i+3] = ( (DWORD) ucRed * 30 +
  148. (DWORD) ucGreen * 59 +
  149. (DWORD) ucBlue * 11 ) / 100;
  150. nLoc[i+3] = ( i + l ) * 2 + nWidthBytes;
  151. }
  152. for( i=0; i<3; i++ ){
  153. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes*2+(i+l)*2] );
  154. dwMedianList[i+6] = ( (DWORD) ucRed * 30 +
  155. (DWORD) ucGreen * 59 +
  156. (DWORD) ucBlue * 11 ) / 100;
  157. nLoc[i+6] = ( i + l ) * 2 + nWidthBytes * 2;
  158. }
  159. // Sort the list;
  160. for( i=1; i<9; i++ ){
  161. for( j=0; j<i; j++ ){
  162. if( dwMedianList[i] < dwMedianList[j] ){
  163. DWORD dwTmp;
  164. int nTmp;
  165. dwTmp = dwMedianList[i];
  166. nTmp = nLoc[i];
  167. for( k=i; k>j; k-- ){
  168. dwMedianList[k] = dwMedianList[k-1];
  169. nLoc[k] = nLoc[k-1];
  170. }
  171. dwMedianList[j] = dwTmp;
  172. nLoc[j] = nTmp;
  173. break;
  174. }
  175. }
  176. }
  177. // Get the median RGB values and store them
  178. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nLoc[4]] );
  179. PUTRGB555( ucRed, ucGreen, ucBlue, pNewTemp );
  180. pNewTemp += 2;
  181. l++;
  182. }
  183. }
  184. break;
  185. case 24:
  186. for( y=nY1; y<=nY2; y++ ){
  187. pOldTemp = pOldBits;
  188. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  189. pOldTemp += ( ( nX1 - 1 ) * 3 );
  190. pNewTemp = pNewBits;
  191. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  192. pNewTemp += ( nX1 * 3 );
  193. l = 0;
  194. for( x=nX1; x<=nX2; x++ ){
  195. // List all pixel gray values in the 3x3 area
  196. for( i=0; i<3; i++ ){
  197. dwMedianList[i] = ( (DWORD) pOldTemp[(i+l)*3+2] * 30 +
  198. (DWORD) pOldTemp[(i+l)*3+1] * 59 +
  199. (DWORD) pOldTemp[(i+l)*3] * 11 ) / 100;
  200. nLoc[i] = ( i + l ) * 3;
  201. }
  202. for( i=0; i<3; i++ ){
  203. dwMedianList[i+3] = ( (DWORD) pOldTemp[nWidthBytes+(i+l)*3+2] * 30 +
  204. (DWORD) pOldTemp[nWidthBytes+(i+l)*3+1] * 59 +
  205. (DWORD) pOldTemp[nWidthBytes+(i+l)*3] * 11 ) / 100;
  206. nLoc[i+3] = ( i + l ) * 3 + nWidthBytes;
  207. }
  208. for( i=0; i<3; i++ ){
  209. dwMedianList[i+6] = ( (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3+2] * 30 +
  210. (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3+1] * 59 +
  211. (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3] * 11 ) / 100;
  212. nLoc[i+6] = ( i + l ) * 3 + nWidthBytes * 2;
  213. }
  214. // Sort the list;
  215. for( i=1; i<9; i++ ){
  216. for( j=0; j<i; j++ ){
  217. if( dwMedianList[i] < dwMedianList[j] ){
  218. DWORD dwTmp;
  219. int nTmp;
  220. dwTmp = dwMedianList[i];
  221. nTmp = nLoc[i];
  222. for( k=i; k>j; k-- ){
  223. dwMedianList[k] = dwMedianList[k-1];
  224. nLoc[k] = nLoc[k-1];
  225. }
  226. dwMedianList[j] = dwTmp;
  227. nLoc[j] = nTmp;
  228. break;
  229. }
  230. }
  231. }
  232. // Get the median RGB values and store them
  233. *pNewTemp++ = pOldTemp[nLoc[4]];
  234. *pNewTemp++ = pOldTemp[nLoc[4]+1];
  235. *pNewTemp++ = pOldTemp[nLoc[4]+2];
  236. l++;
  237. }
  238. }
  239. break;
  240. case 32:
  241. for( y=nY1; y<=nY2; y++ ){
  242. pOldTemp = pOldBits;
  243. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  244. pOldTemp += ( ( nX1 - 1 ) * 4 );
  245. pNewTemp = pNewBits;
  246. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  247. pNewTemp += ( nX1 * 4 );
  248. l = 0;
  249. for( x=nX1; x<=nX2; x++ ){
  250. // List all pixel gray values in the 3x3 area
  251. for( i=0; i<3; i++ ){
  252. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[(i+l)*4] ); 
  253. dwMedianList[i] = ( (DWORD) ucRed * 30 +
  254. (DWORD) ucGreen * 59 +
  255. (DWORD) ucBlue * 11 ) / 100;
  256. nLoc[i] = ( i + l ) * 4;
  257. }
  258. for( i=0; i<3; i++ ){
  259. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(i+l)*4] ); 
  260. dwMedianList[i+3] = ( (DWORD) ucRed * 30 +
  261. (DWORD) ucGreen * 59 +
  262. (DWORD) ucBlue * 11 ) / 100;
  263. nLoc[i+3] = ( i + l ) * 4 + nWidthBytes;
  264. }
  265. for( i=0; i<3; i++ ){
  266. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes*2+(i+l)*4] ); 
  267. dwMedianList[i+6] = ( (DWORD) ucRed * 30 +
  268. (DWORD) ucGreen * 59 +
  269. (DWORD) ucBlue * 11 ) / 100;
  270. nLoc[i+6] = ( i + l ) * 4 + nWidthBytes * 2;
  271. }
  272. // Sort the list;
  273. for( i=1; i<9; i++ ){
  274. for( j=0; j<i; j++ ){
  275. if( dwMedianList[i] < dwMedianList[j] ){
  276. DWORD dwTmp;
  277. int nTmp;
  278. dwTmp = dwMedianList[i];
  279. nTmp = nLoc[i];
  280. for( k=i; k>j; k-- ){
  281. dwMedianList[k] = dwMedianList[k-1];
  282. nLoc[k] = nLoc[k-1];
  283. }
  284. dwMedianList[j] = dwTmp;
  285. nLoc[j] = nTmp;
  286. break;
  287. }
  288. }
  289. }
  290. // Get the median RGB values and store them
  291. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nLoc[4]] );
  292. PUTRGB888( ucRed, ucGreen, ucBlue, pNewTemp );
  293. pNewTemp += 4;
  294. l++;
  295. }
  296. }
  297. break;
  298. }
  299. ::GlobalUnlock( m_pImageObject->GetDib() );
  300. ::GlobalFree( m_pImageObject->GetDib() );
  301. ::GlobalUnlock( hNewDib );
  302. m_pImageObject->SetDib( hNewDib );
  303. return( TRUE );
  304. }
  305. BOOL CImageAreaProcesses::ChangeContrast( int nContrast, int nX1, int nY1, int nX2, int nY2, CImageObject *pImageObject )
  306. {
  307. if( pImageObject != NULL ) m_pImageObject = pImageObject;
  308. if( m_pImageObject == NULL ) return( FALSE );
  309. if( m_pImageObject->GetNumBits() == 1 ) return( FALSE );
  310. if( nContrast == 100 ) return( TRUE );
  311. return( EqualizeContrast( nX1, nY1, nX2, nY2, nContrast ) );
  312. }
  313. BOOL CImageAreaProcesses::EqualizeContrast( int nX1, int nY1, int nX2, int nY2, int nThresholdFactor, CImageObject *pImageObject )
  314. {
  315. if( pImageObject != NULL ) m_pImageObject = pImageObject;
  316. if( m_pImageObject == NULL ) return( FALSE );
  317. if( m_pImageObject->GetNumBits() == 1 ) return( FALSE );
  318. int nDestMin = 0;
  319. int nDestMax = 255;
  320. BOOL bLessThanHalf, bCompleteImage;
  321. m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2, &bCompleteImage, &bLessThanHalf );
  322. unsigned char *pBuffer, *pBits, *pTemp;
  323. RGBQUAD *pPalette;
  324. int nWidthBytes, nNumColors;
  325. pBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() );
  326. if( pBuffer == NULL ) return( FALSE );
  327. nNumColors = m_pImageObject->GetNumColors();
  328. pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  329. pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  330. int *pnHistogramBuffer;
  331. pnHistogramBuffer = CreateHistogram( nX1, nY1, nX2, nY2, pBits, pPalette, nWidthBytes );
  332. if( pnHistogramBuffer == NULL ){
  333. ::GlobalUnlock( m_pImageObject->GetDib() );
  334. return( FALSE );
  335. }
  336. int x, y, nTemp, i;
  337. int nMinIndex = pnHistogramBuffer[256*4+2];
  338. int nMaxIndex = pnHistogramBuffer[256*4+3];
  339. int nNumSteps;
  340. int nThreshold = pnHistogramBuffer[256*4+1];
  341. if( nMinIndex >= 253 && nMaxIndex <= 2 ){
  342. ::GlobalUnlock( m_pImageObject->GetDib() );
  343. return( FALSE );
  344. }
  345. nNumSteps = nMaxIndex - nMinIndex + 1;
  346. if( nThresholdFactor != -1 ){
  347. nDestMin = ( nMinIndex * ( 200 - nThresholdFactor ) ) / 100;
  348. if( nDestMin > 255 ) nDestMin = 255;
  349. nDestMax = 255 - ( ( ( 255 - nMaxIndex ) * ( 200 - nThresholdFactor ) ) / 100 );
  350. if( nDestMax < 0 ) nDestMax = 0;
  351. while( nDestMin > nDestMax ) nDestMin--, nDestMax++;
  352. if( nDestMin > 255 ) nDestMin = 255;
  353. if( nDestMax < 0 ) nDestMax = 0;
  354. }
  355. double dStep = 256.0 / (double) nNumSteps;
  356. double dDestStep = (double) ( nDestMax - nDestMin + 1 ) / 256.0;
  357. double result;
  358. unsigned char ucRed, ucGreen, ucBlue, ucData;
  359. DWORD dwGray, dwNewGray;
  360. CPalette *_pPalette = m_pImageObject->GetPalette();
  361. RGBQUAD OldPalette[256];
  362. for( i=0; i<256; i++ ) memset( &OldPalette[i], 0, sizeof( RGBQUAD ) );
  363. for( i=0; i<nNumColors; i++ ) OldPalette[i] = pPalette[i];
  364. if( m_pImageObject->GetNumBits() <= 8 && ( bCompleteImage || !bLessThanHalf ) ){
  365. for( i=0; i<nNumColors; i++ ){
  366. OldPalette[i] = pPalette[i];
  367. dwGray = ( (DWORD) pPalette[i].rgbRed * 30 +
  368. (DWORD) pPalette[i].rgbGreen * 59 +
  369. (DWORD) pPalette[i].rgbBlue * 11 ) / 100;
  370. if( dwGray <= (DWORD) nThreshold ) pPalette[i].rgbRed = pPalette[i].rgbGreen = pPalette[i].rgbBlue = 0;
  371. else{
  372. nTemp = (int) dwGray - nMinIndex;
  373. if( nTemp < 0 ) nTemp = 0;
  374. result = (double) nTemp;
  375. result *= dStep;
  376. result += (double) nDestMin;
  377. result *= dDestStep;
  378. dwNewGray = (DWORD) result;
  379. if( dwNewGray > 255 ) dwNewGray = 255;
  380. if( dwNewGray > dwGray ){
  381. do{
  382. if( pPalette[i].rgbRed < 255 ) pPalette[i].rgbRed++;
  383. if( pPalette[i].rgbGreen < 255 ) pPalette[i].rgbGreen++;
  384. if( pPalette[i].rgbBlue < 255 ) pPalette[i].rgbBlue++;
  385. dwGray = ( (DWORD) pPalette[i].rgbRed * 30 +
  386. (DWORD) pPalette[i].rgbGreen * 59 +
  387. (DWORD) pPalette[i].rgbBlue * 11 ) / 100;
  388. } while( dwGray < dwNewGray );
  389. }
  390. else if( dwNewGray < dwGray ){
  391. do{
  392. if( pPalette[i].rgbRed > 0 ) pPalette[i].rgbRed--;
  393. if( pPalette[i].rgbGreen > 0 ) pPalette[i].rgbGreen--;
  394. if( pPalette[i].rgbBlue > 0 ) pPalette[i].rgbBlue--;
  395. dwGray = ( (DWORD) pPalette[i].rgbRed * 30 +
  396. (DWORD) pPalette[i].rgbGreen * 59 +
  397. (DWORD) pPalette[i].rgbBlue * 11 ) / 100;
  398. } while( dwGray > dwNewGray );
  399. }
  400. }
  401. }
  402. _pPalette->DeleteObject();
  403. LOGPALETTE *pLogPal = m_pImageObject->CreateLogPalette( pPalette, nNumColors );
  404. if( pLogPal != NULL ){
  405. _pPalette->CreatePalette( pLogPal );
  406. delete [] pLogPal;
  407. }
  408. }
  409. int nWidth = m_pImageObject->GetWidth();
  410. int nHeight = m_pImageObject->GetHeight();
  411. switch( m_pImageObject->GetNumBits() ){
  412. case 4:
  413. if( !bCompleteImage ){
  414. if( !bLessThanHalf ){
  415. for( y=0; y<nHeight; y++ ){
  416. pTemp = pBits;
  417. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  418. for( x=0; x<nWidth; x++ ){
  419. if( !( x >= nX1 && y >= nY1 && x <= nX2 && y <= nY2 ) ){
  420. ucData = pTemp[0];
  421. ucRed = OldPalette[ucData].rgbRed;
  422. ucGreen = OldPalette[ucData].rgbGreen;
  423. ucBlue = OldPalette[ucData].rgbBlue;
  424. ucData = (unsigned char) m_pImageObject->GetNearestIndex( ucRed, ucGreen, ucBlue, pPalette, nNumColors );
  425. pTemp[0] = ucData;
  426. }
  427. pTemp++;
  428. }
  429. }
  430. }
  431. for( y=nY1; y<=nY2; y++ ){
  432. pTemp = pBits;
  433. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  434. pTemp += ( nX1 / 2 );
  435. for( x=nX1; x<=nX2; x++ ){
  436. ucData = pTemp[0];
  437. if( !( x & 1 ) ) ucData >>= 4;
  438. ucData &= 0x0f;
  439. ucRed = OldPalette[ucData].rgbRed;
  440. ucGreen = OldPalette[ucData].rgbGreen;
  441. ucBlue = OldPalette[ucData].rgbBlue;
  442. dwGray = ( (DWORD) ucRed * 30 +
  443. (DWORD) ucGreen * 59 +
  444. (DWORD) ucBlue * 11 ) / 100;
  445. nTemp = (int) dwGray - nMinIndex;
  446. if( nTemp < 0 ) nTemp = 0;
  447. result = (double) nTemp;
  448. result *= dStep;
  449. result += (double) nDestMin;
  450. result *= dDestStep;
  451. dwNewGray = (DWORD) result;
  452. if( dwNewGray > 255 ) dwNewGray = 255;
  453. if( dwNewGray > dwGray ){
  454. do{
  455. if( ucRed < 255 ) ucRed++;
  456. if( ucGreen < 255 ) ucGreen++;
  457. if( ucBlue < 255 ) ucBlue++;
  458. dwGray = ( (DWORD) ucRed * 30 +
  459. (DWORD) ucGreen * 59 +
  460. (DWORD) ucBlue * 11 ) / 100;
  461. } while( dwGray < dwNewGray );
  462. }
  463. else if( dwNewGray < dwGray ){
  464. do{
  465. if( ucRed > 0 ) ucRed--;
  466. if( ucGreen > 0 ) ucGreen--;
  467. if( ucBlue > 0 ) ucBlue--;
  468. dwGray = ( (DWORD) ucRed * 30 +
  469. (DWORD) ucGreen * 59 +
  470. (DWORD) ucBlue * 11 ) / 100;
  471. } while( dwGray > dwNewGray );
  472. }
  473. ucData = (unsigned char) m_pImageObject->GetNearestIndex( ucRed, ucGreen, ucBlue, pPalette, nNumColors );
  474. if( !( x & 1 ) ) pTemp[0] = ( ucData << 4 );
  475. else pTemp[0] |= ucData;
  476. }
  477. if( ( x & 1 ) ) pTemp++;
  478. }
  479. }
  480. break;
  481. case 8:
  482. if( !bCompleteImage ){
  483. if( !bLessThanHalf ){
  484. for( y=0; y<nHeight; y++ ){
  485. pTemp = pBits;
  486. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  487. for( x=0; x<nWidth; x++ ){
  488. if( !( x >= nX1 && y >= nY1 && x <= nX2 && y <= nY2 ) ){
  489. ucData = pTemp[0];
  490. ucRed = OldPalette[ucData].rgbRed;
  491. ucGreen = OldPalette[ucData].rgbGreen;
  492. ucBlue = OldPalette[ucData].rgbBlue;
  493. ucData = (unsigned char) m_pImageObject->GetNearestIndex( ucRed, ucGreen, ucBlue, pPalette, nNumColors );
  494. pTemp[0] = ucData;
  495. }
  496. pTemp++;
  497. }
  498. }
  499. }
  500. for( y=nY1; y<=nY2; y++ ){
  501. pTemp = pBits;
  502. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  503. pTemp += nX1;
  504. for( x=nX1; x<=nX2; x++ ){
  505. ucData = pTemp[0];
  506. ucRed = OldPalette[ucData].rgbRed;
  507. ucGreen = OldPalette[ucData].rgbGreen;
  508. ucBlue = OldPalette[ucData].rgbBlue;
  509. dwGray = ( (DWORD) ucRed * 30 +
  510. (DWORD) ucGreen * 59 +
  511. (DWORD) ucBlue * 11 ) / 100;
  512. nTemp = (int) dwGray - nMinIndex;
  513. if( nTemp < 0 ) nTemp = 0;
  514. result = (double) nTemp;
  515. result *= dStep;
  516. result += (double) nDestMin;
  517. result *= dDestStep;
  518. dwNewGray = (DWORD) result;
  519. if( dwNewGray > 255 ) dwNewGray = 255;
  520. if( dwNewGray > dwGray ){
  521. do{
  522. if( ucRed < 255 ) ucRed++;
  523. if( ucGreen < 255 ) ucGreen++;
  524. if( ucBlue < 255 ) ucBlue++;
  525. dwGray = ( (DWORD) ucRed * 30 +
  526. (DWORD) ucGreen * 59 +
  527. (DWORD) ucBlue * 11 ) / 100;
  528. } while( dwGray < dwNewGray );
  529. }
  530. else if( dwNewGray < dwGray ){
  531. do{
  532. if( ucRed > 0 ) ucRed--;
  533. if( ucGreen > 0 ) ucGreen--;
  534. if( ucBlue > 0 ) ucBlue--;
  535. dwGray = ( (DWORD) ucRed * 30 +
  536. (DWORD) ucGreen * 59 +
  537. (DWORD) ucBlue * 11 ) / 100;
  538. } while( dwGray > dwNewGray );
  539. }
  540. ucData = (unsigned char) m_pImageObject->GetNearestIndex( ucRed, ucGreen, ucBlue, pPalette, nNumColors );
  541. *pTemp++ = ucData;
  542. }
  543. }
  544. }
  545. break;
  546. case 16:
  547. for( y=nY1; y<=nY2; y++ ){
  548. pTemp = pBits;
  549. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  550. pTemp += ( nX1 * 2 );
  551. for( x=nX1; x<=nX2; x++ ){
  552. GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
  553. dwGray = ( (DWORD) ucRed * 30 +
  554. (DWORD) ucGreen * 59 +
  555. (DWORD) ucBlue * 11 ) / 100;
  556. nTemp = (int) dwGray - nMinIndex;
  557. if( nTemp < 0 ) nTemp = 0;
  558. result = (double) nTemp;
  559. result *= dStep;
  560. result += (double) nDestMin;
  561. result *= dDestStep;
  562. dwNewGray = (DWORD) result;
  563. if( dwNewGray > 255 ) dwNewGray = 255;
  564. if( dwNewGray > dwGray ){
  565. do{
  566. if( ucRed < 255 ) ucRed++;
  567. if( ucGreen < 255 ) ucGreen++;
  568. if( ucBlue < 255 ) ucBlue++;
  569. dwGray = ( (DWORD) ucRed * 30 +
  570. (DWORD) ucGreen * 59 +
  571. (DWORD) ucBlue * 11 ) / 100;
  572. } while( dwGray < dwNewGray );
  573. }
  574. else if( dwNewGray < dwGray ){
  575. do{
  576. if( ucRed > 0 ) ucRed--;
  577. if( ucGreen > 0 ) ucGreen--;
  578. if(ucBlue > 0 ) ucBlue--;
  579. dwGray = ( (DWORD) ucRed * 30 +
  580. (DWORD) ucGreen * 59 +
  581. (DWORD) ucBlue * 11 ) / 100;
  582. } while( dwGray > dwNewGray );
  583. }
  584. PUTRGB555( ucRed, ucGreen, ucBlue, pTemp );
  585. pTemp += 2;
  586. }
  587. }
  588. break;
  589. case 24:
  590. for( y=nY1; y<=nY2; y++ ){
  591. pTemp = pBits;
  592. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  593. pTemp += ( nX1 * 3 );
  594. for( x=nX1; x<=nX2; x++ ){
  595. dwGray = ( (DWORD) pTemp[2] * 30 +
  596. (DWORD) pTemp[1] * 59 +
  597. (DWORD) pTemp[0] * 11 ) / 100;
  598. nTemp = (int) dwGray - nMinIndex;
  599. if( nTemp < 0 ) nTemp = 0;
  600. result = (double) nTemp;
  601. result *= dStep;
  602. result += (double) nDestMin;
  603. result *= dDestStep;
  604. dwNewGray = (DWORD) result;
  605. if( dwNewGray > 255 ) dwNewGray = 255;
  606. if( dwNewGray > dwGray ){
  607. do{
  608. if( pTemp[0] < 255 ) pTemp[0]++;
  609. if( pTemp[1] < 255 ) pTemp[1]++;
  610. if( pTemp[2] < 255 ) pTemp[2]++;
  611. dwGray = ( (DWORD) pTemp[2] * 30 +
  612. (DWORD) pTemp[1] * 59 +
  613. (DWORD) pTemp[0] * 11 ) / 100;
  614. } while( dwGray < dwNewGray );
  615. }
  616. else if( dwNewGray < dwGray ){
  617. do{
  618. if( pTemp[0] > 0 ) pTemp[0]--;
  619. if( pTemp[1] > 0 ) pTemp[1]--;
  620. if( pTemp[2] > 0 ) pTemp[2]--;
  621. dwGray = ( (DWORD) pTemp[2] * 30 +
  622. (DWORD) pTemp[1] * 59 +
  623. (DWORD) pTemp[0] * 11 ) / 100;
  624. } while( dwGray > dwNewGray );
  625. }
  626. pTemp += 3;
  627. }
  628. }
  629. break;
  630. case 32:
  631. for( y=nY1; y<=nY2; y++ ){
  632. pTemp = pBits;
  633. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  634. pTemp += ( nX1 * 4 );
  635. for( x=nX1; x<=nX2; x++ ){
  636. GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
  637. dwGray = ( (DWORD) ucRed * 30 +
  638. (DWORD) ucGreen * 59 +
  639. (DWORD) ucBlue * 11 ) / 100;
  640. nTemp = (int) dwGray - nMinIndex;
  641. if( nTemp < 0 ) nTemp = 0;
  642. result = (double) nTemp;
  643. result *= dStep;
  644. result += (double) nDestMin;
  645. result *= dDestStep;
  646. dwNewGray = (DWORD) result;
  647. if( dwNewGray > 255 ) dwNewGray = 255;
  648. if( dwNewGray > dwGray ){
  649. do{
  650. if( ucRed < 255 ) ucRed++;
  651. if( ucGreen < 255 ) ucGreen++;
  652. if( ucBlue < 255 ) ucBlue++;
  653. dwGray = ( (DWORD) ucRed * 30 +
  654. (DWORD) ucGreen * 59 +
  655. (DWORD) ucBlue * 11 ) / 100;
  656. } while( dwGray < dwNewGray );
  657. }
  658. else if( dwNewGray < dwGray ){
  659. do{
  660. if( ucRed > 0 ) ucRed--;
  661. if( ucGreen > 0 ) ucGreen--;
  662. if(ucBlue > 0 ) ucBlue--;
  663. dwGray = ( (DWORD) ucRed * 30 +
  664. (DWORD) ucGreen * 59 +
  665. (DWORD) ucBlue * 11 ) / 100;
  666. } while( dwGray > dwNewGray );
  667. }
  668. PUTRGB888( ucRed, ucGreen, ucBlue, pTemp );
  669. pTemp += 4;
  670. }
  671. }
  672. break;
  673. }
  674. ::GlobalUnlock( m_pImageObject->GetDib() );
  675. return( TRUE );
  676. }
  677. BOOL CImageAreaProcesses::HighpassFilter( int nX1, int nY1, int nX2, int nY2, CImageObject *pImageObject )
  678. {
  679. if( pImageObject != NULL ) m_pImageObject = pImageObject;
  680. if( m_pImageObject == NULL ) return( FALSE );
  681. static DWORD dwFact2[] = { 1, 1, 1, 1, 16, 1, 1, 1, 1 };
  682. LowpassFilter( nX1, nY1, nX2, nY2, dwFact2 );
  683. return( TRUE );
  684. }
  685. BOOL CImageAreaProcesses::LowpassFilter( int nX1, int nY1, int nX2, int nY2, DWORD *dwFact, CImageObject *pImageObject )
  686. {
  687. if( pImageObject != NULL ) m_pImageObject = pImageObject;
  688. if( m_pImageObject == NULL ) return( FALSE );
  689. if( m_pImageObject->GetNumBits() == 1 ) return( FALSE );
  690. m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
  691. int nWidth = m_pImageObject->GetWidth();
  692. int nHeight = m_pImageObject->GetHeight();
  693. if( nX1 < 2 ) nX1 = 2;
  694. if( nY1 < 2 ) nY1 = 2;
  695. if( nX2 >= nWidth - 2 ) nX2 = nWidth - 2;
  696. if( nY2 >= nHeight - 2 ) nY2 = nHeight - 2;
  697. DWORD dwGrayTotal, dwDivisor = 0;
  698. unsigned char Data;
  699. DWORD *dwFactor;
  700. static DWORD dwFact1[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
  701. if( dwFact == NULL ) dwFactor = dwFact1;
  702. else dwFactor = dwFact;
  703. int i;
  704. for( i=0; i<9; i++ ) dwDivisor += dwFactor[i];
  705. unsigned char *pOldBuffer, *pNewBuffer, *pOldBits, *pNewBits, *pOldTemp, *pNewTemp;
  706. BITMAPFILEHEADER *pOldBFH, *pNewBFH;
  707. BITMAPINFOHEADER *pOldBIH, *pNewBIH;
  708. RGBQUAD *pOldPalette, *pNewPalette;
  709. int nWidthBytes, nNumColors, x, y, j, l;
  710. pOldBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() );
  711. if( pOldBuffer == NULL ) return( FALSE );
  712. pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
  713. pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
  714. nNumColors = m_pImageObject->GetNumColors();
  715. pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  716. pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  717. DWORD dwNewSize, dwGray, dwTemp;
  718. HGLOBAL hNewDib;
  719. dwNewSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumColors * sizeof( RGBQUAD ) + nWidthBytes * nHeight;
  720. hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
  721. if( hNewDib == NULL ){
  722. m_pImageObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
  723. ::GlobalUnlock( m_pImageObject->GetDib() );
  724. return( FALSE );
  725. }
  726. pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
  727. if( pNewBuffer == NULL ){
  728. ::GlobalFree( hNewDib );
  729. m_pImageObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
  730. ::GlobalUnlock( m_pImageObject->GetDib() );
  731. return( FALSE );
  732. }
  733. pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
  734. pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
  735. pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  736. pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  737. *pNewBFH = *pOldBFH;
  738. *pNewBIH = *pOldBIH;
  739. for( i=0; i<nNumColors; i++ ) pNewPalette[i] = pOldPalette[i];
  740. memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );
  741. unsigned char ucRed, ucGreen, ucBlue;
  742. switch( m_pImageObject->GetNumBits() ){
  743. case 8:
  744. for( y=nY1; y<=nY2; y++ ){
  745. pOldTemp = pOldBits;
  746. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  747. pOldTemp += ( nX1 - 1 );
  748. pNewTemp = pNewBits;
  749. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  750. pNewTemp += nX1;
  751. l = 0;
  752. for( x=nX1; x<=nX2; x++ ){
  753. // List all pixel gray values in the 3x3 area
  754. j = 0;
  755. for( i=0; i<3; i++ ){
  756. Data = pOldTemp[i+l];
  757. dwGrayTotal += ( ( ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  758. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  759. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100 ) * dwFactor[j++] );
  760. }
  761. for( i=0; i<3; i++ ){
  762. Data = pOldTemp[i+l+nWidthBytes];
  763. dwGrayTotal += ( ( ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  764. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  765. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100 ) * dwFactor[j++] );
  766. }
  767. for( i=0; i<3; i++ ){
  768. Data = pOldTemp[i+l+nWidthBytes*2];
  769. dwGrayTotal += ( ( ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  770. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  771. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100 ) * dwFactor[j++] );
  772. }
  773. dwGrayTotal /= dwDivisor;
  774. Data = pOldTemp[1+nWidthBytes];
  775. ucRed = pOldPalette[Data].rgbRed;
  776. ucGreen = pOldPalette[Data].rgbGreen;
  777. ucBlue = pOldPalette[Data].rgbBlue;
  778. dwGray = ( ( (DWORD) ucRed * 30 +
  779. (DWORD) ucGreen * 59 +
  780. (DWORD) ucBlue * 11 ) / 100 );
  781. if( dwGray != 0 ) ucRed = (unsigned char) ( ( (DWORD) pOldPalette[Data].rgbRed * dwGrayTotal ) / dwGray );
  782. else ucRed = (unsigned char) ( ( dwGray + dwGrayTotal ) / 2 );
  783. if( dwGray != 0 ) ucGreen = (unsigned char) ( ( (DWORD) pOldPalette[Data].rgbGreen * dwGrayTotal ) / dwGray );
  784. else ucGreen = (unsigned char) ( ( dwGray + dwGrayTotal ) / 2 );
  785. if( dwGray != 0 ) ucBlue = (unsigned char) ( ( (DWORD) pOldPalette[Data].rgbBlue * dwGrayTotal ) / dwGray );
  786. else ucBlue = (unsigned char) ( ( dwGray + dwGrayTotal ) / 2 );
  787. *pNewTemp++ = (unsigned char) m_pImageObject->GetNearestIndex( ucRed, ucGreen, ucBlue, pNewPalette, nNumColors );
  788. l++;
  789. }
  790. }
  791. break;
  792. case 16:
  793. for( y=nY1; y<=nY2; y++ ){
  794. pOldTemp = pOldBits;
  795. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  796. pOldTemp += ( ( nX1 - 1 ) * 2 );
  797. pNewTemp = pNewBits;
  798. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  799. pNewTemp += ( nX1 * 2 );
  800. l = 0;
  801. for( x=nX1; x<=nX2; x++ ){
  802. dwGrayTotal = 0;
  803. j = 0;
  804. // List all pixel gray values in the 3x3 area
  805. for( i=0; i<3; i++ ){
  806. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[(i+l)*2] );
  807. dwGrayTotal += ( ( ( (DWORD) ucRed * 30 +
  808. (DWORD) ucGreen * 59 +
  809. (DWORD) ucBlue * 11 ) / 100 ) * dwFactor[j++] );
  810. }
  811. for( i=0; i<3; i++ ){
  812. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(i+l)*2] );
  813. dwGrayTotal += ( ( ( (DWORD) ucRed * 30 +
  814. (DWORD) ucGreen * 59 +
  815. (DWORD) ucBlue * 11 ) / 100 ) * dwFactor[j++] );
  816. }
  817. for( i=0; i<3; i++ ){
  818. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes*2+(i+l)*2] );
  819. dwGrayTotal += ( ( ( (DWORD) ucRed * 30 +
  820. (DWORD) ucGreen * 59 +
  821. (DWORD) ucBlue * 11 ) / 100 ) * dwFactor[j++] );
  822. }
  823. dwGrayTotal /= dwDivisor;
  824. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(1+l)*2] );
  825. dwGray = ( ( (DWORD) ucRed * 30 +
  826. (DWORD) ucGreen * 59 +
  827. (DWORD) ucBlue * 11 ) / 100 );
  828. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(1+l)*2] );
  829. if( dwGray != 0 ) dwTemp = ( ( (DWORD) ucRed * dwGrayTotal ) / dwGray );
  830. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  831. if( dwTemp > 255 ) dwTemp = 255;
  832. ucRed = (unsigned char) dwTemp;
  833. if( dwGray != 0 ) dwTemp = ( ( (DWORD) ucGreen * dwGrayTotal ) / dwGray );
  834. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  835. if( dwTemp > 255 ) dwTemp = 255;
  836. ucGreen = (unsigned char) dwTemp;
  837. if( dwGray != 0 ) dwTemp = ( ( (DWORD) ucBlue * dwGrayTotal ) / dwGray );
  838. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  839. if( dwTemp > 255 ) dwTemp = 255;
  840. ucBlue = (unsigned char) dwTemp;
  841. PUTRGB555( ucRed, ucGreen, ucBlue, pNewTemp );
  842. pNewTemp += 2;
  843. l++;
  844. }
  845. }
  846. break;
  847. case 24:
  848. for( y=nY1; y<=nY2; y++ ){
  849. pOldTemp = pOldBits;
  850. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  851. pOldTemp += ( ( nX1 - 1 ) * 3 );
  852. pNewTemp = pNewBits;
  853. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  854. pNewTemp += ( nX1 * 3 );
  855. l = 0;
  856. for( x=nX1; x<=nX2; x++ ){
  857. dwGrayTotal = 0;
  858. j = 0;
  859. // List all pixel gray values in the 3x3 area
  860. for( i=0; i<3; i++ ){
  861. dwGrayTotal += ( ( ( (DWORD) pOldTemp[(i+l)*3+2] * 30 +
  862. (DWORD) pOldTemp[(i+l)*3+1] * 59 +
  863. (DWORD) pOldTemp[(i+l)*3] * 11 ) / 100 ) * dwFactor[j++] );
  864. }
  865. for( i=0; i<3; i++ ){
  866. dwGrayTotal += ( ( ( (DWORD) pOldTemp[nWidthBytes+(i+l)*3+2] * 30 +
  867. (DWORD) pOldTemp[nWidthBytes+(i+l)*3+1] * 59 +
  868. (DWORD) pOldTemp[nWidthBytes+(i+l)*3] * 11 ) / 100 ) * dwFactor[j++] );
  869. }
  870. for( i=0; i<3; i++ ){
  871. dwGrayTotal += ( ( ( (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3+2] * 30 +
  872. (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3+1] * 59 +
  873. (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3] * 11 ) / 100 ) * dwFactor[j++] );
  874. }
  875. dwGrayTotal /= dwDivisor;
  876. dwGray = ( ( (DWORD) pOldTemp[nWidthBytes+(1+l)*3+2] * 30 +
  877. (DWORD) pOldTemp[nWidthBytes+(1+l)*3+1] * 59 +
  878. (DWORD) pOldTemp[nWidthBytes+(1+l)*3] * 11 ) / 100 );
  879. if( dwGray != 0 ) dwTemp = ( ( (DWORD) pOldTemp[(l+1)*3+nWidthBytes+2] * dwGrayTotal ) / dwGray );
  880. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  881. if( dwTemp > 255 ) dwTemp = 255;
  882. pNewTemp[2] = (unsigned char) dwTemp;
  883. if( dwGray != 0 ) dwTemp = ( ( (DWORD) pOldTemp[(l+1)*3+nWidthBytes+1] * dwGrayTotal ) / dwGray );
  884. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  885. if( dwTemp > 255 ) dwTemp = 255;
  886. pNewTemp[1] = (unsigned char) dwTemp;
  887. if( dwGray != 0 ) dwTemp = ( ( (DWORD) pOldTemp[(l+1)*3+nWidthBytes] * dwGrayTotal ) / dwGray );
  888. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  889. if( dwTemp > 255 ) dwTemp = 255;
  890. pNewTemp[0] = (unsigned char) dwTemp;
  891. pNewTemp += 3;
  892. l++;
  893. }
  894. }
  895. break;
  896. case 32:
  897. for( y=nY1; y<=nY2; y++ ){
  898. pOldTemp = pOldBits;
  899. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  900. pOldTemp += ( ( nX1 - 1 ) * 4 );
  901. pNewTemp = pNewBits;
  902. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  903. pNewTemp += ( nX1 * 4 );
  904. l = 0;
  905. for( x=nX1; x<=nX2; x++ ){
  906. dwGrayTotal = 0;
  907. j = 0;
  908. // List all pixel gray values in the 3x3 area
  909. for( i=0; i<3; i++ ){
  910. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[(i+l)*4] );
  911. dwGrayTotal += ( ( ( (DWORD) ucRed * 30 +
  912. (DWORD) ucGreen * 59 +
  913. (DWORD) ucBlue * 11 ) / 100 ) * dwFactor[j++] );
  914. }
  915. for( i=0; i<3; i++ ){
  916. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(i+l)*4] );
  917. dwGrayTotal += ( ( ( (DWORD) ucRed * 30 +
  918. (DWORD) ucGreen * 59 +
  919. (DWORD) ucBlue * 11 ) / 100 ) * dwFactor[j++] );
  920. }
  921. for( i=0; i<3; i++ ){
  922. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes*2+(i+l)*4] );
  923. dwGrayTotal += ( ( ( (DWORD) ucRed * 30 +
  924. (DWORD) ucGreen * 59 +
  925. (DWORD) ucBlue * 11 ) / 100 ) * dwFactor[j++] );
  926. }
  927. dwGrayTotal /= dwDivisor;
  928. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(1+l)*4] );
  929. dwGray = ( ( (DWORD) ucRed * 30 +
  930. (DWORD) ucGreen * 59 +
  931. (DWORD) ucBlue * 11 ) / 100 );
  932. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(1+l)*4] );
  933. if( dwGray != 0 ) dwTemp = ( ( (DWORD) ucRed * dwGrayTotal ) / dwGray );
  934. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  935. if( dwTemp > 255 ) dwTemp = 255;
  936. ucRed = (unsigned char) dwTemp;
  937. if( dwGray != 0 ) dwTemp = ( ( (DWORD) ucGreen * dwGrayTotal ) / dwGray );
  938. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  939. if( dwTemp > 255 ) dwTemp = 255;
  940. ucGreen = (unsigned char) dwTemp;
  941. if( dwGray != 0 ) dwTemp = ( ( (DWORD) ucBlue * dwGrayTotal ) / dwGray );
  942. else dwTemp = ( dwGrayTotal + dwGray ) / 2;
  943. if( dwTemp > 255 ) dwTemp = 255;
  944. ucBlue = (unsigned char) dwTemp;
  945. PUTRGB888( ucRed, ucGreen, ucBlue, pNewTemp );
  946. pNewTemp += 4;
  947. l++;
  948. }
  949. }
  950. break;
  951. }
  952. ::GlobalUnlock( m_pImageObject->GetDib() );
  953. ::GlobalFree( m_pImageObject->GetDib() );
  954. ::GlobalUnlock( hNewDib );
  955. m_pImageObject->SetDib( hNewDib );
  956. return( TRUE );
  957. }
  958. BOOL CImageAreaProcesses::EdgeEnhance( int nX1, int nY1, int nX2, int nY2, CImageObject *pImageObject )
  959. {
  960. if( pImageObject != NULL ) m_pImageObject = pImageObject;
  961. if( m_pImageObject == NULL ) return( FALSE );
  962. if( m_pImageObject->GetNumBits() == 1 ) return( FALSE );
  963. m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
  964. int nWidth = m_pImageObject->GetWidth();
  965. int nHeight = m_pImageObject->GetHeight();
  966. if( nX1 < 2 ) nX1 = 2;
  967. if( nY1 < 2 ) nY1 = 2;
  968. if( nX2 >= nWidth - 2 ) nX2 = nWidth - 2;
  969. if( nY2 >= nHeight - 2 ) nY2 = nHeight - 2;
  970. DWORD dwGrayTotal;
  971. unsigned char Data;
  972. unsigned char *pOldBuffer, *pNewBuffer, *pOldBits, *pNewBits, *pOldTemp, *pNewTemp;
  973. BITMAPFILEHEADER *pOldBFH, *pNewBFH;
  974. BITMAPINFOHEADER *pOldBIH, *pNewBIH;
  975. RGBQUAD *pOldPalette, *pNewPalette;
  976. int nWidthBytes, nNumColors, x, y, j, l;
  977. pOldBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() );
  978. if( pOldBuffer == NULL ) return( FALSE );
  979. pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
  980. pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
  981. nNumColors = m_pImageObject->GetNumColors();
  982. pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  983. pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  984. DWORD dwNewSize, dwTemp, dwGrayList[9];
  985. HGLOBAL hNewDib;
  986. dwNewSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumColors * sizeof( RGBQUAD ) + nWidthBytes * nHeight;
  987. hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
  988. if( hNewDib == NULL ){
  989. m_pImageObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
  990. ::GlobalUnlock( m_pImageObject->GetDib() );
  991. return( FALSE );
  992. }
  993. pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
  994. if( pNewBuffer == NULL ){
  995. ::GlobalFree( hNewDib );
  996. m_pImageObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
  997. ::GlobalUnlock( m_pImageObject->GetDib() );
  998. return( FALSE );
  999. }
  1000. pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
  1001. pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
  1002. pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  1003. pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  1004. *pNewBFH = *pOldBFH;
  1005. *pNewBIH = *pOldBIH;
  1006. int i;
  1007. for( i=0; i<nNumColors; i++ ) pNewPalette[i] = pOldPalette[i];
  1008. memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );
  1009. unsigned char ucRed, ucGreen, ucBlue;
  1010. DWORD dwLineAEIAveBelow, dwLineAEIAveAbove, dwLineAEIMaxDif;
  1011. DWORD dwLineBEHAveBelow, dwLineBEHAveAbove, dwLineBEHMaxDif;
  1012. DWORD dwLineCEGAveBelow, dwLineCEGAveAbove, dwLineCEGMaxDif;
  1013. DWORD dwLineDEFAveBelow, dwLineDEFAveAbove, dwLineDEFMaxDif;
  1014. DWORD dwMaxDif;
  1015. switch( m_pImageObject->GetNumBits() ){
  1016. case 8:
  1017. for( y=nY1; y<=nY2; y++ ){
  1018. pOldTemp = pOldBits;
  1019. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  1020. pOldTemp += ( nX1 - 1 );
  1021. pNewTemp = pNewBits;
  1022. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1023. pNewTemp += nX1;
  1024. l = 0;
  1025. for( x=nX1; x<=nX2; x++ ){
  1026. // List all pixel gray values in the 3x3 area
  1027. j = 0;
  1028. for( i=0; i<3; i++ ){
  1029. Data = pOldTemp[i+l];
  1030. dwGrayList[j++] = ( ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  1031. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  1032. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100 );
  1033. }
  1034. for( i=0; i<3; i++ ){
  1035. Data = pOldTemp[i+l+nWidthBytes];
  1036. dwGrayList[j++] = ( ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  1037. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  1038. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100 );
  1039. }
  1040. for( i=0; i<3; i++ ){
  1041. Data = pOldTemp[i+l+nWidthBytes*2];
  1042. dwGrayList[j++] = ( ( (DWORD) pOldPalette[Data].rgbRed * 30 +
  1043. (DWORD) pOldPalette[Data].rgbGreen * 59 +
  1044. (DWORD) pOldPalette[Data].rgbBlue * 11 ) / 100 );
  1045. }
  1046. dwLineAEIAveBelow = ( dwGrayList[3] + dwGrayList[6] + dwGrayList[7] ) / 3;
  1047. dwLineAEIAveAbove = ( dwGrayList[1] + dwGrayList[2] + dwGrayList[5] ) / 3;
  1048. if( dwLineAEIAveBelow > dwLineAEIAveAbove ) dwLineAEIMaxDif = dwLineAEIAveBelow - dwLineAEIAveAbove;
  1049. else dwLineAEIMaxDif = dwLineAEIAveAbove - dwLineAEIAveBelow;
  1050. dwLineBEHAveBelow = ( dwGrayList[0] + dwGrayList[3] + dwGrayList[6] ) / 3;
  1051. dwLineBEHAveAbove = ( dwGrayList[2] + dwGrayList[4] + dwGrayList[8] ) / 3;
  1052. if( dwLineBEHAveBelow > dwLineBEHAveAbove ) dwLineBEHMaxDif = dwLineBEHAveBelow - dwLineBEHAveAbove;
  1053. else dwLineBEHMaxDif = dwLineBEHAveAbove - dwLineBEHAveBelow;
  1054. dwLineCEGAveBelow = ( dwGrayList[5] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1055. dwLineCEGAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[3] ) / 3;
  1056. if( dwLineCEGAveBelow > dwLineCEGAveAbove ) dwLineCEGMaxDif = dwLineCEGAveBelow - dwLineCEGAveAbove;
  1057. else dwLineCEGMaxDif = dwLineCEGAveAbove - dwLineCEGAveBelow;
  1058. dwLineDEFAveBelow = ( dwGrayList[6] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1059. dwLineDEFAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[2] ) / 3;
  1060. if( dwLineDEFAveBelow > dwLineDEFAveAbove ) dwLineDEFMaxDif = dwLineDEFAveBelow - dwLineDEFAveAbove;
  1061. else dwLineDEFMaxDif = dwLineDEFAveAbove - dwLineDEFAveBelow;
  1062. dwMaxDif = MAX( dwLineAEIMaxDif, dwLineBEHMaxDif );
  1063. dwMaxDif = MAX( dwLineCEGMaxDif, dwMaxDif );
  1064. dwMaxDif = MAX( dwLineDEFMaxDif, dwMaxDif );
  1065. Data = pOldTemp[1+l+nWidthBytes];
  1066. if( dwMaxDif > 20 ){
  1067. ucRed = pOldPalette[Data].rgbRed;
  1068. ucGreen = pOldPalette[Data].rgbGreen;
  1069. ucBlue = pOldPalette[Data].rgbBlue;
  1070. dwTemp = ( ( (DWORD) ucRed * 12 ) / 10 );
  1071. if( dwTemp > 255 ) dwTemp = 255;
  1072. ucRed = (unsigned char) dwTemp;
  1073. dwTemp = ( ( (DWORD) ucGreen * 12 ) / 10 );
  1074. if( dwTemp > 255 ) dwTemp = 255;
  1075. ucGreen = (unsigned char) dwTemp;
  1076. dwTemp = ( ( (DWORD) ucBlue * 12 ) / 10 );
  1077. if( dwTemp > 255 ) dwTemp = 255;
  1078. ucBlue = (unsigned char) dwTemp;
  1079. Data = m_pImageObject->GetNearestIndex( ucRed, ucGreen, ucBlue, pNewPalette, nNumColors );
  1080. }
  1081. *pNewTemp++ = Data;
  1082. l++;
  1083. }
  1084. }
  1085. break;
  1086. case 16:
  1087. for( y=nY1; y<=nY2; y++ ){
  1088. pOldTemp = pOldBits;
  1089. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  1090. pOldTemp += ( ( nX1 - 1 ) * 2 );
  1091. pNewTemp = pNewBits;
  1092. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1093. pNewTemp += ( nX1 * 2 );
  1094. l = 0;
  1095. for( x=nX1; x<=nX2; x++ ){
  1096. dwGrayTotal = 0;
  1097. j = 0;
  1098. // List all pixel gray values in the 3x3 area
  1099. for( i=0; i<3; i++ ){
  1100. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[(i+l)*2] );
  1101. dwGrayList[j++] = ( ( (DWORD) ucRed * 30 +
  1102. (DWORD) ucGreen * 59 +
  1103. (DWORD) ucBlue * 11 ) / 100 );
  1104. }
  1105. for( i=0; i<3; i++ ){
  1106. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(i+l)*2] );
  1107. dwGrayList[j++] = ( ( (DWORD) ucRed * 30 +
  1108. (DWORD) ucGreen * 59 +
  1109. (DWORD) ucBlue * 11 ) / 100 );
  1110. }
  1111. for( i=0; i<3; i++ ){
  1112. GETRGB555( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes*2+(i+l)*2] );
  1113. dwGrayList[j++] = ( ( (DWORD) ucRed * 30 +
  1114. (DWORD) ucGreen * 59 +
  1115. (DWORD) ucBlue * 11 ) / 100 );
  1116. }
  1117. dwLineAEIAveBelow = ( dwGrayList[3] + dwGrayList[6] + dwGrayList[7] ) / 3;
  1118. dwLineAEIAveAbove = ( dwGrayList[1] + dwGrayList[2] + dwGrayList[5] ) / 3;
  1119. if( dwLineAEIAveBelow > dwLineAEIAveAbove ) dwLineAEIMaxDif = dwLineAEIAveBelow - dwLineAEIAveAbove;
  1120. else dwLineAEIMaxDif = dwLineAEIAveAbove - dwLineAEIAveBelow;
  1121. dwLineBEHAveBelow = ( dwGrayList[0] + dwGrayList[3] + dwGrayList[6] ) / 3;
  1122. dwLineBEHAveAbove = ( dwGrayList[2] + dwGrayList[4] + dwGrayList[8] ) / 3;
  1123. if( dwLineBEHAveBelow > dwLineBEHAveAbove ) dwLineBEHMaxDif = dwLineBEHAveBelow - dwLineBEHAveAbove;
  1124. else dwLineBEHMaxDif = dwLineBEHAveAbove - dwLineBEHAveBelow;
  1125. dwLineCEGAveBelow = ( dwGrayList[5] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1126. dwLineCEGAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[3] ) / 3;
  1127. if( dwLineCEGAveBelow > dwLineCEGAveAbove ) dwLineCEGMaxDif = dwLineCEGAveBelow - dwLineCEGAveAbove;
  1128. else dwLineCEGMaxDif = dwLineCEGAveAbove - dwLineCEGAveBelow;
  1129. dwLineDEFAveBelow = ( dwGrayList[6] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1130. dwLineDEFAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[2] ) / 3;
  1131. if( dwLineDEFAveBelow > dwLineDEFAveAbove ) dwLineDEFMaxDif = dwLineDEFAveBelow - dwLineDEFAveAbove;
  1132. else dwLineDEFMaxDif = dwLineDEFAveAbove - dwLineDEFAveBelow;
  1133. dwMaxDif = MAX( dwLineAEIMaxDif, dwLineBEHMaxDif );
  1134. dwMaxDif = MAX( dwLineCEGMaxDif, dwMaxDif );
  1135. dwMaxDif = MAX( dwLineDEFMaxDif, dwMaxDif );
  1136. if( dwMaxDif > 20 ){
  1137. GETRGB555( ucRed, ucGreen, ucBlue, pOldTemp[(1+l)*2+nWidthBytes] );
  1138. dwTemp = ( ( (DWORD) ucRed * 12 ) / 10 );
  1139. if( dwTemp > 255 ) dwTemp = 255;
  1140. ucRed = (unsigned char) dwTemp;
  1141. dwTemp = ( ( (DWORD) ucGreen * 12 ) / 10 );
  1142. if( dwTemp > 255 ) dwTemp = 255;
  1143. ucGreen = (unsigned char) dwTemp;
  1144. dwTemp = ( ( (DWORD) ucBlue * 12 ) / 10 );
  1145. if( dwTemp > 255 ) dwTemp = 255;
  1146. ucBlue = (unsigned char) dwTemp;
  1147. PUTRGB555( ucRed, ucGreen, ucBlue, pNewTemp );
  1148. }
  1149. else{
  1150. GETRGB555( ucRed, ucGreen, ucBlue, pOldTemp[(1+l)*2+nWidthBytes] );
  1151. PUTRGB555( ucRed, ucGreen, ucBlue, pNewTemp );
  1152. }
  1153. pNewTemp += 2;
  1154. l++;
  1155. }
  1156. }
  1157. break;
  1158. case 24:
  1159. for( y=nY1; y<=nY2; y++ ){
  1160. pOldTemp = pOldBits;
  1161. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  1162. pOldTemp += ( ( nX1 - 1 ) * 3 );
  1163. pNewTemp = pNewBits;
  1164. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1165. pNewTemp += ( nX1 * 3 );
  1166. l = 0;
  1167. for( x=nX1; x<=nX2; x++ ){
  1168. dwGrayTotal = 0;
  1169. j = 0;
  1170. // List all pixel gray values in the 3x3 area
  1171. for( i=0; i<3; i++ ){
  1172. dwGrayList[j++] = ( ( (DWORD) pOldTemp[(i+l)*3+2] * 30 +
  1173. (DWORD) pOldTemp[(i+l)*3+1] * 59 +
  1174. (DWORD) pOldTemp[(i+l)*3] * 11 ) / 100 );
  1175. }
  1176. for( i=0; i<3; i++ ){
  1177. dwGrayList[j++] = ( ( (DWORD) pOldTemp[nWidthBytes+(i+l)*3+2] * 30 +
  1178. (DWORD) pOldTemp[nWidthBytes+(i+l)*3+1] * 59 +
  1179. (DWORD) pOldTemp[nWidthBytes+(i+l)*3] * 11 ) / 100 );
  1180. }
  1181. for( i=0; i<3; i++ ){
  1182. dwGrayList[j++] = ( ( (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3+2] * 30 +
  1183. (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3+1] * 59 +
  1184. (DWORD) pOldTemp[nWidthBytes*2+(i+l)*3] * 11 ) / 100 );
  1185. }
  1186. dwLineAEIAveBelow = ( dwGrayList[3] + dwGrayList[6] + dwGrayList[7] ) / 3;
  1187. dwLineAEIAveAbove = ( dwGrayList[1] + dwGrayList[2] + dwGrayList[5] ) / 3;
  1188. if( dwLineAEIAveBelow > dwLineAEIAveAbove ) dwLineAEIMaxDif = dwLineAEIAveBelow - dwLineAEIAveAbove;
  1189. else dwLineAEIMaxDif = dwLineAEIAveAbove - dwLineAEIAveBelow;
  1190. dwLineBEHAveBelow = ( dwGrayList[0] + dwGrayList[3] + dwGrayList[6] ) / 3;
  1191. dwLineBEHAveAbove = ( dwGrayList[2] + dwGrayList[4] + dwGrayList[8] ) / 3;
  1192. if( dwLineBEHAveBelow > dwLineBEHAveAbove ) dwLineBEHMaxDif = dwLineBEHAveBelow - dwLineBEHAveAbove;
  1193. else dwLineBEHMaxDif = dwLineBEHAveAbove - dwLineBEHAveBelow;
  1194. dwLineCEGAveBelow = ( dwGrayList[5] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1195. dwLineCEGAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[3] ) / 3;
  1196. if( dwLineCEGAveBelow > dwLineCEGAveAbove ) dwLineCEGMaxDif = dwLineCEGAveBelow - dwLineCEGAveAbove;
  1197. else dwLineCEGMaxDif = dwLineCEGAveAbove - dwLineCEGAveBelow;
  1198. dwLineDEFAveBelow = ( dwGrayList[6] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1199. dwLineDEFAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[2] ) / 3;
  1200. if( dwLineDEFAveBelow > dwLineDEFAveAbove ) dwLineDEFMaxDif = dwLineDEFAveBelow - dwLineDEFAveAbove;
  1201. else dwLineDEFMaxDif = dwLineDEFAveAbove - dwLineDEFAveBelow;
  1202. dwMaxDif = MAX( dwLineAEIMaxDif, dwLineBEHMaxDif );
  1203. dwMaxDif = MAX( dwLineCEGMaxDif, dwMaxDif );
  1204. dwMaxDif = MAX( dwLineDEFMaxDif, dwMaxDif );
  1205. if( dwMaxDif > 20 ){
  1206. dwTemp = ( ( (DWORD) pOldTemp[(1+l)*3+nWidthBytes] * 12 ) / 10 );
  1207. if( dwTemp > 255 ) dwTemp = 255;
  1208. pNewTemp[0] = (unsigned char) dwTemp;
  1209. dwTemp = ( ( (DWORD) pOldTemp[(1+l)*3+nWidthBytes+1] * 12 ) / 10 );
  1210. if( dwTemp > 255 ) dwTemp = 255;
  1211. pNewTemp[1] = (unsigned char) dwTemp;
  1212. dwTemp = ( ( (DWORD) pOldTemp[(1+l)*3+nWidthBytes+2] * 12 ) / 10 );
  1213. if( dwTemp > 255 ) dwTemp = 255;
  1214. pNewTemp[2] = (unsigned char) dwTemp;
  1215. }
  1216. else{
  1217. pNewTemp[0] = pOldTemp[(1+l)*3+nWidthBytes];
  1218. pNewTemp[1] = pOldTemp[(1+l)*3+nWidthBytes+1];
  1219. pNewTemp[2] = pOldTemp[(1+l)*3+nWidthBytes+2];
  1220. }
  1221. pNewTemp += 3;
  1222. l++;
  1223. }
  1224. }
  1225. break;
  1226. case 32:
  1227. for( y=nY1; y<=nY2; y++ ){
  1228. pOldTemp = pOldBits;
  1229. pOldTemp += ( ( nHeight - 1 - y - 1 ) * nWidthBytes );
  1230. pOldTemp += ( ( nX1 - 1 ) * 4 );
  1231. pNewTemp = pNewBits;
  1232. pNewTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1233. pNewTemp += ( nX1 * 4 );
  1234. l = 0;
  1235. for( x=nX1; x<=nX2; x++ ){
  1236. dwGrayTotal = 0;
  1237. j = 0;
  1238. // List all pixel gray values in the 3x3 area
  1239. for( i=0; i<3; i++ ){
  1240. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[(i+l)*4] );
  1241. dwGrayList[j++] = ( ( (DWORD) ucRed * 30 +
  1242. (DWORD) ucGreen * 59 +
  1243. (DWORD) ucBlue * 11 ) / 100 );
  1244. }
  1245. for( i=0; i<3; i++ ){
  1246. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes+(i+l)*4] );
  1247. dwGrayList[j++] = ( ( (DWORD) ucRed * 30 +
  1248. (DWORD) ucGreen * 59 +
  1249. (DWORD) ucBlue * 11 ) / 100 );
  1250. }
  1251. for( i=0; i<3; i++ ){
  1252. GETRGB888( ucRed, ucGreen, ucBlue, &pOldTemp[nWidthBytes*2+(i+l)*4] );
  1253. dwGrayList[j++] = ( ( (DWORD) ucRed * 30 +
  1254. (DWORD) ucGreen * 59 +
  1255. (DWORD) ucBlue * 11 ) / 100 );
  1256. }
  1257. dwLineAEIAveBelow = ( dwGrayList[3] + dwGrayList[6] + dwGrayList[7] ) / 3;
  1258. dwLineAEIAveAbove = ( dwGrayList[1] + dwGrayList[2] + dwGrayList[5] ) / 3;
  1259. if( dwLineAEIAveBelow > dwLineAEIAveAbove ) dwLineAEIMaxDif = dwLineAEIAveBelow - dwLineAEIAveAbove;
  1260. else dwLineAEIMaxDif = dwLineAEIAveAbove - dwLineAEIAveBelow;
  1261. dwLineBEHAveBelow = ( dwGrayList[0] + dwGrayList[3] + dwGrayList[6] ) / 3;
  1262. dwLineBEHAveAbove = ( dwGrayList[2] + dwGrayList[4] + dwGrayList[8] ) / 3;
  1263. if( dwLineBEHAveBelow > dwLineBEHAveAbove ) dwLineBEHMaxDif = dwLineBEHAveBelow - dwLineBEHAveAbove;
  1264. else dwLineBEHMaxDif = dwLineBEHAveAbove - dwLineBEHAveBelow;
  1265. dwLineCEGAveBelow = ( dwGrayList[5] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1266. dwLineCEGAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[3] ) / 3;
  1267. if( dwLineCEGAveBelow > dwLineCEGAveAbove ) dwLineCEGMaxDif = dwLineCEGAveBelow - dwLineCEGAveAbove;
  1268. else dwLineCEGMaxDif = dwLineCEGAveAbove - dwLineCEGAveBelow;
  1269. dwLineDEFAveBelow = ( dwGrayList[6] + dwGrayList[7] + dwGrayList[8] ) / 3;
  1270. dwLineDEFAveAbove = ( dwGrayList[0] + dwGrayList[1] + dwGrayList[2] ) / 3;
  1271. if( dwLineDEFAveBelow > dwLineDEFAveAbove ) dwLineDEFMaxDif = dwLineDEFAveBelow - dwLineDEFAveAbove;
  1272. else dwLineDEFMaxDif = dwLineDEFAveAbove - dwLineDEFAveBelow;
  1273. dwMaxDif = MAX( dwLineAEIMaxDif, dwLineBEHMaxDif );
  1274. dwMaxDif = MAX( dwLineCEGMaxDif, dwMaxDif );
  1275. dwMaxDif = MAX( dwLineDEFMaxDif, dwMaxDif );
  1276. if( dwMaxDif > 20 ){
  1277. GETRGB888( ucRed, ucGreen, ucBlue, pOldTemp[(1+l)*4+nWidthBytes] );
  1278. dwTemp = ( ( (DWORD) ucRed * 12 ) / 10 );
  1279. if( dwTemp > 255 ) dwTemp = 255;
  1280. ucRed = (unsigned char) dwTemp;
  1281. dwTemp = ( ( (DWORD) ucGreen * 12 ) / 10 );
  1282. if( dwTemp > 255 ) dwTemp = 255;
  1283. ucGreen = (unsigned char) dwTemp;
  1284. dwTemp = ( ( (DWORD) ucBlue * 12 ) / 10 );
  1285. if( dwTemp > 255 ) dwTemp = 255;
  1286. ucBlue = (unsigned char) dwTemp;
  1287. PUTRGB888( ucRed, ucGreen, ucBlue, pNewTemp );
  1288. }
  1289. else{
  1290. GETRGB888( ucRed, ucGreen, ucBlue, pOldTemp[(1+l)*4+nWidthBytes] );
  1291. PUTRGB888( ucRed, ucGreen, ucBlue, pNewTemp );
  1292. }
  1293. pNewTemp += 4;
  1294. l++;
  1295. }
  1296. }
  1297. break;
  1298. }
  1299. ::GlobalUnlock( m_pImageObject->GetDib() );
  1300. ::GlobalFree( m_pImageObject->GetDib() );
  1301. ::GlobalUnlock( hNewDib );
  1302. m_pImageObject->SetDib( hNewDib );
  1303. return( TRUE );
  1304. }
  1305. int *CImageAreaProcesses::GetHistogram( int nX1, int nY1, int nX2, int nY2 )
  1306. {
  1307. m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
  1308. unsigned char *pBuffer, *pBits;
  1309. RGBQUAD *pPalette;
  1310. int nWidthBytes, nNumColors;
  1311. pBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() );
  1312. if( pBuffer == NULL ) return( NULL );
  1313. nNumColors = m_pImageObject->GetNumColors();
  1314. pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  1315. pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  1316. int *nHistogramBuffer = CreateHistogram( nX1, nY1, nX2, nY2, pBits, pPalette, nWidthBytes );
  1317. ::GlobalUnlock( m_pImageObject->GetDib() );
  1318. return( nHistogramBuffer );
  1319. }
  1320. int *CImageAreaProcesses::CreateHistogram( int nX1, int nY1, int nX2, int nY2, unsigned char *pData, RGBQUAD *pPalette, int nWidthBytes )
  1321. {
  1322. m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
  1323. int *pBuffer = new int [256*4+4];
  1324. if( pBuffer == NULL ) return( NULL );
  1325. memset( pBuffer, 0, ( 256 * 4 + 4 ) * sizeof( int ) );
  1326. DWORD dwGray;
  1327. int x, y;
  1328. unsigned char *pTemp, ucRed, ucGreen, ucBlue;
  1329. int Pixels = 0;
  1330. int nWidth = m_pImageObject->GetWidth();
  1331. int nHeight = m_pImageObject->GetHeight();
  1332. switch( m_pImageObject->GetNumBits() ){
  1333. case 1:
  1334. break;
  1335. case 4:
  1336. break;
  1337. case 8:
  1338. for( y=0; y<nHeight; y++ ){
  1339. pTemp = pData;
  1340. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1341. pTemp += nX1;
  1342. for( x=nX1; x<=nX2; x++ ){
  1343. ucRed = pPalette[pTemp[x]].rgbRed;
  1344. ucGreen = pPalette[pTemp[x]].rgbGreen;
  1345. ucBlue = pPalette[pTemp[x]].rgbBlue;
  1346. dwGray = ( (DWORD) ucRed * 30 +
  1347. (DWORD) ucGreen * 59 +
  1348. (DWORD) ucBlue * 11 ) / 100;
  1349. dwGray &= 0x000000ff;
  1350. pBuffer[dwGray]++;
  1351. pBuffer[256+ucRed]++;
  1352. pBuffer[512+ucBlue]++;
  1353. pBuffer[768+ucGreen]++;
  1354. Pixels++;
  1355. }
  1356. }
  1357. break;
  1358. case 16:
  1359. for( y=0; y<nHeight; y++ ){
  1360. pTemp = pData;
  1361. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1362. pTemp += ( nX1 * 2 );
  1363. for( x=nX1; x<=nX2; x++ ){
  1364. GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
  1365. dwGray = ( (DWORD) ucRed * 30 +
  1366. (DWORD) ucGreen * 59 +
  1367. (DWORD) ucBlue * 11 ) / 100;
  1368. dwGray &= 0x000000ff;
  1369. pBuffer[dwGray]++;
  1370. pBuffer[256+pTemp[x*3]]++;
  1371. pBuffer[512+pTemp[x*3+1]]++;
  1372. pBuffer[768+pTemp[x*3+2]]++;
  1373. Pixels++;
  1374. pTemp += 2;
  1375. }
  1376. }
  1377. break;
  1378. case 24:
  1379. for( y=0; y<nHeight; y++ ){
  1380. pTemp = pData;
  1381. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1382. pTemp += ( nX1 * 3 );
  1383. for( x=nX1; x<=nX2; x++ ){
  1384. dwGray = ( (DWORD) pTemp[x*3+2] * 30 +
  1385. (DWORD) pTemp[x*3+1] * 59 +
  1386. (DWORD) pTemp[x*3] * 11 ) / 100;
  1387. dwGray &= 0x000000ff;
  1388. pBuffer[dwGray]++;
  1389. pBuffer[256+pTemp[x*3]]++;
  1390. pBuffer[512+pTemp[x*3+1]]++;
  1391. pBuffer[768+pTemp[x*3+2]]++;
  1392. Pixels++;
  1393. }
  1394. }
  1395. break;
  1396. case 32:
  1397. for( y=0; y<m_pImageObject->GetHeight(); y++ ){
  1398. pTemp = pData;
  1399. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  1400. pTemp += ( nX1 * 4 );
  1401. for( x=nX1; x<=nX2; x++ ){
  1402. GETRGB888( ucRed, ucGreen, ucBlue, pTemp );
  1403. dwGray = ( (DWORD) ucRed * 30 +
  1404. (DWORD) ucGreen * 59 +
  1405. (DWORD) ucBlue * 11 ) / 100;
  1406. dwGray &= 0x000000ff;
  1407. pBuffer[dwGray]++;
  1408. pBuffer[256+pTemp[x*3]]++;
  1409. pBuffer[512+pTemp[x*3+1]]++;
  1410. pBuffer[768+pTemp[x*3+2]]++;
  1411. Pixels++;
  1412. pTemp += 4;
  1413. }
  1414. }
  1415. break;
  1416. }
  1417. pBuffer[0] = pBuffer[256] = pBuffer[512] = pBuffer[768] = 0;
  1418. int Highest = 0, i, j;
  1419. for( i=0; i<256*4; i++ ){
  1420. if( pBuffer[i] > Highest ) Highest = pBuffer[i];
  1421. }
  1422. for( j=0; j<4; j++ ){
  1423. for( i=0; i<256; i++ ) pBuffer[j*256+i] = ( pBuffer[j*256+i] * 255 ) / Highest;
  1424. }
  1425. Highest = 0;
  1426. for( i=0; i<256*4; i++ ){
  1427. if( pBuffer[i] > Highest ) Highest = pBuffer[i];
  1428. }
  1429. pBuffer[256*4] = Highest;
  1430. pBuffer[256*4+1] = Highest / 25;
  1431. for( i=0; i<256; i++ ){
  1432. if( pBuffer[i] >= pBuffer[256*4+1] ) break;
  1433. }
  1434. pBuffer[256*4+2] = i;
  1435. for( i=255; i>=0; i-- ){
  1436. if( pBuffer[i] >= pBuffer[256*4+1] ) break;
  1437. }
  1438. pBuffer[256*4+3] = i;
  1439. if( pBuffer[256*4+2] > 255 ) pBuffer[256*4+2] = 255;
  1440. if( pBuffer[256*4+3] < 0 ) pBuffer[256*4+3] = 0;
  1441. return( pBuffer );
  1442. }