mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
2411 lines
67 KiB
C++
2411 lines
67 KiB
C++
#pragma once
|
||
|
||
#include "resource.h"
|
||
#include <atlsafe.h>
|
||
#include <comdef.h>
|
||
#include <stdio.h>
|
||
#include <gdiplusex.h>
|
||
#include <graydither.h>
|
||
#include <math.h>
|
||
#include <imagestudioutils.h>
|
||
#include "pcx.h"
|
||
#include "ras.h"
|
||
#include "tga.h"
|
||
#include "j2k.h"
|
||
#include "MetaData.h"
|
||
#include <ImageIO.h>
|
||
#include <MemoryUtils.h>
|
||
|
||
#include "../Common/ImageFileFormatChecker.h"
|
||
|
||
// TODO: #define DISABLE_REGISTRATION
|
||
|
||
const int c_nBitmapType32bpp = 0;
|
||
const int c_nBitmapType24bpp = 1;
|
||
const int c_nBitmapType8bppLightness = 2;
|
||
const int c_nBitmapType8bppIntensity = 3;
|
||
const int c_nBitmapType8bppBrightness = 4;
|
||
const int c_nBitmapType1bpp = 5;
|
||
const int c_nBitmapType1bppDither = 6;
|
||
|
||
const int c_nTiffCompressionNone = 0;
|
||
const int c_nTiffCompressionLzw = 1;
|
||
const int c_nTiffCompressionRle = 2;
|
||
const int c_nTiffCompressionCCITT3 = 3;
|
||
const int c_nTiffCompressionCCITT4 = 4;
|
||
|
||
[object, uuid("7879A2A8-02D0-48a7-929D-1316FC6C97AA"), dual, pointer_default(unique)]
|
||
__interface IImageFile3 : IDispatch
|
||
{
|
||
[id(11)] HRESULT LoadImage([in] BSTR Path, [out, satype("BYTE")] SAFEARRAY** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(12)] HRESULT LoadPicture([in] IPictureDisp* Picture, [out, satype("BYTE")] SAFEARRAY** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(13)] HRESULT LoadScreenshot([out, satype("BYTE")] SAFEARRAY** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(14)] HRESULT LoadFrame([in] BSTR Path, [in] long Frame, [out, satype("BYTE")] SAFEARRAY** Image, [out, retval] VARIANT_BOOL* Success);
|
||
|
||
[id(20)] HRESULT GetFrameCount([in] BSTR Path, [out, retval] long* Count);
|
||
|
||
[id(50)] HRESULT SaveAsBmp([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(51)] HRESULT SaveAsGif([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(52)] HRESULT SaveAsJpeg([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(53)] HRESULT SaveAsPng([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(54)] HRESULT SaveAsTiff([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(55)] HRESULT SaveAsWmf([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(56)] HRESULT SaveAsEmf([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(57)] HRESULT SaveAsPcx([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(58)] HRESULT SaveAsTga([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(59)] HRESULT SaveAsRas([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(60)] HRESULT SaveAsJ2k([in, satype("BYTE")] SAFEARRAY** Image, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
|
||
[id(80)] HRESULT SavePicture([in, satype("BYTE")] SAFEARRAY** Image, [out] IPictureDisp** Picture, [out, retval] VARIANT_BOOL* Success);
|
||
[id(81)] HRESULT SaveFrame([in, satype("BYTE")] SAFEARRAY** Image, [in] VARIANT_BOOL LastFrame, [out, retval] VARIANT_BOOL* Success);
|
||
|
||
[id(101), propget] HRESULT JpegQuality([out, retval] long *Quality);
|
||
[id(101), propput] HRESULT JpegQuality([in] long Quality);
|
||
[id(102), propget] HRESULT TiffCompression([out, retval] long *Compression);
|
||
[id(102), propput] HRESULT TiffCompression([in] long Compression);
|
||
[id(103), propget] HRESULT TiffMultipaged([out, retval] VARIANT_BOOL *Multipaged);
|
||
[id(103), propput] HRESULT TiffMultipaged([in] VARIANT_BOOL Multipaged);
|
||
[id(104), propget] HRESULT BitmapType([out, retval] long *Type);
|
||
[id(104), propput] HRESULT BitmapType([in] long Type);
|
||
|
||
[id(1000), propget] HRESULT InfoTitle([out, retval] BSTR* Value);
|
||
[id(1000), propput] HRESULT InfoTitle([in] BSTR Value);
|
||
[id(1001), propget] HRESULT InfoDescription([out, retval] BSTR* Value);
|
||
[id(1001), propput] HRESULT InfoDescription([in] BSTR Value);
|
||
[id(1002), propget] HRESULT InfoDateTime([out, retval] BSTR* Value);
|
||
[id(1002), propput] HRESULT InfoDateTime([in] BSTR Value);
|
||
[id(1003), propget] HRESULT InfoAuthor([out, retval] BSTR* Value);
|
||
[id(1003), propput] HRESULT InfoAuthor([in] BSTR Value);
|
||
[id(1004), propget] HRESULT InfoCopyright([out, retval] BSTR* Value);
|
||
[id(1004), propput] HRESULT InfoCopyright([in] BSTR Value);
|
||
[id(1005), propget] HRESULT InfoEquipmentType([out, retval] BSTR* Value);
|
||
[id(1005), propput] HRESULT InfoEquipmentType([in] BSTR Value);
|
||
[id(1006), propget] HRESULT InfoEquipmentModel([out, retval] BSTR* Value);
|
||
[id(1006), propput] HRESULT InfoEquipmentModel([in] BSTR Value);
|
||
[id(1007), propget] HRESULT InfoVerticalResolution([out, retval] double* Value);
|
||
[id(1007), propput] HRESULT InfoVerticalResolution([in] double Value);
|
||
[id(1008), propget] HRESULT InfoHorizontalResolution([out, retval] double* Value);
|
||
[id(1008), propput] HRESULT InfoHorizontalResolution([in] double Value);
|
||
|
||
// new version
|
||
[id(10011)] HRESULT LoadImage2([in] BSTR Path, [out] IUnknown** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(10012)] HRESULT LoadPicture2([in] IPictureDisp* Picture, [out] IUnknown** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(10013)] HRESULT LoadScreenshot2([out] IUnknown** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(10014)] HRESULT LoadFrame2([in] BSTR Path, [in] long Frame, [out] IUnknown** Image, [out, retval] VARIANT_BOOL* Success);
|
||
[id(10050)] HRESULT SaveImage2([in] IUnknown** Image, [in] LONG Format, [in] BSTR Path, [out, retval] VARIANT_BOOL* Success);
|
||
[id(10080)] HRESULT SavePicture2([in] IUnknown** Image, [out] IPictureDisp** Picture, [out, retval] VARIANT_BOOL* Success);
|
||
[id(10081)] HRESULT SaveFrame2([in] IUnknown** Image, [in] VARIANT_BOOL LastFrame, [out, retval] VARIANT_BOOL* Success);
|
||
};
|
||
|
||
|
||
[
|
||
object,
|
||
uuid("B67C0F8F-C9F5-4398-B10D-3A7AB31A9BC6"), dual,
|
||
helpstring("IImageMetaData Interface"),
|
||
pointer_default(unique)
|
||
]
|
||
__interface IImageMetaData : IDispatch
|
||
{
|
||
[id(1), helpstring("method SetMetaData")] HRESULT SetMetaData([in] BSTR bsMetaDataXML);
|
||
[id(2), helpstring("method GetMetaData")] HRESULT GetMetaData([out] BSTR * bsMetaDataXML);
|
||
[id(3), helpstring("method MetaDataFromFile")] HRESULT MetaDataFromFile([in] BSTR Path);
|
||
|
||
[id(101), helpstring("method SetAdditionalParam")] HRESULT SetAdditionalParam([in] BSTR ParamName, [in] VARIANT ParamValue);
|
||
[id(102), helpstring("method GetAdditionalParam")] HRESULT GetAdditionalParam([in] BSTR ParamName, [out] VARIANT * ParamValue);
|
||
|
||
};
|
||
|
||
[coclass, uuid("837801EA-28BC-4777-8484-C57A3BE57BAC"), threading(apartment), vi_progid("AVSImageFile3.ImageFile3"), progid("AVSImageFile3.ImageFile3.1"), version(1.0)]
|
||
class ATL_NO_VTABLE ImageFile3 : public IImageFile3, public IImageMetaData
|
||
{
|
||
protected:
|
||
|
||
CGdiPlusInit m_oGdiPlusInit;
|
||
|
||
Bitmap* m_bitmap;
|
||
|
||
int m_nMultipagedFormat; // 0 - Tiff, 1 - GIF <20><><EFBFBD> APNG
|
||
double m_dAnimationDuration; //<2F> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
long m_nAnimationWidth;
|
||
long m_nAnimationHeight;
|
||
bool m_bAnimationGifWithAlpha;
|
||
|
||
long m_JpegQuality;
|
||
long m_BitmapType;
|
||
long m_TiffCompression;
|
||
VARIANT_BOOL m_TiffMultipaged;
|
||
VARIANT_BOOL m_UpdateSize;
|
||
|
||
BYTE* m_backup;
|
||
BYTE* m_palette;
|
||
|
||
CString m_strInfoXML;
|
||
// information
|
||
CString m_InfoTitle;
|
||
CString m_InfoDescription; // Comment
|
||
CString m_InfoDateTime;
|
||
CString m_InfoAuthor;
|
||
CString m_InfoCopyright;
|
||
CString m_InfoEquipmentType;
|
||
CString m_InfoEquipmentModel;
|
||
|
||
CString m_InfoJobTime;
|
||
CString m_InfoJobName;
|
||
CString m_InfoSofftwareID;
|
||
CString m_InfoSoftwareVersion;
|
||
CString m_InfoHostComputer;
|
||
CString m_InfoWarning;
|
||
|
||
double m_InfoVerticalResolution;
|
||
double m_InfoHorizontalResolution;
|
||
double m_InfoVerticalResolutionStorage;
|
||
double m_InfoHorizontalResolutionStorage;
|
||
short m_InfoResolutionUnit;
|
||
short m_InfoResolutionUnitX;
|
||
short m_InfoResolutionUnitY;
|
||
short m_InfoOrientation;
|
||
short m_InfoImageWidth;
|
||
short m_InfoImageHeight;
|
||
|
||
MemoryUtils::CMemoryUtils m_oMemoryUtils;
|
||
|
||
CMetaData m_oMetaData;
|
||
|
||
protected:
|
||
|
||
ImageFile3()
|
||
{
|
||
m_oGdiPlusInit.Init();
|
||
|
||
// setup default values
|
||
m_bitmap = 0;
|
||
|
||
m_nMultipagedFormat = 0;
|
||
m_dAnimationDuration = 1000;
|
||
m_nAnimationWidth = -1;
|
||
m_nAnimationHeight = -1;
|
||
m_bAnimationGifWithAlpha = false;
|
||
m_JpegQuality = 75;
|
||
m_BitmapType = c_nBitmapType24bpp;
|
||
m_TiffCompression = 0;
|
||
m_TiffMultipaged = VARIANT_FALSE;
|
||
m_UpdateSize = VARIANT_FALSE;
|
||
|
||
m_backup = 0;
|
||
m_palette = new BYTE[258*4];
|
||
|
||
// setup default information
|
||
m_InfoTitle = _T("");
|
||
m_InfoDescription = _T("");
|
||
m_InfoDateTime = _T("");
|
||
m_InfoAuthor = _T("");
|
||
m_InfoCopyright = _T("");
|
||
m_InfoEquipmentType = _T("");
|
||
m_InfoEquipmentModel = _T("");
|
||
m_InfoVerticalResolution = -1;
|
||
m_InfoHorizontalResolution = -1;
|
||
m_InfoResolutionUnit = 2;
|
||
m_InfoResolutionUnitX = 1;
|
||
m_InfoResolutionUnitY = 1;
|
||
m_InfoOrientation = 1;
|
||
|
||
m_strInfoXML = _T("");
|
||
}
|
||
~ImageFile3()
|
||
{
|
||
// delete existing memory
|
||
ClearBitmap();
|
||
|
||
ClearBackup();
|
||
|
||
if (m_palette)
|
||
{
|
||
delete[] m_palette;
|
||
m_palette = 0;
|
||
}
|
||
}
|
||
|
||
void ClearBackup()
|
||
{
|
||
if (m_backup)
|
||
{
|
||
delete[] m_backup;
|
||
m_backup = 0;
|
||
}
|
||
}
|
||
void ClearBitmap()
|
||
{
|
||
if (m_bitmap)
|
||
{
|
||
delete m_bitmap;
|
||
m_bitmap = 0;
|
||
}
|
||
}
|
||
|
||
void ArrayToImage(void** Image, Bitmap** pBitmap, int nType = c_nBitmapType32bpp)
|
||
{
|
||
SAFEARRAY** pArray = (SAFEARRAY**) Image;
|
||
|
||
// check for valid input parameters
|
||
if (!pArray || !pBitmap)
|
||
throw 0;
|
||
|
||
// attach ATL wrapper
|
||
CComSafeArray<BYTE> safeArray; safeArray.Attach(*pArray);
|
||
|
||
// check for valid pixel array size
|
||
if (safeArray.GetDimensions() != 3 || safeArray.GetType() != VT_UI1)
|
||
{
|
||
safeArray.Detach();
|
||
throw 0;
|
||
}
|
||
|
||
// retrieve image attributes
|
||
long nChannels = safeArray.GetCount(0);
|
||
long nWidth = safeArray.GetCount(1);
|
||
long nHeight = safeArray.GetCount(2);
|
||
BYTE* pSource = (BYTE*)(safeArray.m_psa->pvData);
|
||
|
||
// copy memory to image
|
||
if (!MemoryToImage(pSource, pBitmap, nType, nWidth, nHeight, nChannels))
|
||
{
|
||
safeArray.Detach();
|
||
throw 0;
|
||
}
|
||
|
||
// detach the array
|
||
safeArray.Detach();
|
||
}
|
||
void InterfaceToImage(void** Image, Bitmap** pBitmap, int nType = c_nBitmapType32bpp)
|
||
{
|
||
IUnknown** pInterface = (IUnknown**)Image;
|
||
|
||
// check for valid input parameters
|
||
if (!pInterface || !*pInterface)
|
||
throw 0;
|
||
|
||
int nWidth = 0;
|
||
int nHeight = 0;
|
||
BYTE* pPixels = 0;
|
||
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL;
|
||
if (!ImageStudioUtils::MediaDataToByteArray(pInterface, pMediaData, pPixels, nWidth, nHeight))
|
||
throw 0;
|
||
|
||
Bitmap* pGdiImage = NULL;
|
||
|
||
if (!MemoryToImage(pPixels, &pGdiImage/*pBitmap*/, nType, nWidth, nHeight, 4))
|
||
{
|
||
pMediaData->Release();
|
||
throw 0;
|
||
}
|
||
|
||
long nAspectX = pMediaData->GetAspectRatioX();
|
||
long nAspectY = pMediaData->GetAspectRatioY();
|
||
long nNewWidth = nWidth;
|
||
long nNewHeight = nWidth * nAspectY / nAspectX;
|
||
|
||
*pBitmap = new Bitmap( nNewWidth, nNewHeight, PixelFormat32bppARGB );
|
||
if( Gdiplus::Ok == (*pBitmap)->GetLastStatus() )
|
||
{
|
||
Gdiplus::Graphics oRender( *pBitmap );
|
||
if( Gdiplus::Ok == oRender.GetLastStatus() )
|
||
{
|
||
oRender.DrawImage( pGdiImage, Rect(0, 0, nNewWidth, nNewHeight), 0, 0, nWidth, nHeight, Gdiplus::Unit::UnitPixel );
|
||
|
||
delete pGdiImage;
|
||
pMediaData->Release();
|
||
|
||
return;
|
||
}
|
||
delete pBitmap;
|
||
}
|
||
|
||
*pBitmap = pGdiImage;
|
||
|
||
pMediaData->Release();
|
||
}
|
||
BOOL MemoryToImage(BYTE* pSource, Bitmap** pBitmap, int nType, long nWidth, long nHeight, long nChannels)
|
||
{
|
||
// check for valid input parameters
|
||
if (!pSource || !pBitmap)
|
||
return FALSE;
|
||
|
||
// check for vlaid image size
|
||
if (nChannels != 4 || nWidth < 1 || nHeight < 1)
|
||
return FALSE;
|
||
|
||
// clear existing memory
|
||
ClearBackup();
|
||
|
||
// create output image
|
||
if (nType == c_nBitmapType32bpp)
|
||
{
|
||
m_backup = new BYTE[4*nWidth*nHeight]; ZeroMemory(m_backup, 4*nWidth*nHeight);
|
||
|
||
memcpy(m_backup, pSource, 4*nWidth*nHeight);
|
||
|
||
(*pBitmap) = new Bitmap(nWidth, nHeight, nWidth * 4, PixelFormat32bppARGB, m_backup);
|
||
}
|
||
else if (nType == c_nBitmapType24bpp)
|
||
{
|
||
int nLineSize = ImageStudioUtils::WidthBytes(24*nWidth);
|
||
|
||
m_backup = new BYTE[nLineSize*nHeight]; ZeroMemory(m_backup, nLineSize*nHeight);
|
||
|
||
for (int nY = 0; nY < nHeight; ++nY)
|
||
{
|
||
// reset bit index and bits
|
||
BYTE* pResult = m_backup + nLineSize*nY;
|
||
int nIndex = nY*4*nWidth;
|
||
|
||
// convert all colors to 1-bit values
|
||
for (int nX = 0; nX < nWidth; ++nX, nIndex += 4, pResult += 3)
|
||
{
|
||
pResult[2] = pSource[nIndex + 2];
|
||
pResult[1] = pSource[nIndex + 1];
|
||
pResult[0] = pSource[nIndex + 0];
|
||
}
|
||
}
|
||
|
||
(*pBitmap) = new Bitmap(nWidth, nHeight, nLineSize, PixelFormat24bppRGB, m_backup);
|
||
}
|
||
else if (nType == c_nBitmapType8bppLightness || nType == c_nBitmapType8bppBrightness || nType == c_nBitmapType8bppIntensity)
|
||
{
|
||
int nLineSize = ImageStudioUtils::WidthBytes(8*nWidth);
|
||
|
||
m_backup = new BYTE[nLineSize*nHeight]; ZeroMemory(m_backup, nLineSize*nHeight);
|
||
|
||
for (int nY = 0; nY < nHeight; ++nY)
|
||
{
|
||
// reset bit index and bits
|
||
BYTE* pResult = m_backup + nLineSize*nY;
|
||
int nIndex = nY*4*nWidth;
|
||
|
||
// convert all colors to 1-bit values
|
||
for (int nX = 0; nX < nWidth; ++nX, nIndex += 4, pResult++)
|
||
{
|
||
if (nType == c_nBitmapType8bppIntensity)
|
||
*pResult = ImageStudioUtils::GetIntensity(pSource[nIndex + 2], pSource[nIndex + 1], pSource[nIndex + 0]);
|
||
else if (nType == c_nBitmapType8bppLightness)
|
||
*pResult = ImageStudioUtils::GetLightness(pSource[nIndex + 2], pSource[nIndex + 1], pSource[nIndex + 0]);
|
||
else if (nType == c_nBitmapType8bppBrightness)
|
||
*pResult = ImageStudioUtils::GetBrightness(pSource[nIndex + 2], pSource[nIndex + 1], pSource[nIndex + 0]);
|
||
}
|
||
}
|
||
|
||
// create image
|
||
(*pBitmap) = new Bitmap(nWidth, nHeight, nLineSize, PixelFormat8bppIndexed, m_backup);
|
||
|
||
// variables
|
||
UINT* pPalette = (UINT*)m_palette;
|
||
|
||
// compose grayscale palette
|
||
*pPalette = PaletteFlagsGrayScale; pPalette++;
|
||
*pPalette = 256; pPalette++;
|
||
for (int nIndex = 0; nIndex < 255; ++nIndex, ++pPalette)
|
||
*pPalette = RGB(nIndex, nIndex, nIndex);
|
||
|
||
// set the palette to the image
|
||
(*pBitmap)->SetPalette((ColorPalette*)m_palette);
|
||
}
|
||
else
|
||
{
|
||
// dither image if necessary
|
||
if (nType == c_nBitmapType1bppDither)
|
||
Dither32Image(pSource, nWidth, nHeight);
|
||
|
||
int nLineSize = ImageStudioUtils::WidthBytes(nWidth);
|
||
|
||
m_backup = new BYTE[nLineSize*nHeight]; ZeroMemory(m_backup, nLineSize*nHeight);
|
||
|
||
// fill the memory
|
||
for (int nY = 0; nY < nHeight; ++nY)
|
||
{
|
||
// reset bit index and bits
|
||
int nBitIndex = 0;
|
||
BYTE* pResult = m_backup + nLineSize*nY;
|
||
int nIndex = nY*4*nWidth;
|
||
|
||
// convert all colors to 1-bit values
|
||
for (int nX = 0; nX < nWidth; ++nX, nIndex += 4)
|
||
{
|
||
// check for pixel color and setup new bit value
|
||
if (ImageStudioUtils::GetLightness(pSource[nIndex + 2], pSource[nIndex + 1], pSource[nIndex + 0]) >= 127)
|
||
ImageStudioUtils::SetBit(pResult, nBitIndex, false);
|
||
else
|
||
ImageStudioUtils::SetBit(pResult, nBitIndex, true);
|
||
|
||
// update bit index
|
||
nBitIndex++;
|
||
|
||
// check for valid index
|
||
if (nBitIndex == 8)
|
||
{
|
||
nBitIndex = 0;
|
||
pResult++;
|
||
}
|
||
}
|
||
}
|
||
|
||
// update image width
|
||
if (nWidth % 8 == 0)
|
||
nWidth -= 1;
|
||
|
||
(*pBitmap) = new Bitmap(nWidth, nHeight, nLineSize, PixelFormat1bppIndexed, m_backup);
|
||
}
|
||
|
||
if (!(*pBitmap) || (*pBitmap)->GetLastStatus() != Ok)
|
||
return FALSE;
|
||
|
||
if ((*pBitmap)->RotateFlip(RotateNoneFlipY) != Ok)
|
||
return FALSE;
|
||
|
||
if ((*pBitmap)->GetLastStatus() != Ok)
|
||
return FALSE;
|
||
|
||
return TRUE;
|
||
}
|
||
void GetEncoderClsid(const wchar_t* pFormat, CLSID* pClsid)
|
||
{
|
||
// variables
|
||
UINT nEncoders = 0;
|
||
UINT nSize = 0;
|
||
ImageCodecInfo* pImageCodecInfo = 0;
|
||
|
||
// retrieve encoders info
|
||
GetImageEncodersSize(&nEncoders, &nSize);
|
||
|
||
// check for valid encoders
|
||
if (!nSize)
|
||
throw 0;
|
||
|
||
// create encoders info structure of necessary size
|
||
pImageCodecInfo = (ImageCodecInfo*)(malloc(nSize));
|
||
|
||
// check for valid encoder
|
||
if (!pImageCodecInfo)
|
||
throw 0;
|
||
|
||
// retrieve all encoders
|
||
GetImageEncoders(nEncoders, nSize, pImageCodecInfo);
|
||
|
||
// locate necessary encoder
|
||
for (UINT nEncoder = 0; nEncoder < nEncoders; ++nEncoder)
|
||
{
|
||
// compare MIME strings
|
||
if (ImageStudioUtils::CompareStrings(pImageCodecInfo[nEncoder].MimeType, pFormat) == 0)
|
||
{
|
||
// save CLSID
|
||
*pClsid = pImageCodecInfo[nEncoder].Clsid;
|
||
|
||
// clear memory
|
||
free(pImageCodecInfo);
|
||
|
||
// all ok
|
||
return;
|
||
}
|
||
}
|
||
|
||
// clear memory
|
||
free(pImageCodecInfo);
|
||
|
||
// codec not found
|
||
throw 0;
|
||
}
|
||
void CaptureScreen(BYTE*& pixels, Bitmap*& bitmap)
|
||
{
|
||
// check for valid object
|
||
if (pixels || bitmap)
|
||
return;
|
||
|
||
// variables
|
||
HDC hdcScreen = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
|
||
HDC hdcCompatible = CreateCompatibleDC(hdcScreen);
|
||
|
||
// compute screen size
|
||
int nWidth = GetDeviceCaps(hdcScreen, HORZRES);
|
||
int nHeight = GetDeviceCaps(hdcScreen, VERTRES);
|
||
|
||
// create a compatible bitmap for hdcScreen.
|
||
HBITMAP hbmScreen = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight);
|
||
|
||
// check for valid bitmap
|
||
if (hbmScreen == 0)
|
||
return;
|
||
|
||
// select the bitmaps into the compatible DC
|
||
HGDIOBJ hObject = SelectObject(hdcCompatible, hbmScreen);
|
||
|
||
// check for valid selected bitmap
|
||
if (!hObject)
|
||
return;
|
||
|
||
// copy color data for the entire display into a bitmap that is selected into a compatible DC.
|
||
if (BitBlt(hdcCompatible, 0, 0, nWidth, nHeight, hdcScreen, 0, 0, SRCCOPY))
|
||
{
|
||
// create pixel array
|
||
pixels = new BYTE[4*nWidth*nHeight];
|
||
|
||
// compose bitmap info
|
||
BITMAPINFO info;
|
||
info.bmiHeader.biBitCount = 32;
|
||
info.bmiHeader.biClrImportant = 0;
|
||
info.bmiHeader.biClrUsed = 0;
|
||
info.bmiHeader.biCompression = BI_RGB;
|
||
info.bmiHeader.biHeight = -nHeight;
|
||
info.bmiHeader.biPlanes = 1;
|
||
info.bmiHeader.biSize = sizeof(BITMAPINFO);
|
||
info.bmiHeader.biSizeImage = 4*nWidth*nHeight;
|
||
info.bmiHeader.biWidth = nWidth;
|
||
info.bmiHeader.biXPelsPerMeter = 0;
|
||
info.bmiHeader.biYPelsPerMeter = 0;
|
||
|
||
// extract pixels from HBITMAP
|
||
if (::GetDIBits(hdcCompatible, hbmScreen, 0, nHeight, pixels, &info, DIB_RGB_COLORS) != nHeight)
|
||
{
|
||
delete[] pixels;
|
||
pixels = 0;
|
||
}
|
||
|
||
// compose resulting image
|
||
if (pixels)
|
||
bitmap = new Bitmap(nWidth, nHeight, nWidth*4, PixelFormat32bppRGB, pixels);
|
||
}
|
||
|
||
// restore previous object
|
||
SelectObject(hdcCompatible, hObject);
|
||
|
||
// delete objects
|
||
DeleteObject(hbmScreen);
|
||
DeleteDC(hdcCompatible);
|
||
DeleteDC(hdcScreen);
|
||
}
|
||
void UpdateSize(Bitmap*& pImage)
|
||
{
|
||
// check whether we need to correct size
|
||
if (m_UpdateSize != VARIANT_TRUE)
|
||
return;
|
||
|
||
// retrieve current resolution values
|
||
double dOldHRes = pImage->GetHorizontalResolution();
|
||
double dOldVRes = pImage->GetVerticalResolution();
|
||
|
||
// check for the same resolution values
|
||
if (fabs(dOldHRes - dOldVRes) < 0.001)
|
||
return;
|
||
|
||
// check for zero values
|
||
if (fabs(dOldHRes) < 0.001 || fabs(dOldVRes) < 0.001)
|
||
return;
|
||
|
||
// compute new resolution values
|
||
double dNewRes = max(dOldHRes, dOldVRes);
|
||
|
||
// retrieve current dimension values
|
||
int nOldW = pImage->GetWidth();
|
||
int nOldH = pImage->GetHeight();
|
||
|
||
// compute new sizes
|
||
int nNewW = (int)(nOldW*dNewRes/dOldHRes);
|
||
int nNewH = (int)(nOldH*dNewRes/dOldVRes);
|
||
|
||
// retrieve thumbnail image
|
||
Bitmap* pNewImage = (Bitmap*)pImage->GetThumbnailImage(nNewW, nNewH);
|
||
|
||
// check for valid image
|
||
if (!pNewImage)
|
||
return;
|
||
|
||
pNewImage->SetResolution((REAL)dNewRes, (REAL)dNewRes);
|
||
|
||
// remove old image
|
||
delete pImage;
|
||
|
||
// update image
|
||
pImage = pNewImage;
|
||
}
|
||
void UpdateProperties(Bitmap*& bitmap, BOOL bLoad)
|
||
{
|
||
if (bLoad)
|
||
{
|
||
// retrieve info properties
|
||
// ...
|
||
// retrieve bitmap resolution
|
||
m_InfoHorizontalResolution = bitmap->GetHorizontalResolution();
|
||
m_InfoVerticalResolution = bitmap->GetVerticalResolution();
|
||
|
||
}
|
||
else
|
||
{
|
||
// set the bitmap resolution in dpi
|
||
bitmap->SetResolution((REAL)m_InfoHorizontalResolution, (REAL)m_InfoVerticalResolution);
|
||
|
||
// save info properties
|
||
SetPropertyShort(bitmap, PropertyTagOrientation, m_InfoOrientation);
|
||
SetPropertyShort(bitmap, PropertyTagImageWidth, m_InfoImageWidth);
|
||
|
||
}
|
||
|
||
// remove property load-save errors here
|
||
if (bitmap->GetLastStatus() != Ok)
|
||
return;
|
||
}
|
||
void GetPropertyShort(Bitmap*& pImage, PROPID nId, int& nValue)
|
||
{
|
||
// reset value
|
||
nValue = -1;
|
||
|
||
// retrieve property size
|
||
UINT nSize = pImage->GetPropertyItemSize(nId);
|
||
|
||
// check for valid size
|
||
if (nSize > 0)
|
||
{
|
||
// allocate memory for tag
|
||
PropertyItem* pProp = (PropertyItem*)(malloc(nSize));
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// read tag to buffer
|
||
pImage->GetPropertyItem(nId, nSize, pProp);
|
||
|
||
// copy data to buffer
|
||
if ( NULL != pProp->value )
|
||
nValue = *(short*)pProp->value;
|
||
|
||
// release buffer
|
||
free(pProp);
|
||
}
|
||
}
|
||
void GetPropertyInt(Bitmap*& pImage, PROPID nId, int& nValue)
|
||
{
|
||
// reset value
|
||
nValue = -1;
|
||
|
||
// retrieve property size
|
||
UINT nSize = pImage->GetPropertyItemSize(nId);
|
||
|
||
// check for valid size
|
||
if (nSize > 0)
|
||
{
|
||
// allocate memory for tag
|
||
PropertyItem* pProp = (PropertyItem*)(malloc(nSize));
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// read tag to buffer
|
||
pImage->GetPropertyItem(nId, nSize, pProp);
|
||
|
||
// copy data to buffer
|
||
if ( NULL != pProp->value )
|
||
nValue = *(int*)pProp->value;
|
||
|
||
// release buffer
|
||
free(pProp);
|
||
}
|
||
}
|
||
void GetPropertyStr(Bitmap*& pImage, PROPID nId, CString& sValue)
|
||
{
|
||
// reset value
|
||
sValue = "";
|
||
|
||
// retrieve property size
|
||
UINT nSize = pImage->GetPropertyItemSize(nId);
|
||
|
||
// check for valid size
|
||
if (nSize > 0)
|
||
{
|
||
// allocate memory for tag
|
||
PropertyItem* pProp = (PropertyItem*)(malloc(nSize));
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// read tag to buffer
|
||
pImage->GetPropertyItem(nId, nSize, pProp);
|
||
|
||
// copy data to buffer
|
||
if ( NULL != pProp->value )
|
||
sValue = (const char*)pProp->value;
|
||
|
||
// release buffer
|
||
free(pProp);
|
||
}
|
||
}
|
||
void GetPropertyRational(Bitmap*& pImage, PROPID nId, double& dValue)
|
||
{
|
||
// reset value
|
||
dValue = 0;
|
||
|
||
// retrieve property size
|
||
UINT nSize = pImage->GetPropertyItemSize(nId);
|
||
|
||
// check for valid size
|
||
if (nSize > 0)
|
||
{
|
||
// allocate memory for tag
|
||
PropertyItem* pProp = (PropertyItem*)(malloc(nSize));
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// read tag to buffer
|
||
pImage->GetPropertyItem(nId, nSize, pProp);
|
||
|
||
long *values;
|
||
// compute number of values
|
||
if ( NULL != pProp->value )
|
||
values = (long*)pProp->value;
|
||
else
|
||
{
|
||
free(pProp);
|
||
return;
|
||
}
|
||
int count = pProp->length/sizeof(double);
|
||
|
||
// compute value
|
||
for (int index = 0; index < count; ++index)
|
||
dValue += values[2*index + 0]/(double)values[2*index + 1];
|
||
|
||
// release buffer
|
||
free(pProp);
|
||
}
|
||
}
|
||
void SetPropertyStr(Bitmap*& pImage, PROPID nId, CString& sValue)
|
||
{
|
||
// check for valid string
|
||
if (sValue.GetLength() < 1)
|
||
return;
|
||
|
||
// create new property item
|
||
PropertyItem* pProp = new PropertyItem;
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// compose property item
|
||
pProp->id = nId;
|
||
pProp->length = (nId == PropertyTagDateTime) ? 20 : sValue.GetLength() + 1;
|
||
pProp->type = PropertyTagTypeASCII;
|
||
pProp->value = (TCHAR*)(LPCTSTR)sValue;
|
||
|
||
// sset property item
|
||
pImage->SetPropertyItem(pProp);
|
||
|
||
// delete property item
|
||
delete pProp;
|
||
}
|
||
void SetPropertyShort(Bitmap*& pImage, PROPID nId, short& nValue)
|
||
{
|
||
// create new property item
|
||
PropertyItem* pProp = new PropertyItem;
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// compose property item
|
||
pProp->id = nId;
|
||
pProp->length = sizeof(short);
|
||
pProp->type = PropertyTagTypeShort;
|
||
pProp->value = (short*)(&nValue);
|
||
|
||
// sset property item
|
||
pImage->SetPropertyItem(pProp);
|
||
|
||
// delete property item
|
||
delete pProp;
|
||
}
|
||
void SetPropertyRational(Bitmap*& pImage, PROPID nId, double& dValue)
|
||
{
|
||
// check for valid string
|
||
if (dValue < 0)
|
||
return;
|
||
|
||
// create new property item
|
||
PropertyItem* pProp = new PropertyItem;
|
||
if ( NULL == pProp )
|
||
return;
|
||
|
||
// compose property item
|
||
pProp->id = nId;
|
||
pProp->length = sizeof(double);
|
||
pProp->type = PropertyTagTypeRational;
|
||
pProp->value = (double*)&dValue;
|
||
|
||
// sset property item
|
||
pImage->SetPropertyItem(pProp);
|
||
|
||
// delete property item
|
||
delete pProp;
|
||
}
|
||
Bitmap* LoadCursor(BSTR Path)
|
||
{
|
||
USES_CONVERSION;
|
||
|
||
// load cursor from file
|
||
HCURSOR hCursor = ::LoadCursorFromFile(OLE2T(Path));
|
||
|
||
// check handle
|
||
if (!hCursor)
|
||
return 0; // invalid cursor file
|
||
|
||
// retrive cursor information
|
||
ICONINFO infoCursor; ::ZeroMemory(&infoCursor, sizeof(ICONINFO));
|
||
if (!::GetIconInfo(hCursor, &infoCursor) || !infoCursor.hbmMask)
|
||
return 0; // can't read cursor information
|
||
|
||
// retrive cursor size
|
||
Bitmap bmpCursor(infoCursor.hbmMask, 0);
|
||
CSize sizeCursor(bmpCursor.GetWidth(), bmpCursor.GetHeight());
|
||
|
||
// create Bitmap object
|
||
Bitmap* bitmap = new Bitmap(sizeCursor.cx, sizeCursor.cy, PixelFormat32bppRGB);
|
||
if (!bitmap || bitmap->GetLastStatus() != Ok)
|
||
return 0;
|
||
|
||
// create Graphics object for cursor drawing
|
||
Graphics graphics(bitmap); graphics.Clear(Color::White);
|
||
if (graphics.GetLastStatus() != Ok)
|
||
return 0;
|
||
|
||
// retrive device context
|
||
HDC graphicsDC = graphics.GetHDC();
|
||
if (graphics.GetLastStatus() != Ok)
|
||
return 0;
|
||
|
||
// draw cursor
|
||
if (!::DrawIcon(graphicsDC, 0, 0, hCursor))
|
||
return 0;
|
||
|
||
// release device context
|
||
graphics.ReleaseHDC(graphicsDC);
|
||
if (graphics.GetLastStatus() != Ok)
|
||
return 0;
|
||
|
||
// destroy cursor handle
|
||
::DestroyCursor(hCursor);
|
||
|
||
// all ok-na
|
||
return bitmap;
|
||
}
|
||
|
||
protected:
|
||
|
||
static BOOL ImageToMemory(Bitmap* pBitmap, BYTE* pPixels)
|
||
{
|
||
// pre-flip the image
|
||
BOOL Flipped = (pBitmap->RotateFlip(RotateNoneFlipY) == Ok);
|
||
|
||
// create locking settings
|
||
Rect rectLock(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
|
||
BitmapData* pBitmapData = new BitmapData();
|
||
|
||
// variables
|
||
BOOL Success = FALSE;
|
||
int nX, nY, nIndex = 0;
|
||
int nOffset = 0;
|
||
|
||
// try to process 24bpp image first
|
||
|
||
// lock the bitmap bits
|
||
if ((pBitmap->GetPixelFormat() == PixelFormat1bppIndexed ||
|
||
pBitmap->GetPixelFormat() == PixelFormat4bppIndexed ||
|
||
pBitmap->GetPixelFormat() == PixelFormat16bppGrayScale ||
|
||
pBitmap->GetPixelFormat() == PixelFormat16bppRGB555 ||
|
||
pBitmap->GetPixelFormat() == PixelFormat16bppRGB565 ||
|
||
pBitmap->GetPixelFormat() == PixelFormat24bppRGB ||
|
||
pBitmap->GetPixelFormat() == PixelFormat32bppRGB ) &&
|
||
pBitmap->LockBits(&rectLock, ImageLockModeRead, PixelFormat24bppRGB, pBitmapData) == Ok)
|
||
{
|
||
// compute stride value
|
||
int nStride = pBitmapData->Stride; if (!Flipped) nStride *= -1;
|
||
|
||
// retrieve pointer to the locked bits
|
||
BYTE* pBitmapPixels = (BYTE*)pBitmapData->Scan0;
|
||
|
||
int nWidth = pBitmap->GetWidth();
|
||
int nHeight = pBitmap->GetHeight();
|
||
|
||
// copy pixel info
|
||
for (nY = 0; nY < nHeight; ++nY)
|
||
{
|
||
nOffset = (nStride < 0) ? (nHeight - 1 - nY)*(-nStride) : nY*nStride;
|
||
|
||
for (nX = 0; nX < nWidth; ++nX, nIndex += 4, nOffset += 3)
|
||
{
|
||
pPixels[nIndex + 0] = pBitmapPixels[nOffset + 0];
|
||
pPixels[nIndex + 1] = pBitmapPixels[nOffset + 1];
|
||
pPixels[nIndex + 2] = pBitmapPixels[nOffset + 2];
|
||
pPixels[nIndex + 3] = 255;
|
||
}
|
||
}
|
||
|
||
// unlock the bits
|
||
pBitmap->UnlockBits(pBitmapData);
|
||
|
||
// update output flag
|
||
Success = TRUE;
|
||
}
|
||
else
|
||
{
|
||
// lock the bitmap bits
|
||
if (pBitmap->LockBits(&rectLock, ImageLockModeRead, PixelFormat32bppARGB, pBitmapData) == Ok)
|
||
{
|
||
// compute stride value
|
||
int nStride = pBitmapData->Stride; if (!Flipped) nStride *= -1;
|
||
|
||
// retrieve pointer to the locked bits
|
||
BYTE* pBitmapPixels = (BYTE*)pBitmapData->Scan0;
|
||
|
||
int nWidth = pBitmap->GetWidth();
|
||
int nHeight = pBitmap->GetHeight();
|
||
|
||
// copy pixel info
|
||
for (nY = 0; nY < nHeight; ++nY)
|
||
{
|
||
nOffset = (nStride < 0) ? (nHeight - 1 - nY)*(-nStride) : nY*nStride;
|
||
|
||
for (nX = 0; nX < nWidth; ++nX, nIndex += 4, nOffset += 4)
|
||
{
|
||
pPixels[nIndex + 0] = pBitmapPixels[nOffset + 0];
|
||
pPixels[nIndex + 1] = pBitmapPixels[nOffset + 1];
|
||
pPixels[nIndex + 2] = pBitmapPixels[nOffset + 2];
|
||
pPixels[nIndex + 3] = pBitmapPixels[nOffset + 3];
|
||
}
|
||
}
|
||
|
||
// unlock the bits
|
||
pBitmap->UnlockBits(pBitmapData);
|
||
|
||
// update output flag
|
||
Success = TRUE;
|
||
}
|
||
}
|
||
|
||
// delete unnecessary bitmap data pointer
|
||
if (pBitmapData)
|
||
delete pBitmapData;
|
||
|
||
// raise error (if necessary)
|
||
return Success;
|
||
}
|
||
static BOOL ImageToArray(Bitmap* pBitmap, void** Image)
|
||
{
|
||
SAFEARRAY** pArray = (SAFEARRAY**) Image;
|
||
|
||
// check for valid input parameters
|
||
if (!pBitmap || !pArray)
|
||
return FALSE;
|
||
|
||
// destroy array (if non empty)
|
||
ImageStudioUtils::DestroySafeArray(pArray);
|
||
|
||
// compute SAFEARRAY bounds
|
||
SAFEARRAYBOUND rgsaBound[3];
|
||
rgsaBound[0].lLbound = 0;
|
||
rgsaBound[0].cElements = 4;
|
||
rgsaBound[1].lLbound = 0;
|
||
rgsaBound[1].cElements = pBitmap->GetWidth();
|
||
rgsaBound[2].lLbound = 0;
|
||
rgsaBound[2].cElements = pBitmap->GetHeight();
|
||
|
||
// compose SAFEARRAY with image data
|
||
*pArray = SafeArrayCreate(VT_UI1, 3, rgsaBound);
|
||
|
||
// check for valid array
|
||
if (!*pArray)
|
||
return FALSE;
|
||
|
||
// retrieve pointer to a pixel data
|
||
BYTE* pPixels = (BYTE*)(*pArray)->pvData;
|
||
|
||
return ImageToMemory(pBitmap, pPixels);
|
||
}
|
||
static BOOL PrepareInterface(IUnknown** pInterface, int nWidth, int nHeight, int nChannels, BYTE*& pBufferPtr)
|
||
{
|
||
if (!pInterface)
|
||
return FALSE;
|
||
|
||
// create result interface
|
||
*pInterface = NULL;
|
||
HRESULT hRes = CoCreateInstance(MediaCore::CLSID_CAVSUncompressedVideoFrame, NULL, CLSCTX_ALL, MediaCore::IID_IAVSUncompressedVideoFrame, (void**)pInterface);
|
||
if (hRes != S_OK || NULL == *pInterface)
|
||
return FALSE;
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaData = (MediaCore::IAVSUncompressedVideoFrame*)*pInterface;
|
||
//(*pInterface)->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pMediaData));
|
||
//if (NULL == pMediaData)
|
||
// return FALSE;
|
||
|
||
// compute safearray's buffer size
|
||
int nBufferSize = nChannels*nWidth*nHeight;
|
||
if (nBufferSize < 1)
|
||
return FALSE;
|
||
|
||
// allocate necesasry buffer
|
||
pMediaData->put_ColorSpace(CSP_BGRA | CSP_VFLIP);
|
||
pMediaData->put_Width(nWidth);
|
||
pMediaData->put_Height(nHeight);
|
||
pMediaData->put_AspectRatioX(nWidth);
|
||
pMediaData->put_AspectRatioY(nHeight);
|
||
pMediaData->put_Interlaced(VARIANT_FALSE);
|
||
pMediaData->put_Stride(0, 4*nWidth);
|
||
pMediaData->AllocateBuffer(nBufferSize);
|
||
|
||
pBufferPtr = 0;
|
||
long nCreatedBufferSize = 0;
|
||
pMediaData->get_Buffer(&pBufferPtr);
|
||
pMediaData->get_BufferSize(&nCreatedBufferSize);
|
||
pMediaData->put_Plane(0, pBufferPtr);
|
||
|
||
// check for valid created buffer
|
||
if (!pBufferPtr || nCreatedBufferSize != nBufferSize)
|
||
return FALSE;
|
||
|
||
// save interface
|
||
*pInterface = pMediaData;
|
||
|
||
return TRUE;
|
||
}
|
||
static BOOL ImageToInterface(Bitmap* pBitmap, void** Image)
|
||
{
|
||
IUnknown** pInterface = (IUnknown**) Image;
|
||
|
||
// check for valid input parameters
|
||
if (!pBitmap)
|
||
return FALSE;
|
||
|
||
// create result interface
|
||
BYTE* pBufferPtr = 0;
|
||
if (!PrepareInterface(pInterface, pBitmap->GetWidth(), pBitmap->GetHeight(), 4, pBufferPtr))
|
||
return FALSE;
|
||
|
||
// copy data to the buffer
|
||
return ImageToMemory(pBitmap, pBufferPtr);
|
||
}
|
||
static BOOL CopyToInterface(SAFEARRAY* psarr, void** Image)
|
||
{
|
||
IUnknown** pInterface = (IUnknown**) Image;
|
||
|
||
// check for valid input parameters
|
||
if (!psarr || !pInterface)
|
||
return FALSE;
|
||
|
||
// copy psarr to Interface
|
||
if (ImageStudioUtils::SafeArrayToMediaData(psarr, pInterface, FALSE))
|
||
return TRUE;
|
||
|
||
return FALSE;
|
||
}
|
||
static BOOL CopyToArray(SAFEARRAY* psarr, void** Image)
|
||
{
|
||
SAFEARRAY** pArray = (SAFEARRAY**) Image;
|
||
|
||
// check for valid input parameters
|
||
if (!psarr || !pArray)
|
||
return FALSE;
|
||
|
||
// destroy array (if non empty)
|
||
ImageStudioUtils::DestroySafeArray(pArray);
|
||
|
||
// copy psarr to pArray
|
||
if (SafeArrayCopy(psarr, pArray) != S_OK)
|
||
return TRUE;
|
||
|
||
return FALSE;
|
||
}
|
||
static BYTE* ExtractImageFromInterface(IUnknown** pInterface, MediaCore::IAVSUncompressedVideoFrame*& pMediaData, int& nWidth, int& nHeight)
|
||
{
|
||
nWidth = 0;
|
||
nHeight = 0;
|
||
BYTE* pPixels = 0;
|
||
|
||
if (!ImageStudioUtils::MediaDataToByteArray(pInterface, pMediaData, pPixels, nWidth, nHeight))
|
||
throw 0;
|
||
|
||
return pPixels;
|
||
}
|
||
BOOL LoadImageTo(_ImageFileFormats eFileType, BSTR Path, ImageStudio::Core::Image & oImage,BOOL & bVerFlip, BOOL bArray)
|
||
{
|
||
BOOL bLoading = FALSE;
|
||
|
||
CW2T convert(Path);
|
||
CString sFilePath( convert );
|
||
|
||
|
||
int nFormat = ImageStudio::IO::c_nFormat_Uncompressed_32bpp;
|
||
|
||
try
|
||
{
|
||
if(eFileType == c_Gdiplus
|
||
|| eFileType == c_Bmp
|
||
|| eFileType == c_Gif
|
||
|| eFileType == c_Jpg
|
||
|| eFileType == c_Png
|
||
|| eFileType == c_Tiff)
|
||
{
|
||
ImageStudio::IO::Bitmap oReaderBmp;
|
||
bLoading = oReaderBmp.FromFile( sFilePath, nFormat, &oImage, 0/*nFrame*/, &m_InfoHorizontalResolution, &m_InfoVerticalResolution );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Psd )
|
||
{
|
||
ImageStudio::IO::Psd oReaderPsd;
|
||
bLoading = oReaderPsd.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Tga)
|
||
{
|
||
ImageStudio::IO::Tga oReaderTga;
|
||
bLoading = oReaderTga.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Pcx)
|
||
{
|
||
ImageStudio::IO::Pcx oReaderPcx;
|
||
bLoading = oReaderPcx.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Ras)
|
||
{
|
||
ImageStudio::IO::Ras oReaderRas;
|
||
bLoading = oReaderRas.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Jpeg2000)
|
||
{
|
||
ImageStudio::IO::Jp2 oReaderJp2;
|
||
bLoading = oReaderJp2.FromFile( sFilePath, nFormat, &oImage );
|
||
bVerFlip = !(bVerFlip);
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_WebShots)
|
||
{
|
||
ImageStudio::IO::WebShots::Wb1 oReaderWB1;
|
||
bLoading = oReaderWB1.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_iPode)
|
||
{
|
||
ImageStudio::IO::Ithmb oReaderIPod;
|
||
bLoading = oReaderIPod.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if (eFileType == c_Metafile)
|
||
{
|
||
ImageStudio::IO::Meta oReaderMeta;
|
||
bLoading = oReaderMeta.FromFile( sFilePath, nFormat, &oImage );
|
||
bVerFlip = !(bVerFlip);
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_RawFotos)
|
||
{
|
||
#ifndef NO_RAW_CHECKER
|
||
const TCHAR * settingsXML = _T("<ImageRaw3 mode=\"0\" xmlns=\"http://tempuri.org/ImageRaw3Options.xsd\"> \
|
||
<SimpleMode ver=\"1\"><CameraWhiteBalance use=\"1\"/><CameraMatrix use=\"0\"/> \
|
||
</SimpleMode></ImageRaw3>");
|
||
|
||
ImageStudio::IO::Raw oRenderRaw;
|
||
bLoading = oRenderRaw.FromFile( sFilePath, nFormat, &oImage, settingsXML);
|
||
bVerFlip = !(bVerFlip);
|
||
#else
|
||
bLoading = FALSE;
|
||
#endif
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Sfw)
|
||
{
|
||
#ifndef NO_SWF_CHECKER
|
||
ImageStudio::IO::Sfw oRenderSfw;
|
||
bLoading = oRenderSfw.FromFile( sFilePath, nFormat, &oImage );
|
||
bVerFlip = !(bVerFlip);
|
||
#else
|
||
bLoading = FALSE;
|
||
#endif
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Swf)
|
||
{
|
||
#ifndef NO_SWF_CHECKER
|
||
ImageStudio::IO::Swf oRenderSwf;
|
||
bLoading = oRenderSwf.FromFile( sFilePath, nFormat, &oImage );
|
||
#else
|
||
bLoading = FALSE;
|
||
#endif
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Svm)
|
||
{
|
||
ImageStudio::IO::Svm oRenderSvm;
|
||
bLoading = oRenderSvm.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Wbz )
|
||
{
|
||
ImageStudio::IO::WebShots::Wbz oReaderWbz;
|
||
bLoading = oReaderWbz.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
else
|
||
if( eFileType ==_ImageFileFormats::c_Wbc)
|
||
{
|
||
ImageStudio::IO::WebShots::Wbc oReaderWbc;
|
||
bLoading = oReaderWbc.FromFile( sFilePath, nFormat, &oImage );
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
return bLoading;
|
||
}
|
||
VARIANT_BOOL LoadImageTo(BSTR Path, void** pData, BOOL (*ImageTo)(Bitmap*, void**), BOOL bArray)
|
||
{
|
||
// reset output value
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
try
|
||
{
|
||
MetaDataFromFile( Path ); // load metadata from file
|
||
CStringW wsFilePath( Path );
|
||
|
||
const int c_nCountFileFormats = sizeof(tableSupportImageFormats) / sizeof(tableSupportImageFormats[0]);
|
||
|
||
_ImageFileFormats eFileType = tableSupportImageFormats[0].format;
|
||
|
||
int nPos = wsFilePath.ReverseFind( L'.' );
|
||
if( nPos > 0 )
|
||
{
|
||
CStringW sFileEx = wsFilePath.Right( wsFilePath.GetLength() - nPos - 1 );
|
||
sFileEx.MakeLower();
|
||
|
||
for( int i = 1; i < c_nCountFileFormats; i++ )
|
||
{
|
||
if( sFileEx == tableSupportImageFormats[i].str )
|
||
{
|
||
eFileType = tableSupportImageFormats[i].format;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
CImageFileFormatChecker checker(Path);
|
||
|
||
BOOL bLoading = FALSE;
|
||
ImageStudio::Core::Image oImage;
|
||
BOOL bVerFlip = FALSE;
|
||
|
||
if (checker.eFileType>0 && checker.eFileType == eFileType)
|
||
{
|
||
bLoading = LoadImageTo(eFileType,Path,oImage,bVerFlip,bArray);
|
||
}
|
||
else if (checker.eFileType || eFileType)
|
||
{
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> sync-word <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
if (eFileType)
|
||
{
|
||
bLoading = LoadImageTo(eFileType,Path,oImage,bVerFlip,bArray); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
|
||
if (!bLoading && checker.eFileType)
|
||
{
|
||
bLoading = LoadImageTo(checker.eFileType,Path,oImage,bVerFlip,bArray); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
}
|
||
|
||
if( oImage.IsValid() )
|
||
{
|
||
int nWidth = oImage.GetWidth();
|
||
int nHeight = oImage.GetHeight();
|
||
|
||
if( nWidth * nHeight > 100000000 )
|
||
{
|
||
oImage.Destroy();
|
||
Success = VARIANT_FALSE;
|
||
return Success;
|
||
}
|
||
|
||
if( bArray )
|
||
bLoading = oImage.ToSafeArray((SAFEARRAY**)pData);
|
||
else
|
||
bLoading = oImage.ToMediaData((IUnknown**)pData, bVerFlip);
|
||
|
||
return bLoading ? VARIANT_TRUE : VARIANT_FALSE;
|
||
}
|
||
else
|
||
{
|
||
Gdiplus::Bitmap* bitmap = LoadCursor(Path);
|
||
|
||
// check for valid bitmap
|
||
if( bitmap )
|
||
{
|
||
if( bitmap->GetLastStatus() == Gdiplus::Ok )
|
||
{
|
||
if( ImageTo( bitmap, pData ) )
|
||
{
|
||
Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
|
||
delete bitmap;
|
||
}
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
// update status flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL LoadPictureTo(IPictureDisp* Picture, void** pData, BOOL (*ImageTo)(Bitmap*, void**))
|
||
{
|
||
// reset output value
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
// convert IPictureDisp to image
|
||
try
|
||
{
|
||
// variables
|
||
HRESULT hResult = S_OK;
|
||
IStreamPtr pStream;
|
||
|
||
// create memory stream
|
||
if (SUCCEEDED(hResult = CreateStreamOnHGlobal(0, TRUE, &pStream)))
|
||
{
|
||
// obtain IPicture
|
||
IPicturePtr pOlePicture = Picture;
|
||
|
||
// save picture to stream
|
||
if (SUCCEEDED(pOlePicture->SaveAsFile(pStream, TRUE, 0)))
|
||
{
|
||
// load image from file
|
||
Bitmap bitmap(pStream);
|
||
|
||
// check for last error
|
||
if (bitmap.GetLastStatus() == Ok)
|
||
{
|
||
// retrieve image pixels
|
||
if (ImageTo(&bitmap, pData))
|
||
{
|
||
// update output value
|
||
Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
// update status flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL LoadScreenshotTo(void** pData, BOOL (*ImageTo)(Bitmap*, void**))
|
||
{
|
||
// reset output value
|
||
VARIANT_BOOL Success = VARIANT_TRUE;
|
||
|
||
|
||
// Gdi+ Bitmap object
|
||
BYTE* pixels = 0;
|
||
Bitmap* bitmap = 0;
|
||
|
||
// load image from screen
|
||
try
|
||
{
|
||
// attempt to get desktop screenshot
|
||
CaptureScreen(pixels, bitmap);
|
||
|
||
// check pointer
|
||
if (bitmap)
|
||
{
|
||
// retrieve image pixels
|
||
if (ImageTo(bitmap, pData))
|
||
{
|
||
// update output value
|
||
Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
// update status flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// free memory
|
||
if (bitmap)
|
||
delete bitmap;
|
||
if (pixels)
|
||
delete[] pixels;
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL LoadFrameTo(BSTR Path, long Frame, void** pData, BOOL (*ImageTo)(Bitmap*, void**), BOOL bArray)
|
||
{
|
||
// reset output value
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
|
||
// check for valid input parameters
|
||
if (Frame < 0)
|
||
return VARIANT_FALSE;
|
||
|
||
// check for simpliest case
|
||
if (Frame == 0)
|
||
return LoadImageTo(Path, pData, (bArray)? ImageToArray : ImageToInterface, bArray);
|
||
|
||
// Gdi+ Bitmap object
|
||
Bitmap* bitmap = 0;
|
||
|
||
// load image from file
|
||
try
|
||
{
|
||
// attempt to load image with Gdi+
|
||
bitmap = new Bitmap(Path);
|
||
|
||
// check for valid bitmap
|
||
if (bitmap && bitmap->GetLastStatus() == Ok)
|
||
{
|
||
// variables
|
||
GUID format;
|
||
long nFrameCount = 0;
|
||
|
||
// retrieve image format
|
||
bitmap->GetRawFormat(&format);
|
||
|
||
// check for format type
|
||
if (format == ImageFormatTIFF)
|
||
nFrameCount = bitmap->GetFrameCount(&FrameDimensionPage);
|
||
else if (format == ImageFormatGIF)
|
||
nFrameCount = bitmap->GetFrameCount(&FrameDimensionTime);
|
||
|
||
// check for frame count
|
||
if (Frame >= 0 && Frame < nFrameCount)
|
||
{
|
||
// select necessary frame
|
||
if (format == ImageFormatTIFF)
|
||
bitmap->SelectActiveFrame(&FrameDimensionPage, Frame);
|
||
else if (format == ImageFormatGIF)
|
||
bitmap->SelectActiveFrame(&FrameDimensionTime, Frame);
|
||
|
||
// update bitmap properties and size
|
||
UpdateProperties(bitmap, TRUE);
|
||
UpdateSize(bitmap);
|
||
|
||
// retrieve image pixels
|
||
if (ImageTo(bitmap, pData))
|
||
{
|
||
// update output value
|
||
Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
// update status flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// free memory
|
||
if (bitmap)
|
||
delete bitmap;
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL SaveImageAs(BSTR Path, int nType, const wchar_t* pImageFormat, EncoderParameters* settings, void** Image, BOOL bArrayOrInterface = TRUE)
|
||
{
|
||
// update result flag
|
||
VARIANT_BOOL Success = VARIANT_TRUE;
|
||
|
||
// variables
|
||
Bitmap* bitmap = 0;
|
||
|
||
// save image to file
|
||
try
|
||
{
|
||
// convert array to image
|
||
if (bArrayOrInterface)
|
||
ArrayToImage(Image, &bitmap, nType);
|
||
else
|
||
InterfaceToImage(Image, &bitmap, nType);
|
||
|
||
// locate encoder CLSID
|
||
CLSID encoder; GetEncoderClsid(pImageFormat, &encoder);
|
||
|
||
// save info properties
|
||
|
||
UpdateProperties(bitmap, FALSE);
|
||
|
||
if ( !(L"image/png" == pImageFormat) )
|
||
m_oMetaData.SaveToBMP(bitmap);
|
||
//else
|
||
// SaveAsPNG(bitmap);
|
||
|
||
|
||
// save image
|
||
bitmap->Save(Path, &encoder, settings);
|
||
|
||
// check for last error
|
||
if (bitmap->GetLastStatus() != Ok)
|
||
throw 0;
|
||
}
|
||
catch(...)
|
||
{
|
||
// update result flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// clear memory
|
||
if (L"image/tiff" == pImageFormat && m_TiffMultipaged == VARIANT_TRUE)
|
||
m_bitmap = bitmap;
|
||
else
|
||
delete bitmap;
|
||
|
||
// delete backup
|
||
ClearBackup();
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL SaveImageAsJpeg(BSTR Path, void** Image, BOOL bArrayOrInterface = TRUE)
|
||
{
|
||
// create encoder settings structure
|
||
EncoderParameters settings;
|
||
|
||
// setup encoder settings
|
||
settings.Count = 1;
|
||
settings.Parameter[0].Guid = EncoderQuality;
|
||
settings.Parameter[0].Type = EncoderParameterValueTypeLong;
|
||
settings.Parameter[0].NumberOfValues = 1;
|
||
|
||
// prepare quality parameter
|
||
ULONG Quality = m_JpegQuality;
|
||
|
||
// setup quality setting
|
||
settings.Parameter[0].Value = &Quality;
|
||
|
||
return SaveImageAs(Path, c_nBitmapType32bpp, L"image/jpeg", &settings, Image, bArrayOrInterface);
|
||
}
|
||
VARIANT_BOOL SaveImageAsTiff(BSTR Path, void** Image, BOOL bArrayOrInterface = TRUE)
|
||
{
|
||
// update result flag
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
m_nMultipagedFormat = 0;
|
||
|
||
// save image to file
|
||
try
|
||
{
|
||
// delete existing image
|
||
ClearBitmap();
|
||
|
||
// compute bpp value
|
||
int nBpp = (m_TiffCompression == c_nTiffCompressionCCITT3 || m_TiffCompression == c_nTiffCompressionCCITT4 || m_TiffCompression == c_nTiffCompressionRle) ? c_nBitmapType1bppDither : c_nBitmapType32bpp;
|
||
|
||
// setup encoder values
|
||
ULONG Value0, Value1, Value2;
|
||
|
||
// create encoder settings structure
|
||
EncoderParameters* settings = (EncoderParameters*)malloc(sizeof(EncoderParameters) + 3 * sizeof(EncoderParameter));
|
||
|
||
// update value settings
|
||
settings->Parameter[0].Guid = EncoderColorDepth;
|
||
settings->Parameter[0].Type = EncoderParameterValueTypeLong;
|
||
settings->Parameter[0].NumberOfValues = 1;
|
||
settings->Parameter[0].Value = &Value0;
|
||
settings->Parameter[1].Guid = EncoderCompression;
|
||
settings->Parameter[1].Type = EncoderParameterValueTypeLong;
|
||
settings->Parameter[1].NumberOfValues = 1;
|
||
settings->Parameter[1].Value = &Value1;
|
||
settings->Parameter[2].Guid = EncoderSaveFlag;
|
||
settings->Parameter[2].Type = EncoderParameterValueTypeLong;
|
||
settings->Parameter[2].NumberOfValues = 1;
|
||
settings->Parameter[2].Value = &Value2;
|
||
|
||
// update values
|
||
Value0 = (nBpp == c_nBitmapType1bppDither || nBpp == c_nBitmapType1bpp) ? 1 : 32;
|
||
Value2 = EncoderValueMultiFrame;
|
||
|
||
// update value
|
||
if (m_TiffCompression == c_nTiffCompressionNone)
|
||
Value1 = EncoderValueCompressionNone;
|
||
else if (m_TiffCompression == c_nTiffCompressionLzw)
|
||
Value1 = EncoderValueCompressionLZW;
|
||
else if (m_TiffCompression == c_nTiffCompressionRle)
|
||
Value1 = EncoderValueCompressionRle;
|
||
else if (m_TiffCompression == c_nTiffCompressionCCITT3)
|
||
Value1 = EncoderValueCompressionCCITT3;
|
||
else if (m_TiffCompression == c_nTiffCompressionCCITT4)
|
||
Value1 = EncoderValueCompressionCCITT4;
|
||
|
||
// update values count
|
||
settings->Count = (m_TiffMultipaged == VARIANT_TRUE) ? 3 : 2;
|
||
|
||
Success = SaveImageAs(Path, nBpp, L"image/tiff", settings, Image, bArrayOrInterface);
|
||
|
||
// clear memory
|
||
free(settings);
|
||
}
|
||
catch(...)
|
||
{
|
||
// update result flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL SaveImageAsAnimated(BSTR Path, LONG Format, void** Image, BOOL bArrayOrInterface = TRUE)
|
||
{
|
||
return S_OK;
|
||
|
||
}
|
||
VARIANT_BOOL SaveImageAsFrame(void** Image, VARIANT_BOOL LastFrame, BOOL bArrayOrInterface = TRUE)
|
||
{
|
||
if ( 0 == m_nMultipagedFormat )
|
||
{
|
||
// update result flag
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
// check for valid image
|
||
if (!m_bitmap)
|
||
return VARIANT_FALSE;
|
||
|
||
// update result flag
|
||
Success = VARIANT_TRUE;
|
||
|
||
// variables
|
||
Bitmap* bitmap = 0;
|
||
|
||
// save image to file
|
||
try
|
||
{
|
||
// compute bpp value
|
||
int nBpp = (m_TiffCompression == c_nTiffCompressionCCITT3 || m_TiffCompression == c_nTiffCompressionCCITT4 || m_TiffCompression == c_nTiffCompressionRle) ? c_nBitmapType1bppDither : c_nBitmapType32bpp;
|
||
|
||
// convert array to image
|
||
if (bArrayOrInterface)
|
||
ArrayToImage(Image, &bitmap, nBpp);
|
||
else
|
||
InterfaceToImage(Image, &bitmap, nBpp);
|
||
|
||
// save info properties
|
||
UpdateProperties(bitmap, FALSE);
|
||
|
||
// locate encoder CLSID
|
||
CLSID encoder; GetEncoderClsid(L"image/tiff", &encoder);
|
||
|
||
// setup encoder values
|
||
ULONG Value0, Value1, Value2;
|
||
|
||
// create encoder settings structure
|
||
EncoderParameters* settings = (EncoderParameters*)malloc(sizeof(EncoderParameters) + 3 * sizeof(EncoderParameter));
|
||
|
||
// update value settings
|
||
settings->Parameter[0].Guid = EncoderColorDepth;
|
||
settings->Parameter[0].Type = EncoderParameterValueTypeLong;
|
||
settings->Parameter[0].NumberOfValues = 1;
|
||
settings->Parameter[0].Value = &Value0;
|
||
settings->Parameter[1].Guid = EncoderCompression;
|
||
settings->Parameter[1].Type = EncoderParameterValueTypeLong;
|
||
settings->Parameter[1].NumberOfValues = 1;
|
||
settings->Parameter[1].Value = &Value1;
|
||
settings->Parameter[2].Guid = EncoderSaveFlag;
|
||
settings->Parameter[2].Type = EncoderParameterValueTypeLong;
|
||
settings->Parameter[2].NumberOfValues = 1;
|
||
settings->Parameter[2].Value = &Value2;
|
||
|
||
// update values
|
||
Value0 = (nBpp == c_nBitmapType1bpp || nBpp == c_nBitmapType1bppDither) ? 1 : 32;
|
||
Value2 = EncoderValueFrameDimensionPage;
|
||
|
||
// update value
|
||
if (m_TiffCompression == c_nTiffCompressionNone)
|
||
Value1 = EncoderValueCompressionNone;
|
||
else if (m_TiffCompression == c_nTiffCompressionLzw)
|
||
Value1 = EncoderValueCompressionLZW;
|
||
else if (m_TiffCompression == c_nTiffCompressionRle)
|
||
Value1 = EncoderValueCompressionRle;
|
||
else if (m_TiffCompression == c_nTiffCompressionCCITT3)
|
||
Value1 = EncoderValueCompressionCCITT3;
|
||
else if (m_TiffCompression == c_nTiffCompressionCCITT4)
|
||
Value1 = EncoderValueCompressionCCITT4;
|
||
|
||
// update values count
|
||
settings->Count = 3;
|
||
|
||
// save image
|
||
m_bitmap->SaveAdd(bitmap, settings);
|
||
|
||
// check for last error
|
||
if (m_bitmap->GetLastStatus() != Ok)
|
||
{
|
||
// clear memory
|
||
free(settings);
|
||
|
||
// raise error
|
||
throw 0;
|
||
}
|
||
|
||
// close file if necessary
|
||
if (LastFrame == VARIANT_TRUE)
|
||
{
|
||
// update encoder settings
|
||
Value2 = EncoderValueFlush;
|
||
|
||
// close the multiframe file
|
||
m_bitmap->SaveAdd(settings);
|
||
|
||
// check for last error
|
||
if (m_bitmap->GetLastStatus() != Ok)
|
||
{
|
||
// clear memory
|
||
free(settings);
|
||
|
||
// raise error
|
||
throw 0;
|
||
}
|
||
}
|
||
|
||
// clear memory
|
||
free(settings);
|
||
}
|
||
catch(...)
|
||
{
|
||
// update result flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// clear memory
|
||
delete bitmap;
|
||
|
||
// close multipaged file
|
||
if (LastFrame == VARIANT_TRUE)
|
||
ClearBitmap();
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
return S_OK;
|
||
|
||
}
|
||
VARIANT_BOOL SaveImageAsPicture(void** Image, IPictureDisp** Picture, BOOL bArrayOrInterface = TRUE)
|
||
{
|
||
// update result flag
|
||
VARIANT_BOOL Success = VARIANT_TRUE;
|
||
|
||
// variables
|
||
Bitmap* bitmap = 0;
|
||
|
||
// convert image to PictureDisp
|
||
try
|
||
{
|
||
// convert array to image
|
||
if (bArrayOrInterface)
|
||
ArrayToImage(Image, &bitmap);
|
||
else
|
||
InterfaceToImage(Image, &bitmap);
|
||
|
||
// locate encoder CLSID
|
||
CLSID encoder; GetEncoderClsid(L"image/bmp", &encoder);
|
||
|
||
// setup picture
|
||
PICTDESC pict; ::ZeroMemory(&pict, sizeof(PICTDESC));
|
||
pict.cbSizeofstruct = sizeof(PICTDESC); pict.picType = PICTYPE_BITMAP;
|
||
if (bitmap->GetHBITMAP(Color::White, &pict.bmp.hbitmap) != Ok)
|
||
throw 0;
|
||
|
||
// create picture
|
||
if (FAILED(OleCreatePictureIndirect(&pict, IID_IPictureDisp, TRUE, (void**)Picture)))
|
||
throw 0;
|
||
}
|
||
catch (...)
|
||
{
|
||
// update result flag
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// clear memory
|
||
delete bitmap;
|
||
|
||
// delete backup
|
||
ClearBackup();
|
||
|
||
// all ok
|
||
return Success;
|
||
}
|
||
|
||
template<class T> // save image as pcx, tga and ras
|
||
VARIANT_BOOL SaveImageAsT(T& ImageFormat, BSTR Path, void** Image, BOOL bArray = TRUE)
|
||
{
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
|
||
int nWidth = 0;
|
||
int nHeight = 0;
|
||
int nChannels = 4;
|
||
BYTE* pPixels = 0;
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL;
|
||
|
||
try
|
||
{
|
||
if (bArray)
|
||
pPixels = ImageStudioUtils::ExtractImage((SAFEARRAY**)Image, nWidth, nHeight, nChannels);
|
||
else
|
||
pPixels = ExtractImageFromInterface((IUnknown**)Image, pMediaData, nWidth, nHeight);
|
||
|
||
if (nWidth > 1 && nHeight > 1 && nChannels == 4 && pPixels)
|
||
{
|
||
if (ImageFormat.Save(Path, nWidth, nHeight, nChannels, pPixels, 1))
|
||
Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
catch (...)
|
||
{
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
if (NULL != pMediaData)
|
||
pMediaData->Release();
|
||
|
||
return Success;
|
||
}
|
||
VARIANT_BOOL SaveImageAsMF(BSTR Path, void** Image, BOOL bEnhancedMetaFile, BOOL bArray = TRUE)
|
||
{
|
||
USES_CONVERSION;
|
||
|
||
VARIANT_BOOL Success = VARIANT_TRUE;
|
||
|
||
|
||
int nWidth = 0;
|
||
int nHeight = 0;
|
||
int nChannels = 4;
|
||
BYTE* pPixels = 0;
|
||
MediaCore::IAVSUncompressedVideoFrame* pMediaData = NULL;
|
||
|
||
try
|
||
{
|
||
if (bArray)
|
||
pPixels = ImageStudioUtils::ExtractImage((SAFEARRAY**)Image, nWidth, nHeight, nChannels);
|
||
else
|
||
pPixels = ExtractImageFromInterface((IUnknown**)Image, pMediaData, nWidth, nHeight);
|
||
|
||
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Wmf <20><><EFBFBD> Emf, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: R = 13, G = 11, B = 12. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> 13 <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>-<2D><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
|
||
BYTE *pCur = pPixels;
|
||
for ( int nY = 0; nY < nHeight; nY++ )
|
||
{
|
||
for ( int nX = 0; nX < nWidth; nX++, pCur += 4 )
|
||
{
|
||
if ( 12 == pCur[0] && 11 == pCur[1] && 13 == pCur[2] )
|
||
pCur[0] = 13;
|
||
}
|
||
}
|
||
//-------------------------------------------------------------------------------------
|
||
|
||
// create file
|
||
HDC metafileDC = 0;
|
||
if (!bEnhancedMetaFile)
|
||
metafileDC = CreateMetaFile(OLE2T(Path));
|
||
else
|
||
metafileDC = CreateEnhMetaFile(0, OLE2T(Path), 0, 0);
|
||
|
||
if (!metafileDC)
|
||
throw 0; // error creating metafile
|
||
|
||
// make BITMAPINFO
|
||
BITMAPINFO* pBmpInfo = (BITMAPINFO*)GlobalAlloc(GPTR, sizeof(BITMAPINFOHEADER) + nWidth * nHeight * nChannels);
|
||
|
||
// setup bitmap header
|
||
pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||
pBmpInfo->bmiHeader.biWidth = nWidth;
|
||
pBmpInfo->bmiHeader.biHeight = nHeight;
|
||
pBmpInfo->bmiHeader.biPlanes = 1;
|
||
pBmpInfo->bmiHeader.biBitCount = nChannels*8;
|
||
pBmpInfo->bmiHeader.biCompression = BI_RGB;
|
||
pBmpInfo->bmiHeader.biSizeImage = pBmpInfo->bmiHeader.biWidth * pBmpInfo->bmiHeader.biHeight * nChannels;
|
||
|
||
// setup bitmap data
|
||
CopyMemory(((BYTE*)pBmpInfo) + sizeof(BITMAPINFOHEADER), pPixels, pBmpInfo->bmiHeader.biSizeImage);
|
||
|
||
// draw bitmap in metafile
|
||
SetDIBitsToDevice(metafileDC, 0, 0, pBmpInfo->bmiHeader.biWidth, pBmpInfo->bmiHeader.biHeight,
|
||
0, 0, 0, pBmpInfo->bmiHeader.biHeight, ((BYTE*)pBmpInfo) + sizeof(BITMAPINFOHEADER), pBmpInfo, DIB_RGB_COLORS);
|
||
|
||
// close file and delete metafile handle
|
||
if (!bEnhancedMetaFile)
|
||
DeleteMetaFile(CloseMetaFile(metafileDC));
|
||
else
|
||
DeleteEnhMetaFile(CloseEnhMetaFile(metafileDC));
|
||
|
||
// delete image
|
||
GlobalFree(pBmpInfo);
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
Success = VARIANT_FALSE;
|
||
}
|
||
|
||
if (NULL != pMediaData)
|
||
pMediaData->Release();
|
||
|
||
return Success;
|
||
}
|
||
|
||
public:
|
||
|
||
STDMETHOD(GetFrameCount)(BSTR Path, long* Count)
|
||
{
|
||
// reset output value
|
||
*Count = 0;
|
||
|
||
// Gdi+ Bitmap object
|
||
Bitmap* bitmap = 0;
|
||
|
||
// load image from file
|
||
try
|
||
{
|
||
// attempt to load image with Gdi+
|
||
bitmap = new Bitmap(Path);
|
||
|
||
// check for valid bitmap
|
||
if (bitmap && bitmap->GetLastStatus() == Ok)
|
||
{
|
||
// variables
|
||
GUID format;
|
||
|
||
// retrieve image format
|
||
bitmap->GetRawFormat(&format);
|
||
|
||
// check for format type
|
||
if (format == ImageFormatTIFF)
|
||
*Count = bitmap->GetFrameCount(&FrameDimensionPage);
|
||
else if (format == ImageFormatGIF)
|
||
*Count = bitmap->GetFrameCount(&FrameDimensionTime);
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
}
|
||
|
||
// free memory
|
||
if (bitmap)
|
||
delete bitmap;
|
||
|
||
// check for valid count
|
||
if (*Count < 1)
|
||
{
|
||
// variables
|
||
SAFEARRAY* Array = 0;
|
||
VARIANT_BOOL Success = VARIANT_FALSE;
|
||
|
||
// try to load image
|
||
LoadImage(Path, &Array, &Success);
|
||
|
||
// check for valid image
|
||
if (Success == VARIANT_TRUE)
|
||
*Count = 1;
|
||
|
||
// destroy temporary safe array
|
||
ImageStudioUtils::DestroySafeArray(&Array);
|
||
}
|
||
|
||
// all ok
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsBmp)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAs(Path, m_BitmapType, L"image/bmp", NULL, (void**) Image, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsGif)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAs(Path, c_nBitmapType32bpp, L"image/gif", NULL, (void**) Image, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsJpeg)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsJpeg(Path, (void**) Image, TRUE);
|
||
//m_oMetaData.SaveToBMP(Path);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsPng)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAs(Path, m_BitmapType, L"image/png", NULL, (void**) Image, TRUE);
|
||
CString sFilePath(Path);
|
||
m_oMetaData.SaveToPNG(sFilePath);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsTiff)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsTiff(Path, (void**) Image, TRUE);
|
||
//m_oMetaData.SaveToBMP(sFilePath);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveFrame)(SAFEARRAY** Image, VARIANT_BOOL LastFrame, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsFrame((void**) Image, LastFrame, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveFrame2)(IUnknown** Image, VARIANT_BOOL LastFrame, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsFrame((void**) Image, LastFrame, FALSE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SavePicture)(SAFEARRAY** Image, IPictureDisp** Picture, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsPicture((void**) Image, Picture, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SavePicture2)(IUnknown** Image, IPictureDisp** Picture, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsPicture((void**) Image, Picture, FALSE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveImage2)(IUnknown** Image, LONG Format, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = VARIANT_FALSE;
|
||
|
||
switch (Format)
|
||
{
|
||
case IMAGEFORMAT_BMP: { *Success = SaveImageAs(Path, m_BitmapType, L"image/bmp", NULL, (void**) Image, FALSE); break; }
|
||
case IMAGEFORMAT_GIF: { if( VARIANT_FALSE == m_TiffMultipaged )
|
||
*Success = SaveImageAs(Path, c_nBitmapType32bpp, L"image/gif", NULL, (void**) Image, FALSE);
|
||
else
|
||
*Success = SaveImageAsAnimated(Path, IMAGEFORMAT_GIF, (void**) Image, FALSE);
|
||
break; }
|
||
case IMAGEFORMAT_JPE: { *Success = SaveImageAsJpeg(Path, (void**) Image, FALSE); break; }
|
||
case IMAGEFORMAT_PNG: { if( VARIANT_FALSE == m_TiffMultipaged )
|
||
*Success = SaveImageAs(Path, m_BitmapType, L"image/png", NULL, (void**) Image, FALSE);
|
||
else
|
||
*Success = SaveImageAsAnimated(Path, IMAGEFORMAT_PNG, (void**) Image, FALSE);
|
||
break; }
|
||
case IMAGEFORMAT_TIF: { *Success = SaveImageAsTiff(Path, (void**) Image, FALSE); break; }
|
||
case IMAGEFORMAT_WMF: { *Success = SaveImageAsMF(Path, (void**) Image, FALSE, FALSE); break; }
|
||
case IMAGEFORMAT_EMF: { *Success = SaveImageAsMF(Path, (void**) Image, TRUE, FALSE); break; }
|
||
//case IMAGEFORMAT_PCX: { ImgFilesPCX imgPcx; *Success = SaveImageAsT(imgPcx, Path, (void**) Image, FALSE); break; }
|
||
//case IMAGEFORMAT_TGA: { ImgFilesTGA imgTga; *Success = SaveImageAsT(imgTga, Path, (void**) Image, FALSE); break; }
|
||
//case IMAGEFORMAT_RAS: { ImgFilesRAS imgRas; *Success = SaveImageAsT(imgRas, Path, (void**) Image, FALSE); break; }
|
||
case IMAGEFORMAT_PCX:
|
||
{
|
||
ImageStudio::Core::Image oImage;
|
||
|
||
if (!oImage.FromMediaData( *Image, FALSE))
|
||
{
|
||
*Success = VARIANT_FALSE;
|
||
}
|
||
else
|
||
{
|
||
oImage.RotateFlip( Gdiplus::RotateNoneFlipY );
|
||
|
||
ImageStudio::IO::Pcx oWriter;
|
||
|
||
BOOL bResult = oWriter.ToFile(&oImage, ATL::CString( Path ), ImageStudio::IO::c_nFormat_Uncompressed_32bpp);
|
||
*Success = bResult ? VARIANT_TRUE : VARIANT_FALSE;
|
||
}
|
||
}
|
||
break;
|
||
case IMAGEFORMAT_TGA:
|
||
{
|
||
ImageStudio::Core::Image oImage;
|
||
|
||
if (!oImage.FromMediaData( *Image, FALSE))
|
||
{
|
||
*Success = VARIANT_FALSE;
|
||
}
|
||
else
|
||
{
|
||
oImage.RotateFlip( Gdiplus::RotateNoneFlipY );
|
||
|
||
ImageStudio::IO::Tga oWriter;
|
||
|
||
BOOL bResult = oWriter.ToFile(&oImage, ATL::CString( Path ), ImageStudio::IO::c_nFormat_Uncompressed_32bpp);
|
||
*Success = bResult ? VARIANT_TRUE : VARIANT_FALSE;
|
||
}
|
||
}
|
||
break;
|
||
case IMAGEFORMAT_RAS:
|
||
{
|
||
ImageStudio::Core::Image oImage;
|
||
|
||
if (!oImage.FromMediaData( *Image, FALSE))
|
||
{
|
||
*Success = VARIANT_FALSE;
|
||
}
|
||
else
|
||
{
|
||
oImage.RotateFlip( Gdiplus::RotateNoneFlipY );
|
||
|
||
ImageStudio::IO::Ras oWriter;
|
||
|
||
BOOL bResult = oWriter.ToFile(&oImage, ATL::CString( Path ), ImageStudio::IO::c_nFormat_Uncompressed_32bpp);
|
||
*Success = bResult ? VARIANT_TRUE : VARIANT_FALSE;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (Format >= 1024)
|
||
{
|
||
ImageStudio::IO::IPod oFileIPod;
|
||
|
||
if (oFileIPod.FromMediaData(*Image, FALSE))
|
||
{
|
||
if (oFileIPod.ToFile(CString(Path), Format))
|
||
*Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsPcx)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
ImgFilesPCX imgPcx;
|
||
|
||
*Success = SaveImageAsT(imgPcx, Path, (void**) Image, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsTga)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
ImgFilesTGA imgTga;
|
||
|
||
*Success = SaveImageAsT(imgTga, Path, (void**) Image, TRUE);
|
||
CString sFilePath(Path);
|
||
m_oMetaData.SaveToTGA(sFilePath);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsRas)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
ImgFilesRAS imgRas;
|
||
|
||
*Success = SaveImageAsT(imgRas, Path, (void**) Image, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsWmf)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsMF(Path, (void**) Image, FALSE, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsEmf)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = SaveImageAsMF(Path, (void**) Image, TRUE, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(SaveAsJ2k)(SAFEARRAY** Image, BSTR Path, VARIANT_BOOL* Success)
|
||
{
|
||
// update result flag
|
||
*Success = VARIANT_FALSE;
|
||
// save image to file
|
||
try
|
||
{
|
||
// variables
|
||
ImgFilesJ2K imgJ2k;
|
||
|
||
// save image to file
|
||
if (imgJ2k.SaveJ2k(Path, Image, m_JpegQuality))
|
||
{
|
||
// update result flag
|
||
*Success = VARIANT_TRUE;
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
// update result flag
|
||
*Success = VARIANT_FALSE;
|
||
}
|
||
|
||
// all ok-na
|
||
return S_OK;
|
||
}
|
||
|
||
// general properties
|
||
STDMETHOD(get_JpegQuality)(long *Quality)
|
||
{ *Quality = m_JpegQuality; return S_OK; }
|
||
STDMETHOD(put_JpegQuality)(long Quality)
|
||
{ m_JpegQuality = Quality; return S_OK; }
|
||
STDMETHOD(get_TiffCompression)(long *Compression)
|
||
{ *Compression = m_TiffCompression; return S_OK; }
|
||
STDMETHOD(put_TiffCompression)(long Compression)
|
||
{ m_TiffCompression = Compression; return S_OK; }
|
||
STDMETHOD(get_TiffMultipaged)(VARIANT_BOOL *Multipaged)
|
||
{ *Multipaged = m_TiffMultipaged; return S_OK; }
|
||
STDMETHOD(put_TiffMultipaged)(VARIANT_BOOL Multipaged)
|
||
{ m_TiffMultipaged = Multipaged; return S_OK; }
|
||
STDMETHOD(get_BitmapType)(long *Type)
|
||
{ *Type = m_BitmapType; return S_OK; }
|
||
STDMETHOD(put_BitmapType)(long Type)
|
||
{ m_BitmapType = Type; return S_OK; }
|
||
|
||
// information properties
|
||
STDMETHOD(get_InfoTitle)(BSTR* Value)
|
||
{ *Value = m_InfoTitle.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoTitle)(BSTR Value)
|
||
{ m_InfoTitle = Value; return S_OK; }
|
||
STDMETHOD(get_InfoDescription)(BSTR* Value)
|
||
{ *Value = m_InfoDescription.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoDescription)(BSTR Value)
|
||
{ m_InfoDescription = Value; return S_OK; }
|
||
STDMETHOD(get_InfoDateTime)(BSTR* Value)
|
||
{ *Value = m_InfoDateTime.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoDateTime)(BSTR Value)
|
||
{ m_InfoDateTime = Value; return S_OK; }
|
||
STDMETHOD(get_InfoAuthor)(BSTR* Value)
|
||
{ *Value = m_InfoAuthor.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoAuthor)(BSTR Value)
|
||
{ m_InfoAuthor = Value; return S_OK; }
|
||
STDMETHOD(get_InfoCopyright)(BSTR* Value)
|
||
{ *Value = m_InfoCopyright.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoCopyright)(BSTR Value)
|
||
{ m_InfoCopyright = Value; return S_OK; }
|
||
STDMETHOD(get_InfoEquipmentType)(BSTR* Value)
|
||
{ *Value = m_InfoEquipmentType.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoEquipmentType)(BSTR Value)
|
||
{ m_InfoEquipmentType = Value; return S_OK; }
|
||
STDMETHOD(get_InfoEquipmentModel)(BSTR* Value)
|
||
{ *Value = m_InfoEquipmentModel.AllocSysString(); return S_OK; }
|
||
STDMETHOD(put_InfoEquipmentModel)(BSTR Value)
|
||
{ m_InfoEquipmentModel = Value; return S_OK; }
|
||
STDMETHOD(get_InfoVerticalResolution)(double* Value)
|
||
{ *Value = m_InfoVerticalResolution; return S_OK; }
|
||
STDMETHOD(put_InfoVerticalResolution)(double Value)
|
||
{ m_InfoVerticalResolution = Value; return S_OK; }
|
||
STDMETHOD(get_InfoHorizontalResolution)(double* Value)
|
||
{ *Value = m_InfoHorizontalResolution; return S_OK; }
|
||
STDMETHOD(put_InfoHorizontalResolution)(double Value)
|
||
{ m_InfoHorizontalResolution = Value; return S_OK; }
|
||
|
||
STDMETHOD(LoadImage)(BSTR Path, SAFEARRAY** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadImageTo(Path, (void**) Image, ImageToArray, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadImage2)(BSTR Path, IUnknown** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadImageTo(Path, (void**) Image, ImageToInterface, FALSE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadPicture)(IPictureDisp* Picture, SAFEARRAY** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadPictureTo(Picture, (void**) Image, ImageToArray);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadPicture2)(IPictureDisp* Picture, IUnknown** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadPictureTo(Picture, (void**) Image, ImageToInterface);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadScreenshot)(SAFEARRAY** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadScreenshotTo((void**) Image, ImageToArray);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadScreenshot2)(IUnknown** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadScreenshotTo((void**) Image, ImageToInterface);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadFrame)(BSTR Path, long Frame, SAFEARRAY** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadFrameTo(Path, Frame, (void**) Image, ImageToArray, TRUE);
|
||
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(LoadFrame2)(BSTR Path, long Frame, IUnknown** Image, VARIANT_BOOL* Success)
|
||
{
|
||
*Success = LoadFrameTo(Path, Frame, (void**) Image, ImageToInterface, FALSE);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetMetaData)(BSTR bsMetaDataXML)
|
||
{
|
||
CW2T convert(bsMetaDataXML);
|
||
m_strInfoXML = convert;
|
||
m_oMetaData.SetXML(m_strInfoXML);
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetMetaData)(BSTR * bsMetaDataXML)
|
||
{
|
||
*bsMetaDataXML = m_strInfoXML.AllocSysString();
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(SetAdditionalParam)(BSTR ParamName, VARIANT ParamValue)
|
||
{
|
||
CComBSTR ParamStr = ParamName;
|
||
|
||
if ( ParamStr == L"AnimationDuration" && ParamValue.vt == VT_R8 )
|
||
{
|
||
m_dAnimationDuration = ParamValue.dblVal;
|
||
}
|
||
else if ( ParamStr == L"AnimationWidth" && ParamValue.vt == VT_I4 )
|
||
{
|
||
m_nAnimationWidth = ParamValue.lVal;
|
||
}
|
||
else if ( ParamStr == L"AnimationHeight" && ParamValue.vt == VT_I4 )
|
||
{
|
||
m_nAnimationHeight = ParamValue.lVal;
|
||
}
|
||
else if( ParamStr == L"AnimationAlpha" && ParamValue.vt == VT_BOOL )
|
||
{
|
||
if( VARIANT_FALSE == ParamValue.boolVal )
|
||
m_bAnimationGifWithAlpha = false;
|
||
else
|
||
m_bAnimationGifWithAlpha = true;
|
||
}
|
||
return S_OK;
|
||
}
|
||
STDMETHOD(GetAdditionalParam)(BSTR ParamName, VARIANT * ParamValue)
|
||
{
|
||
if (ParamName == L"Orientation")
|
||
{
|
||
(*ParamValue).iVal = m_oMetaData.GetOrientation();
|
||
}
|
||
return S_OK;
|
||
}
|
||
|
||
STDMETHOD(MetaDataFromFile)(BSTR Path)
|
||
{
|
||
m_strInfoXML = _T("");
|
||
|
||
CW2T convert(Path);
|
||
|
||
CString sPath(convert);
|
||
m_oMetaData.Clear();
|
||
m_oMetaData.FromFile(sPath);
|
||
|
||
m_strInfoXML = m_oMetaData.GetXML();
|
||
return S_OK;
|
||
}
|
||
|
||
};
|
||
|