DIBS.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:59k
源码类别:
Windows编程
开发平台:
Visual C++
- //THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- //ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright 1994-1997 Microsoft Corporation. All Rights Reserved.
- //
- // FILE:
- // DIBS.C
- //
- // PURPOSE:
- // DIB routines for the ICMVIEW application.
- //
- // PLATFORMS:
- // Windows 95, Windows NT
- //
- // SPECIAL INSTRUCTIONS: N/A
- //
- // Windows Header Files:
- #pragma warning(disable:4001) // Single-line comment warnings
- #pragma warning(disable:4115) // Named type definition in parentheses
- #pragma warning(disable:4201) // Nameless struct/union warning
- #pragma warning(disable:4214) // Bit field types other than int warnings
- #pragma warning(disable:4514) // Unreferenced inline function has been removed
- // Windows Header Files:
- #include <Windows.h>
- #include <WindowsX.h>
- //#include <CommCtrl.h>
- #include <icm.h>
- // Restore the warnings--leave the single-line comment warning OFF
- #pragma warning(default:4115) // Named type definition in parentheses
- #pragma warning(default:4201) // Nameless struct/union warning
- #pragma warning(default:4214) // Bit field types other than int warnings
- #pragma warning(default:4514) // Unreferenced inline function has been removed
- // C RunTime Header Files
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <TCHAR.H>
- // Local Header Files
- #include "icmview.h" // specific to this program
- #include "child.h"
- #include "dibinfo.h"
- #include "dibs.h" // specific to this file
- #include "dialogs.h"
- #include "debug.h"
- #include "print.h"
- #include "regutil.h"
- #include "resource.h"
- // local definitions
- DWORD NumColorsInDIB(LPBITMAPINFOHEADER lpbi);
- LONG DIBHeight (LPBYTE lpDIB);
- LONG DIBWidth (LPBYTE lpDIB);
- LPLOGCOLORSPACE GetColorSpaceFromBitmap(LPBITMAPINFOHEADER lpBitmapInfo, DWORD dwIntent, LPBOOL pbDeleteProfile);
- HPROFILE OpenColorProfileFromFile(LPTSTR lpszProfileName);
- BOOL TranslateColorTable(HTRANSFORM hColorTransform, PCOLOR paInputColors, DWORD nColors, COLORTYPE ctInput, PCOLOR paOutputColors, COLORTYPE ctOutput, int biBitCount);
- // default settings
- // external functions
- // external data
- // public data
- // private data
- // public functions
- // private functions
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: DIBPaint
- //
- // Purpose: Painting routine for a DIB. Calls StretchDIBits() or
- // SetDIBitsToDevice() to paint the DIB. The DIB is
- // output to the specified DC, at the coordinates given
- // in lpDCRect. The area of the DIB to be output is
- // given by lpDIBRect. The specified palette is used.
- //
- // Parms: hDC == DC to do output to.
- // lpDCRect == Rectangle on DC to do output to.
- // hDIB == Handle to global memory with a DIB spec
- // in it (either a BITMAPINFO or BITMAPCOREINFO
- // followed by the DIB bits).
- // lpDIBRect == Rect of DIB to output into lpDCRect.
- // hPal == Palette to be used.
- //
- ///////////////////////////////////////////////////////////////////////
- void DIBPaint (HDC hDC, LPRECT lpDCRect, HGLOBAL hDIB,LPRECT lpDIBRect,
- LPDIBINFO lpDIBInfo)
- {
- int iScanLines;
- HDC hDCPrinter;
- BOOL bRC;
- LPBYTE lpbDIBBits;
- HPALETTE hOldPal;
- LPBITMAPINFOHEADER lpDIBHdr;
- LPBITMAPINFOHEADER lpbi;
- // Initialize variables
- if (!hDIB)
- {
- return;
- }
- ASSERT(hDC != NULL);
- hDCPrinter = NULL;
- SetLastError(0);
- hOldPal = NULL;
- lpbi = NULL;
- // Lock down DIB, get a pointer to the beginning of the bit buffer.
- lpDIBHdr = GlobalLock(hDIB);
- if (NULL == lpDIBHdr )
- {
- goto Release;
- }
- lpbDIBBits = FindDIBBits(lpDIBHdr);
- if (NULL == lpbDIBBits)
- {
- goto Release;
- }
- // If size > BITMAPINFOHEADER header then
- // need to convert to BITMAPINFOHEADER.
- lpbi = lpDIBHdr;
- #ifdef OSR2
- if (sizeof(BITMAPINFOHEADER) < lpDIBHdr->biSize)
- {
- DWORD dwColorTableSize;
- DWORD dwHeaderDataSize;
- // Allocate Bitmapinfo memory.
- dwHeaderDataSize = sizeof(BITMAPINFOHEADER) + (lpDIBHdr->biCompression == BI_BITFIELDS ? 12 : 0);
- dwColorTableSize = NumColorsInDIB(lpDIBHdr) * sizeof(RGBQUAD);
- lpbi = (LPBITMAPINFOHEADER) GlobalAlloc(GPTR, dwHeaderDataSize + dwColorTableSize);
- if (NULL == lpbi)
- {
- goto Release;
- }
- // Convert header data into bitmapinfo header.
- memcpy(lpbi, lpDIBHdr, dwHeaderDataSize);
- lpbi->biSize = sizeof(BITMAPINFOHEADER);
- // Copy color table if any.
- if (0 != dwColorTableSize)
- memcpy((LPBYTE)lpbi + dwHeaderDataSize, (LPBYTE)lpDIBHdr + lpDIBHdr->biSize, dwColorTableSize);
- }
- #endif
- SetupDC(hDC, lpDIBInfo, &hOldPal, &hDCPrinter);
- // Determine whether to call StretchDIBits() or SetDIBitsToDevice().
- if (!(lpDIBInfo->bStretch))
- {
- iScanLines = SetDIBitsToDevice (hDC, // hDC
- lpDCRect->left, // dest upper-left x
- lpDCRect->top, // dest upper-left y
- RECTWIDTH (lpDCRect), // src width
- RECTHEIGHT (lpDCRect), // src height
- lpDIBRect->left, // src lower-left x
- (int) DIBHeight((LPBYTE)lpDIBHdr) -
- lpDIBRect->top -
- RECTHEIGHT (lpDIBRect), // src lower-left y
- 0, // nStartScan
- (UINT) DIBHeight((LPBYTE)lpDIBHdr), // nNumScans
- lpbDIBBits, // lpBits
- (LPBITMAPINFO) lpbi, // lpBitsInfo
- DIB_RGB_COLORS); // wUsage
- }
- else
- {
- // Use the specified stretch mode
- SetStretchBltMode (hDC, (int)lpDIBInfo->dwStretchBltMode);
- iScanLines = StretchDIBits (hDC, // hDC
- lpDCRect->left, // dest upper-left x
- lpDCRect->top, // dest upper-left y
- RECTWIDTH (lpDCRect), // src width
- RECTHEIGHT (lpDCRect), // src height
- lpDIBRect->left, // src lower-left x
- lpDIBRect->top, // src lower-left y
- RECTWIDTH (lpDIBRect), // nStartScan
- RECTHEIGHT (lpDIBRect), // nNumScans
- lpbDIBBits, // lpBits
- (LPBITMAPINFO)lpbi, // lpBitsInfo
- DIB_RGB_COLORS, // wUsage
- SRCCOPY); // dwROP
- }
- if (DIBHeight((LPBYTE)lpDIBHdr) != iScanLines)
- {
- DebugMsg(__TEXT("DIBS.C : DIBPaint: iScanLines expected %ld, returned %ldrn"), DIBHeight((LPBYTE)lpDIBHdr), iScanLines);
- }
- // Fix up the palette.
- if (NULL == SelectPalette (hDC, hOldPal, TRUE))
- {
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- Release:
- if (lpbi != lpDIBHdr)
- GlobalFree((HANDLE)lpbi);
- if (NULL != lpDIBHdr)
- {
- GlobalUnlock(hDIB);
- }
- if (hDCPrinter)
- {
- bRC = ColorMatchToTarget(hDC, hDCPrinter, CS_DISABLE);
- if (0 == bRC)
- {
- DebugMsg(__TEXT("DIBS.C : DIBPaint : ColorMatchToTarget failed to DISABLE transform.rn"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC,GetLastError());
- }
- bRC = ColorMatchToTarget(hDC, hDCPrinter, CS_DELETE_TRANSFORM);
- if (0 == bRC)
- {
- DebugMsg( __TEXT( "DIBS.C : DIBPaint : ColorMatchToTarget failed to DELETE transform.rn"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC,GetLastError());
- }
- bRC = DeleteDC(hDCPrinter);
- if (0 == bRC)
- {
- DebugMsg(__TEXT("DIBS.C : DIBPaint : Failed to delete printer DCrn"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC,GetLastError());
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: CreateDIBPalette
- //
- // Purpose: Given a handle to a DIB, constructs a logical palette,
- // and returns a handle to this palette.
- //
- // Stolen almost verbatim from ShowDIB.
- //
- // Parms: hDIB == HANDLE to global memory with a DIB header
- // (either BITMAPINFOHEADER or BITMAPCOREHEADER)
- //
- ///////////////////////////////////////////////////////////////////////
- HPALETTE CreateDIBPalette(HANDLE hDIB)
- {
- LPLOGPALETTE lpPal;
- HGLOBAL hLogPal;
- HPALETTE hPal = NULL;
- UINT i;
- DWORD dwNumColors;
- LPBITMAPINFOHEADER lpBmpInfoHdr;
- LPBITMAPINFO lpbmi;
- LPBITMAPCOREINFO lpbmc;
- BOOL bWinStyleDIB;
- if (!hDIB)
- {
- return NULL;
- }
- lpBmpInfoHdr = GlobalLock (hDIB);
- lpbmi = (LPBITMAPINFO)lpBmpInfoHdr;
- lpbmc = (LPBITMAPCOREINFO)lpBmpInfoHdr;
- dwNumColors = NumColorsInDIB(lpBmpInfoHdr);
- bWinStyleDIB = IS_WIN30_DIB(lpBmpInfoHdr);
- if (0 != dwNumColors)
- {
- hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) + sizeof (PALETTEENTRY) * dwNumColors);
- if (!hLogPal)
- {
- GlobalUnlock(hDIB);
- return NULL;
- }
- lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
- lpPal->palVersion = PALVERSION;
- lpPal->palNumEntries = (WORD)dwNumColors;
- for (i = 0; i < dwNumColors; i++)
- {
- if (bWinStyleDIB)
- {
- lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
- lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
- lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
- lpPal->palPalEntry[i].peFlags = 0;
- }
- else
- {
- lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
- lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
- lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
- lpPal->palPalEntry[i].peFlags = 0;
- }
- }
- hPal = CreatePalette (lpPal);
- GlobalUnlock(hLogPal);
- GlobalFree(hLogPal);
- }
- GlobalUnlock(hDIB);
- return(hPal);
- }
- //////////////////////////////////////////////////////////////////////////
- // Function: GetDefaultICMProfile
- //
- // Description:
- // Uses GetICMProfile to retrieve the filename of the default ICM
- // profile for the DC.
- //
- // Parameters:
- // @@@
- //
- // Returns:
- // LPTSTR
- //
- // Comments:
- //
- //
- //////////////////////////////////////////////////////////////////////////
- LPTSTR GetDefaultICMProfile(HDC hDC)
- {
- // Local variables
- LPTSTR lpszProfileName;
- BOOL bProfile;
- DWORD dwProfileLen;
- TCHAR stProfileName[MAX_PATH+1];
- HGLOBAL hFree;
- // Initialize variables
- lpszProfileName = NULL;
- dwProfileLen = 0;
- stProfileName[0] = __TEXT(' ');
- // Query for size of profile name string
- bProfile = GetICMProfile(hDC, &dwProfileLen, NULL);
- if (bProfile)
- {
- DebugMsg(__TEXT("GetDefaultICMProfile: GetICMProfile returned TRUE on query, dwProfileLen = %ldrn"), dwProfileLen);
- return(FALSE);
- }
- if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
- {
- DebugMsg(__TEXT("GetDefaultICMProfile: GetICMProfile set unexpected LastError %ld on query, dwProfileLen = %ldrn"),
- GetLastError(), dwProfileLen);
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- dwProfileLen = MAX_PATH;
- }
- else
- {
- if (0 == dwProfileLen)
- {
- DebugMsg(__TEXT("GetDefaultICMProfile: GetICMProfile returned FALSE on query, DID NOT SET dwProfileLenrn"));
- return(FALSE);
- }
- }
- // Fill in lpszProfileName with actual profile filename
- lpszProfileName = GlobalAlloc(GPTR, (dwProfileLen+1) * sizeof(TCHAR));
- if (lpszProfileName != NULL)
- {
- bProfile = GetICMProfile(hDC, &dwProfileLen, lpszProfileName);
- if (!bProfile)
- {
- DebugMsg(__TEXT("GetDefaultICMProfile: GetICMProfile FAILEDrn"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- hFree = GlobalFree(lpszProfileName);
- return(NULL);
- }
- else // Successfully id'd default profile
- {
- TCHAR szName[MAX_PATH], szExt[MAX_PATH];
- DebugMsg(__TEXT("Full profile name: <%s>rn"), lpszProfileName);
- _tsplitpath(lpszProfileName, NULL, NULL, szName, szExt);
- wsprintf(lpszProfileName, __TEXT("%s%s"), szName, szExt);
- }
- }
- else
- {
- DebugMsg(__TEXT("GetDefaultICMProfile: Unable to allocate lpszProfileName.rn"));
- }
- return(lpszProfileName);
- } // End of function GetDefaultICMProfile
- //////////////////////////////////////////////////////////////////////////
- // Function: TransformDIBOutsideDC
- //
- // Description:
- // Transforms the provided hDIB using the provided profile names.
- //
- // Parameters:
- // HANDLE Handle to DIB to process
- // LPTSTR Destination profile
- // LPTSTR Target profile
- //
- // Returns:
- // HANDLE to transformed bits; NULL upon failure.
- //
- // Comments:
- // Uses ICM functions
- // CreateColorTransform
- // TranslateBitmapBits
- // TranslateColors
- //
- //////////////////////////////////////////////////////////////////////////
- HANDLE TransformDIBOutsideDC(HANDLE hDIB, BMFORMAT bmInput, LPTSTR lpszDestProfile,
- LPTSTR lpszTargetProfile, DWORD dwIntent, PBMCALLBACKFN pBMCallback,
- ULONG ulCallbackData)
- {
- // Local variables
- HANDLE hDIBTransformed; // Handle to transformed DIB
- HPROFILE hDestProfile, hTargetProfile;
- HTRANSFORM hTransform;
- LPLOGCOLORSPACE lpLogColorSpace;
- PVOID pSrcBits, pDestBits;
- LPBITMAPINFOHEADER lpbSrcDIBHdr, lpbDestDIBHdr;
- BOOL bTranslated, bProfileClosed, bDeleted, bDeleteProfile;
- DWORD dwCopySize;
- // Initialize variables
- ASSERT(NULL != hDIB);
- ASSERT(NULL != lpszDestProfile);
- hDIBTransformed = NULL;
- SetLastError(0);
- hTransform = NULL;
- bTranslated = FALSE;
- hDestProfile = OpenColorProfileFromFile(lpszDestProfile );
- hTargetProfile = OpenColorProfileFromFile(lpszTargetProfile);
- if (NULL == hDestProfile)
- {
- DebugMsg(__TEXT("TransformDIBOutsideDC : NULL dest filern"));
- return(NULL);
- }
- // Get bits from original DIB
- lpbSrcDIBHdr = GlobalLock(hDIB);
- pSrcBits = (PVOID)FindDIBBits(lpbSrcDIBHdr);
- // Get LPLOGCOLORSPACE for transform
- lpLogColorSpace = GetColorSpaceFromBitmap(lpbSrcDIBHdr, dwIntent, &bDeleteProfile);
- if (NULL != lpLogColorSpace)
- {
- //Create the transform to use
- SetLastError(0);
- hTransform = CreateColorTransform(lpLogColorSpace, hDestProfile, hTargetProfile, ENABLE_GAMUT_CHECKING | NORMAL_MODE | 0x80000000);
- if (NULL != hTransform)
- {
- // Allocate for new DIB
- hDIBTransformed = GlobalAlloc(GHND, GlobalSize(hDIB));
- lpbDestDIBHdr = GlobalLock(hDIBTransformed);
- switch (BITCOUNT(lpbSrcDIBHdr))
- {
- DWORD dwSrcOffBytes, dwDestOffBytes;
- case 1: // BM_1GRAY:
- case 4:
- case 8:
- ASSERT((((LPBITMAPV5HEADER)lpbSrcDIBHdr)->bV5ClrUsed) <= (DWORD)( 1 << ((LPBITMAPV5HEADER)lpbSrcDIBHdr)->bV5BitCount));
- // Copy entire DIB. Color table will be replaced by TranslateColors
- dwCopySize = GlobalSize(hDIB);
- memset(lpbDestDIBHdr, 0x17, dwCopySize);
- memcpy(lpbDestDIBHdr, lpbSrcDIBHdr, dwCopySize);
- dwSrcOffBytes = *(LPDWORD)lpbSrcDIBHdr;
- dwDestOffBytes = *(LPDWORD)lpbDestDIBHdr;
- pSrcBits = (PBYTE)lpbSrcDIBHdr + dwSrcOffBytes;
- pDestBits = (PBYTE)lpbDestDIBHdr + dwDestOffBytes;
- // Needed to use different translation if BITMAPCORE bitmap.
- if (dwSrcOffBytes >= sizeof(BITMAPINFOHEADER))
- {
- bTranslated = TranslateColorTable(hTransform,
- (PCOLOR)pSrcBits, // paInputColors,
- ((LPBITMAPV5HEADER)lpbSrcDIBHdr)->bV5ClrUsed, // nColors,
- COLOR_RGB, // ctInput,
- (PCOLOR)pDestBits, // paOutputColors,
- COLOR_RGB, // ctOutput)
- lpbSrcDIBHdr->biBitCount);
- }
- else
- {
- bTranslated = TranslateBitmapBits(hTransform,
- pSrcBits,
- BM_RGBTRIPLETS,
- NumColorsInDIB(lpbSrcDIBHdr),
- 1,
- 0,
- pDestBits,
- BM_RGBTRIPLETS,
- 0,
- NULL,
- 0);
- }
- if (0 == bTranslated)
- {
- DebugMsg(__TEXT("TransformDIBOutsideDC : TranslateColors failed, :"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- break;
- case 16: // BM_RGBTRIPLETS:
- case 24: // BM_xRGBQUADS:
- case 32: // BM_x555RGB:
- // Copy header from original DIB to new DIB
- memcpy(lpbDestDIBHdr, lpbSrcDIBHdr, sizeof(BITMAPV5HEADER));
- pDestBits = (PVOID)FindDIBBits(lpbDestDIBHdr);
- bTranslated = TranslateBitmapBits(hTransform,
- pSrcBits,
- bmInput,
- BITMAPWIDTH(lpbSrcDIBHdr),
- abs(BITMAPHEIGHT(lpbSrcDIBHdr)),
- 0,
- pDestBits,
- bmInput,
- 0,
- pBMCallback,
- ulCallbackData);
- if (0 == bTranslated)
- {
- DebugMsg(__TEXT("TransformDIBOutsideDC : TranslateBitmapBits failed:rn"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- break;
- default: // 8bpp
- DebugMsg(__TEXT("TransformDIBOutsideDC : Unrecognized formatrn"));
- bTranslated = FALSE;
- break;
- }
- bDeleted = DeleteColorTransform(hTransform);
- if (0 == bDeleted)
- {
- DebugMsg(__TEXT("TransformDIBOutsideDC : DeleteColorTransform failed, : "));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- }
- else
- {
- ErrMsg(NULL, __TEXT("TransformDIBOutsideDC : CreateColorTransform failed"));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- if (bDeleteProfile)
- {
- DeleteFile(lpLogColorSpace->lcsFilename);
- }
- GlobalFree((HANDLE)lpLogColorSpace);
- }
- else // Failed to get LOGCOLORSPACE
- {
- ErrMsg(NULL, __TEXT("TransformDIBOutsideDC : Failed to get LOGCOLORSPACE"));
- }
- if (NULL != hDestProfile)
- {
- bProfileClosed = CloseColorProfile(hDestProfile);
- if (0 == bProfileClosed)
- {
- DebugMsg(__TEXT("TransformDIBOutsideDC : Failed to close hDestProfile, "));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- }
- if (NULL != hTargetProfile)
- {
- bProfileClosed = CloseColorProfile(hTargetProfile);
- if (0 == bProfileClosed)
- {
- DebugMsg(__TEXT("TransformDIBOutsideDC : Failed to close hTargetProfile, "));
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- }
- if (NULL != hDIBTransformed)
- {
- GlobalUnlock(hDIBTransformed);
- }
- if ((NULL == hTransform) || (0 == bTranslated))
- {
- if (NULL != hDIBTransformed)
- {
- GlobalFree(hDIBTransformed);
- hDIBTransformed = NULL;
- }
- lpbDestDIBHdr = NULL;
- pDestBits = NULL;
- }
- return(hDIBTransformed);
- } // End of function TransformDIBOutsideDC
- //////////////////////////////////////////////////////////////////////////
- // Function: OpenColorProfileFromFile
- //
- // Description:
- // Creates a color profile based upon the parameters passed.
- //
- // Parameters:
- // LPTSTR Profile name
- //
- // Returns:
- // HPROFILE Handle to PROFILE structure, NULL if failure.
- //
- // Comments:
- //
- //
- //////////////////////////////////////////////////////////////////////////
- HPROFILE OpenColorProfileFromFile(LPTSTR lpszProfileName)
- {
- // Local variables
- PPROFILE pProfile;
- HPROFILE hProfile;
- DWORD cbDataSize;
- DWORD dwProfileSize;
- TCHAR stFullProfile[MAX_PATH];
- BOOL bValid;
- // Initialize variables
- if (NULL == lpszProfileName)
- {
- return(NULL);
- }
- // Add COLOR dir path if profile name does not contain a path.
- if ( (NULL == _tcschr(lpszProfileName, __TEXT(':')))
- &&
- (NULL == _tcschr(lpszProfileName, __TEXT('\')))
- )
- {
- wsprintf(stFullProfile, __TEXT("%s\%s"), gstProfilesDir, lpszProfileName);
- }
- else
- {
- lstrcpy(stFullProfile, lpszProfileName);
- }
- dwProfileSize = sizeof(PROFILE);
- cbDataSize = (lstrlen(stFullProfile) * sizeof(TCHAR)) + sizeof(TCHAR); // String plus NULL
- pProfile = GlobalAlloc(GPTR, (dwProfileSize + cbDataSize));
- #ifdef _DEBUG
- memset(pProfile, UNINIT_BYTE, (cbDataSize+dwProfileSize));
- #endif
- pProfile->dwType = PROFILE_FILENAME;
- pProfile->cbDataSize = cbDataSize;
- pProfile->pProfileData = (PVOID)((LPBYTE)pProfile + dwProfileSize);
- _tcscpy(pProfile->pProfileData, stFullProfile);
- hProfile = OpenColorProfile(pProfile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING);
- if (NULL == hProfile)
- {
- ErrMsg(NULL,__TEXT("Unable to open color profile <%s>"), stFullProfile);
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- }
- else
- {
- // Validate the profile
- bValid = IsColorProfileValid(hProfile, &bValid);
- if (0 == bValid)
- {
- ErrMsg(NULL,__TEXT("Color profile %s is not valid"), stFullProfile);
- DISPLAY_LASTERROR(LASTERROR_NOALLOC, GetLastError());
- CloseColorProfile(hProfile);
- hProfile = NULL;
- }
- }
- // Cleanup
- GlobalFree(GlobalHandle(pProfile));
- return(hProfile);
- } // End of function OpenColorProfileFromDisk
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: GetColorSpaceFromBitmap
- //
- // Purpose: Creates a LOGCOLORSPACE based on information in bitmap.
- //
- //
- // Parms: lpBitmapHeader Pointer to bitmap header and info.
- // dwIntent Color Space Intent.
- // pbDeleteProfile Flag, on return, will indicate if the profile needs
- // to be deleted before LOGCOLORSPACE is freed.
- //
- //
- ///////////////////////////////////////////////////////////////////////
- LPLOGCOLORSPACE GetColorSpaceFromBitmap(LPBITMAPINFOHEADER lpBitmapInfo, DWORD dwIntent,
- LPBOOL pbDeleteProfile)
- {
- LPLOGCOLORSPACE lpColorSpace = NULL;
- PBITMAPV5HEADER lpBitmapV5 = (PBITMAPV5HEADER) lpBitmapInfo;
- // Validate parameters.
- ASSERT(NULL != lpBitmapInfo);
- if ( (NULL == lpBitmapInfo)
- ||
- (NULL == pbDeleteProfile)
- ||
- ( (sizeof(BITMAPCOREHEADER) != lpBitmapInfo->biSize)
- &&
- (sizeof(BITMAPINFOHEADER) != lpBitmapInfo->biSize)
- &&
- (sizeof(BITMAPV4HEADER) != lpBitmapInfo->biSize)
- &&
- (sizeof(BITMAPV5HEADER) != lpBitmapInfo->biSize)
- )
- )
- {
- return NULL;
- }
- // Initalize delete flag.
- *pbDeleteProfile = FALSE;
- // Allocate LOGCOLORSPACE.
- lpColorSpace = (LPLOGCOLORSPACE) GlobalAlloc(GPTR, sizeof(LOGCOLORSPACE));
- if (NULL == lpColorSpace)
- {
- return NULL;
- }
- // Initialize color space.
- lpColorSpace->lcsSignature = 'PSOC'; // The signature should always be 'PSOC'.
- lpColorSpace->lcsVersion = 0x400;
- lpColorSpace->lcsSize = sizeof(LOGCOLORSPACE);
- // If BITMAPCOREHEADER or BITMAPINFOHEADER, bitmap has no information
- // about color space; use sRGB.
- if (sizeof(BITMAPINFOHEADER) >= lpBitmapInfo->biSize)
- {
- // Set color space to default values.
- lpColorSpace->lcsCSType = LCS_sRGB;
- // Set endpoints to sRGB values.
- lpColorSpace->lcsEndpoints.ciexyzRed.ciexyzX = __FXPT2DOT30(.64);
- lpColorSpace->lcsEndpoints.ciexyzRed.ciexyzY = __FXPT2DOT30(.33);
- lpColorSpace->lcsEndpoints.ciexyzRed.ciexyzZ = __FXPT2DOT30(.03);
- lpColorSpace->lcsEndpoints.ciexyzGreen.ciexyzX = __FXPT2DOT30(.3);
- lpColorSpace->lcsEndpoints.ciexyzGreen.ciexyzY = __FXPT2DOT30(.6);
- lpColorSpace->lcsEndpoints.ciexyzGreen.ciexyzZ = __FXPT2DOT30(.1);
- lpColorSpace->lcsEndpoints.ciexyzBlue.ciexyzX = __FXPT2DOT30( .15);
- lpColorSpace->lcsEndpoints.ciexyzBlue.ciexyzY = __FXPT2DOT30(.06);
- lpColorSpace->lcsEndpoints.ciexyzBlue.ciexyzZ = __FXPT2DOT30(.79);
- // Just so that if monitor has 2.2 gamma, the over all gamma is 1.0.
- lpColorSpace->lcsGammaRed = __FXPT16DOT16(0.45);
- lpColorSpace->lcsGammaGreen = __FXPT16DOT16(0.45);
- lpColorSpace->lcsGammaBlue = __FXPT16DOT16(0.45);
- }
- else
- {
- // Copy information from portion that is similar between BITMAPV4HEADERs and
- // BITMAPV5HEADERs.
- memcpy(&lpColorSpace->lcsEndpoints, &lpBitmapV5->bV5Endpoints, sizeof(CIEXYZTRIPLE));
- lpColorSpace->lcsGammaRed = lpBitmapV5->bV5GammaRed;
- lpColorSpace->lcsGammaGreen = lpBitmapV5->bV5GammaGreen;
- lpColorSpace->lcsGammaBlue = lpBitmapV5->bV5GammaBlue;
- // BITMAPV4HEADERs do not have complete color space information,
- // we need to assume some things.
- if (sizeof(BITMAPV4HEADER) == lpBitmapInfo->biSize)
- {
- // Fill in default values for fields that do not
- // have equivalents in BITMAPV4HEADER.
- lpColorSpace->lcsCSType = lpBitmapV5->bV5CSType;
- lpColorSpace->lcsIntent = LCS_GM_IMAGES;
- }
- else
- {
- // BITMAPV5HEADERs have complete color space information.
- // No assumptions to make.
- lpColorSpace->lcsIntent = lpBitmapV5->bV5Intent;
- // Look to see if no, linked, or embedded profile.
- switch (lpBitmapV5->bV5CSType)
- {
- case 'MBED':
- // Need to create profile file and reference
- // profile in the color space.
- lpColorSpace->lcsCSType = LCS_CALIBRATED_RGB;
- // Make sure that profile data offset is valid and not zero length.
- if ( (lpBitmapV5->bV5Size > lpBitmapV5->bV5ProfileData)
- ||
- (0L == lpBitmapV5->bV5ProfileSize)
- )
- {
- GlobalFree((HANDLE)lpColorSpace);
- return NULL;
- }
- // Create unique temp name.
- {
- DWORD dwWritten;
- TCHAR szTempPath[MAX_PATH];
- HANDLE hFile;
- GetTempPath(MAX_PATH, szTempPath);
- if (!GetTempFileName(szTempPath, __TEXT("ICM"), 0, lpColorSpace->lcsFilename))
- {
- GlobalFree((HANDLE)lpColorSpace);
- return NULL;
- }
- // Create temp profile that contains the embedded profile.
- hFile = CreateFile(lpColorSpace->lcsFilename, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE == hFile)
- {
- GlobalFree((HANDLE)lpColorSpace);
- return NULL;
- }
- // Write embedded profile to disk.
- WriteFile(hFile, GETPROFILEDATA(lpBitmapV5), lpBitmapV5->bV5ProfileSize,
- &dwWritten, NULL);
- // No longer need file open.
- CloseHandle(hFile);
- // Need to indicate to caller that this file needs to be deleted
- // before LOGCOLORSPACE is freed.
- *pbDeleteProfile = TRUE;
- }
- break;
- case 'LINK':
- // Need to reference profile.
- lpColorSpace->lcsCSType = LCS_CALIBRATED_RGB;
- lstrcpyn(lpColorSpace->lcsFilename, (LPTSTR) GETPROFILEDATA(lpBitmapV5), MAX_PATH);
- break;
- default:
- // Just use color space type in the bitmap.
- lpColorSpace->lcsCSType = lpBitmapV5->bV5CSType;
- break;
- }
- }
- }
- // Set intent to default or to users selection.
- if (0xffffffffL == dwIntent)
- {
- lpColorSpace->lcsIntent = LCS_GM_IMAGES;
- }
- else
- {
- lpColorSpace->lcsIntent = dwIntent;
- }
- return(lpColorSpace);
- }
- //
- // Functions for extracting information from DIBs
- //
- //////////////////////////////////////////////////////////////////////////
- // Function: NumColorsInDIB
- //
- // Description:
- // Determines the number of colors in the DIB by looking at the
- // BitCount field in the info block.
- //
- // Parameters:
- // LPBINTMAPV5HEADER Pointer to BITMAPINFO structure
- //
- // Returns:
- // DWORD Number of colors in the DIB
- //
- // Comments:
- //
- //
- //////////////////////////////////////////////////////////////////////////
- DWORD NumColorsInDIB(LPBITMAPINFOHEADER lpbi)
- {
- WORD wBitCount;
- DWORD dwColors = 0;
- // If this is a Windows style DIB, the number of colors in the
- // color table can be less than the number of bits per pixel
- // allows for (i.e. lpbi->biClrUsed can be set to some value).
- // If this is the case, return the appropriate value.
- if ( (sizeof(BITMAPINFOHEADER) <= lpbi->biSize)
- &&
- (0 != lpbi->biClrUsed)
- )
- {
- dwColors = lpbi->biClrUsed;
- }
- else
- {
- // Calculate the number of colors in the color table based on
- // the number of bits per pixel for the DIB.
- wBitCount = BITCOUNT(lpbi);
- if (MAX_BPP_COLOR_TABLE >= wBitCount)
- {
- dwColors = 1 << wBitCount; // Colors = 2^BitCount
- }
- }
- return dwColors;
- } // End of function NumColorsInDIB
- //////////////////////////////////////////////////////////////////////////
- // Function: PaletteSize
- //
- // Description:
- // Calculates the palette size in bytes.
- //
- // Parameters:
- // @@@
- //
- // Returns:
- // DWORD Palette size in bytes.
- //
- // Comments:
- //
- //
- //////////////////////////////////////////////////////////////////////////
- DWORD PaletteSize(LPBITMAPINFOHEADER lpbi)
- {
- DWORD dwSize = 0L;
- if (sizeof(BITMAPINFOHEADER) <= lpbi->biSize)
- {
- dwSize = NumColorsInDIB(lpbi) * sizeof(RGBQUAD);
- if ( (lpbi->biCompression == BI_BITFIELDS)
- &&
- (sizeof(BITMAPV4HEADER) > lpbi->biSize)
- )
- {
- dwSize = 3 * sizeof(DWORD);
- }
- }
- else
- {
- dwSize = NumColorsInDIB(lpbi) * sizeof (RGBTRIPLE);
- }
- return dwSize;
- } // End of function PaletteSize
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: FindDIBBits
- //
- // Purpose: Given a pointer to a DIB, returns a pointer to the
- // DIB's bitmap bits.
- //
- // Parms: lpbi == pointer to DIB header (either BITMAPINFOHEADER
- // or BITMAPCOREHEADER)
- //
- ///////////////////////////////////////////////////////////////////////
- LPBYTE FindDIBBits(LPBITMAPINFOHEADER lpbi)
- {
- ASSERT(NULL != lpbi);
- return ((LPBYTE)lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi) + PROFILESIZE(lpbi));
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: FindDIBBits
- //
- // Purpose: Given a pointer to a DIB, returns a pointer to the
- // DIB's bitmap bits.
- //
- // Parms: lpbi == pointer to DIB header (either BITMAPINFOHEADER
- // or BITMAPCOREHEADER)
- //
- ///////////////////////////////////////////////////////////////////////
- LPBYTE FindColorTable(LPBITMAPINFOHEADER lpbi)
- {
- ASSERT(NULL != lpbi);
- return ((LPBYTE)lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi) + PROFILESIZE(lpbi));
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: DIBHeight
- //
- // Purpose: Given a pointer to a DIB, returns the ABSOLUTE VALUE of
- // its height. Note that it returns a DWORD (since a Win30
- // DIB can have a DWORD in its height field), but under
- // Win30, the high order word isn't used!
- //
- // Parms: lpDIB == pointer to DIB header (either BITMAPINFOHEADER
- // or BITMAPCOREHEADER)
- //
- ///////////////////////////////////////////////////////////////////////
- LONG DIBHeight (LPBYTE lpDIB)
- {
- LPBITMAPINFOHEADER lpbmi;
- LPBITMAPCOREHEADER lpbmc;
- lpbmi = (LPBITMAPINFOHEADER) lpDIB;
- lpbmc = (LPBITMAPCOREHEADER) lpDIB;
- if (lpbmi->biSize >= sizeof (BITMAPINFOHEADER))
- {
- return labs(lpbmi->biHeight); // biHeight can now be negative! 8/9/93
- }
- else
- {
- return (LONG) lpbmc->bcHeight;
- }
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Function: DIBWidth
- //
- // Purpose: Given a pointer to a DIB, returns its width. Note
- // that it returns a DWORD (since a Win30 DIB can have
- // a DWORD in its width field), but under Win30, the
- // high order word isn't used!
- //
- // Parms: lpDIB == pointer to DIB header (either BITMAPINFOHEADER
- // or BITMAPCOREHEADER)
- //
- ///////////////////////////////////////////////////////////////////////
- LONG DIBWidth (LPBYTE lpDIB)
- {
- LPBITMAPINFOHEADER lpbmi;
- LPBITMAPCOREHEADER lpbmc;
- lpbmi = (LPBITMAPINFOHEADER) lpDIB;
- lpbmc = (LPBITMAPCOREHEADER) lpDIB;
- if (lpbmi->biSize >= sizeof (BITMAPINFOHEADER))
- {
- return lpbmi->biWidth;
- }
- else
- {
- return (LONG) lpbmc->bcWidth;
- }
- }
- //
- // Functions for reading DIBs
- //
- //////////////////////////////////////////////////////////////////////////
- // Function: ReadDIBFile
- //
- // Description:
- // Open a DIB file and create
- // -a memory DIB
- // -a memory handle containing BITMAPINFO, palette, and the bits
- //
- //
- // Parameters:
- // @@@
- //
- // Returns:
- // HGLOBAL Handle to DIB memory; NULL upon failure.
- //
- // Comments:
- //
- //////////////////////////////////////////////////////////////////////////
- HGLOBAL ReadDIBFile(LPTSTR lpszFileName)
- {
- // Local variables
- HGLOBAL hDIBInfo;
- LPDIBINFO lpDIBInfo;
- BOOL bGotDIBInfo;
- // Initialize variables
- hDIBInfo = CreateDIBInfo();
- if (hDIBInfo == NULL)
- {
- return(NULL);
- }
- lpDIBInfo = GlobalLock(hDIBInfo);
- if (lpDIBInfo == (LPDIBINFO)NULL)
- {
- GlobalFree(hDIBInfo);
- return(NULL);
- }
- bGotDIBInfo = fReadDIBInfo(lpszFileName, lpDIBInfo);
- GlobalUnlock(hDIBInfo);
- if (0 == bGotDIBInfo) // failed to open file
- {
- fFreeDIBInfo(hDIBInfo, TRUE);
- hDIBInfo = NULL;
- }
- return(hDIBInfo);
- } // End of function ReadDIBFile
- //////////////////////////////////////////////////////////////////////////
- // Function: ReadDIBFromFile
- //
- // Description:
- // Reads in the bitmap information.
- //
- // Parameters:
- // hFile Handle to bitmap file.
- //
- // Returns: Handle to DIB Bitmap. NULL on error.
- //
- // Comments:
- //
- //////////////////////////////////////////////////////////////////////////
- HANDLE ReadDIBFromFile(HANDLE hFile)
- {
- UINT nNumColors;
- DWORD offBits;
- DWORD dwRead;
- DWORD dwImageBytes;
- DWORD dwSizeImage;
- HANDLE hDIB;
- BITMAPFILEHEADER BmpFileHeader;
- LPBITMAPINFOHEADER lpbi;
- // Make sure non-null file handle.
- if (NULL == hFile)
- {
- return NULL;
- }
- // Read in Bitmap file header.
- if (0L != SetFilePointer(hFile, 0, NULL, FILE_BEGIN))
- {
- return NULL;
- }
- ReadFile(hFile, &BmpFileHeader, sizeof(BITMAPFILEHEADER), &dwRead, NULL);
- if (sizeof(BITMAPFILEHEADER) != dwRead)
- {
- return NULL;
- }
- // Make sure that the file is a bitmap file.
- if (BFT_BITMAP != BmpFileHeader.bfType)
- {
- return NULL;
- }
- // Detemine size of bitmap header.
- ReadFile(hFile, &dwImageBytes, sizeof(DWORD), &dwRead, NULL);
- if (sizeof(DWORD) != dwRead)
- {
- return NULL;
- }
- // Allocate memory for header & color table.
- // We'll enlarge this memory as needed.
- hDIB = GlobalAlloc(GHND, dwImageBytes + (256L * sizeof(RGBQUAD)));
- if (!hDIB)
- {
- return NULL;
- }
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- if (!lpbi)
- {
- GlobalFree(hDIB);
- return NULL;
- }
- // Back up to begining of bitmap header and read bitmap header.
- SetFilePointer(hFile, sizeof(BITMAPFILEHEADER), NULL, FILE_BEGIN);
- ReadFile(hFile, lpbi, dwImageBytes, &dwRead, NULL);
- if (dwRead != dwImageBytes)
- {
- GlobalUnlock(hDIB);
- GlobalFree(hDIB);
- return NULL;
- }
- // Dump debug info about type of bitmap opened.
- #ifdef MAXDEBUG
- DumpBmpHeader((LPVOID)lpbi);
- #endif
- // Check to see that it's a Windows DIB or an OS/2 DIB.
- // It assumed that anything that is not a OS/2 DIB is a Windows DIB.
- // This at least allows the opening of newer bitmap types, although GDI
- // may not handle them so we may not be able to display them.
- // More critical checking could be done by checking against
- // BITMAPV4HEADER and BITMAPV5HEADER sizes.
- if (lpbi->biSize >= sizeof(BITMAPINFOHEADER))
- {
- DWORD dwProfileData = 0;
- DWORD dwColorTableSize;
- HANDLE hTemp;
- // Now determine the size of the color table and read it. Since the
- // bitmap bits are offset in the file by bfOffBits, we need to do some
- // special processing here to make sure the bits directly follow
- // the color table (because that's the format we are susposed to pass
- // back)
- // no color table for 24-bit, default size otherwise
- nNumColors = (UINT)lpbi->biClrUsed;
- if (0 == nNumColors)
- {
- if (lpbi->biBitCount <= MAX_BPP_COLOR_TABLE)
- {
- nNumColors = 1 << lpbi->biBitCount; // standard size table
- }
- }
- // Fill in some default values if they are zero
- if (0 == lpbi->biClrUsed)
- {
- lpbi->biClrUsed = nNumColors;
- }
- if (0 == lpbi->biSizeImage)
- {
- // Calculate size using DWORD alignment
- dwSizeImage = (((lpbi->biWidth * lpbi->biBitCount + 31) & ~31)
- >> 3) * abs(lpbi->biHeight);
- }
- else
- {
- dwSizeImage = lpbi->biSizeImage;
- }
- // get a proper-sized buffer for header, color table and bits
- // Figure out the size of the bitmap AND it's color table.
- dwColorTableSize = PaletteSize(lpbi);
- // Calculate profile data size;
- // zero if not BITMAPV5HEADER, else in use bV5ProfileSize.
- dwProfileData = PROFILESIZE(lpbi);
- // Resize DIB buffer.
- dwImageBytes = lpbi->biSize + dwSizeImage + dwColorTableSize + dwProfileData;
- GlobalUnlock(hDIB);
- hTemp = GlobalReAlloc(hDIB, dwImageBytes, GHND);
- DebugMsg(__TEXT("ReadDIBFromFile: Allocating %lu bytes for header, color table, and imagern"), dwImageBytes);
- if (NULL == hTemp) // can't resize buffer for loading
- {
- GlobalFree(hDIB);
- return NULL;
- }
- hDIB = hTemp;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
- // read the color table, if any, into buffer starting past Bitmap header.
- if (0 != dwColorTableSize)
- {
- ReadFile(hFile, (LPBYTE)lpbi + lpbi->biSize, dwColorTableSize, &dwRead, NULL);
- if (dwColorTableSize != dwRead)
- {
- GlobalUnlock(hDIB);
- GlobalFree(hDIB);
- return NULL;
- }
- }
- // Load profile data, if any.
- if (0 != dwProfileData)
- {
- // Move to profile data.
- SetFilePointer(hFile, sizeof(BITMAPFILEHEADER)
- + ((LPBITMAPV5HEADER)lpbi)->bV5ProfileData, NULL, FILE_BEGIN);
- // Read the profile data in after the header and color table.
- ReadFile(hFile, (LPBYTE)lpbi + lpbi->biSize + dwColorTableSize, dwProfileData, &dwRead, NULL);
- if (dwProfileData != dwRead)
- {
- GlobalUnlock(hDIB);
- GlobalFree(hDIB);
- return NULL;
- }
- // Need to change the offset in the header.
- ((LPBITMAPV5HEADER)lpbi)->bV5ProfileData = lpbi->biSize + dwColorTableSize;
- }
- // offset to the bits from start of DIB header
- offBits = lpbi->biSize + dwColorTableSize + dwProfileData;
- DumpBmpHeader((LPVOID)lpbi);
- }
- else
- {
- // It's an OS/2 DIB, the color table is an array of RGBTRIPLEs.
- HANDLE hTemp;
- LPBITMAPCOREHEADER lpbc = (LPBITMAPCOREHEADER) lpbi;
- // Gotta back up to beginning of color table.
- SetFilePointer(hFile, sizeof (BITMAPFILEHEADER) + sizeof (BITMAPCOREHEADER), NULL, FILE_BEGIN);
- // Now determine the size of the color table and read it. Since the
- // bitmap bits are offset in the file by bfOffBits, we need to do some
- // special processing here to make sure the bits directly follow
- // the color table (because that's the format we are susposed to pass
- // back)
- if (lpbc->bcBitCount <= MAX_BPP_COLOR_TABLE)
- {
- nNumColors = 1 << lpbc->bcBitCount; // standard size table
- }
- else
- {
- nNumColors = 0;
- }
- // Determine the size of the image
- dwSizeImage = (((lpbc->bcWidth * lpbc->bcBitCount + 31) & ~31) >> 3)
- * lpbc->bcHeight;
- // get a proper-sized buffer for header, color table and bits
- GlobalUnlock(hDIB);
- hTemp = GlobalReAlloc(hDIB, lpbc->bcSize + (nNumColors * sizeof(RGBTRIPLE))
- + dwSizeImage, GHND);
- if (!hTemp) // can't resize buffer for loading
- {
- GlobalFree(hDIB);
- return NULL;
- }
- hDIB = hTemp;
- lpbc = (LPBITMAPCOREHEADER) GlobalLock(hDIB);
- lpbi = (LPBITMAPINFOHEADER) lpbc;
- // read the color table
- ReadFile(hFile, (LPBYTE)lpbc + lpbc->bcSize, nNumColors * sizeof(RGBTRIPLE), &dwRead, NULL);
- if (nNumColors * sizeof(RGBTRIPLE) != dwRead)
- {
- GlobalUnlock(hDIB);
- GlobalFree(hDIB);
- return NULL;
- }
- // offset to the bits from start of DIB header
- offBits = lpbc->bcSize + nNumColors * sizeof(RGBTRIPLE);
- }
- // If the bfOffBits field is non-zero, then the bits might *not* be
- // directly following the color table in the file. Use the value in
- // bfOffBits to seek the bits.
- if (BmpFileHeader.bfOffBits != 0L)
- {
- SetFilePointer(hFile, BmpFileHeader.bfOffBits, NULL, FILE_BEGIN);
- }
- // Read the actual bits
- ReadFile(hFile, (LPBYTE)lpbi + offBits, dwSizeImage, &dwRead, NULL);
- if (dwRead != dwSizeImage)
- {
- GlobalUnlock(hDIB);
- GlobalFree(hDIB);
- return NULL;
- }
- GlobalUnlock(hDIB);
- return hDIB;
- } // End of function ReadDIBFromFile
- //////////////////////////////////////////////////////////////////////////
- // Function: TranslateColorTable
- //
- // Description:
- //
- //
- // Parameters:
- // @@@
- //
- // Returns:
- // BOOL
- //
- // Comments:
- //
- //
- //////////////////////////////////////////////////////////////////////////
- BOOL TranslateColorTable(HTRANSFORM hColorTransform,
- PCOLOR paInputColors,
- DWORD nColors,
- COLORTYPE ctInput,
- PCOLOR paOutputColors,
- COLORTYPE ctOutput,
- int biBitCount
- )
- {
- // Initialize variables
- if (ctInput == COLOR_RGB)
- {
- return(TranslateBitmapBits(hColorTransform,
- (PVOID)paInputColors,
- BM_xRGBQUADS,
- 1<<biBitCount,
- 1,
- 0,
- (PVOID)paOutputColors,
- BM_xRGBQUADS,
- 0,
- NULL,
- 0));
- }
- else
- {
- return(TranslateColors(hColorTransform, paInputColors, nColors, ctInput, paOutputColors, ctOutput));
- }
- } // End of function TranslateColorTable
- //////////////////////////////////////////////////////////////////////////
- // Function: SaveDIBToFile
- //
- // Description:
- //
- //
- // Parameters:
- // @@@
- //
- // Returns:
- // BOOL
- //
- // Comments:
- //
- //
- //////////////////////////////////////////////////////////////////////////
- BOOL SaveDIBToFile(HWND hWnd, LPCTSTR lpszFileName, LPDIBINFO lpDIBInfo, DWORD dwType)
- {
- BOOL bResult = FALSE;
- HANDLE hFile;
- HANDLE hDIBTransformed = NULL;
- PBITMAPINFOHEADER pBitmapInfo;
- // Validate Parameters.
- if ( (NULL == lpszFileName)
- ||
- (NULL == lpDIBInfo)
- ||
- (NULL == lpDIBInfo->hDIB)
- ||
- ( (LCS_sRGB != dwType)
- &&
- (LCS_CALIBRATED_RGB != dwType)
- &&
- (PROFILE_LINKED != dwType)
- &&
- (PROFILE_EMBEDDED != dwType)
- )
- )
- {
- return FALSE;
- }
- pBitmapInfo = (PBITMAPINFOHEADER) GlobalLock(lpDIBInfo->hDIB);
- // Open file handle.
- hFile = CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE != hFile)
- {
- DWORD dwBytes;
- DWORD dwProfileSize;
- PBYTE pProfileData;
- LPSTR lpszProfileName;
- BITMAPV5HEADER BitmapHeader;
- BITMAPFILEHEADER FileHeader;
- // Initialize variables.
- dwProfileSize = PROFILESIZE(pBitmapInfo);
- pProfileData = GETPROFILEDATA(pBitmapInfo);
- lpszProfileName = NULL;
- memset(&BitmapHeader, 0, sizeof(BITMAPV5HEADER));
- memset(&FileHeader, 0, sizeof(BITMAPFILEHEADER));
- // Convert to proper type.
- if (dwType != BITMAPCSTYPE(pBitmapInfo))
- {
- if (PROFILE_LINKED == dwType)
- {
- ASSERT(PROFILE_EMBEDDED == BITMAPCSTYPE(pBitmapInfo));
- // Going from Embedded profile to linked.
- // Save embedded profile data to file.
- // Create file name from manufacture and model name of profile header.
- lpszProfileName = (LPSTR) GlobalAlloc(GPTR, 1024);
- // Get save name and save profile data.
- if (GetProfileSaveName(hWnd, &lpszProfileName, 1024))
- {
- HANDLE hProfile;
- hProfile = CreateFileA(lpszProfileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE != hProfile)
- {
- WriteFile(hProfile, pProfileData, dwProfileSize, &dwBytes, NULL);
- CloseHandle(hProfile);
- }
- // Change profile variables to point to linked name.
- pProfileData = (PBYTE) lpszProfileName;
- dwProfileSize = strlen(lpszProfileName);
- }
- }
- else if (PROFILE_EMBEDDED == dwType)
- {
- DWORD dwSize = 0;
- PROFILE Profile;
- HPROFILE hProfile;
- ASSERT(PROFILE_EMBEDDED == BITMAPCSTYPE(pBitmapInfo));
- // Going from linked profile to Embedded.
- // Embed Linked profile data.
- // Open profile.
- Profile.dwType = PROFILE_FILENAME;
- Profile.pProfileData = pProfileData;
- Profile.cbDataSize = dwProfileSize;
- hProfile = OpenColorProfile(&Profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING);
- // Get profile data form handle.
- if (NULL != hProfile)
- {
- GetColorProfileFromHandle(hProfile, NULL, &dwSize);
- lpszProfileName = (LPSTR) GlobalAlloc(GPTR, dwSize);
- GetColorProfileFromHandle(hProfile, (PBYTE) lpszProfileName, &dwSize);
- CloseColorProfile(hProfile);
- }
- // Change profile variables to point at data to embed.
- pProfileData = (PBYTE) lpszProfileName;
- dwProfileSize = dwSize;
- }
- else if (LCS_sRGB == dwType)
- {
- DWORD dwSize;
- LPTSTR pszSRGB;
- // Need to translate from current type to sRGB.
- // Open sRGB profile.
- GetStandardColorSpaceProfile(NULL, LCS_sRGB, NULL, &dwSize);
- pszSRGB = (LPTSTR) GlobalAlloc(GPTR, dwSize);
- GetStandardColorSpaceProfile(NULL, LCS_sRGB, pszSRGB, &dwSize);
- if (NULL != pszSRGB)
- {
- // Translate DIB.
- hDIBTransformed = TransformDIBOutsideDC(lpDIBInfo->hDIB,
- lpDIBInfo->bmFormat,
- pszSRGB,
- NULL,
- USE_BITMAP_INTENT,
- NULL,
- 0);
- // Clean up.
- GlobalFree((HANDLE)pszSRGB);
- // Change bitmap info variable to point at tranlated DIB.
- pBitmapInfo = (PBITMAPINFOHEADER) GlobalLock(hDIBTransformed);
- }
- }
- }
- if (NULL != pBitmapInfo)
- {
- // Create file header and write it to the file.
- FileHeader.bfType = BFT_BITMAP;
- FileHeader.bfSize = sizeof(BITMAPFILEHEADER);
- FileHeader.bfSize += sizeof(BITMAPV5HEADER);
- FileHeader.bfSize += NumColorsInDIB(pBitmapInfo) * sizeof(RGBQUAD);
- FileHeader.bfSize += BITMAPSIZE(pBitmapInfo);
- FileHeader.bfSize += dwProfileSize;
- FileHeader.bfOffBits = sizeof(BITMAPFILEHEADER);
- FileHeader.bfOffBits += sizeof(BITMAPV5HEADER);
- FileHeader.bfOffBits += NumColorsInDIB(pBitmapInfo) * sizeof(RGBQUAD);
- WriteFile(hFile, &FileHeader, sizeof(BITMAPFILEHEADER), &dwBytes, NULL);
- // Create bitmap header and write it to file.
- BitmapHeader.bV5Size = sizeof(BITMAPV5HEADER);
- BitmapHeader.bV5Width = BITMAPWIDTH(pBitmapInfo);
- BitmapHeader.bV5Height = BITMAPHEIGHT(pBitmapInfo);
- BitmapHeader.bV5Planes = 1;
- BitmapHeader.bV5BitCount = (WORD) BITCOUNT(pBitmapInfo);
- BitmapHeader.bV5Compression = BITMAPCOMPRESSION(pBitmapInfo);
- BitmapHeader.bV5SizeImage = BITMAPIMAGESIZE(pBitmapInfo);
- BitmapHeader.bV5ClrUsed = BITMAPCLRUSED(pBitmapInfo);
- BitmapHeader.bV5ClrImportant = BITMAPCLRIMPORTANT(pBitmapInfo);
- BitmapHeader.bV5RedMask = BITMAPREDMASK(pBitmapInfo);
- BitmapHeader.bV5GreenMask = BITMAPGREENMASK(pBitmapInfo);
- BitmapHeader.bV5BlueMask = BITMAPBLUEMASK(pBitmapInfo);
- BitmapHeader.bV5CSType = dwType;
- if (sizeof(BITMAPV4HEADER) <= *(LPDWORD)pBitmapInfo)
- {
- memcpy(&BitmapHeader.bV5Endpoints, &((PBITMAPV4HEADER)pBitmapInfo)->bV4Endpoints,
- sizeof(CIEXYZTRIPLE) + sizeof(DWORD) * 3);
- }
- BitmapHeader.bV5Intent = BITMAPINTENT(pBitmapInfo);
- BitmapHeader.bV5ProfileData = sizeof(BITMAPV5HEADER);
- BitmapHeader.bV5ProfileData += NumColorsInDIB(pBitmapInfo) * sizeof(RGBQUAD);
- BitmapHeader.bV5ProfileData += BITMAPSIZE(pBitmapInfo);
- BitmapHeader.bV5ProfileSize = dwProfileSize;
- WriteFile(hFile, &BitmapHeader, sizeof(BITMAPV5HEADER), &dwBytes, NULL);
- // Write color table.
- if (!IS_BITMAPCOREHEADER(pBitmapInfo))
- {
- PBYTE pColorTable;
- DWORD dwColorTableSize;
- dwColorTableSize = NumColorsInDIB(pBitmapInfo) * sizeof(RGBQUAD);
- pColorTable = (PBYTE)pBitmapInfo + *(LPDWORD)pBitmapInfo;
- if ( IS_BITMAPINFOHEADER(pBitmapInfo)
- &&
- (BI_BITFIELDS == BITMAPCOMPRESSION(pBitmapInfo))
- )
- {
- dwColorTableSize += sizeof(DWORD) * 3;
- }
- WriteFile(hFile, pColorTable, dwColorTableSize, &dwBytes, NULL);
- }
- else
- {
- PBYTE pColorTable;
- DWORD dwCount;
- RGBQUAD ColorTable[256];
- pColorTable = (PBYTE)pBitmapInfo + *(LPDWORD)pBitmapInfo;
- memset(ColorTable, 0, sizeof(ColorTable));
- for (dwCount = 0; dwCount < NumColorsInDIB(pBitmapInfo); dwCount++)
- memcpy(ColorTable + dwCount, pColorTable + dwCount, sizeof(RGBTRIPLE));
- WriteFile(hFile, ColorTable, NumColorsInDIB(pBitmapInfo) * sizeof(RGBQUAD), &dwBytes, NULL);
- }
- // Save bitmap data.
- WriteFile(hFile, FindDIBBits(pBitmapInfo), BITMAPSIZE(pBitmapInfo), &dwBytes, NULL);
- // Save profile data.
- if (0 != dwProfileSize)
- {
- WriteFile(hFile, pProfileData, dwProfileSize, &dwBytes, NULL);
- }
- bResult = TRUE;
- }
- // Clean up.
- CloseHandle(hFile);
- if (NULL != lpszProfileName)
- GlobalFree((HANDLE)lpszProfileName);
- if (NULL != hDIBTransformed)
- {
- GlobalUnlock(hDIBTransformed);
- GlobalFree(hDIBTransformed);
- }
- // If failed, delete file.
- if (!bResult)
- DeleteFile(lpszFileName);
- }
- //Clean up.
- GlobalUnlock(lpDIBInfo->hDIB);
- return bResult;
- }