/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORPORATION, 1998 * * TITLE: GPHELPER.CPP * * VERSION: 1.0 * * AUTHOR: ShaunIv * * DATE: 10/11/1999 * * DESCRIPTION: Encapsulation of common GDI plus operationss * *******************************************************************************/ #include "precomp.h" #pragma hdrstop #include "gphelper.h" #include #include using namespace Gdiplus; CGdiPlusHelper::CGdiPlusHelper(void) : m_pImageEncoderInfo(NULL), m_nImageEncoderCount(0), m_pImageDecoderInfo(NULL), m_nImageDecoderCount(0) { Initialize(); } CGdiPlusHelper::~CGdiPlusHelper(void) { Destroy(); } HRESULT CGdiPlusHelper::Initialize(void) { WIA_PUSHFUNCTION(TEXT("CGdiPlusHelper::Initialize")); // // Get the installed encoders // UINT cbCodecs = 0; HRESULT hr = GDISTATUS_TO_HRESULT(GetImageEncodersSize( &m_nImageEncoderCount, &cbCodecs )); if (SUCCEEDED(hr)) { if (cbCodecs) { m_pImageEncoderInfo = static_cast(LocalAlloc(LPTR,cbCodecs)); if (m_pImageEncoderInfo) { hr = GDISTATUS_TO_HRESULT(GetImageEncoders( m_nImageEncoderCount, cbCodecs, m_pImageEncoderInfo )); if (FAILED(hr)) { WIA_PRINTHRESULT((hr,TEXT("GetImageEncoders failed"))); } } else { hr = HRESULT_FROM_WIN32(GetLastError()); WIA_PRINTHRESULT((hr,TEXT("LocalAlloc failed"))); } } else { hr = E_INVALIDARG; WIA_PRINTHRESULT((hr,TEXT("GetImageEncodersSize succeeded, but cbCodecs was 0"))); } } else { WIA_PRINTHRESULT((hr,TEXT("GetImageEncodersSize failed"))); } // // Get the installed decoders // if (SUCCEEDED(hr)) { cbCodecs = 0; hr = GDISTATUS_TO_HRESULT(GetImageDecodersSize( &m_nImageDecoderCount, &cbCodecs )); if (SUCCEEDED(hr)) { if (cbCodecs) { m_pImageDecoderInfo = static_cast(LocalAlloc(LPTR,cbCodecs)); if (m_pImageDecoderInfo) { hr = GDISTATUS_TO_HRESULT(GetImageDecoders( m_nImageDecoderCount, cbCodecs, m_pImageDecoderInfo )); if (FAILED(hr)) { WIA_PRINTHRESULT((hr,TEXT("GetImageDecoders failed"))); } } else { hr = HRESULT_FROM_WIN32(GetLastError()); WIA_PRINTHRESULT((hr,TEXT("LocalAlloc failed"))); } } else { hr = E_INVALIDARG; WIA_PRINTHRESULT((hr,TEXT("GetImageDecodersSize succeeded, but cbCodecs was 0"))); } } else { WIA_PRINTHRESULT((hr,TEXT("GetImageDecodersSize failed"))); } } // // If there was a problem, make sure there are no half-initialized things laying around // if (!SUCCEEDED(hr)) { Destroy(); } return hr; } void CGdiPlusHelper::Destroy(void) { #if defined(GDIPLUSHELPER_EXPLICIT_INITIALIZATION) // // Shut down GDI+ // if (m_bGdiplusInitialized) { } #endif // // Free the lists of Encoders and Decoders // if (m_pImageEncoderInfo) { LocalFree(m_pImageEncoderInfo); m_pImageEncoderInfo = NULL; } m_nImageEncoderCount = 0; if (m_pImageDecoderInfo) { LocalFree(m_pImageDecoderInfo); m_pImageDecoderInfo = NULL; } m_nImageDecoderCount = 0; } bool CGdiPlusHelper::IsValid(void) const { // // Make sure we've been completely created // #if defined(GDIPLUSHELPER_EXPLICIT_INITIALIZATION) return(m_bGdiplusInitialized && m_pImageEncoderInfo && m_nImageEncoderCount && m_pImageDecoderInfo && m_nImageDecoderCount); #else return(m_pImageEncoderInfo && m_nImageEncoderCount && m_pImageDecoderInfo && m_nImageDecoderCount); #endif } HRESULT CGdiPlusHelper::GetClsidOfEncoder( const GUID &guidFormatId, CLSID &clsidFormat ) const { // // Given an image format, find the clsid for the output type // if (IsValid()) { for (UINT i=0;i(CopyImage( hSourceBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION )); if (hTargetBitmap) { hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); WIA_PRINTHRESULT((hr,TEXT("CopyImage failed"))); } } else { // // Create the source bitmap. No palette required, we assume it will always be a 24bit DIB. // Bitmap SourceBitmap( hSourceBitmap, NULL ); hr = GDISTATUS_TO_HRESULT(SourceBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get the image width and height // UINT nSourceWidth = SourceBitmap.GetWidth(); UINT nSourceHeight = SourceBitmap.GetHeight(); // // Make sure the width and height are non-zero // if (nSourceWidth && nSourceHeight) { // // Assume the target width and height are zero, so we can detect invalid rotation angles // UINT nTargetWidth = 0; UINT nTargetHeight = 0; RotateFlipType rotateFlipType = RotateNoneFlipNone; // // Find the transformation matrix for this rotation // switch (nRotationAngle % 360) { case -270: case 90: rotateFlipType = Rotate90FlipNone; nTargetWidth = nSourceHeight; nTargetHeight = nSourceWidth; break; case -180: case 180: rotateFlipType = Rotate180FlipNone; nTargetWidth = nSourceWidth; nTargetHeight = nSourceHeight; break; case -90: case 270: rotateFlipType = Rotate270FlipNone; nTargetWidth = nSourceHeight; nTargetHeight = nSourceWidth; break; } // // If either of these are zero, that means an invalid rotation was supplied // if (nTargetWidth && nTargetHeight) { // // Rotate the image // hr = GDISTATUS_TO_HRESULT(SourceBitmap.RotateFlip(rotateFlipType)); if (SUCCEEDED(hr)) { // // Create the target bitmap and make sure it succeeded // Bitmap TargetBitmap( nTargetWidth, nTargetHeight ); hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get a graphics to render to // Graphics *pGraphics = Graphics::FromImage(&TargetBitmap); if (pGraphics) { // // Make sure it is valid // hr = GDISTATUS_TO_HRESULT(pGraphics->GetLastStatus()); if (SUCCEEDED(hr)) { // // Draw image rotated to the graphics // hr = GDISTATUS_TO_HRESULT(pGraphics->DrawImage(&SourceBitmap,0,0)); if (SUCCEEDED(hr)) { // // Get the HBITMAP // hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetHBITMAP( Color::Black, &hTargetBitmap )); if (SUCCEEDED(hr)) { if (!hTargetBitmap) { WIA_ERROR((TEXT("hTargetBitmap was NULL"))); hr = E_FAIL; } } } } // // Clean up our dynamically allocated graphics // delete pGraphics; } else { WIA_ERROR((TEXT("pGraphics was NULL"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("TargetBitmap.GetLastStatus() failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("SourceBitmap.RotateFlip() failed"))); } } else { WIA_ERROR((TEXT("Invalid Target Bitmap Dimensions"))); hr = E_FAIL; } } else { WIA_ERROR((TEXT("Invalid Source Bitmap Dimensions"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("SourceBitmap.GetLastStatus() failed"))); } } // end else if nRotationAngle != 0 } else { WIA_ERROR((TEXT("hSourceBitmap was NULL"))); hr = E_INVALIDARG; } } else { WIA_ERROR((TEXT("IsValid() failed"))); } WIA_PRINTHRESULT((hr,TEXT("Returning"))); return hr; } HRESULT CGdiPlusHelper::LoadAndScale( HBITMAP &hTargetBitmap, IStream *pStream, UINT nMaxWidth, UINT nMaxHeight, bool bStretchSmallImages ) { HRESULT hr = E_FAIL; hTargetBitmap = NULL; // // Make sure we have a valid filename // if (pStream) { Bitmap SourceBitmap( pStream ); hr = GDISTATUS_TO_HRESULT(SourceBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get the image width and height // UINT nSourceWidth = SourceBitmap.GetWidth(); UINT nSourceHeight = SourceBitmap.GetHeight(); // // Make sure the width and height are non-zero // if (nSourceWidth && nSourceHeight) { // // // Assume the source dimensions are fine // UINT nTargetWidth = nSourceWidth; UINT nTargetHeight = nSourceHeight; // // If the height or the width exceed the allowed maximum, scale it down, or if we are allowing stretching // if (nMaxWidth > 0 && nMaxHeight > 0) { if ((nTargetWidth > nMaxWidth) || (nTargetHeight > nMaxHeight) || bStretchSmallImages) { SIZE sizeDesiredImageSize = PrintScanUtil::ScalePreserveAspectRatio( nMaxWidth, nMaxHeight, nTargetWidth, nTargetHeight ); nTargetWidth = sizeDesiredImageSize.cx; nTargetHeight = sizeDesiredImageSize.cy; } } // // Make sure we have valid sizes // if (nTargetWidth && nTargetHeight) { // // Create the target bitmap and make sure it succeeded // Bitmap TargetBitmap( nTargetWidth, nTargetHeight ); hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get a graphics to render to // Graphics *pGraphics = Graphics::FromImage(&TargetBitmap); if (pGraphics) { // // Make sure it is valid // hr = GDISTATUS_TO_HRESULT(pGraphics->GetLastStatus()); if (SUCCEEDED(hr)) { // // Draw scaled image // hr = GDISTATUS_TO_HRESULT(pGraphics->DrawImage(&SourceBitmap, 0, 0, nTargetWidth, nTargetHeight)); if (SUCCEEDED(hr)) { // // Get an HBITMAP for this image // hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetHBITMAP( Color::Black, &hTargetBitmap )); if (!hTargetBitmap) { WIA_ERROR((TEXT("hTargetBitmap was NULL"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("pGraphics->DrawImage failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("pGraphics->GetLastStatus() failed"))); } // // Clean up our dynamically allocated graphics // delete pGraphics; } else { hr = E_FAIL; WIA_ERROR((TEXT("pGraphics was NULL"))); } } else { WIA_PRINTHRESULT((hr,TEXT("TargetBitmap.GetLastStatus() is not OK"))); } } else { WIA_ERROR((TEXT("Invalid Target Bitmap Dimensions (%d,%d)"), nTargetWidth, nTargetHeight)); hr = E_FAIL; } } else { WIA_ERROR((TEXT("Invalid Source Bitmap Dimensions"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("SourceBitmap.GetLastStatus() failed"))); } } else { WIA_ERROR((TEXT("pStream was NULL"))); hr = E_INVALIDARG; } return hr; } HRESULT CGdiPlusHelper::LoadAndScale( HBITMAP &hTargetBitmap, LPCTSTR pszFilename, UINT nMaxWidth, UINT nMaxHeight, bool bStretchSmallImages ) { hTargetBitmap = NULL; HRESULT hr = E_FAIL; // // Make sure we have a valid filename // if (pszFilename && lstrlen(pszFilename)) { Bitmap SourceBitmap( CSimpleStringConvert::WideString(CSimpleString(pszFilename) ) ); hr = GDISTATUS_TO_HRESULT(SourceBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get the image width and height // UINT nSourceWidth = SourceBitmap.GetWidth(); UINT nSourceHeight = SourceBitmap.GetHeight(); // // Make sure the width and height are non-zero // if (nSourceWidth && nSourceHeight) { // // // Assume the source dimensions are fine // UINT nTargetWidth = nSourceWidth; UINT nTargetHeight = nSourceHeight; // // If the height or the width exceed the allowed maximum, scale it down, or if we are allowing stretching // if (nMaxWidth > 0 && nMaxHeight > 0) { if ((nTargetWidth > nMaxWidth) || (nTargetHeight > nMaxHeight) || bStretchSmallImages) { SIZE sizeDesiredImageSize = PrintScanUtil::ScalePreserveAspectRatio( nMaxWidth, nMaxHeight, nTargetWidth, nTargetHeight ); nTargetWidth = sizeDesiredImageSize.cx; nTargetHeight = sizeDesiredImageSize.cy; } } // // Make sure we have valid sizes // if (nTargetWidth && nTargetHeight) { // // Create the target bitmap and make sure it succeeded // Bitmap TargetBitmap( nTargetWidth, nTargetHeight ); hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get a graphics to render to // Graphics *pGraphics = Graphics::FromImage(&TargetBitmap); if (pGraphics) { // // Make sure it is valid // hr = GDISTATUS_TO_HRESULT(pGraphics->GetLastStatus()); if (SUCCEEDED(hr)) { // // Draw scaled image // hr = GDISTATUS_TO_HRESULT(pGraphics->DrawImage(&SourceBitmap, 0, 0, nTargetWidth, nTargetHeight)); if (SUCCEEDED(hr)) { // // Get an HBITMAP for this image // hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetHBITMAP( Color::Black, &hTargetBitmap )); if (SUCCEEDED(hr)) { if (!hTargetBitmap) { hr = E_FAIL; } } else { WIA_ERROR((TEXT("TargetBitmap.GetHBITMAP failed"))); } } else { WIA_ERROR((TEXT("pGraphics->DrawImage failed"))); } } else { WIA_ERROR((TEXT("pGraphics->GetLastStatus() failed"))); } // // Clean up our dynamically allocated graphics // delete pGraphics; } else { WIA_ERROR((TEXT("pGraphics was NULL"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("TargetBitmap.GetLastStatus() is not OK"))); } } else { WIA_ERROR((TEXT("Invalid Target Bitmap Dimensions (%d,%d)"), nTargetWidth, nTargetHeight)); hr = E_FAIL; } } else { WIA_ERROR((TEXT("Invalid Source Bitmap Dimensions"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("SourceBitmap.GetLastStatus() failed"))); } } else { WIA_ERROR((TEXT("hSourceBitmap was NULL"))); } return hr; } // // Construct a string like this: JPG;BMP;PNG with all supported extensions // HRESULT CGdiPlusHelper::ConstructCodecExtensionSearchStrings( CSimpleString &strExtensions, Gdiplus::ImageCodecInfo *pImageCodecInfo, UINT nImageCodecCount ) { for (UINT i=0;iParameter[pEncoderParameters->Count].Guid = guidProp; pEncoderParameters->Parameter[pEncoderParameters->Count].Type = nType; pEncoderParameters->Parameter[pEncoderParameters->Count].NumberOfValues = 1; pEncoderParameters->Parameter[pEncoderParameters->Count].Value = pVoid; pEncoderParameters->Count++; } return pEncoderParameters; } HRESULT CGdiPlusHelper::SaveMultipleImagesAsMultiPage( const CSimpleDynamicArray &Filenames, const CSimpleStringWide &strFilename, const GUID &guidOutputFormat ) { // // Assume failure // HRESULT hr = E_FAIL; // // Parameters used in the encoder // ULONG nEncoderValueMultiFrame = EncoderValueMultiFrame; ULONG nEncoderValueFrameDimensionPage = EncoderValueFrameDimensionPage; ULONG nEncoderValueLastFrame = EncoderValueLastFrame; // // Make sure we have some files // if (Filenames.Size()) { // // Get the encoder // CLSID clsidEncoder = IID_NULL; hr = GetClsidOfEncoder( guidOutputFormat, clsidEncoder ); if (SUCCEEDED(hr)) { // // Open the first image // Image SourceImage( Filenames[0] ); hr = GDISTATUS_TO_HRESULT(SourceImage.GetLastStatus()); if (SUCCEEDED(hr)) { EncoderParameters encoderParameters = {0}; if (Filenames.Size() > 1) { AppendEncoderParameter( &encoderParameters, EncoderSaveFlag, EncoderParameterValueTypeLong, &nEncoderValueMultiFrame ); } // // Save the first page // hr = GDISTATUS_TO_HRESULT(SourceImage.Save( strFilename, &clsidEncoder, &encoderParameters )); if (SUCCEEDED(hr)) { // // Save each additional page // for (int i=1;i 0.95f) { fBrightness = 0.95f; /* clamp */ } // // get current contrast as a percentage of full scale // float fContrast = (float) iContrast / 100.0f; if (fContrast > 1.0f) { fContrast = 1.0; /* limit to 1.0 */ } // // convert contrast to a scale value // if (fContrast <= 0.5f) { *scale = fContrast / 0.5f; /* 0 -> 0, .5 -> 1.0 */ } else { if (fContrast == 1.0f) { fContrast = 0.9999f; } *scale = 0.5f / (1.0f - fContrast); /* .5 -> 1.0, 1.0 -> inf */ } *translate = 0.5f - *scale * fBrightness; } HRESULT CGdiPlusHelper::SetBrightnessAndContrast( HBITMAP hSourceBitmap, HBITMAP &hTargetBitmap, BYTE nBrightness, BYTE nContrast ) { WIA_TRACE((TEXT("nBrightness: %d, nContrast: %d"), nBrightness, nContrast )); // // Initialize the result to NULL // hTargetBitmap = NULL; // // Assume failure // HRESULT hr = E_FAIL; // // Make sure we are in a valid state // if (IsValid()) { // // Make sure we have a valid source bitmap // if (hSourceBitmap) { // // Create the source bitmap. No palette required, we assume it will always be a 24bit DIB. // Bitmap SourceBitmap( hSourceBitmap, NULL ); hr = GDISTATUS_TO_HRESULT(SourceBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Create the target bitmap and make sure it succeeded // Bitmap TargetBitmap( SourceBitmap.GetWidth(), SourceBitmap.GetHeight() ); hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get a graphics to render to // Graphics *pGraphics = Graphics::FromImage(&TargetBitmap); if (pGraphics) { // // Make sure it is valid // hr = GDISTATUS_TO_HRESULT(pGraphics->GetLastStatus()); if (SUCCEEDED(hr)) { ImageAttributes imageAttributes; // // Calculate the values needed for the matrix // REAL scale = 0.0; REAL trans = 0.0; CalculateBrightnessAndContrastParams( nBrightness, nContrast, &scale, &trans ); // // Prepare the matrix for brightness and contrast transforms // ColorMatrix brightnessAndContrast = {scale, 0, 0, 0, 0, 0, scale, 0, 0, 0, 0, 0, scale, 0, 0, 0, 0, 0, 1, 0, trans, trans, trans, 0, 1}; imageAttributes.SetColorMatrix(&brightnessAndContrast); Rect rect( 0, 0, SourceBitmap.GetWidth(), SourceBitmap.GetHeight() ); // // Draw the transformed image on the graphics // hr = GDISTATUS_TO_HRESULT(pGraphics->DrawImage(&SourceBitmap,rect,0,0,SourceBitmap.GetWidth(), SourceBitmap.GetHeight(),UnitPixel,&imageAttributes)); if (SUCCEEDED(hr)) { // // Get the HBITMAP // hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetHBITMAP( Color::Black, &hTargetBitmap )); if (SUCCEEDED(hr)) { if (!hTargetBitmap) { WIA_ERROR((TEXT("hTargetBitmap was NULL"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("Bitmap::GetHBITMAP failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("pGraphics->DrawImage failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("pGraphics->GetLastStatus() failed"))); } // // Clean up our dynamically allocated graphics // delete pGraphics; } else { WIA_ERROR((TEXT("pGraphics was NULL"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("TargetBitmap.GetLastStatus() failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("SourceBitmap.GetLastStatus() failed"))); } } else { WIA_ERROR((TEXT("hSourceBitmap was NULL"))); hr = E_FAIL; } } else { WIA_ERROR((TEXT("IsValid() returned false"))); hr = E_FAIL; } WIA_PRINTHRESULT((hr,TEXT("Returning"))); return hr; } HRESULT CGdiPlusHelper::SetThreshold( HBITMAP hSourceBitmap, HBITMAP &hTargetBitmap, BYTE nThreshold ) { // // Initialize the result to NULL // hTargetBitmap = NULL; // // Assume failure // HRESULT hr = E_FAIL; // // Make sure we are in a valid state // if (IsValid()) { // // Make sure we have a valid source bitmap // if (hSourceBitmap) { // // Create the source bitmap. No palette required, we assume it will always be a 24bit DIB. // Bitmap SourceBitmap( hSourceBitmap, NULL ); hr = GDISTATUS_TO_HRESULT(SourceBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Create the target bitmap and make sure it succeeded // Bitmap TargetBitmap( SourceBitmap.GetWidth(), SourceBitmap.GetHeight() ); hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetLastStatus()); if (SUCCEEDED(hr)) { // // Get a graphics to render to // Graphics *pGraphics = Graphics::FromImage(&TargetBitmap); if (pGraphics) { // // Make sure it is valid // hr = GDISTATUS_TO_HRESULT(pGraphics->GetLastStatus()); if (SUCCEEDED(hr)) { ImageAttributes imageAttributes; imageAttributes.SetThreshold(static_cast(100-nThreshold)/100); Rect rect( 0, 0, SourceBitmap.GetWidth(), SourceBitmap.GetHeight() ); // // Draw image rotated to the graphics // hr = GDISTATUS_TO_HRESULT(pGraphics->DrawImage(&SourceBitmap,rect,0,0,SourceBitmap.GetWidth(), SourceBitmap.GetHeight(),UnitPixel,&imageAttributes)); if (SUCCEEDED(hr)) { // // Get the HBITMAP // hr = GDISTATUS_TO_HRESULT(TargetBitmap.GetHBITMAP( Color::Black, &hTargetBitmap )); if (SUCCEEDED(hr)) { if (!hTargetBitmap) { WIA_ERROR((TEXT("hTargetBitmap was NULL"))); hr = E_FAIL; } } else { WIA_PRINTHRESULT((hr,TEXT("Bitmap::GetHBITMAP failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("pGraphics->DrawImage failed"))); } } else { WIA_PRINTHRESULT((hr,TEXT("pGraphics->GetLastStatus() failed"))); } // // Clean up our dynamically allocated graphics // delete pGraphics; } else { WIA_ERROR((TEXT("pGraphics was NULL"))); hr = E_FAIL; } } } else { WIA_PRINTHRESULT((hr,TEXT("SourceBitmap.GetLastStatus() failed"))); } } else { WIA_ERROR((TEXT("hSourceBitmap was NULL"))); hr = E_FAIL; } } WIA_PRINTHRESULT((hr,TEXT("Returning"))); return hr; } CImageFileFormatVerifier::CImageFileFormatVerifierItem::CImageFileFormatVerifierItem(void) : m_pSignature(NULL), m_pMask(NULL), m_nLength(0), m_guidFormat(IID_NULL), m_clsidDecoder(IID_NULL) { } CImageFileFormatVerifier::CImageFileFormatVerifierItem::CImageFileFormatVerifierItem( const PBYTE pSignature, const PBYTE pMask, int nLength, const GUID &guidFormat, const CLSID &guidDecoder ) : m_pSignature(NULL), m_pMask(NULL), m_nLength(0), m_guidFormat(IID_NULL), m_clsidDecoder(IID_NULL) { Assign( pSignature, pMask, nLength, guidFormat, guidDecoder ); } CImageFileFormatVerifier::CImageFileFormatVerifierItem::CImageFileFormatVerifierItem( const CImageFileFormatVerifierItem &other ) : m_pSignature(NULL), m_pMask(NULL), m_nLength(0), m_guidFormat(IID_NULL), m_clsidDecoder(IID_NULL) { Assign( other.Signature(), other.Mask(), other.Length(), other.Format(), other.Decoder() ); } CImageFileFormatVerifier::CImageFileFormatVerifierItem &CImageFileFormatVerifier::CImageFileFormatVerifierItem::operator=( const CImageFileFormatVerifierItem &other ) { if (this != &other) { return Assign( other.Signature(), other.Mask(), other.Length(), other.Format(), other.Decoder() ); } else return *this; } CImageFileFormatVerifier::CImageFileFormatVerifierItem &CImageFileFormatVerifier::CImageFileFormatVerifierItem::Assign( const PBYTE pSignature, const PBYTE pMask, int nLength, const GUID &guidFormat, const CLSID &clsidDecoder ) { Destroy(); bool bOK = false; m_nLength = nLength; m_guidFormat = guidFormat; m_clsidDecoder = clsidDecoder; if (nLength && pSignature && pMask) { m_pSignature = new BYTE[nLength]; m_pMask = new BYTE[nLength]; if (m_pSignature && m_pMask) { CopyMemory( m_pSignature, pSignature, nLength ); CopyMemory( m_pMask, pMask, nLength ); bOK = true; } } if (!bOK) Destroy(); return *this; } void CImageFileFormatVerifier::CImageFileFormatVerifierItem::Destroy(void) { if (m_pSignature) delete[] m_pSignature; m_pSignature = NULL; if (m_pMask) delete[] m_pMask; m_pMask = NULL; m_nLength = 0; m_guidFormat = IID_NULL; m_clsidDecoder = IID_NULL; } CImageFileFormatVerifier::CImageFileFormatVerifierItem::~CImageFileFormatVerifierItem(void) { Destroy(); } PBYTE CImageFileFormatVerifier::CImageFileFormatVerifierItem::Signature(void) const { return m_pSignature; } PBYTE CImageFileFormatVerifier::CImageFileFormatVerifierItem::Mask(void) const { return m_pMask; } int CImageFileFormatVerifier::CImageFileFormatVerifierItem::Length(void) const { return m_nLength; } GUID CImageFileFormatVerifier::CImageFileFormatVerifierItem::Format(void) const { return m_guidFormat; } CLSID CImageFileFormatVerifier::CImageFileFormatVerifierItem::Decoder(void) const { return m_clsidDecoder; } bool CImageFileFormatVerifier::CImageFileFormatVerifierItem::Match( PBYTE pBytes, int nLen ) const { WIA_PUSH_FUNCTION((TEXT("CImageFileFormatVerifierItem::Match"))); WIA_PRINTGUID((m_clsidDecoder,TEXT("Decoder"))); if (nLen < Length()) { return false; } for (int i=0;i(LocalAlloc(LPTR,cbCodecs)); if (pImageDecoderInfo) { // // Get the actual decoder info // if (Gdiplus::Ok == Gdiplus::GetImageDecoders( nImageDecoderCount, cbCodecs, pImageDecoderInfo )) { // // Add each decoder to the format list // for (UINT i=0;i m_nMaxSignatureLength) { m_nMaxSignatureLength = m_FileFormatVerifierList[i].Length(); } } // // If we have a valid max length, allocate a buffer to hold the file's data // if (m_nMaxSignatureLength) { m_pSignatureBuffer = new BYTE[m_nMaxSignatureLength]; } // // If anything failed, free everything // if (!IsValid()) { Destroy(); } } void CImageFileFormatVerifier::Destroy(void) { // // Free the file signature buffer // if (m_pSignatureBuffer) { delete[] m_pSignatureBuffer; m_pSignatureBuffer = NULL; } m_nMaxSignatureLength = 0; m_FileFormatVerifierList.Destroy(); } bool CImageFileFormatVerifier::IsValid(void) const { return (m_pSignatureBuffer && m_nMaxSignatureLength && m_FileFormatVerifierList.Size()); } CImageFileFormatVerifier::~CImageFileFormatVerifier(void) { Destroy(); } GUID CImageFileFormatVerifier::GetImageType( IStream * pStream ) { WIA_PUSH_FUNCTION((TEXT("CImageFileFormatVerifier::GetImageType( via IStream )"))); // // Assume we will not find a match // GUID guidResult = IID_NULL; // // Make sure we have a valid IStream object... // if (pStream) { // // Read the maximum signature length number of bytes // ULONG uBytesRead = 0; HRESULT hr = pStream->Read( m_pSignatureBuffer, m_nMaxSignatureLength, &uBytesRead ); // // Make sure we got some bytes // if (SUCCEEDED(hr) && uBytesRead) { // // Go though the list and try to find a match // for (int i=0;iRead() failed w/hr = 0x%x"),hr)); } } else { WIA_ERROR((TEXT("pStream was NULL"))); } // // This will contain IID_NULL if no matching image type was found // return guidResult; } bool CImageFileFormatVerifier::IsImageFile( LPCTSTR pszFilename ) { WIA_PUSH_FUNCTION((TEXT("CImageFileFormatVerifier::IsImageFile(%s)"),pszFilename)); GUID guidImageType = IID_NULL; // // Get a stream object over the file... // IStream * pStream = NULL; HRESULT hr = SHCreateStreamOnFile(pszFilename, STGM_READ | STGM_SHARE_DENY_WRITE, &pStream ); if (SUCCEEDED(hr) && pStream) { guidImageType = GetImageType(pStream); } if (pStream) { pStream->Release(); } WIA_PRINTGUID((guidImageType,TEXT("guidImageType"))); // // If the image type is IID_NULL, it isn't an image // return ((IID_NULL != guidImageType) != FALSE); } bool CImageFileFormatVerifier::IsSupportedImageFromStream( IStream * pStream, GUID * pGuidOfFormat ) { WIA_PUSH_FUNCTION((TEXT("CImageFileFormatVerifier::IsSupportedImageFromStream()"))); GUID guidImageType = IID_NULL; // // Get an IStream pointer for this file... // if (pStream) { guidImageType = GetImageType(pStream); } WIA_PRINTGUID((guidImageType,TEXT("guidImageType"))); if (pGuidOfFormat) { *pGuidOfFormat = guidImageType; } // // If the image type is IID_NULL, it isn't an image // return ((IID_NULL != guidImageType) != FALSE); } CGdiPlusInit::CGdiPlusInit() : m_pGdiplusToken(NULL) { // // Make sure GDI+ is initialized // GdiplusStartupInput StartupInput; GdiplusStartup(&m_pGdiplusToken,&StartupInput,NULL); } CGdiPlusInit::~CGdiPlusInit() { GdiplusShutdown(m_pGdiplusToken); }