Source code of Windows XP (NT5)
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.

1007 lines
22 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: bmpfile.cxx
  7. //
  8. // Contents: CBitmapFile implementation
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 4-23-94 KirtD Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "headers.hxx"
  18. #pragma hdrstop
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Member: CBitmapFile::CBitmapFile
  22. //
  23. // Synopsis: Constructor
  24. //
  25. // Arguments: (none)
  26. //
  27. // Returns: nothing
  28. //
  29. // History: 4-23-94 KirtD Created
  30. //
  31. // Notes:
  32. //
  33. //----------------------------------------------------------------------------
  34. CBitmapFile::CBitmapFile ()
  35. {
  36. //
  37. // Initialize private members
  38. //
  39. //
  40. // The name
  41. //
  42. _pszBitmapFile[0] = '\0';
  43. _cBitmapFile = 0;
  44. //
  45. // The bitmap information
  46. //
  47. _cbi = 0;
  48. _pbi = NULL;
  49. //
  50. // The bits
  51. //
  52. _cbData = 0;
  53. _pbData = NULL;
  54. }
  55. //+---------------------------------------------------------------------------
  56. //
  57. // Member: CBitmapFile::~CBitmapFile
  58. //
  59. // Synopsis: Destructor
  60. //
  61. // Arguments: (none)
  62. //
  63. // Returns: nothing
  64. //
  65. // History: 4-23-94 KirtD Created
  66. //
  67. // Notes:
  68. //
  69. //----------------------------------------------------------------------------
  70. CBitmapFile::~CBitmapFile ()
  71. {
  72. //
  73. // Delete any possibly allocated things
  74. //
  75. delete _pbi;
  76. delete _pbData;
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // Member: CBitmapFile::LoadBitmapFile
  81. //
  82. // Synopsis: loads a bitmap file
  83. //
  84. // Arguments: [pszFile] -- the file
  85. //
  86. // Returns: HRESULT
  87. //
  88. // History: 4-23-94 KirtD Created
  89. //
  90. // Notes:
  91. //
  92. //----------------------------------------------------------------------------
  93. HRESULT
  94. CBitmapFile::LoadBitmapFile (LPSTR pszFile)
  95. {
  96. HRESULT hr = ResultFromScode(S_OK);
  97. HANDLE hFile = INVALID_HANDLE_VALUE;
  98. HANDLE hMap = INVALID_HANDLE_VALUE;
  99. DWORD dwFileSizeLow = 0;
  100. DWORD dwFileSizeHigh = 0;
  101. LPBYTE pbuffer = NULL;
  102. //
  103. // First open the file
  104. //
  105. hFile = CreateFileA(pszFile,
  106. GENERIC_READ,
  107. FILE_SHARE_READ,
  108. NULL,
  109. OPEN_EXISTING,
  110. FILE_ATTRIBUTE_NORMAL,
  111. NULL);
  112. if (hFile == INVALID_HANDLE_VALUE)
  113. {
  114. hr = HRESULT_FROM_WIN32(GetLastError());
  115. }
  116. //
  117. // Get the size of the file
  118. //
  119. if (SUCCEEDED(hr))
  120. {
  121. dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh);
  122. if ((dwFileSizeLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
  123. {
  124. hr = HRESULT_FROM_WIN32(GetLastError());
  125. }
  126. else if (dwFileSizeHigh != 0)
  127. {
  128. //
  129. // Bitmap files can't be greater than 4G
  130. //
  131. hr = ResultFromScode(E_FAIL);
  132. }
  133. }
  134. //
  135. // Create a file mapping object on the file
  136. //
  137. if (SUCCEEDED(hr))
  138. {
  139. hMap = CreateFileMapping(hFile,
  140. NULL,
  141. PAGE_READONLY,
  142. 0,
  143. dwFileSizeLow,
  144. NULL);
  145. if (hMap == INVALID_HANDLE_VALUE)
  146. {
  147. hr = HRESULT_FROM_WIN32(GetLastError());
  148. }
  149. }
  150. //
  151. // Now map a view of the file into our address space
  152. //
  153. if (SUCCEEDED(hr))
  154. {
  155. pbuffer = (LPBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
  156. if (pbuffer == NULL)
  157. {
  158. hr = HRESULT_FROM_WIN32(GetLastError());
  159. }
  160. }
  161. //
  162. // Get the bitmap data from the buffer
  163. //
  164. if (SUCCEEDED(hr))
  165. {
  166. hr = _GetBitmapDataFromBuffer(pbuffer, (ULONG)dwFileSizeLow);
  167. }
  168. //
  169. // Record the file name
  170. //
  171. if (SUCCEEDED(hr))
  172. {
  173. ULONG cFile;
  174. //
  175. // Get the length of the file name
  176. //
  177. cFile = strlen(pszFile);
  178. //
  179. // Check to see that our buffer is big enough and then copy
  180. // it. NOTE that I can use sizeof here since the buffer is
  181. // in characters which are 1 byte.
  182. //
  183. if (cFile < sizeof(_pszBitmapFile))
  184. {
  185. strcpy(_pszBitmapFile, pszFile);
  186. _cBitmapFile = cFile;
  187. }
  188. else
  189. {
  190. hr = ResultFromScode(E_FAIL);
  191. }
  192. }
  193. //
  194. // Cleanup
  195. //
  196. if (hMap != INVALID_HANDLE_VALUE)
  197. {
  198. CloseHandle(hMap);
  199. }
  200. if (hFile != INVALID_HANDLE_VALUE)
  201. {
  202. CloseHandle(hFile);
  203. }
  204. return(hr);
  205. }
  206. //+---------------------------------------------------------------------------
  207. //
  208. // Member: CBitmapFile::GetBitmapFileName
  209. //
  210. // Synopsis: gets the file name used to set the bitmap
  211. //
  212. // Arguments: [pszFile] -- the file
  213. // [cChar] -- the length of the buffer in characters
  214. //
  215. // Returns: HRESULT
  216. //
  217. // History: 4-23-94 KirtD Created
  218. //
  219. // Notes:
  220. //
  221. //----------------------------------------------------------------------------
  222. HRESULT
  223. CBitmapFile::GetBitmapFileName (LPSTR pszFile, ULONG cChar) const
  224. {
  225. //
  226. // Check the length of the receiving buffer, making sure the buffer size
  227. // includes the null terminator
  228. //
  229. if (cChar <= _cBitmapFile)
  230. {
  231. return(ResultFromScode(E_INVALIDARG));
  232. }
  233. //
  234. // Copy the string
  235. //
  236. strcpy(pszFile, _pszBitmapFile);
  237. return(ResultFromScode(S_OK));
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Member: CBitmapFile::GetBitmapFileNameLength
  242. //
  243. // Synopsis: returns _cBitmapFile
  244. //
  245. // Arguments: (none)
  246. //
  247. // Returns: ULONG
  248. //
  249. // History: 4-23-94 KirtD Created
  250. //
  251. // Notes:
  252. //
  253. //----------------------------------------------------------------------------
  254. ULONG
  255. CBitmapFile::GetBitmapFileNameLength () const
  256. {
  257. return(_cBitmapFile);
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Member: CBitmapFile::GetDIBHeight
  262. //
  263. // Synopsis: gets the height in pixels of the DIB
  264. //
  265. // Arguments: (none)
  266. //
  267. // Returns: LONG
  268. //
  269. // History: 4-23-94 KirtD Created
  270. //
  271. // Notes:
  272. //
  273. //----------------------------------------------------------------------------
  274. LONG
  275. CBitmapFile::GetDIBHeight () const
  276. {
  277. if (_pbi)
  278. {
  279. return(_pbi->bmiHeader.biHeight);
  280. }
  281. else
  282. {
  283. return(0);
  284. }
  285. }
  286. //+---------------------------------------------------------------------------
  287. //
  288. // Member: CBitmapFile::GetDIBWidth
  289. //
  290. // Synopsis: gets the width in pixels of the DIB
  291. //
  292. // Arguments: (none)
  293. //
  294. // Returns: LONG
  295. //
  296. // History: 4-23-94 KirtD Created
  297. //
  298. // Notes:
  299. //
  300. //----------------------------------------------------------------------------
  301. LONG
  302. CBitmapFile::GetDIBWidth () const
  303. {
  304. if (_pbi)
  305. {
  306. return(_pbi->bmiHeader.biWidth);
  307. }
  308. else
  309. {
  310. return(0);
  311. }
  312. }
  313. //+---------------------------------------------------------------------------
  314. //
  315. // Member: CBitmapFile::GetLogicalPalette
  316. //
  317. // Synopsis: gets the logical palette from the DIB
  318. //
  319. // Arguments: [pplogpal] -- logical palette goes here
  320. //
  321. // Returns: HRESULT
  322. //
  323. // History: 4-23-94 KirtD Created
  324. //
  325. // Notes:
  326. //
  327. //----------------------------------------------------------------------------
  328. HRESULT
  329. CBitmapFile::GetLogicalPalette (LPLOGPALETTE *pplogpal) const
  330. {
  331. HRESULT hr = ResultFromScode(S_OK);
  332. LOGPALETTE *plogpal = NULL;
  333. WORD cPalEntry;
  334. LPMALLOC pMalloc = NULL;
  335. //
  336. // First check to see if we have been initialized with a bitmap
  337. //
  338. if (_pbi == NULL)
  339. {
  340. return(ResultFromScode(E_FAIL));
  341. }
  342. //
  343. // Check to see if this bit count allows a palette
  344. //
  345. if (HasPaletteData() == FALSE)
  346. {
  347. return(ResultFromScode(E_FAIL));
  348. }
  349. //
  350. // NOTE: We are about to get the number of palette entries we
  351. // need to allocate, we do NOT use biClrUsed since we
  352. // know that if this field was set the bitmap would
  353. // not have been loaded, see BUGBUG in
  354. // _GetBitmapDataFromBuffer notes section. This is
  355. // probably a good candidate for an assert.
  356. //
  357. //
  358. // Get the palette entries
  359. //
  360. cPalEntry = (WORD) (1 << _pbi->bmiHeader.biBitCount);
  361. //
  362. // Allocate a LOGPALETTE
  363. //
  364. hr = CoGetMalloc(MEMCTX_TASK, &pMalloc);
  365. if (SUCCEEDED(hr))
  366. {
  367. plogpal = (LOGPALETTE *)pMalloc->Alloc(sizeof(LOGPALETTE)+
  368. ((cPalEntry-1)*
  369. sizeof(PALETTEENTRY)));
  370. if (plogpal == NULL)
  371. {
  372. hr = ResultFromScode(E_OUTOFMEMORY);
  373. }
  374. }
  375. //
  376. // Copy the palette information
  377. //
  378. if (SUCCEEDED(hr))
  379. {
  380. ULONG cCount;
  381. plogpal->palVersion = 0x300;
  382. plogpal->palNumEntries = cPalEntry;
  383. for (cCount = 0; cCount < cPalEntry; cCount++)
  384. {
  385. plogpal->palPalEntry[cCount].peRed = _pbi->bmiColors[cCount].rgbRed;
  386. plogpal->palPalEntry[cCount].peGreen = _pbi->bmiColors[cCount].rgbGreen;
  387. plogpal->palPalEntry[cCount].peBlue = _pbi->bmiColors[cCount].rgbBlue;
  388. plogpal->palPalEntry[cCount].peFlags = PC_NOCOLLAPSE;
  389. }
  390. *pplogpal = plogpal;
  391. }
  392. //
  393. // Cleanup
  394. //
  395. if (pMalloc)
  396. {
  397. pMalloc->Release();
  398. }
  399. return(hr);
  400. }
  401. //+---------------------------------------------------------------------------
  402. //
  403. // Member: CBitmapFile::CreateDIBInHGlobal
  404. //
  405. // Synopsis: creates a DIB i.e. info and data in a GlobalAlloc'd buffer
  406. //
  407. // Arguments: [phGlobal] -- handle goes here
  408. //
  409. // Returns: HRESULT
  410. //
  411. // History: 5-06-94 KirtD Created
  412. //
  413. // Notes:
  414. //
  415. //----------------------------------------------------------------------------
  416. HRESULT
  417. CBitmapFile::CreateDIBInHGlobal (HGLOBAL *phGlobal) const
  418. {
  419. HRESULT hr = ResultFromScode(S_OK);
  420. ULONG cb = 0;
  421. LPBYTE pb = NULL;
  422. HGLOBAL hGlobal = NULL;
  423. ULONG cbPalEntry = 0;
  424. //
  425. // Check to see if we are initialized
  426. //
  427. if (_pbi == NULL)
  428. {
  429. return(ResultFromScode(E_FAIL));
  430. }
  431. //
  432. // The size to allocate for the data must be calculated
  433. // from the following ...
  434. //
  435. //
  436. // The size of the bitmap info plus the size of the data
  437. //
  438. cb = _cbi + _cbData;
  439. //
  440. // Allocate
  441. //
  442. hGlobal = GlobalAlloc(GHND, cb);
  443. if (hGlobal == NULL)
  444. {
  445. hr = HRESULT_FROM_WIN32(GetLastError());
  446. }
  447. //
  448. // Lock the handle
  449. //
  450. if (SUCCEEDED(hr))
  451. {
  452. pb = (LPBYTE)GlobalLock(hGlobal);
  453. if (pb == NULL)
  454. {
  455. hr = HRESULT_FROM_WIN32(GetLastError());
  456. }
  457. }
  458. //
  459. // Copy the information
  460. //
  461. if (SUCCEEDED(hr))
  462. {
  463. //
  464. // First the bitmap info
  465. //
  466. memcpy(pb, _pbi, _cbi);
  467. //
  468. // Move pointer but if there is no palette compensate
  469. // for the extra RGBQUAD
  470. //
  471. if (_pbi->bmiHeader.biBitCount == BMP_24_BITSPERPIXEL)
  472. {
  473. pb += (_cbi - sizeof(RGBQUAD));
  474. }
  475. else
  476. {
  477. pb += _cbi;
  478. }
  479. //
  480. // Now the bits
  481. //
  482. memcpy(pb, _pbData, _cbData);
  483. }
  484. //
  485. // Cleanup
  486. //
  487. //
  488. // If we locked the handle, unlock it
  489. //
  490. if (pb)
  491. {
  492. GlobalUnlock(hGlobal);
  493. }
  494. //
  495. // If we succeeded, set the out parameter, if we failed and
  496. // we had allocated the hGlobal, free it
  497. //
  498. if (SUCCEEDED(hr))
  499. {
  500. *phGlobal = hGlobal;
  501. }
  502. else if (hGlobal)
  503. {
  504. GlobalFree(hGlobal);
  505. }
  506. return(hr);
  507. }
  508. //+---------------------------------------------------------------------------
  509. //
  510. // Member: CBitmapFile::HasPaletteData
  511. //
  512. // Synopsis: returns whether or not the dib has palette data
  513. //
  514. // Arguments: (none)
  515. //
  516. // Returns: BOOL
  517. //
  518. // History: 5-16-94 kirtd Created
  519. //
  520. // Notes:
  521. //
  522. //----------------------------------------------------------------------------
  523. BOOL
  524. CBitmapFile::HasPaletteData () const
  525. {
  526. //
  527. // If we are not initialized return FALSE
  528. //
  529. if (_pbi == NULL)
  530. {
  531. return(FALSE);
  532. }
  533. //
  534. // If we are a 24, 16 or 32 bpp DIB then we do not have
  535. // palette data
  536. //
  537. // BUGBUG: The case where biClrUsed is set is not dealt
  538. // with
  539. //
  540. if ((_pbi->bmiHeader.biBitCount == BMP_24_BITSPERPIXEL) ||
  541. (_pbi->bmiHeader.biBitCount == BMP_16_BITSPERPIXEL) ||
  542. (_pbi->bmiHeader.biBitCount == BMP_32_BITSPERPIXEL))
  543. {
  544. return(FALSE);
  545. }
  546. //
  547. // Otherwise we do have palette data
  548. //
  549. return(TRUE);
  550. }
  551. //+---------------------------------------------------------------------------
  552. //
  553. // Member: CBitmapFile::GetDIBBits
  554. //
  555. // Synopsis: gets the bits
  556. //
  557. // Arguments: (none)
  558. //
  559. // Returns: LPBYTE
  560. //
  561. // History: 5-02-94 KirtD Created
  562. //
  563. // Notes:
  564. //
  565. //----------------------------------------------------------------------------
  566. LPBYTE
  567. CBitmapFile::GetDIBBits ()
  568. {
  569. return(_pbData);
  570. }
  571. //+---------------------------------------------------------------------------
  572. //
  573. // Member: CBitmapFile::GetBitmapInfo
  574. //
  575. // Synopsis: gets the bitmap info pointer
  576. //
  577. // Arguments: (none)
  578. //
  579. // Returns: LPBITMAPINFO
  580. //
  581. // History: 5-14-94 kirtd Created
  582. //
  583. // Notes:
  584. //
  585. //----------------------------------------------------------------------------
  586. LPBITMAPINFO
  587. CBitmapFile::GetBitmapInfo ()
  588. {
  589. return(_pbi);
  590. }
  591. //+---------------------------------------------------------------------------
  592. //
  593. // Member: CBitmapFile::_GetBitmapDataFromBuffer
  594. //
  595. // Synopsis: gets the bitmap data from the given buffer
  596. //
  597. // Arguments: [pbuffer] -- the buffer
  598. // [cb] -- the buffer size
  599. //
  600. // Returns: HRESULT
  601. //
  602. // History: 4-23-94 KirtD Created
  603. //
  604. // Notes: BUGBUG: If biClrUsed is set the bitmap is not loaded
  605. //
  606. //----------------------------------------------------------------------------
  607. HRESULT
  608. CBitmapFile::_GetBitmapDataFromBuffer (LPBYTE pbuffer, ULONG cb)
  609. {
  610. HRESULT hr = ResultFromScode(S_OK);
  611. BITMAPFILEHEADER bmfh;
  612. BITMAPCOREHEADER *pbch;
  613. BITMAPINFOHEADER bih;
  614. LPBYTE pbStart;
  615. ULONG cbi = 0;
  616. ULONG cbData;
  617. LPBITMAPINFO pbi = NULL;
  618. LPBYTE pbData = NULL;
  619. DWORD dwSizeOfHeader;
  620. //
  621. // Record the starting position
  622. //
  623. pbStart = pbuffer;
  624. //
  625. // First validate the buffer for size
  626. //
  627. if (cb < sizeof(BITMAPFILEHEADER))
  628. {
  629. return(ResultFromScode(E_FAIL));
  630. }
  631. //
  632. // Now get the bitmap file header
  633. //
  634. memcpy(&bmfh, pbuffer, sizeof(BITMAPFILEHEADER));
  635. //
  636. // Validate the information
  637. //
  638. hr = _ValidateBitmapFileHeader (&bmfh, cb);
  639. //
  640. // Get the next 4 bytes which will represent the size of the
  641. // next structure and allow us to determine the type
  642. //
  643. if (SUCCEEDED(hr))
  644. {
  645. pbuffer += sizeof(BITMAPFILEHEADER);
  646. memcpy(&dwSizeOfHeader, pbuffer, sizeof(DWORD));
  647. if (dwSizeOfHeader == sizeof(BITMAPCOREHEADER))
  648. {
  649. pbch = (BITMAPCOREHEADER *)pbuffer;
  650. memset(&bih, 0, sizeof(BITMAPINFOHEADER));
  651. bih.biSize = sizeof(BITMAPINFOHEADER);
  652. bih.biWidth = pbch->bcWidth;
  653. bih.biHeight = pbch->bcHeight;
  654. bih.biPlanes = pbch->bcPlanes;
  655. bih.biBitCount = pbch->bcBitCount;
  656. pbuffer += sizeof(BITMAPCOREHEADER);
  657. }
  658. else if (dwSizeOfHeader == sizeof(BITMAPINFOHEADER))
  659. {
  660. memcpy(&bih, pbuffer, sizeof(BITMAPINFOHEADER));
  661. pbuffer += sizeof(BITMAPINFOHEADER);
  662. }
  663. else
  664. {
  665. hr = ResultFromScode(E_FAIL);
  666. }
  667. }
  668. //
  669. // Check if biClrUsed is set since we do not handle that
  670. // case at this time
  671. //
  672. if (SUCCEEDED(hr))
  673. {
  674. if (bih.biClrUsed != 0)
  675. {
  676. hr = ResultFromScode(E_FAIL);
  677. }
  678. }
  679. //
  680. // Now we need to calculate the size of the BITMAPINFO we need
  681. // to allocate including any palette information
  682. //
  683. if (SUCCEEDED(hr))
  684. {
  685. //
  686. // First the size of the header
  687. //
  688. cbi = sizeof(BITMAPINFOHEADER);
  689. //
  690. // Now the palette
  691. //
  692. if (bih.biBitCount == BMP_24_BITSPERPIXEL)
  693. {
  694. //
  695. // Just add on the 1 RGBQUAD for the structure but
  696. // there is no palette
  697. //
  698. cbi += sizeof(RGBQUAD);
  699. }
  700. else if ((bih.biBitCount == BMP_16_BITSPERPIXEL) ||
  701. (bih.biBitCount == BMP_32_BITSPERPIXEL))
  702. {
  703. //
  704. // Add on the 3 DWORD masks which are used to
  705. // get the colors out of the data
  706. //
  707. cbi += (3 * sizeof(DWORD));
  708. }
  709. else
  710. {
  711. //
  712. // Anything else we just use the bit count to calculate
  713. // the number of entries
  714. //
  715. cbi += ((1 << bih.biBitCount) * sizeof(RGBQUAD));
  716. }
  717. //
  718. // Now allocate the BITMAPINFO
  719. //
  720. pbi = (LPBITMAPINFO) new BYTE [cbi];
  721. if (pbi == NULL)
  722. {
  723. hr = ResultFromScode(E_OUTOFMEMORY);
  724. }
  725. }
  726. //
  727. // Fill in the BITMAPINFO data structure and get the bits
  728. //
  729. if (SUCCEEDED(hr))
  730. {
  731. //
  732. // First copy the header data
  733. //
  734. memcpy(&(pbi->bmiHeader), &bih, sizeof(BITMAPINFOHEADER));
  735. //
  736. // Now the palette data
  737. //
  738. if (bih.biBitCount == BMP_24_BITSPERPIXEL)
  739. {
  740. //
  741. // No palette data to copy
  742. //
  743. }
  744. else if ((bih.biBitCount == BMP_16_BITSPERPIXEL) ||
  745. (bih.biBitCount == BMP_32_BITSPERPIXEL))
  746. {
  747. //
  748. // Copy the 3 DWORD masks
  749. //
  750. memcpy(&(pbi->bmiColors), pbuffer, 3*sizeof(DWORD));
  751. }
  752. else
  753. {
  754. //
  755. // If we were a BITMAPCOREHEADER type then we have our
  756. // palette data in the form of RGBTRIPLEs so we must
  757. // explicitly copy each. Otherwise we can just memcpy
  758. // the RGBQUADs
  759. //
  760. if (dwSizeOfHeader == sizeof(BITMAPCOREHEADER))
  761. {
  762. ULONG cPalEntry = (1 << bih.biBitCount);
  763. ULONG cCount;
  764. RGBTRIPLE *argbt = (RGBTRIPLE *)pbuffer;
  765. for (cCount = 0; cCount < cPalEntry; cCount++)
  766. {
  767. pbi->bmiColors[cCount].rgbRed =
  768. argbt[cCount].rgbtRed;
  769. pbi->bmiColors[cCount].rgbGreen =
  770. argbt[cCount].rgbtGreen;
  771. pbi->bmiColors[cCount].rgbBlue =
  772. argbt[cCount].rgbtBlue;
  773. pbi->bmiColors[cCount].rgbReserved = 0;
  774. }
  775. }
  776. else
  777. {
  778. ULONG cbPalette = (1 << bih.biBitCount) * sizeof(RGBQUAD);
  779. memcpy(&(pbi->bmiColors), pbuffer, cbPalette);
  780. }
  781. }
  782. //
  783. // Now find out where the bits are
  784. //
  785. pbuffer = pbStart + bmfh.bfOffBits;
  786. //
  787. // Get the size to copy
  788. //
  789. cbData = cb - bmfh.bfOffBits;
  790. //
  791. // Allocate the buffer to hold the bits
  792. //
  793. pbData = new BYTE [cbData];
  794. if (pbData == NULL)
  795. {
  796. hr = ResultFromScode(E_OUTOFMEMORY);
  797. }
  798. if (SUCCEEDED(hr))
  799. {
  800. memcpy(pbData, pbuffer, cbData);
  801. }
  802. }
  803. //
  804. // If everything succeeded record the data
  805. //
  806. if (SUCCEEDED(hr))
  807. {
  808. //
  809. // Record the info
  810. //
  811. delete _pbi;
  812. _cbi = cbi;
  813. _pbi = pbi;
  814. //
  815. // Record the data
  816. //
  817. delete _pbData;
  818. _cbData = cbData;
  819. _pbData = pbData;
  820. }
  821. else
  822. {
  823. //
  824. // Cleanup
  825. //
  826. delete pbi;
  827. delete pbData;
  828. }
  829. return(hr);
  830. }
  831. //+---------------------------------------------------------------------------
  832. //
  833. // Member: CBitmapFile::_ValidateBitmapFileHeader
  834. //
  835. // Synopsis: validates a bitmap file header
  836. //
  837. // Arguments: [pbmfh] -- bitmap file header
  838. // [cbFile] -- bitmap file size
  839. //
  840. // Returns: HRESULT
  841. //
  842. // History: 4-23-94 KirtD Created
  843. //
  844. // Notes:
  845. //
  846. //----------------------------------------------------------------------------
  847. HRESULT
  848. CBitmapFile::_ValidateBitmapFileHeader (BITMAPFILEHEADER *pbmfh, ULONG cbFile)
  849. {
  850. //
  851. // Check for the following,
  852. //
  853. // 1. The bfType member contains 'BM'
  854. // 2. The bfOffset member is NOT greater than the size of the file
  855. //
  856. if ((pbmfh->bfType == 0x4d42) && (pbmfh->bfOffBits <= cbFile))
  857. {
  858. return(ResultFromScode(S_OK));
  859. }
  860. return(ResultFromScode(E_FAIL));
  861. }