DIBFILE.CPP (22104B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 //******************************************************************* 17 // 18 // file.c 19 // 20 // Source file for Device-Independent Bitmap (DIB) API. Provides 21 // the following functions: 22 // 23 // SaveDIB() - Saves the specified dib in a file 24 // LoadDIB() - Loads a DIB from a file 25 // DestroyDIB() - Deletes DIB when finished using it 26 // 27 // Development Team: Mark Bader 28 // Patrick Schreiber 29 // Garrett McAuliffe 30 // Eric Flo 31 // Tony Claflin 32 // 33 // Written by Microsoft Product Support Services, Developer Support. 34 // COPYRIGHT: 35 // 36 // (C) Copyright Microsoft Corp. 1993. All rights reserved. 37 // 38 // You have a royalty-free right to use, modify, reproduce and 39 // distribute the Sample Files (and/or any modified version) in 40 // any way you find useful, provided that you agree that 41 // Microsoft has no warranty obligations or liability for any 42 // Sample Application Files which are modified. 43 // 44 //******************************************************************* 45 #if (0) // ST - 5/8/2019 46 47 #include <windows.h> 48 #include <string.h> 49 #include <stdio.h> 50 #include <math.h> 51 #include <io.h> 52 #include <direct.h> 53 #include <stdlib.h> 54 #include "dibutil.h" 55 #include "dibapi.h" 56 57 //#include "WolDebug.h" 58 59 /* 60 * Dib Header Marker - used in writing DIBs to files 61 */ 62 #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B') 63 64 /********************************************************************* 65 * 66 * Local Function Prototypes 67 * 68 *********************************************************************/ 69 70 71 HANDLE ReadDIBFile(int); 72 BOOL MyRead(int, LPSTR, DWORD); 73 BOOL SaveDIBFile(void); 74 BOOL WriteDIB(LPSTR, HANDLE); 75 DWORD PASCAL MyWrite(int, VOID FAR *, DWORD); 76 77 /************************************************************************* 78 * 79 * LoadDIB() 80 * 81 * Loads the specified DIB from a file, allocates memory for it, 82 * and reads the disk file into the memory. 83 * 84 * 85 * Parameters: 86 * 87 * LPSTR lpFileName - specifies the file to load a DIB from 88 * 89 * Returns: A handle to a DIB, or NULL if unsuccessful. 90 * 91 * NOTE: The DIB API were not written to handle OS/2 DIBs; This 92 * function will reject any file that is not a Windows DIB. 93 * 94 * History: Date Author Reason 95 * 9/15/91 Mark Bader Based on DIBVIEW 96 * 97 *************************************************************************/ 98 99 100 HDIB FAR LoadDIB(LPSTR lpFileName) 101 { 102 HDIB hDIB; 103 int hFile; 104 OFSTRUCT ofs; 105 106 /* 107 * Set the cursor to a hourglass, in case the loading operation 108 * takes more than a sec, the user will know what's going on. 109 */ 110 111 SetCursor(LoadCursor(NULL, IDC_WAIT)); 112 if ((hFile = OpenFile(lpFileName, &ofs, OF_READ)) != -1) 113 { 114 hDIB = ReadDIBFile(hFile); 115 _lclose(hFile); 116 SetCursor(LoadCursor(NULL, IDC_ARROW)); 117 return hDIB; 118 } 119 else 120 { 121 // DIBError(ERR_FILENOTFOUND); 122 SetCursor(LoadCursor(NULL, IDC_ARROW)); 123 return NULL; 124 } 125 } 126 127 128 /************************************************************************* 129 * 130 * SaveDIB() 131 * 132 * Saves the specified DIB into the specified file name on disk. No 133 * error checking is done, so if the file already exists, it will be 134 * written over. 135 * 136 * Parameters: 137 * 138 * HDIB hDib - Handle to the dib to save 139 * 140 * LPSTR lpFileName - pointer to full pathname to save DIB under 141 * 142 * Return value: 0 if successful, or one of: 143 * ERR_INVALIDHANDLE 144 * ERR_OPEN 145 * ERR_LOCK 146 * 147 * History: 148 * 149 * NOTE: The DIB API were not written to handle OS/2 DIBs, so this 150 * function will not save a file if it is not a Windows DIB. 151 * 152 * History: Date Author Reason 153 * 9/15/91 Mark Bader Taken from DIBVIEW (which was taken 154 * from SHOWDIB) 155 * 1/30/92 Mark Bader Fixed problem of writing too many 156 * bytes to the file 157 * 6/24/92 Mark Bader Added check for OS/2 DIB 158 * 159 *************************************************************************/ 160 161 162 WORD FAR SaveDIB(HDIB hDib, LPSTR lpFileName) 163 { 164 BITMAPFILEHEADER bmfHdr; // Header for Bitmap file 165 LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure 166 int fh; // file handle for opened file 167 OFSTRUCT of; // OpenFile structure 168 DWORD dwDIBSize; 169 DWORD dwError; // Error return from MyWrite 170 171 if (!hDib) 172 return ERR_INVALIDHANDLE; 173 fh = OpenFile(lpFileName, &of, OF_CREATE | OF_READWRITE); 174 if (fh == -1) 175 return ERR_OPEN; 176 177 /* 178 * Get a pointer to the DIB memory, the first of which contains 179 * a BITMAPINFO structure 180 */ 181 lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib); 182 if (!lpBI) 183 return ERR_LOCK; 184 185 // Check to see if we're dealing with an OS/2 DIB. If so, don't 186 // save it because our functions aren't written to deal with these 187 // DIBs. 188 189 if (lpBI->biSize != sizeof(BITMAPINFOHEADER)) 190 { 191 GlobalUnlock(hDib); 192 return ERR_NOT_DIB; 193 } 194 195 /* 196 * Fill in the fields of the file header 197 */ 198 199 /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */ 200 bmfHdr.bfType = DIB_HEADER_MARKER; // "BM" 201 202 // Calculating the size of the DIB is a bit tricky (if we want to 203 // do it right). The easiest way to do this is to call GlobalSize() 204 // on our global handle, but since the size of our global memory may have 205 // been padded a few bytes, we may end up writing out a few too 206 // many bytes to the file (which may cause problems with some apps, 207 // like HC 3.0). 208 // 209 // So, instead let's calculate the size manually. 210 // 211 // To do this, find size of header plus size of color table. Since the 212 // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains 213 // the size of the structure, let's use this. 214 215 dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI); // Partial Calculation 216 217 // Now calculate the size of the image 218 219 if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) { 220 221 // It's an RLE bitmap, we can't calculate size, so trust the 222 // biSizeImage field 223 224 dwDIBSize += lpBI->biSizeImage; 225 } 226 else { 227 DWORD dwBmBitsSize; // Size of Bitmap Bits only 228 229 // It's not RLE, so size is Width (DWORD aligned) * Height 230 231 dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight; 232 233 dwDIBSize += dwBmBitsSize; 234 235 // Now, since we have calculated the correct size, why don't we 236 // fill in the biSizeImage field (this will fix any .BMP files which 237 // have this field incorrect). 238 239 lpBI->biSizeImage = dwBmBitsSize; 240 } 241 242 243 // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) 244 245 bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); 246 bmfHdr.bfReserved1 = 0; 247 bmfHdr.bfReserved2 = 0; 248 249 /* 250 * Now, calculate the offset the actual bitmap bits will be in 251 * the file -- It's the Bitmap file header plus the DIB header, 252 * plus the size of the color table. 253 */ 254 bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + 255 PaletteSize((LPSTR)lpBI); 256 257 /* Write the file header */ 258 _lwrite(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); 259 260 /* 261 * Write the DIB header and the bits -- use local version of 262 * MyWrite, so we can write more than 32767 bytes of data 263 */ 264 dwError = MyWrite(fh, (LPSTR)lpBI, dwDIBSize); 265 GlobalUnlock(hDib); 266 _lclose(fh); 267 268 if (dwError == 0) 269 return ERR_OPEN; // oops, something happened in the write 270 else 271 return 0; // Success code 272 } 273 274 275 /************************************************************************* 276 * 277 * DestroyDIB () 278 * 279 * Purpose: Frees memory associated with a DIB 280 * 281 * Returns: Nothing 282 * 283 * History: Date Author Reason 284 * 9/15/91 Mark Bader Created 285 * 286 *************************************************************************/ 287 288 289 WORD FAR DestroyDIB(HDIB hDib) 290 { 291 GlobalFree(hDib); 292 return 0; 293 } 294 295 296 //************************************************************************ 297 // 298 // Auxiliary Functions which the above procedures use 299 // 300 //************************************************************************ 301 302 303 /************************************************************************* 304 * 305 * Function: ReadDIBFile (int) 306 * 307 * Purpose: Reads in the specified DIB file into a global chunk of 308 * memory. 309 * 310 * Returns: A handle to a dib (hDIB) if successful. 311 * NULL if an error occurs. 312 * 313 * Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything 314 * from the end of the BITMAPFILEHEADER structure on is 315 * returned in the global memory handle. 316 * 317 * 318 * NOTE: The DIB API were not written to handle OS/2 DIBs, so this 319 * function will reject any file that is not a Windows DIB. 320 * 321 * History: Date Author Reason 322 * 9/15/91 Mark Bader Based on DIBVIEW 323 * 6/25/92 Mark Bader Added check for OS/2 DIB 324 * 7/21/92 Mark Bader Added code to deal with bfOffBits 325 * field in BITMAPFILEHEADER 326 * 9/11/92 Mark Bader Fixed Realloc Code to free original mem 327 * 328 *************************************************************************/ 329 330 HANDLE ReadDIBFile(int hFile) 331 { 332 BITMAPFILEHEADER bmfHeader; 333 DWORD dwBitsSize; 334 UINT nNumColors; // Number of colors in table 335 HANDLE hDIB; 336 HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB 337 LPBITMAPINFOHEADER lpbi; 338 DWORD offBits; 339 340 /* 341 * get length of DIB in bytes for use when reading 342 */ 343 344 dwBitsSize = filelength(hFile); 345 346 // Allocate memory for header & color table. We'll enlarge this 347 // memory as needed. 348 349 hDIB = GlobalAlloc(GMEM_MOVEABLE, 350 (DWORD)(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD))); 351 352 if (!hDIB) return NULL; 353 354 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 355 if (!lpbi) 356 { 357 GlobalFree(hDIB); 358 return NULL; 359 } 360 361 // read the BITMAPFILEHEADER from our file 362 363 if (sizeof (BITMAPFILEHEADER) != _lread (hFile, (LPSTR)&bmfHeader, sizeof (BITMAPFILEHEADER))) 364 goto ErrExit; 365 366 if (bmfHeader.bfType != 0x4d42) /* 'BM' */ 367 goto ErrExit; 368 369 // read the BITMAPINFOHEADER 370 371 if (sizeof(BITMAPINFOHEADER) != _lread (hFile, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER))) 372 goto ErrExit; 373 374 // Check to see that it's a Windows DIB -- an OS/2 DIB would cause 375 // strange problems with the rest of the DIB API since the fields 376 // in the header are different and the color table entries are 377 // smaller. 378 // 379 // If it's not a Windows DIB (e.g. if biSize is wrong), return NULL. 380 381 if (lpbi->biSize == sizeof(BITMAPCOREHEADER)) 382 goto ErrExit; 383 384 // Now determine the size of the color table and read it. Since the 385 // bitmap bits are offset in the file by bfOffBits, we need to do some 386 // special processing here to make sure the bits directly follow 387 // the color table (because that's the format we are susposed to pass 388 // back) 389 nNumColors = (UINT)lpbi->biClrUsed; 390 if (!nNumColors) 391 { 392 // no color table for 24-bit, default size otherwise 393 if (lpbi->biBitCount != 24) 394 nNumColors = 1 << lpbi->biBitCount; /* standard size table */ 395 } 396 397 // fill in some default values if they are zero 398 if (lpbi->biClrUsed == 0) 399 lpbi->biClrUsed = nNumColors; 400 401 if (lpbi->biSizeImage == 0) 402 { 403 lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) 404 * lpbi->biHeight; 405 } 406 407 // get a proper-sized buffer for header, color table and bits 408 GlobalUnlock(hDIB); 409 hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize + 410 nNumColors * sizeof(RGBQUAD) + 411 lpbi->biSizeImage, 0); 412 413 if (!hDIBtmp) // can't resize buffer for loading 414 goto ErrExitNoUnlock; //MPB 415 else 416 hDIB = hDIBtmp; 417 418 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 419 420 // read the color table 421 _lread (hFile, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD)); 422 423 // offset to the bits from start of DIB header 424 offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD); 425 426 // If the bfOffBits field is non-zero, then the bits might *not* be 427 // directly following the color table in the file. Use the value in 428 // bfOffBits to seek the bits. 429 430 if (bmfHeader.bfOffBits != 0L) 431 _llseek(hFile, bmfHeader.bfOffBits, SEEK_SET); 432 433 if (MyRead(hFile, (LPSTR)lpbi + offBits, lpbi->biSizeImage)) 434 goto OKExit; 435 436 437 ErrExit: 438 GlobalUnlock(hDIB); 439 ErrExitNoUnlock: 440 GlobalFree(hDIB); 441 return NULL; 442 443 OKExit: 444 GlobalUnlock(hDIB); 445 return hDIB; 446 } 447 448 /************************************************************************* 449 450 Function: MyRead (int, LPSTR, DWORD) 451 452 Purpose: Routine to read files greater than 64K in size. 453 454 Returns: TRUE if successful. 455 FALSE if an error occurs. 456 457 458 History: Date Author Reason 459 9/15/91 Mark Bader Based on DIBVIEW 460 461 *************************************************************************/ 462 463 464 BOOL MyRead(int hFile, LPSTR lpBuffer, DWORD dwSize) 465 { 466 char huge *lpInBuf = (char huge *)lpBuffer; 467 int nBytes; 468 469 /* 470 * Read in the data in 32767 byte chunks (or a smaller amount if it's 471 * the last chunk of data read) 472 */ 473 474 while (dwSize) 475 { 476 nBytes = (int)(dwSize > (DWORD)32767 ? 32767 : LOWORD (dwSize)); 477 if (_lread(hFile, (LPSTR)lpInBuf, nBytes) != (WORD)nBytes) 478 return FALSE; 479 dwSize -= nBytes; 480 lpInBuf += nBytes; 481 } 482 return TRUE; 483 } 484 485 486 /**************************************************************************** 487 488 FUNCTION : MyWrite(int fh, VOID FAR *pv, DWORD ul) 489 490 PURPOSE : Writes data in steps of 32k till all the data is written. 491 Normal _lwrite uses a WORD as 3rd parameter, so it is 492 limited to 32767 bytes, but this procedure is not. 493 494 RETURNS : 0 - If write did not proceed correctly. 495 number of bytes written otherwise. 496 497 History: Date Author Reason 498 9/15/91 Mark Bader Based on DIBVIEW 499 500 ****************************************************************************/ 501 502 503 DWORD PASCAL MyWrite(int iFileHandle, VOID FAR *lpBuffer, DWORD dwBytes) 504 { 505 DWORD dwBytesTmp = dwBytes; // Save # of bytes for return value 506 BYTE huge *hpBuffer = (BYTE huge *)lpBuffer; // make a huge pointer to the data 507 508 /* 509 * Write out the data in 32767 byte chunks. 510 */ 511 512 while (dwBytes > 32767) 513 { 514 if (_lwrite(iFileHandle, (LPSTR)hpBuffer, (WORD)32767) != 32767) 515 return 0; 516 dwBytes -= 32767; 517 hpBuffer += 32767; 518 } 519 520 /* Write out the last chunk (which is < 32767 bytes) */ 521 if (_lwrite(iFileHandle, (LPSTR)hpBuffer, (WORD)dwBytes) != (WORD)dwBytes) 522 return 0; 523 return dwBytesTmp; 524 } 525 526 // ajw added 527 // Added to allow "loading" from a location in memory. 528 // A modification of ReadDIBFile(), above. 529 //*********************************************************************************************** 530 HDIB LoadDIB_FromMemory( const unsigned char* pData, DWORD dwBitsSize ) 531 { 532 BITMAPFILEHEADER bmfHeader; 533 UINT nNumColors; // Number of colors in table 534 HANDLE hDIB; 535 HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB 536 LPBITMAPINFOHEADER lpbi; 537 DWORD offBits; 538 539 const unsigned char* const pDataStart = pData; 540 const unsigned char* pDataEnd = pData + dwBitsSize; // One char past end of "file". 541 542 // Allocate memory for header & color table. We'll enlarge this 543 // memory as needed. 544 545 // debugprint( "LoadDIB_FromMemory, GlobalAlloc\n" ); 546 hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD))); 547 // debugprint( "hDIB from GlobalALloc is %i\n", hDIB ); 548 549 if (!hDIB) 550 { 551 // debugprint( "LoadDIB_FromMemory error: failed alloc\n" ); 552 return NULL; 553 } 554 555 // debugprint( "LoadDIB_FromMemory, lpbi Lock\n" ); 556 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 557 // debugprint( "lpbi is %i\n", lpbi ); 558 if (!lpbi) 559 { 560 // debugprint( "LoadDIB_FromMemory error: failed lock\n" ); 561 GlobalFree(hDIB); 562 return NULL; 563 } 564 565 // read the BITMAPFILEHEADER from our file 566 // if (sizeof (BITMAPFILEHEADER) != _lread (hFile, (LPSTR)&bmfHeader, sizeof (BITMAPFILEHEADER))) 567 // goto ErrExit; 568 if( pData + sizeof( BITMAPFILEHEADER ) >= pDataEnd ) 569 { 570 // debugprint( "LoadDIB_FromMemory error: bad size\n" ); 571 goto ErrExit; 572 } 573 // debugprint( "LoadDIB_FromMemory, memcpy BITMAPFILEHEADER %i bytes\n", sizeof( BITMAPFILEHEADER ) ); 574 memcpy( &bmfHeader, pData, sizeof( BITMAPFILEHEADER ) ); 575 pData += sizeof( BITMAPFILEHEADER ); 576 577 if (bmfHeader.bfType != 0x4d42) /* 'BM' */ 578 { 579 // debugprint( "LoadDIB_FromMemory error: no BM\n" ); 580 goto ErrExit; 581 } 582 583 // read the BITMAPINFOHEADER 584 // if (sizeof(BITMAPINFOHEADER) != _lread (hFile, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER))) 585 // goto ErrExit; 586 if( pData + sizeof( BITMAPINFOHEADER ) >= pDataEnd ) 587 { 588 // debugprint( "LoadDIB_FromMemory error: bad size 2\n" ); 589 goto ErrExit; 590 } 591 // debugprint( "LoadDIB_FromMemory, memcpy BITMAPINFOHEADER %i bytes\n", sizeof( BITMAPINFOHEADER ) ); 592 memcpy( lpbi, pData, sizeof( BITMAPINFOHEADER ) ); 593 pData += sizeof( BITMAPINFOHEADER ); 594 595 // Check to see that it's a Windows DIB -- an OS/2 DIB would cause 596 // strange problems with the rest of the DIB API since the fields 597 // in the header are different and the color table entries are 598 // smaller. 599 // 600 // If it's not a Windows DIB (e.g. if biSize is wrong), return NULL. 601 602 if (lpbi->biSize == sizeof(BITMAPCOREHEADER)) 603 { 604 // debugprint( "LoadDIB_FromMemory error: lpbi->biSize bad\n" ); 605 goto ErrExit; 606 } 607 608 if( lpbi->biCompression != BI_RGB ) 609 { 610 // debugprint( "LoadDIB_FromMemory error: Image is compressed\n" ); 611 goto ErrExit; 612 } 613 614 // Now determine the size of the color table and read it. Since the 615 // bitmap bits are offset in the file by bfOffBits, we need to do some 616 // special processing here to make sure the bits directly follow 617 // the color table (because that's the format we are susposed to pass 618 // back) 619 nNumColors = (UINT)lpbi->biClrUsed; 620 if (!nNumColors) 621 { 622 // no color table for 24-bit, default size otherwise 623 if (lpbi->biBitCount != 24) 624 nNumColors = 1 << lpbi->biBitCount; /* standard size table */ 625 } 626 627 // fill in some default values if they are zero 628 if (lpbi->biClrUsed == 0) 629 lpbi->biClrUsed = nNumColors; 630 631 // debugprint( "biSizeImage is %i. I would say it was %i, because the bpp is %i.\n", lpbi->biSizeImage, ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight, lpbi->biBitCount ); 632 if (lpbi->biSizeImage == 0) 633 { 634 lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight; 635 } 636 637 // get a proper-sized buffer for header, color table and bits 638 GlobalUnlock(hDIB); 639 // debugprint( "LoadDIB_FromMemory, GlobalReAlloc: lpbi->biSize=%i, nNumColors=%i, lpbi->biSizeImage=%i\n", lpbi->biSize, nNumColors,lpbi->biSizeImage ); 640 hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize + nNumColors * sizeof(RGBQUAD) + lpbi->biSizeImage, 0); 641 642 if (!hDIBtmp) // can't resize buffer for loading 643 { 644 // debugprint( "LoadDIB_FromMemory error: realloc failed\n" ); 645 goto ErrExitNoUnlock; //MPB 646 } 647 else 648 hDIB = hDIBtmp; 649 650 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 651 652 // read the color table 653 // _lread (hFile, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD)); 654 // debugprint( "LoadDIB_FromMemory, memcpy color table %i colors, so %i bytes\n", nNumColors, nNumColors * sizeof(RGBQUAD) ); 655 memcpy( (LPSTR)(lpbi) + lpbi->biSize, pData, nNumColors * sizeof(RGBQUAD) ); 656 pData += nNumColors * sizeof(RGBQUAD); 657 658 // offset to the bits from start of DIB header 659 offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD); 660 661 // If the bfOffBits field is non-zero, then the bits might *not* be 662 // directly following the color table in the file. Use the value in 663 // bfOffBits to seek the bits. 664 665 if (bmfHeader.bfOffBits != 0L) 666 // _llseek(hFile, bmfHeader.bfOffBits, SEEK_SET); 667 pData = pDataStart + bmfHeader.bfOffBits; 668 669 // debugprint( "bmfHeader.bfOffBits is %i\n", bmfHeader.bfOffBits ); 670 671 // if (MyRead(hFile, (LPSTR)lpbi + offBits, lpbi->biSizeImage)) 672 // goto OKExit; 673 // debugprint( "Checking that pData(%i) + biSizeImage(%i), which is %i, is equal to pDataEnd(%i)\n", 674 // pData, lpbi->biSizeImage, pData + lpbi->biSizeImage, pDataEnd ); 675 // if( pData + lpbi->biSizeImage != pDataEnd ) condition relaxed 676 // { 677 // debugprint( "LoadDIB_FromMemory error: bad size 3\n" ); 678 // goto ErrExit; 679 // } 680 681 // debugprint( "LoadDIB_FromMemory, memcpy the bits, %i bytes. Image is w %i, h.%i\n", 682 // lpbi->biSizeImage, lpbi->biWidth, lpbi->biHeight ); 683 // debugprint( "Writing to lpbi (%i) + offBits (%i)\n", lpbi, offBits ); 684 685 memcpy( (LPSTR)lpbi + offBits, pData, lpbi->biSizeImage ); 686 // pData += lpbi->biSizeImage; 687 // if( pData != pDataEnd ) // Should end up one byte past end of data. - condition relaxed 688 // debugprint( "LoadDIB_FromMemory: ERROR! Ended up at %i instead of %i\n", pData, pDataEnd ); 689 goto OKExit; 690 691 ErrExit: 692 GlobalUnlock(hDIB); 693 ErrExitNoUnlock: 694 GlobalFree(hDIB); 695 // debugprint( "LoadDIB_FromMemory Error!\n" ); 696 return NULL; 697 698 OKExit: 699 GlobalUnlock(hDIB); 700 return hDIB; 701 } 702 #endif