Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2223 lines
48 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. bmpcvt.cpp
  5. Abstract:
  6. Bitmap conversion object
  7. Environment:
  8. Windows Whistler
  9. Revision History:
  10. 08/23/99
  11. Created it.
  12. --*/
  13. #include "xlpdev.h"
  14. #include "xldebug.h"
  15. #include "pclxle.h"
  16. #include "xlbmpcvt.h"
  17. BPP
  18. NumToBPP(
  19. ULONG ulBPP)
  20. /*++
  21. Routine Description:
  22. Converts Bits per pixel to BPP enum.
  23. Arguments:
  24. Bits per pixel.
  25. Return Value:
  26. BPP enum
  27. Note:
  28. BPP enum is defined in xlbmpcvt.h.
  29. --*/
  30. {
  31. BPP Bpp;
  32. switch (ulBPP)
  33. {
  34. case 1:
  35. Bpp = e1bpp;
  36. break;
  37. case 4:
  38. Bpp = e4bpp;
  39. break;
  40. case 8:
  41. Bpp = e8bpp;
  42. break;
  43. case 16:
  44. Bpp = e16bpp;
  45. break;
  46. case 24:
  47. Bpp = e24bpp;
  48. break;
  49. case 32:
  50. Bpp = e32bpp;
  51. break;
  52. }
  53. return Bpp;
  54. }
  55. ULONG
  56. UlBPPtoNum(
  57. BPP Bpp)
  58. /*++
  59. Routine Description:
  60. Converts BPP enum to bits per pixel.
  61. Arguments:
  62. BPP enum
  63. Return Value:
  64. Bits per pixel.
  65. Note:
  66. BPP enum is defined in xlbmpcvt.h.
  67. --*/
  68. {
  69. ULONG ulRet;
  70. switch (Bpp)
  71. {
  72. case e1bpp:
  73. ulRet = 1;
  74. break;
  75. case e4bpp:
  76. ulRet = 4;
  77. break;
  78. case e8bpp:
  79. ulRet = 8;
  80. break;
  81. case e16bpp:
  82. ulRet = 16;
  83. break;
  84. case e24bpp:
  85. ulRet = 24;
  86. break;
  87. case e32bpp:
  88. ulRet = 32;
  89. break;
  90. }
  91. return ulRet;
  92. }
  93. //
  94. // Constructor/Destructor
  95. //
  96. BMPConv::
  97. BMPConv( VOID ):
  98. /*++
  99. Routine Description:
  100. BMPConv constructor
  101. Arguments:
  102. Return Value:
  103. Note:
  104. Initializes values. There is no memory allocation.
  105. --*/
  106. m_flags(0),
  107. m_dwOutputBuffSize(0),
  108. m_dwRLEOutputBuffSize(0),
  109. m_dwDRCOutputBuffSize(0),
  110. m_OddPixelStart(eOddPixelZero),
  111. m_FirstBit(eBitZero),
  112. m_pxlo(NULL),
  113. m_pubOutputBuff(NULL),
  114. m_pubRLEOutputBuff(NULL),
  115. m_pubDRCOutputBuff(NULL),
  116. m_pubDRCPrevOutputBuff(NULL),
  117. m_CMode(eNoCompression)
  118. {
  119. #if DBG
  120. SetDbgLevel(DBG_WARNING);
  121. #endif
  122. XL_VERBOSE(("BMPConv: Ctor\n"));
  123. }
  124. BMPConv::
  125. ~BMPConv( VOID )
  126. /*++
  127. Routine Description:
  128. BMPConv destructor
  129. Arguments:
  130. Return Value:
  131. Note:
  132. m_pubOutputBuff and m_pubRLEOutputBuff are allocaed ConvertBMP.
  133. ConvertBMP is scaline base bitmap conversion function.
  134. --*/
  135. {
  136. XL_VERBOSE(("BMPConv: Dtor\n"));
  137. //
  138. // DRCPrevOutputBuff and OutputBuff are contiguous.
  139. if (m_pubOutputBuff)
  140. MemFree(m_pubOutputBuff);
  141. if (m_pubRLEOutputBuff)
  142. MemFree(m_pubRLEOutputBuff);
  143. if (m_pubDRCOutputBuff)
  144. MemFree(m_pubDRCOutputBuff);
  145. }
  146. //
  147. // Public functions
  148. //
  149. #if DBG
  150. VOID
  151. BMPConv::
  152. SetDbgLevel(
  153. DWORD dwLevel)
  154. /*++
  155. Routine Description:
  156. Arguments:
  157. Return Value:
  158. Note:
  159. --*/
  160. {
  161. m_dbglevel = dwLevel;
  162. }
  163. #endif
  164. BOOL
  165. BMPConv::
  166. BSetInputBPP(
  167. BPP InputBPP)
  168. /*++
  169. Routine Description:
  170. Sets source bitmap BPP in BMPConv.
  171. Arguments:
  172. Source bitmap BPP enum (bits per pixel)
  173. Return Value:
  174. TRUE if succeeded.
  175. Note:
  176. --*/
  177. {
  178. XL_VERBOSE(("BMPConv: BSetInputBPP\n"));
  179. m_flags |= BMPCONV_SET_INPUTBPP;
  180. m_InputBPP = InputBPP;
  181. return TRUE;
  182. }
  183. BOOL
  184. BMPConv::
  185. BSetOutputBPP(
  186. BPP OutputBPP)
  187. /*++
  188. Routine Description:
  189. Sets destination bimtap BPP in BMPConv.
  190. Arguments:
  191. Destination bitmap BPP enum
  192. Return Value:
  193. TRUE if succeeded.
  194. Note:
  195. --*/
  196. {
  197. XL_VERBOSE(("BMPConv: BSetOutputBPP\n"));
  198. m_OutputBPP = OutputBPP;
  199. return TRUE;
  200. }
  201. BOOL
  202. BMPConv::
  203. BSetOutputBMPFormat(
  204. OutputFormat BitmapFormat)
  205. /*++
  206. Routine Description:
  207. Sets output bitmap format (GrayScale/Palette/RGB/CMYK).
  208. Arguments:
  209. OutputFormat enum.
  210. Return Value:
  211. TRUE if succeeded.
  212. Note:
  213. --*/
  214. {
  215. XL_VERBOSE(("BMPConv: BSetOutputBMPFormat\n"));
  216. m_OutputFormat = BitmapFormat;
  217. return TRUE;
  218. }
  219. BOOL
  220. BMPConv::
  221. BSetCompressionType(
  222. CompressMode CMode)
  223. /*++
  224. Routine Description:
  225. Set compression type.
  226. Arguments:
  227. CompressMode {eNoCompression, eRLECompression, eDeltaRowCompression}
  228. Return Value:
  229. TRUE if it succeeded.
  230. Note:
  231. --*/
  232. {
  233. XL_VERBOSE(("BMPConv: BSetCompressionType.\n"));
  234. m_CMode = CMode;
  235. return TRUE;
  236. }
  237. CompressMode
  238. BMPConv::
  239. GetCompressionType(VOID)
  240. /*++
  241. Routine Description:
  242. CompressMode
  243. Arguments:
  244. Return Value:
  245. Note:
  246. --*/
  247. {
  248. XL_VERBOSE(("BMPConv: BGetRLEStatus\n"));
  249. return m_CMode;
  250. }
  251. BOOL
  252. BMPConv::
  253. BSetXLATEOBJ(
  254. XLATEOBJ *pxlo)
  255. /*++
  256. Routine Description:
  257. Sets XLATEOBJ in BMPConv.
  258. Arguments:
  259. A pointer to XLATEOBJ.
  260. Return Value:
  261. Note:
  262. --*/
  263. {
  264. XL_VERBOSE(("BMPConv: BSetXLATEOBJ\n"));
  265. //
  266. // XL_ERRor check
  267. //
  268. if (NULL == pxlo)
  269. {
  270. XL_ERR(("BMPConv::BSetXLATEOBJ: an invalid parameter.\n"));
  271. return FALSE;
  272. }
  273. m_pxlo = pxlo;
  274. m_flags |= DwCheckXlateObj(pxlo, m_InputBPP);
  275. return TRUE;
  276. }
  277. PBYTE
  278. BMPConv::
  279. PubConvertBMP(
  280. PBYTE pubSrc,
  281. DWORD dwcbSrcSize)
  282. /*++
  283. Routine Description:
  284. Scaline base bitmap conversion function.
  285. Arguments:
  286. pubSrc - a pointer to the source bitmap.
  287. dwcbSrcSize - the size of the source bitmap.
  288. Return Value:
  289. A pointer to the destination bitmap.
  290. Note:
  291. The pointer to the destination bitmap is stored in BMPConv.
  292. It is going to be freed in the BMPConv destructor.
  293. --*/
  294. {
  295. DWORD dwcbDstSize, dwInputBPP;
  296. LONG lWidth, lHeight;
  297. PBYTE pubRet = NULL;
  298. XL_VERBOSE(("BMPConv: BConvertBMP\n"));
  299. //
  300. // Calculate the number of pixels and the size of dest buffer
  301. // Output data has to be DWORD aligned on PCL-XL.
  302. //
  303. dwInputBPP = UlBPPtoNum(m_InputBPP);
  304. m_dwWidth = ((dwcbSrcSize << 3 ) + dwInputBPP - 1) / dwInputBPP;
  305. dwcbDstSize = ((UlBPPtoNum(m_OutputBPP) * m_dwWidth + 31 ) >> 5 ) << 2;
  306. //
  307. // Allocate destination buffer
  308. //
  309. if (NULL == m_pubOutputBuff || NULL == m_pubDRCPrevOutputBuff)
  310. {
  311. //
  312. // Allocate main and previous output buffer for DRC.
  313. //
  314. m_pubOutputBuff = (PBYTE)MemAlloc(dwcbDstSize * 2);
  315. if (NULL == m_pubOutputBuff)
  316. {
  317. XL_ERR(("BMPConv::PubConvertBMP: m_pubOutputBuff[0x%x] allocation failed..\n", dwcbDstSize));
  318. return NULL;
  319. }
  320. m_dwOutputBuffSize = dwcbDstSize;
  321. //
  322. // Zero init seed row.
  323. // PCL XL exception about DRC.
  324. // 1) the seed row is initialized to zeroes and contains the number
  325. // of bytes defined by SourceWidth in the BeginImage operator.
  326. //
  327. m_pubDRCPrevOutputBuff = m_pubOutputBuff + dwcbDstSize;
  328. m_dwDRCPrevOutputBuffSize = dwcbDstSize;
  329. memset(m_pubDRCPrevOutputBuff, 0, m_dwDRCPrevOutputBuffSize);
  330. }
  331. //
  332. // Allocate RLE destination buffer if RLE is on.
  333. //
  334. if (m_CMode == eRLECompression && NULL == m_pubRLEOutputBuff)
  335. {
  336. m_pubRLEOutputBuff = (PBYTE)MemAlloc(dwcbDstSize * 3);
  337. m_dwRLEOutputBuffSize = dwcbDstSize * 3;
  338. if (NULL == m_pubRLEOutputBuff)
  339. {
  340. XL_ERR(("BMPConv::PubConvertBMP: m_pubOutputBuff[0x%x] allocation failed..\n", dwcbDstSize));
  341. MemFree(m_pubOutputBuff);
  342. m_pubOutputBuff = NULL;
  343. m_dwOutputBuffSize = 0;
  344. m_pubDRCPrevOutputBuff = NULL;
  345. m_dwDRCPrevOutputBuffSize = 0;
  346. return NULL;
  347. }
  348. }
  349. //
  350. // Allocate DRC destination buffer if DRC is on.
  351. //
  352. if (m_CMode == eDeltaRowCompression && NULL == m_pubDRCOutputBuff)
  353. {
  354. m_pubDRCOutputBuff = (PBYTE)MemAlloc(dwcbDstSize * 3);
  355. m_dwDRCOutputBuffSize = dwcbDstSize * 3;
  356. if (NULL == m_pubDRCOutputBuff)
  357. {
  358. XL_ERR(("BMPConv::PubConvertBMP: m_pubOutputBuff[0x%x] allocation failed..\n", dwcbDstSize));
  359. MemFree(m_pubOutputBuff);
  360. m_pubOutputBuff = NULL;
  361. m_pubDRCPrevOutputBuff = NULL;
  362. MemFree(m_pubRLEOutputBuff);
  363. m_pubRLEOutputBuff = NULL;
  364. return NULL;
  365. }
  366. }
  367. //
  368. // Converrt source bitmap to destination.
  369. // Source and Destination format is set by SetXXX functions.
  370. //
  371. if (BConversionProc(pubSrc, (dwcbSrcSize * 8 + dwInputBPP - 1) / dwInputBPP))
  372. {
  373. if (m_CMode == eRLECompression)
  374. {
  375. if (BCompressRLE())
  376. pubRet = m_pubRLEOutputBuff;
  377. else
  378. pubRet = NULL;
  379. }
  380. else
  381. if (m_CMode == eDeltaRowCompression)
  382. {
  383. if (BCompressDRC())
  384. pubRet = m_pubDRCOutputBuff;
  385. else
  386. pubRet = NULL;
  387. //
  388. // Update seed row for DRC.
  389. //
  390. CopyMemory(m_pubDRCPrevOutputBuff, m_pubOutputBuff, m_dwDRCPrevOutputBuffSize);
  391. }
  392. else
  393. pubRet = m_pubOutputBuff;
  394. }
  395. else
  396. pubRet = NULL;
  397. return pubRet;
  398. }
  399. BOOL
  400. BMPConv::
  401. BCompressRLE(
  402. VOID)
  403. /*++
  404. Routine Description:
  405. RLE compression function
  406. Arguments:
  407. Return Value:
  408. TRUE if it succeeded.
  409. Note:
  410. --*/
  411. {
  412. DWORD dwSrcSize, dwDstSize, dwCount, dwErr, dwInputBPP, dwWidth;
  413. PBYTE pubSrcBuff, pubDstBuff, pubLiteralNum;
  414. BYTE ubCurrentData;
  415. BOOL bLiteral;
  416. XL_VERBOSE(("BMPConv: BCompressRLE\n"));
  417. if ( NULL == m_pubRLEOutputBuff ||
  418. NULL == m_pubOutputBuff )
  419. return FALSE;
  420. //
  421. //
  422. // PCL XL Run Length Encoding Compression Method (eRLECompression)
  423. // The PCL XL RLE compression method employs control bytes followed by data
  424. // bytes. Each
  425. // control byte in the compressed data sequence is a signed, two's
  426. // complement byte.
  427. // If bit 7 of the control byte is zero (0 <= control byte <= 127) the bytes
  428. // following are literal.
  429. // Literal bytes are simply uncompressed data bytes. The number of literal
  430. // bytes following a control
  431. // byte is one plus the value of the control byte. Thus, a control byte of 0
  432. // means 1 literal byte
  433. // follows; a control byte of 6 means 7 literal bytes follow; and so on.
  434. // If bit 7 of the control byte is 1 (-127 <= control byte <= -1), the byte
  435. // following the control byte
  436. // will occur two or more times as decompressed data. A byte following a
  437. // control byte in this range
  438. // is called a repeat byte. The control byte39s absolute value plus one is
  439. // the number of times the byte
  440. // following will occur in the decompressed sequence of bytes. For example,
  441. // a control byte of -5
  442. // means the subsequent byte will occur 6 times as decompressed data.
  443. // A control byte of -128 is ignored and is not included in the decompressed
  444. // data. The byte
  445. // following a control byte of 128 is treated as the next control byte.
  446. // It is more efficient to code two consecutive identical bytes as a
  447. // repeated byte, unless these bytes
  448. // are preceded and followed by literal bytes. Three-byte repeats should
  449. // always be encoded using a
  450. // repeat control byte.
  451. //
  452. // Literal byte <= 127
  453. // Repeated byte <= 128
  454. //
  455. bLiteral = FALSE;
  456. dwCount = 1;
  457. dwSrcSize = m_dwOutputBuffSize;
  458. pubSrcBuff = m_pubOutputBuff;
  459. pubDstBuff = m_pubRLEOutputBuff;
  460. m_dwRLEOutputDataSize = 0;
  461. while (dwSrcSize > 0 && m_dwRLEOutputDataSize + 2 < m_dwRLEOutputBuffSize)
  462. {
  463. ubCurrentData = *pubSrcBuff++;
  464. while (dwSrcSize > dwCount &&
  465. ubCurrentData == *pubSrcBuff &&
  466. dwCount < 128 )
  467. {
  468. dwCount++;
  469. pubSrcBuff++;
  470. }
  471. if (dwCount > 1)
  472. {
  473. bLiteral = FALSE;
  474. *pubDstBuff++ = 1-(char)dwCount;
  475. *pubDstBuff++ = ubCurrentData;
  476. m_dwRLEOutputDataSize += 2;
  477. }
  478. else
  479. {
  480. if (bLiteral)
  481. {
  482. (*pubLiteralNum) ++;
  483. *pubDstBuff++ = ubCurrentData;
  484. m_dwRLEOutputDataSize ++;
  485. if (*pubLiteralNum == 127)
  486. {
  487. bLiteral = FALSE;
  488. }
  489. }
  490. else
  491. {
  492. bLiteral = TRUE;
  493. pubLiteralNum = pubDstBuff;
  494. *pubDstBuff++ = 0;
  495. *pubDstBuff++ = ubCurrentData;
  496. m_dwRLEOutputDataSize += 2;
  497. }
  498. }
  499. dwSrcSize -= dwCount;
  500. dwCount = 1;
  501. }
  502. if (dwSrcSize == 0)
  503. return TRUE;
  504. else
  505. return FALSE;
  506. }
  507. BOOL
  508. BMPConv::
  509. BCompressDRC(
  510. VOID)
  511. /*++
  512. Routine Description:
  513. This function is called to compress a scan line of data using
  514. delta row compression.
  515. Arguments:
  516. Return Value:
  517. Number of compressed bytes or -1 if too large for buffer
  518. Note:
  519. A return value of 0 is valid since it implies the two lines
  520. are identical.
  521. --*/
  522. {
  523. BYTE *pbI;
  524. BYTE *pbO; /* Record output location */
  525. BYTE *pbOEnd; /* As far as we will go in the output buffer */
  526. BYTE *pbIEnd;
  527. BYTE *pbStart;
  528. BYTE *pb;
  529. int iDelta;
  530. int iOffset; // index of current data stream
  531. int iSize; /* Number of bytes in the run */
  532. int iSrcSize;
  533. //
  534. // The control byte has the following format:
  535. // Number of delta bytes: Bits 5-7 indicate the number of consecutive
  536. // replacement bytes that follow the commands byte. The actual number
  537. // of of replacement bytes is always one more than the value
  538. // (000 = 1, 111 = 8). If more than 8 delta bytes are needed,
  539. // additional command byte/delta bytes are added.
  540. // [ (Command Byte) (1-8 Delta Bytes) ]
  541. // [ (Command Byte) (1-8 Delta Bytes) ] . . .
  542. // Offset: Bits 0-4 show where to position the replacement byte string.
  543. // This is the offset: it specifies a byte placement, counting from left
  544. // to right from the current byte position. The current byte is the
  545. // first unaltered byte that follows the last replacement bytes; at the
  546. // beginning of a row, the current byte immediately follows the left
  547. // raster margin. Bits 0-4 allow a maximum value of 31, but larger
  548. // offsets are possible. A value of 0 to 30 indicates the delta bytes
  549. // are offset from the 1st to the 31st bytes.
  550. // A value of 31 indicates that an additional offset byte follows the
  551. // command byte.
  552. //
  553. // To summarize, bits 0-4 have the following meaning:
  554. // 0 to 30: the offset is 0 to 30.
  555. // 31: the offset is 31 or greater. If the offset is 31, an additional
  556. // offset byte follows the command byte. The offset in the command bytes
  557. // is added to the offset bytes. If the offset byte is 0, the offset is
  558. // 31; if the offset byte is 255 additional offset bytes follow.
  559. // The last offset byte will have a value less than 255. All the offset
  560. // bytes are added to the offset in the command byte to get the offset
  561. // value. For example, if there are two offset bytes, and the last
  562. // byte contains 175, the total offset would be: 31+255+175=461.
  563. //
  564. /*
  565. * Limit the amount of data we will generate. For performance
  566. * reasons we will ignore the effects of an offset value
  567. * greater than 30 since it implies we were able to already skip
  568. * that many bytes. However, for safety sake we will reduce the
  569. * max allowable size by 2 bytes.
  570. */
  571. XL_VERBOSE(("BMPConv: BCompressDRC\n"));
  572. m_dwDRCOutputDataSize = 0;
  573. if ( NULL == m_pubDRCOutputBuff ||
  574. NULL == m_pubDRCPrevOutputBuff ||
  575. NULL == m_pubOutputBuff )
  576. return FALSE;
  577. pbI = m_pubOutputBuff; /* Working copy */
  578. iSrcSize = (UlBPPtoNum(m_OutputBPP) * m_dwWidth + 7) >> 3;
  579. pbIEnd = m_pubOutputBuff + iSrcSize;
  580. pbO = m_pubDRCOutputBuff; /* Working copy */
  581. pbOEnd = m_pubDRCOutputBuff + m_dwDRCOutputBuffSize - 2;
  582. //
  583. // m_pubDRCPrevOutputBuff is continuously followed by m_putOutputBuff.
  584. // Both has m_dwOutputBuffSize size of memory.
  585. //
  586. iDelta = (int)(m_pubDRCPrevOutputBuff - m_pubOutputBuff);
  587. pbStart = m_pubOutputBuff;
  588. //
  589. // PCL XL exception.
  590. // 2) the delta row is preceded by a 2-byte byte count which
  591. // indicates the number of bytes to follow for the delta row.
  592. // The byte count is expected to be in LSB MSB order.
  593. //
  594. *((PWORD)pbO) = 0x0000;
  595. pbO += 2;
  596. //
  597. // this is the main loop for compressing the data
  598. //
  599. while (pbI < pbIEnd)
  600. {
  601. // fast skip for matching dwords
  602. //
  603. if (!((ULONG_PTR)pbI & 3))
  604. {
  605. while (pbI <= (pbIEnd-4) && *(DWORD *)pbI == *(DWORD *)&pbI[iDelta])
  606. pbI += 4;
  607. if (pbI >= pbIEnd)
  608. break;
  609. }
  610. // test for non-matching bytes and output the necessary compression string
  611. //
  612. if (*pbI != pbI[iDelta])
  613. {
  614. // determine the run length
  615. pb = pbI;
  616. do {
  617. pb++;
  618. } while (pb < pbIEnd && *pb != pb[iDelta]);
  619. iSize = (int)(pb - pbI);
  620. // Lets make sure we have room in the buffer before
  621. // we continue this, this compression algorithm adds
  622. // 1 byte for every 8 bytes of data worst case.
  623. //
  624. if (((iSize * 9 + 7) >> 3) > (pbOEnd - pbO)) // gives tighter code
  625. return FALSE;
  626. iOffset = (int)(pbI - pbStart);
  627. if (iOffset > 30)
  628. {
  629. if (iSize < 8)
  630. *pbO++ = ((iSize-1) << 5) + 31;
  631. else
  632. *pbO++ = (7 << 5) + 31;
  633. iOffset -= 31;
  634. while (iOffset >= 255)
  635. {
  636. iOffset -= 255;
  637. *pbO++ = 255;
  638. }
  639. *pbO++ = (BYTE)iOffset;
  640. if (iSize > 8)
  641. goto FastEightByteRun;
  642. }
  643. else if (iSize > 8)
  644. {
  645. *pbO++ = (7 << 5) + iOffset;
  646. FastEightByteRun:
  647. while (1)
  648. {
  649. CopyMemory(pbO,pbI,8);
  650. pbI += 8;
  651. pbO += 8;
  652. if ((iSize -= 8) <= 8)
  653. break;
  654. *pbO++ = (7 << 5);
  655. }
  656. *pbO++ = (iSize-1) << 5;
  657. }
  658. else
  659. *pbO++ = ((iSize-1) << 5) + iOffset;
  660. CopyMemory (pbO,pbI,iSize);
  661. pbI += iSize;
  662. pbO += iSize;
  663. pbStart = pbI;
  664. }
  665. pbI++;
  666. }
  667. //
  668. // PCL XL exception.
  669. // 2) the delta row is preceded by a 2-byte byte count which
  670. // indicates the number of bytes to follow for the delta row.
  671. // The byte count is expected to be in LSB MSB order.
  672. //
  673. m_dwDRCOutputDataSize = (DWORD)(pbO - m_pubDRCOutputBuff);
  674. (*(PWORD)m_pubDRCOutputBuff) = (WORD)m_dwDRCOutputDataSize - 2;
  675. return TRUE;
  676. }
  677. DWORD
  678. BMPConv::
  679. DwGetDstSize(VOID)
  680. /*++
  681. Routine Description:
  682. Returns the size of destination bitmap.
  683. Arguments:
  684. Return Value:
  685. Note:
  686. --*/
  687. {
  688. XL_VERBOSE(("BMPConv: DwGetDstSize\n"));
  689. if (m_CMode == eDeltaRowCompression)
  690. return m_dwDRCOutputDataSize;
  691. else
  692. if (m_CMode == eRLECompression)
  693. return m_dwRLEOutputDataSize;
  694. else
  695. return m_dwOutputBuffSize;
  696. }
  697. //
  698. // Scanline basis DIB conversion functions
  699. //
  700. BOOL
  701. BMPConv::
  702. BCopy(
  703. PBYTE pubSrc,
  704. DWORD dwSrcPixelNum)
  705. /*++
  706. Routine Description:
  707. DIB conversion function. Simple copy for 1BPP, 4,8BPP palette image.
  708. Arguments:
  709. pubSrc - Source DIB buffer
  710. dwSrcPixelNum - the number of source pixel
  711. Return Value:
  712. Return TRUE if succeeded, otherwise FALSE.
  713. --*/
  714. {
  715. DWORD dwByteIndex, dwBitIndex, dwSrcBytes, dwSrcRemainderBits;
  716. XL_VERBOSE(("BMPConv: BCopy\n"));
  717. if (m_InputBPP == e8bpp || m_FirstBit == eBitZero)
  718. {
  719. dwSrcBytes = (dwSrcPixelNum * (DWORD)UlBPPtoNum(m_InputBPP) + 7) >> 3;
  720. CopyMemory(m_pubOutputBuff, pubSrc, dwSrcBytes);
  721. }
  722. else
  723. {
  724. //
  725. // m_InputBPP is either 1 or 4, m_FirstBit is in [1,7].
  726. //
  727. ASSERT((m_InputBPP == e1bpp) || (m_InputBPP == e4bpp));
  728. ASSERT(m_FirstBit != eBitZero);
  729. dwSrcBytes = (dwSrcPixelNum * (DWORD)UlBPPtoNum(m_InputBPP)) >> 3;
  730. dwSrcRemainderBits = (dwSrcPixelNum * (DWORD)UlBPPtoNum(m_InputBPP)) % 8;
  731. //
  732. // Now dwSrcBytes is the number of full bytes we need to copy from the source,
  733. // dwSrcRemainderBits is the number of remaining bits after dwSrcBytes number
  734. // of bytes in the source we need to copy.
  735. //
  736. // We first copy the full bytes from source.
  737. //
  738. for (dwByteIndex = 0; dwByteIndex < dwSrcBytes; dwByteIndex++)
  739. {
  740. //
  741. // Compose the destination byte from two adjacent source bytes.
  742. //
  743. m_pubOutputBuff[dwByteIndex] = (BYTE)(pubSrc[dwByteIndex] << ((DWORD)m_FirstBit)) |
  744. (BYTE)(pubSrc[dwByteIndex+1] >> (8 - (DWORD)m_FirstBit));
  745. }
  746. if (dwSrcRemainderBits)
  747. {
  748. //
  749. // Now copy the remaining source bits. There are 2 cases:
  750. //
  751. // (1) the remaining source bits are in 1 byte;
  752. // (2) the remaining source bits run across 2 bytes;
  753. //
  754. if (((DWORD)m_FirstBit + dwSrcRemainderBits - 1) < 8)
  755. m_pubOutputBuff[dwByteIndex] = (BYTE)(pubSrc[dwByteIndex] << ((DWORD)m_FirstBit));
  756. else
  757. m_pubOutputBuff[dwByteIndex] = (BYTE)(pubSrc[dwByteIndex] << ((DWORD)m_FirstBit)) |
  758. (BYTE)(pubSrc[dwByteIndex+1] >> (8 - (DWORD)m_FirstBit));
  759. }
  760. }
  761. return TRUE;
  762. }
  763. BOOL
  764. BMPConv::
  765. B4BPPtoCMYK(
  766. PBYTE pubSrc,
  767. DWORD dwSrcPixelNum)
  768. /*++
  769. Routine Description:
  770. DIB conversion function. 4BPP to CMYK.
  771. Arguments:
  772. pubSrc - Source DIB buffer
  773. dwSrcPixelNum - the number of source pixel
  774. Return Value:
  775. Return TRUE if succeeded, otherwise FALSE.
  776. --*/
  777. {
  778. PDWORD pdwColorTable;
  779. PBYTE pubDst;
  780. DWORD dwConvSize;
  781. ULONG ulIndex;
  782. XL_VERBOSE(("BMPConv: B4BPPtoCMYK\n"));
  783. pdwColorTable = GET_COLOR_TABLE(m_pxlo);
  784. if (pdwColorTable == NULL)
  785. return FALSE;
  786. dwConvSize = (DWORD)m_OddPixelStart;
  787. dwSrcPixelNum += dwConvSize;
  788. pubDst = m_pubOutputBuff;
  789. while (dwConvSize < dwSrcPixelNum)
  790. {
  791. ulIndex = (dwConvSize++ & 1) ?
  792. pdwColorTable[*pubSrc++ & 0x0F] :
  793. pdwColorTable[*pubSrc >> 4];
  794. pubDst[0] = CYAN(ulIndex);
  795. pubDst[1] = MAGENTA(ulIndex);
  796. pubDst[2] = YELLOW(ulIndex);
  797. pubDst[3] = BLACK(ulIndex);
  798. pubDst += 4;
  799. }
  800. return TRUE;
  801. }
  802. BOOL
  803. BMPConv::
  804. B4BPPtoRGB(
  805. PBYTE pubSrc,
  806. DWORD dwSrcPixelNum)
  807. /*++
  808. Routine Description:
  809. DIB conversion function. 4BPP to RGB.
  810. Arguments:
  811. pubSrc - Source DIB buffer
  812. dwSrcPixelNum - the number of source pixel
  813. Return Value:
  814. Return TRUE if succeeded, otherwise FALSE.
  815. --*/
  816. {
  817. PDWORD pdwColorTable;
  818. DWORD dwConvSize;
  819. ULONG ulIndex;
  820. PBYTE pubDst;
  821. XL_VERBOSE(("BMPConv: B4BPPtoRGB\n"));
  822. pdwColorTable = GET_COLOR_TABLE(m_pxlo);
  823. if (pdwColorTable == NULL)
  824. return FALSE;
  825. dwConvSize = m_OddPixelStart;
  826. dwSrcPixelNum += dwConvSize;
  827. pubDst = m_pubOutputBuff;
  828. while (dwConvSize < dwSrcPixelNum)
  829. {
  830. ulIndex = (dwConvSize++ & 1) ?
  831. pdwColorTable[*pubSrc++ & 0x0F] :
  832. pdwColorTable[*pubSrc >> 4];
  833. pubDst[0] = RED(ulIndex);
  834. pubDst[1] = GREEN(ulIndex);
  835. pubDst[2] = BLUE(ulIndex);
  836. pubDst += 3;
  837. }
  838. return TRUE;
  839. }
  840. BOOL
  841. BMPConv::
  842. B4BPPtoGray(
  843. PBYTE pubSrc,
  844. DWORD dwSrcPixelNum)
  845. /*++
  846. Routine Description:
  847. DIB conversion function. 4BPP to Gray.
  848. Arguments:
  849. pubSrc - Source DIB buffer
  850. dwSrcPixelNum - the number of source pixel
  851. Return Value:
  852. Return TRUE if succeeded, otherwise FALSE.
  853. --*/
  854. {
  855. PDWORD pdwColorTable;
  856. ULONG ulIndex;
  857. DWORD dwConvSize;
  858. PBYTE pubDst;
  859. XL_VERBOSE(("BMPConv: B4BPPtoGray\n"));
  860. pdwColorTable = GET_COLOR_TABLE(m_pxlo);
  861. if (pdwColorTable == NULL)
  862. return FALSE;
  863. dwConvSize = m_OddPixelStart;
  864. dwSrcPixelNum += dwConvSize;
  865. pubDst = m_pubOutputBuff;
  866. while (dwConvSize < dwSrcPixelNum)
  867. {
  868. ulIndex = (dwConvSize++ & 1) ?
  869. pdwColorTable[*pubSrc++ & 0x0F] :
  870. pdwColorTable[*pubSrc >> 4];
  871. *pubDst++ = DWORD2GRAY(ulIndex);
  872. }
  873. return TRUE;
  874. }
  875. BOOL
  876. BMPConv::
  877. B8BPPtoGray(
  878. IN PBYTE pubSrc,
  879. IN DWORD dwSrcPixelNum
  880. )
  881. /*++
  882. Routine Description:
  883. DIB conversion function - 8BPP to grayscale.
  884. Arguments:
  885. pubSrc - Source DIB buffer
  886. dwSrcPixelNum - the number of source pixel
  887. Return Value:
  888. Return TRUE if succeeded, otherwise FALSE.
  889. --*/
  890. {
  891. PDWORD pdwColorTable;
  892. DWORD dwColor;
  893. PBYTE pubDst;
  894. XL_VERBOSE(("BMPConv: B8BPPtoGray\n"));
  895. pdwColorTable = GET_COLOR_TABLE(m_pxlo);
  896. if (pdwColorTable == NULL)
  897. return FALSE;
  898. pubDst = m_pubOutputBuff;
  899. while (dwSrcPixelNum--)
  900. {
  901. dwColor = pdwColorTable[*pubSrc++];
  902. *pubDst++ = DWORD2GRAY(dwColor);
  903. }
  904. return TRUE;
  905. }
  906. BOOL
  907. BMPConv::
  908. B8BPPtoRGB(
  909. IN PBYTE pubSrc,
  910. IN DWORD dwSrcPixelNum)
  911. /*++
  912. Routine Description:
  913. DIB conversion function. 8BPP to RGB.
  914. Arguments:
  915. pubSrc - Source DIB buffer
  916. dwSrcPixelNum - the number of source pixel
  917. Return Value:
  918. Return the size of translated destination bitmap
  919. --*/
  920. {
  921. PDWORD pdwColorTable;
  922. ULONG ulIndex;
  923. PBYTE pubDst;
  924. XL_VERBOSE(("BMPConv: B8BPPtoRGB\n"));
  925. pdwColorTable = GET_COLOR_TABLE(m_pxlo);
  926. if (pdwColorTable == NULL)
  927. return FALSE;
  928. pubDst = m_pubOutputBuff;
  929. while (dwSrcPixelNum--)
  930. {
  931. ulIndex = pdwColorTable[*pubSrc++];
  932. pubDst[0] = RED(ulIndex);
  933. pubDst[1] = GREEN(ulIndex);
  934. pubDst[2] = BLUE(ulIndex);
  935. pubDst += 3;
  936. }
  937. return TRUE;
  938. }
  939. BOOL
  940. BMPConv::
  941. B8BPPtoCMYK(
  942. IN PBYTE pubSrc,
  943. IN DWORD dwSrcPixelNum)
  944. /*++
  945. Routine Description:
  946. DIB conversion function. 8BPP to CMYK.
  947. Arguments:
  948. pubSrc - Source DIB buffer
  949. dwSrcPixelNum - the number of source pixel
  950. Return Value:
  951. Return the size of translated destination bitmap
  952. --*/
  953. {
  954. PDWORD pdwColorTable;
  955. ULONG ulIndex;
  956. PBYTE pubDst;
  957. XL_VERBOSE(("BMPConv: B8BPPtoCMYK\n"));
  958. pdwColorTable = GET_COLOR_TABLE(m_pxlo);
  959. if (pdwColorTable == NULL)
  960. return FALSE;
  961. pubDst = m_pubOutputBuff;
  962. while (dwSrcPixelNum--)
  963. {
  964. ulIndex = pdwColorTable[*pubSrc++];
  965. pubDst[0] = CYAN(ulIndex);
  966. pubDst[1] = MAGENTA(ulIndex);
  967. pubDst[2] = YELLOW(ulIndex);
  968. pubDst[3] = BLACK(ulIndex);
  969. pubDst += 4;
  970. }
  971. return TRUE;
  972. }
  973. BOOL
  974. BMPConv::
  975. B16BPPtoGray(
  976. IN PBYTE pubSrc,
  977. IN DWORD dwSrcPixelNum)
  978. /*++
  979. Routine Description:
  980. DIB conversion function. 16BPP to 8 bits gray.
  981. Arguments:
  982. pubSrc - Source DIB buffer
  983. dwSrcPixelNum - the number of source pixel
  984. Return Value:
  985. Return TRUE if succeeded, otherwise FALSE.
  986. --*/
  987. {
  988. DWORD dwColor;
  989. PBYTE pubDst = m_pubOutputBuff;
  990. XL_VERBOSE(("BMPConv: B16BPPtoGray\n"));
  991. while (dwSrcPixelNum--)
  992. {
  993. dwColor = XLATEOBJ_iXlate(m_pxlo, *((PWORD) pubSrc));
  994. pubSrc += 2;
  995. *pubDst++ = DWORD2GRAY(dwColor);
  996. }
  997. return TRUE;
  998. }
  999. BOOL
  1000. BMPConv::
  1001. B16BPPtoRGB(
  1002. IN PBYTE pubSrc,
  1003. IN DWORD dwSrcPixelNum)
  1004. /*++
  1005. Routine Description:
  1006. DIB conversion function. 16BPP to RGB.
  1007. Arguments:
  1008. pubSrc - Source DIB buffer
  1009. dwSrcPixelNum - the number of source pixel
  1010. Return Value:
  1011. Return TRUE if succeeded, otherwise FALSE.
  1012. --*/
  1013. {
  1014. DWORD dwColor;
  1015. PBYTE pubDst = m_pubOutputBuff;
  1016. XL_VERBOSE(("BMPConv: B16BPPtoRGB\n"));
  1017. while (dwSrcPixelNum--)
  1018. {
  1019. dwColor = XLATEOBJ_iXlate(m_pxlo, *((PWORD) pubSrc));
  1020. pubSrc += 2;
  1021. pubDst[0] = RED(dwColor);
  1022. pubDst[1] = GREEN(dwColor);
  1023. pubDst[2] = BLUE(dwColor);
  1024. pubDst += 3;
  1025. }
  1026. return TRUE;
  1027. }
  1028. BOOL
  1029. BMPConv::
  1030. B24BPPtoGray(
  1031. IN PBYTE pubSrc,
  1032. IN DWORD dwSrcPixelNum)
  1033. /*++
  1034. Routine Description:
  1035. DIB conversion function. 24BPP to 8 bits gray.
  1036. Arguments:
  1037. pubSrc - Source DIB buffer
  1038. dwSrcPixelNum - the number of source pixel
  1039. Return Value:
  1040. Return TRUE if succeeded, otherwise FALSE.
  1041. --*/
  1042. {
  1043. DWORD dwColor;
  1044. PBYTE pubDst = m_pubOutputBuff;
  1045. XL_VERBOSE(("BMPConv: B24BPPtoGray\n"));
  1046. if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
  1047. {
  1048. //
  1049. // No special conversion is necessary.
  1050. // Pure 24BPP RGB image.
  1051. //
  1052. while (dwSrcPixelNum--)
  1053. {
  1054. *pubDst++ = RGB2GRAY(pubSrc[0], pubSrc[1], pubSrc[2]);
  1055. pubSrc += 3;
  1056. }
  1057. }
  1058. else if (m_flags & BMPCONV_BGR)
  1059. {
  1060. while (dwSrcPixelNum--)
  1061. {
  1062. *pubDst++ = RGB2GRAY(pubSrc[2], pubSrc[1], pubSrc[0]);
  1063. pubSrc += 3;
  1064. }
  1065. }
  1066. else
  1067. {
  1068. ASSERT(m_flags & BMPCONV_XLATE);
  1069. while (dwSrcPixelNum--)
  1070. {
  1071. dwColor = ((DWORD) pubSrc[0] ) |
  1072. ((DWORD) pubSrc[1] << 8) |
  1073. ((DWORD) pubSrc[2] << 16);
  1074. pubSrc += 3;
  1075. dwColor = XLATEOBJ_iXlate(m_pxlo, dwColor);
  1076. *pubDst++ = DWORD2GRAY(dwColor);
  1077. }
  1078. }
  1079. return TRUE;
  1080. }
  1081. BOOL
  1082. BMPConv::
  1083. B24BPPtoRGB(
  1084. IN PBYTE pubSrc,
  1085. IN DWORD dwSrcPixelNum)
  1086. /*++
  1087. Routine Description:
  1088. DIB conversion function. 24BPP to RGB.
  1089. Arguments:
  1090. pubSrc - Source DIB buffer
  1091. dwSrcPixelNum - the number of source pixel
  1092. Return Value:
  1093. Return TRUE if succeeded, otherwise FALSE.
  1094. --*/
  1095. {
  1096. DWORD dwColor;
  1097. PBYTE pubDst = m_pubOutputBuff;
  1098. XL_VERBOSE(("BMPConv: B24BPPtoRGB\n"));
  1099. if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
  1100. {
  1101. //
  1102. // No special conversion is necessary.
  1103. // Pure 24BPP RGB image.
  1104. //
  1105. CopyMemory(m_pubOutputBuff, pubSrc, dwSrcPixelNum * 3);
  1106. }
  1107. else if (m_flags & BMPCONV_BGR)
  1108. {
  1109. while (dwSrcPixelNum--)
  1110. {
  1111. pubDst[0] = pubSrc[2];
  1112. pubDst[1] = pubSrc[1];
  1113. pubDst[2] = pubSrc[0];
  1114. pubSrc += 3;
  1115. pubDst += 3;
  1116. }
  1117. }
  1118. else if (m_flags & BMPCONV_XLATE)
  1119. {
  1120. while (dwSrcPixelNum--)
  1121. {
  1122. dwColor = ((DWORD) pubSrc[0] ) |
  1123. ((DWORD) pubSrc[1] << 8) |
  1124. ((DWORD) pubSrc[2] << 16);
  1125. pubSrc += 3;
  1126. dwColor = XLATEOBJ_iXlate(m_pxlo, dwColor);
  1127. pubDst[0] = RED(dwColor);
  1128. pubDst[1] = GREEN(dwColor);
  1129. pubDst[2] = BLUE(dwColor);
  1130. pubDst += 3;
  1131. }
  1132. }
  1133. return TRUE;
  1134. }
  1135. BOOL
  1136. BMPConv::
  1137. B32BPPtoGray(
  1138. IN PBYTE pubSrc,
  1139. IN DWORD dwSrcPixelNum)
  1140. /*++
  1141. Routine Description:
  1142. DIB conversion function. 32BPP to 8 bits Gray.
  1143. Arguments:
  1144. pubSrc - Source DIB buffer
  1145. dwSrcPixelNum - the number of source pixel
  1146. Return Value:
  1147. Return TRUE if succeeded, otherwise FALSE.
  1148. --*/
  1149. {
  1150. DWORD dwColor;
  1151. BYTE ubCyan, ubMagenta, ubYellow, ubBlack;
  1152. PBYTE pubDst = m_pubOutputBuff;
  1153. XL_VERBOSE(("BMPConv: B24BPPtoGray\n"));
  1154. if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
  1155. {
  1156. //
  1157. // No special conversion is necessary.
  1158. // Source bitmap is a pure 32BPP CMYK image.
  1159. //
  1160. while (dwSrcPixelNum--)
  1161. {
  1162. ubCyan = *pubSrc++;
  1163. ubMagenta = *pubSrc++;
  1164. ubYellow = *pubSrc++;
  1165. ubBlack = *pubSrc++;
  1166. *pubDst++ = RGB2GRAY(255 - min(255, (ubCyan + ubBlack)),
  1167. 255 - min(255, (ubMagenta + ubBlack)),
  1168. 255 - min(255, (ubYellow + ubBlack)));
  1169. }
  1170. }
  1171. else if (m_flags & BMPCONV_32BPP_RGB)
  1172. {
  1173. while (dwSrcPixelNum--)
  1174. {
  1175. *pubDst++ = RGB2GRAY(pubSrc[0], pubSrc[1], pubSrc[2]);
  1176. pubSrc += 4;
  1177. }
  1178. }
  1179. else if (m_flags & BMPCONV_32BPP_BGR)
  1180. {
  1181. while (dwSrcPixelNum--)
  1182. {
  1183. *pubDst++ = RGB2GRAY(pubSrc[0], pubSrc[1], pubSrc[2]);
  1184. pubSrc += 4;
  1185. }
  1186. }
  1187. else
  1188. {
  1189. ASSERT(m_flags & BMPCONV_XLATE);
  1190. while (dwSrcPixelNum--)
  1191. {
  1192. dwColor = XLATEOBJ_iXlate(m_pxlo, *((PDWORD) pubSrc));
  1193. pubSrc += 4;
  1194. *pubDst++ = DWORD2GRAY(dwColor);
  1195. }
  1196. }
  1197. return TRUE;
  1198. }
  1199. BOOL
  1200. BMPConv::
  1201. B32BPPtoRGB(
  1202. IN PBYTE pubSrc,
  1203. IN DWORD dwSrcPixelNum)
  1204. /*++
  1205. Routine Description:
  1206. DIB conversion function. 32BPP to RGB.
  1207. Arguments:
  1208. pubSrc - Source DIB buffer
  1209. dwSrcPixelNum - the number of source pixel
  1210. Return Value:
  1211. Return TRUE if succeeded, otherwise FALSE.
  1212. --*/
  1213. {
  1214. DWORD dwColor;
  1215. BYTE ubCyan, ubMagenta, ubYellow, ubBlack;
  1216. PBYTE pubDst = m_pubOutputBuff;
  1217. XL_VERBOSE(("BMPConv: B32BPPtoRGB\n"));
  1218. if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
  1219. {
  1220. //
  1221. // No special conversion is necessary.
  1222. // Source bitmap is a pure 32BPP CMYK image.
  1223. //
  1224. while (dwSrcPixelNum--)
  1225. {
  1226. ubCyan = pubSrc[0];
  1227. ubMagenta = pubSrc[1];
  1228. ubYellow = pubSrc[2];
  1229. ubBlack = pubSrc[3];
  1230. pubSrc += 4;
  1231. ubCyan += ubBlack;
  1232. ubMagenta += ubBlack;
  1233. ubYellow += ubBlack;
  1234. pubDst[0] = 255 - min(255, ubCyan);
  1235. pubDst[1] = 255 - min(255, ubMagenta);
  1236. pubDst[2] = 255 - min(255, ubYellow);
  1237. pubDst += 3;
  1238. }
  1239. }
  1240. else if (m_flags & BMPCONV_32BPP_RGB)
  1241. {
  1242. while (dwSrcPixelNum--)
  1243. {
  1244. pubDst[0] = pubSrc[0];
  1245. pubDst[1] = pubSrc[1];
  1246. pubDst[2] = pubSrc[2];
  1247. pubSrc += 4;
  1248. pubDst += 3;
  1249. }
  1250. }
  1251. else if (m_flags & BMPCONV_32BPP_BGR)
  1252. {
  1253. while (dwSrcPixelNum--)
  1254. {
  1255. pubDst[0] = pubSrc[2];
  1256. pubDst[1] = pubSrc[1];
  1257. pubDst[2] = pubSrc[0];
  1258. pubSrc += 4;
  1259. pubDst += 3;
  1260. }
  1261. }
  1262. else
  1263. {
  1264. ASSERT(m_flags & BMPCONV_XLATE);
  1265. while (dwSrcPixelNum--)
  1266. {
  1267. dwColor = XLATEOBJ_iXlate(m_pxlo, *((PDWORD) pubSrc));
  1268. pubSrc += 4;
  1269. pubDst[0] = RED(dwColor);
  1270. pubDst[1] = GREEN(dwColor);
  1271. pubDst[2] = BLUE(dwColor);
  1272. pubDst += 3;
  1273. }
  1274. }
  1275. return TRUE;
  1276. }
  1277. BOOL
  1278. BMPConv::
  1279. B32BPPtoCMYK(
  1280. IN PBYTE pubSrc,
  1281. IN DWORD dwSrcPixelNum)
  1282. /*++
  1283. Routine Description:
  1284. DIB conversion function. 32BPP to CMYK.
  1285. Arguments:
  1286. pubSrc - Source DIB buffer
  1287. dwSrcPixelNum - the number of source pixel
  1288. Return Value:
  1289. Return TRUE if succeeded, otherwise FALSE.
  1290. --*/
  1291. {
  1292. DWORD dwColor;
  1293. PBYTE pubDst = m_pubOutputBuff;
  1294. XL_VERBOSE(("BMPConv: B32BPPtoCMYK\n"));
  1295. if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
  1296. {
  1297. //
  1298. // No special conversion is necessary.
  1299. // Source bitmap is a pure 32BPP CMYK image.
  1300. //
  1301. CopyMemory(m_pubOutputBuff, pubSrc, dwSrcPixelNum * 4);
  1302. }
  1303. else
  1304. {
  1305. ASSERT(m_flags & BMPCONV_XLATE);
  1306. while (dwSrcPixelNum--)
  1307. {
  1308. dwColor = XLATEOBJ_iXlate(m_pxlo, *((PDWORD) pubSrc));
  1309. pubSrc += 4;
  1310. pubDst[0] = 255 - RED(dwColor);
  1311. pubDst[1] = 255 - GREEN(dwColor);
  1312. pubDst[2] = 255 - BLUE(dwColor);
  1313. pubDst[3] = 0;
  1314. pubDst += 4;
  1315. }
  1316. }
  1317. return TRUE;
  1318. }
  1319. BOOL
  1320. BMPConv::
  1321. BArbtoGray(
  1322. PBYTE pubSrc,
  1323. DWORD dwSrcPixelNum)
  1324. /*++
  1325. Routine Description:
  1326. DIB conversion function. Arbitray bitmap to 8 bits Gray scale.
  1327. Arguments:
  1328. pubSrc - Source DIB buffer
  1329. dwSrcPixelNum - the number of source pixel
  1330. Return Value:
  1331. Return TRUE if succeeded, otherwise FALSE.
  1332. --*/
  1333. {
  1334. DWORD dwColor;
  1335. PDWORD pdwSrc;
  1336. PBYTE pubDst = m_pubOutputBuff;
  1337. XL_VERBOSE(("BMPConv: BArbtoGray\n"));
  1338. pdwSrc = (PDWORD) pubSrc;
  1339. while (dwSrcPixelNum--)
  1340. {
  1341. dwColor = XLATEOBJ_iXlate(m_pxlo, *pdwSrc++);
  1342. *pubDst++ = DWORD2GRAY(dwColor);
  1343. }
  1344. return TRUE;
  1345. }
  1346. BOOL
  1347. BMPConv::
  1348. BArbtoRGB(
  1349. PBYTE pubSrc,
  1350. DWORD dwSrcPixelNum)
  1351. /*++
  1352. Routine Description:
  1353. DIB conversion function. Arbitraty bitmap to RGB.
  1354. Arguments:
  1355. pubSrc - Source DIB buffer
  1356. dwSrcPixelNum - the number of source pixel
  1357. Return Value:
  1358. Return TRUE if succeeded, otherwise FALSE.
  1359. --*/
  1360. {
  1361. DWORD dwColor;
  1362. PDWORD pdwSrc;
  1363. PBYTE pubDst = m_pubOutputBuff;
  1364. XL_VERBOSE(("BMPConv: BArbtoRGB\n"));
  1365. pdwSrc = (PDWORD) pubSrc;
  1366. while (dwSrcPixelNum--)
  1367. {
  1368. dwColor = XLATEOBJ_iXlate(m_pxlo, *pdwSrc++);
  1369. pubDst[0] = RED(dwColor);
  1370. pubDst[1] = GREEN(dwColor);
  1371. pubDst[2] = BLUE(dwColor);
  1372. pubDst += 3;
  1373. }
  1374. return TRUE;
  1375. }
  1376. #ifdef WINNT_40
  1377. BOOL
  1378. BMPConv::
  1379. B24BPPToImageMask(
  1380. PBYTE pubSrc,
  1381. DWORD dwSrcPixelNum)
  1382. /*++
  1383. Routine Description:
  1384. DIB conversion function. 24 bpp bitmaps with only one non-white color to image mask.
  1385. Can happen on NT4, where GDI does not optimize for that case.
  1386. Arguments:
  1387. pubSrc - Source DIB buffer
  1388. dwSrcPixelNum - the number of source pixel
  1389. Return Value:
  1390. Return TRUE if succeeded, otherwise FALSE.
  1391. --*/
  1392. {
  1393. DWORD dwColor;
  1394. PDWORD pdwSrc;
  1395. BYTE ubDest = 0;
  1396. DWORD dwIndex = 0;
  1397. DWORD dwTransp = (m_flags & BMPCONV_SRC_COPY) ? RGB_WHITE : RGB_BLACK;
  1398. PBYTE pubDst = m_pubOutputBuff;
  1399. XL_VERBOSE(("BMPConv: B24BPPToImageMask\n"));
  1400. while (dwSrcPixelNum--)
  1401. {
  1402. if (! (m_flags & BMPCONV_CHECKXLATEOBJ))
  1403. {
  1404. //
  1405. // No special conversion is necessary, 24BPP RGB image.
  1406. //
  1407. dwColor = ((DWORD) pubSrc[0] ) |
  1408. ((DWORD) pubSrc[1] << 8) |
  1409. ((DWORD) pubSrc[2] << 16);
  1410. }
  1411. else if (m_flags & BMPCONV_BGR)
  1412. {
  1413. //
  1414. // convert 24BPP BGR to RGB.
  1415. //
  1416. dwColor = ((DWORD) pubSrc[2] ) |
  1417. ((DWORD) pubSrc[1] << 8) |
  1418. ((DWORD) pubSrc[0] << 16);
  1419. }
  1420. else if (m_flags & BMPCONV_XLATE)
  1421. {
  1422. dwColor = ((DWORD) pubSrc[0] ) |
  1423. ((DWORD) pubSrc[1] << 8) |
  1424. ((DWORD) pubSrc[2] << 16);
  1425. dwColor = XLATEOBJ_iXlate(m_pxlo, dwColor);
  1426. }
  1427. ubDest = ubDest << 1;
  1428. dwIndex++;
  1429. pubSrc += 3;
  1430. if (dwColor != dwTransp)
  1431. ubDest |= 0x01;
  1432. if (dwIndex == 8) // one byte completed ?
  1433. {
  1434. *pubDst++ = ubDest;
  1435. dwIndex = 0;
  1436. ubDest = 0;
  1437. }
  1438. }
  1439. if (dwIndex != 0) // flush leftover bits
  1440. *pubDst = ubDest;
  1441. return TRUE;
  1442. }
  1443. #endif
  1444. BOOL
  1445. BMPConv::
  1446. BConversionProc(
  1447. PBYTE pubSrc,
  1448. DWORD dwSrcPixelNum)
  1449. /*++
  1450. Routine Description:
  1451. Return a pointer to the appropriate DIB conversion function
  1452. Arguments:
  1453. pBMPAttrrib - Points to a BMPATTRUTE structure
  1454. Return Value:
  1455. Pointer to a DIB conversion function
  1456. --*/
  1457. {
  1458. //PVOID pfnDibConv[7][4] = {
  1459. // Gray Scale, Palette, RGB, CMYK
  1460. //-----------------------------------------------------------------------
  1461. //{BCopy, BCopy, NULL, NULL}, // 1bpp
  1462. //{B4BPPtoGray, BCopy, B4BPPtoRGB, B4BPPtoCMYK}, // 4bpp
  1463. //{B8BPPtoGray, BCopy, B8BPPtoRGB, B8BPPtoCMYK}, // 8bpp
  1464. //{B16BPPtoGray, NULL, B16BPPtoRGB, NULL}, // 16bpp
  1465. //{B24BPPtoGray, NULL, B24BPPtoRGB, NULL}, // 24bpp
  1466. //{B32BPPtoGray, NULL, B32BPPtoRGB, B32BPPtoCMYK},// 32bpp
  1467. //{BArbtoGray, NULL, BArbtoRGB, NULL} // Arbitrary
  1468. //};
  1469. XL_VERBOSE(("BMPConv: BConversionProc\n"));
  1470. //
  1471. // special case for NT4: GDI passes all bitmaps as 24 bpp, even 1 bpp bitmaps
  1472. // that can be better treated through image masks
  1473. //
  1474. #if 0 // #ifdef WINNT_40
  1475. if (m_flags & BMPCONV_2COLOR_24BPP)
  1476. {
  1477. return B24BPPToImageMask;
  1478. }
  1479. #endif
  1480. BOOL bRet = FALSE;
  1481. //
  1482. // Zero init for DWORD alignment
  1483. //
  1484. ZeroMemory(m_pubOutputBuff, m_dwOutputBuffSize);
  1485. switch (m_InputBPP)
  1486. {
  1487. case e1bpp:
  1488. switch(m_OutputFormat)
  1489. {
  1490. case eOutputGray:
  1491. case eOutputPal:
  1492. BCopy(pubSrc, dwSrcPixelNum);
  1493. bRet = TRUE;
  1494. break;
  1495. case eOutputRGB:
  1496. case eOutputCMYK:
  1497. break;
  1498. }
  1499. break;
  1500. case e4bpp:
  1501. switch(m_OutputFormat)
  1502. {
  1503. case eOutputGray:
  1504. B4BPPtoGray(pubSrc, dwSrcPixelNum);
  1505. bRet = TRUE;
  1506. break;
  1507. case eOutputPal:
  1508. BCopy(pubSrc, dwSrcPixelNum);
  1509. bRet = TRUE;
  1510. break;
  1511. case eOutputRGB:
  1512. B4BPPtoRGB(pubSrc, dwSrcPixelNum);
  1513. bRet = TRUE;
  1514. break;
  1515. case eOutputCMYK:
  1516. B4BPPtoCMYK(pubSrc, dwSrcPixelNum);
  1517. bRet = TRUE;
  1518. break;
  1519. }
  1520. break;
  1521. case e8bpp:
  1522. switch(m_OutputFormat)
  1523. {
  1524. case eOutputGray:
  1525. B8BPPtoGray(pubSrc, dwSrcPixelNum);
  1526. bRet = TRUE;
  1527. break;
  1528. case eOutputPal:
  1529. BCopy(pubSrc, dwSrcPixelNum);
  1530. bRet = TRUE;
  1531. break;
  1532. case eOutputRGB:
  1533. B8BPPtoRGB(pubSrc, dwSrcPixelNum);
  1534. bRet = TRUE;
  1535. break;
  1536. case eOutputCMYK:
  1537. B8BPPtoCMYK(pubSrc, dwSrcPixelNum);
  1538. bRet = TRUE;
  1539. break;
  1540. }
  1541. break;
  1542. case e16bpp:
  1543. switch(m_OutputFormat)
  1544. {
  1545. case eOutputGray:
  1546. B16BPPtoGray(pubSrc, dwSrcPixelNum);
  1547. bRet = TRUE;
  1548. break;
  1549. case eOutputPal:
  1550. BCopy(pubSrc, dwSrcPixelNum);
  1551. bRet = TRUE;
  1552. break;
  1553. break;
  1554. case eOutputRGB:
  1555. B16BPPtoRGB(pubSrc, dwSrcPixelNum);
  1556. bRet = TRUE;
  1557. break;
  1558. case eOutputCMYK:
  1559. XL_ERR(("BMPConv::BConversionProc: 16 to CMYK is not supported yet.\n"));
  1560. break;
  1561. }
  1562. break;
  1563. case e24bpp:
  1564. switch(m_OutputFormat)
  1565. {
  1566. case eOutputGray:
  1567. B24BPPtoGray(pubSrc, dwSrcPixelNum);
  1568. bRet = TRUE;
  1569. break;
  1570. case eOutputPal:
  1571. break;
  1572. case eOutputRGB:
  1573. B24BPPtoRGB(pubSrc, dwSrcPixelNum);
  1574. bRet = TRUE;
  1575. break;
  1576. case eOutputCMYK:
  1577. break;
  1578. }
  1579. break;
  1580. case e32bpp:
  1581. switch(m_OutputFormat)
  1582. {
  1583. case eOutputGray:
  1584. B32BPPtoGray(pubSrc, dwSrcPixelNum);
  1585. bRet = TRUE;
  1586. break;
  1587. case eOutputPal:
  1588. break;
  1589. case eOutputRGB:
  1590. B32BPPtoRGB(pubSrc, dwSrcPixelNum);
  1591. bRet = TRUE;
  1592. break;
  1593. case eOutputCMYK:
  1594. B32BPPtoCMYK(pubSrc, dwSrcPixelNum);
  1595. bRet = TRUE;
  1596. break;
  1597. }
  1598. break;
  1599. default:
  1600. switch(m_OutputFormat)
  1601. {
  1602. case eOutputGray:
  1603. BArbtoGray(pubSrc, dwSrcPixelNum);
  1604. bRet = TRUE;
  1605. break;
  1606. case eOutputPal:
  1607. break;
  1608. case eOutputRGB:
  1609. BArbtoRGB(pubSrc, dwSrcPixelNum);
  1610. bRet = TRUE;
  1611. break;
  1612. case eOutputCMYK:
  1613. XL_ERR(("BMPConv::BConversionProc: Arb to CMYK is not supported yet.\n"));
  1614. break;
  1615. }
  1616. }
  1617. return bRet;
  1618. }
  1619. DWORD
  1620. BMPConv::
  1621. DwCheckXlateObj(
  1622. IN XLATEOBJ *pxlo,
  1623. IN BPP InputBPP)
  1624. /*++
  1625. Routine Description:
  1626. Determines the type of converison.
  1627. *Palette
  1628. *RGB
  1629. *BGR
  1630. *CMYK
  1631. *Call XLATEOBJ_XXX function.
  1632. Arguments:
  1633. Return Value:
  1634. Note:
  1635. --*/
  1636. {
  1637. DWORD dwRet;
  1638. DWORD Dst[4];
  1639. XL_VERBOSE(("BMPConv: DwCheckXlateObj\n"));
  1640. //
  1641. // Init dwRet
  1642. //
  1643. dwRet = 0;
  1644. switch (InputBPP)
  1645. {
  1646. case e16bpp:
  1647. dwRet = BMPCONV_XLATE;
  1648. break;
  1649. case e24bpp:
  1650. if (pxlo->iSrcType == PAL_RGB)
  1651. dwRet = 0;
  1652. else
  1653. if (pxlo->iSrcType == PAL_BGR)
  1654. dwRet = BMPCONV_BGR;
  1655. {
  1656. Dst[0] = XLATEOBJ_iXlate(pxlo, 0x000000FF);
  1657. Dst[1] = XLATEOBJ_iXlate(pxlo, 0x0000FF00);
  1658. Dst[2] = XLATEOBJ_iXlate(pxlo, 0x00FF0000);
  1659. if ((Dst[0] == 0x000000FF) &&
  1660. (Dst[1] == 0x0000FF00) &&
  1661. (Dst[2] == 0x00FF0000) )
  1662. {
  1663. dwRet = 0;
  1664. }
  1665. else if ((Dst[0] == 0x00FF0000) &&
  1666. (Dst[1] == 0x0000FF00) &&
  1667. (Dst[2] == 0x000000FF) )
  1668. {
  1669. dwRet = BMPCONV_BGR;
  1670. }
  1671. }
  1672. break;
  1673. case e32bpp:
  1674. if (pxlo->flXlate & XO_FROM_CMYK)
  1675. dwRet = 0;
  1676. else
  1677. {
  1678. //
  1679. // Translate all 4 bytes from the DWORD
  1680. //
  1681. Dst[0] = XLATEOBJ_iXlate(pxlo, 0x000000FF);
  1682. Dst[1] = XLATEOBJ_iXlate(pxlo, 0x0000FF00);
  1683. Dst[2] = XLATEOBJ_iXlate(pxlo, 0x00FF0000);
  1684. Dst[3] = XLATEOBJ_iXlate(pxlo, 0xFF000000);
  1685. if ((Dst[0] == 0x000000FF) &&
  1686. (Dst[1] == 0x0000FF00) &&
  1687. (Dst[2] == 0x00FF0000) &&
  1688. (Dst[3] == 0x00000000))
  1689. {
  1690. //
  1691. // If translate result is same (4th byte will be zero) then
  1692. // we done with it except if 32bpp then we have to skip one
  1693. // source byte for every 3 bytes
  1694. //
  1695. dwRet = BMPCONV_32BPP_RGB;
  1696. }
  1697. else if ((Dst[0] == 0x00FF0000) &&
  1698. (Dst[1] == 0x0000FF00) &&
  1699. (Dst[2] == 0x000000FF) &&
  1700. (Dst[3] == 0x00000000))
  1701. {
  1702. //
  1703. // Simply swap the R and B component
  1704. //
  1705. dwRet = BMPCONV_32BPP_BGR;
  1706. }
  1707. }
  1708. }
  1709. return dwRet;
  1710. }