Files
core/ASCImageStudio3/ASCImageJpeg2000/J2kFile.h

476 lines
15 KiB
C++
Raw Blame History

// J2kFile.h : Declaration of the CJ2kFile
#pragma once
#include "resource.h" // main symbols
#include "..\..\Common\XmlUtils.h"
#include "Types.h"
#define PROGRESS_MAX 1000000
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
// IJ2kFile
[
object,
uuid("D938D2B5-A639-4C55-B0AE-1A51D2DC718C"),
dual, helpstring("IJ2kFile Interface"),
pointer_default(unique)
]
__interface IJ2kFile : IDispatch
{
[id(1001)] HRESULT J2kToInterface([in]BSTR bsSrcPath, [out]IUnknown **ppImage, [in]BSTR sXmlOptions);
[id(1002)] HRESULT InterfaceToJ2k([in]IUnknown **ppImage, [in]BSTR bsSrcPath, [in]BSTR sXmlOptions);
[id(1003)] HRESULT MakeSavePreview([in]IUnknown **ppSrcImage, [out]IUnknown **ppDstImage, [in]BSTR sXmlOptions);
[id(1004)] HRESULT GetFileInfo([in]BSTR bsSrcPath, [out]BSTR *pbsXmlFileInfo);
[id(10001), helpstring("method SetAdditionalParam")] HRESULT SetAdditionalParam([in] BSTR bsParamName, [in] VARIANT vParamValue);
[id(10002), helpstring("method GetAdditionalParam")] HRESULT GetAdditionalParam([in] BSTR bsParamName, [out] VARIANT *pvParamValue);
};
// _IAVSOfficeFileTemplateEvents
[
dispinterface,
uuid("8B2E4132-B1C2-443e-80A1-4F052FD66D9D"),
helpstring("_IAVSOfficeFileTemplateEvents Interface")
]
__interface _IAVSJ2kFileEvents
{
//Max Value nPercent == 1000000
//Example 23,56 % == 235600
[id(1), helpstring("method OnProgress")] HRESULT OnProgress([in] LONG nID, [in] LONG nPercent);
};
// CJ2kFile
[
coclass,
default(IJ2kFile),
threading(apartment),
event_source(com),
vi_progid("AVSImageJpeg2000.J2kFile"),
progid("AVSImageJpeg2000.J2kFile.1"),
version(1.0),
uuid("1221E292-1767-4F25-BC16-23A5A7E3246F"),
helpstring("J2kFile Class")
]
class ATL_NO_VTABLE CJ2kFile :
public IJ2kFile
{
public:
__event __interface _IAVSJ2kFileEvents;
public:
CJ2kFile()
{
#ifdef _DEBUG
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_WNDW );
#endif
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
long ApplyDecoderOptions(DecoderParams *pParameters, CString sXml)
{
memset( pParameters, 0, sizeof(DecoderParams) );
pParameters->eLimitDecoding = declimNoLimitation;
pParameters->bConvertToRGBA = true;
pParameters->nReduce = 0;
pParameters->nLayer = 0;
if ( sXml.GetLength() > 0 )
{
XmlUtils::CXmlNode oMainNode;
oMainNode.FromXmlString( sXml );
if ( -1 != oMainNode.GetName().Find( _T("Jpeg2000-Options") ) )
{
XmlUtils::CXmlNode oOpenNode;
if ( oMainNode.GetNode( _T("OpenOptions"), oOpenNode ) )
{
XmlUtils::CXmlNode oCurNode;
CString sValue;
// ReduceFactor
if ( oOpenNode.GetNode( _T("ConvertToRGBA"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("value"), _T("0") );
pParameters->bConvertToRGBA = ( _wtoi( sValue.GetBuffer() ) ? true : false );
}
// ReduceFactor
if ( oOpenNode.GetNode( _T("ReduceFactor"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("value"), _T("0") );
pParameters->nReduce = _wtoi( sValue.GetBuffer() );
}
// LayersCount
if ( oOpenNode.GetNode( _T("LayersCount"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("value"), _T("0") );
pParameters->nLayer = _wtoi( sValue.GetBuffer() );
}
}
}
}
return 0;
}
long ApplyEncoderOptions(EncoderParams *pParameters, CString sXml)
{
int nFormat = 0; // J2k
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><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> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memset( pParameters, 0, sizeof(EncoderParams) );
pParameters->nComponentsCount = 3;
pParameters->nResolutionsCount = 6;
pParameters->nCodeBlockHeightInit = 64;
pParameters->nCodeBlockWidthInit = 64;
pParameters->eProgOrder = poLRCP;
pParameters->nROIComponentIndex = -1; // <20><><EFBFBD> ROI
pParameters->nSubSamplingDx = 1;
pParameters->nSubSamplingDy = 1;
pParameters->bTileSizeOn = false;
pParameters->sComment = "Manufactured by Online Media Technologies Ltd.";
if ( sXml.GetLength() > 0 )
{
XmlUtils::CXmlNode oMainNode;
oMainNode.FromXmlString( sXml );
if ( -1 != oMainNode.GetName().Find( _T("Jpeg2000-Options") ) )
{
XmlUtils::CXmlNode oSaveNode;
if ( oMainNode.GetNode( _T("SaveOptions"), oSaveNode ) )
{
XmlUtils::CXmlNode oCurNode;
CString sValue;
// ComponentsCount
if ( oSaveNode.GetNode( _T("ComponentsCount"), oCurNode ) )
{
pParameters->nComponentsCount = XmlUtils::GetInteger( oCurNode.GetAttribute( _T("value"), _T("3") ) );
}
// Format
if ( oSaveNode.GetNode( _T("Format"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("value"), _T("0") );
nFormat = _wtoi( sValue.GetBuffer() );
}
// Tile
if ( oSaveNode.GetNode( _T("Tile"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("width"), _T("32") );
pParameters->nXTsiz = max( 32, _wtoi( sValue.GetBuffer() ) );
sValue = oCurNode.GetAttribute( _T("height"), _T("32") );
pParameters->nYTsiz = max( 32, _wtoi( sValue.GetBuffer() ) );
pParameters->bTileSizeOn = true;
sValue = oCurNode.GetAttribute( _T("offsetx"), _T("0") );
pParameters->nXTOsiz = _wtoi( sValue.GetBuffer() );
sValue = oCurNode.GetAttribute( _T("offsety"), _T("0") );
pParameters->nYTOsiz = _wtoi( sValue.GetBuffer() );
}
// Resolution
if ( oSaveNode.GetNode( _T("Resolution"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("levelscount"), _T("6") );
pParameters->nResolutionsCount = max( 1, min ( J2K_MAXRLVLS, _wtoi( sValue.GetBuffer() ) ) );
}
// PrecinctDimension
if ( oSaveNode.GetNode( _T("PrecinctDimension"), oCurNode ) )
{
sValue = oCurNode.GetText();
wchar_t *wsTemp = sValue.GetBuffer();
char nSeparateChar = 0;
int nPrecinctsCount = 0;
do
{
nSeparateChar = 0;
swscanf( wsTemp, _T("[%d,%d]%c"), &pParameters->anPrecinctWidthInit[nPrecinctsCount], &pParameters->anPrecinctHeightInit[nPrecinctsCount], &nSeparateChar );
pParameters->nCodingStyle |= 0x01;
nPrecinctsCount++;
if ( J2K_MAXRLVLS == nPrecinctsCount )
break;
wsTemp = wcspbrk( wsTemp, _T("]") ) + 2;
}
while ( ',' == nSeparateChar );
pParameters->nPrecinctCount = nPrecinctsCount;
}
// CodeBlockDimension
if ( oSaveNode.GetNode( _T("CodeBlockDimension"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("width"), _T("64") );
pParameters->nCodeBlockWidthInit = max( 4, min( 4096, _wtoi( sValue.GetBuffer() ) ) );
sValue = oCurNode.GetAttribute( _T("height"), _T("64") );
pParameters->nCodeBlockHeightInit = max( 4, min( 4096, _wtoi( sValue.GetBuffer() ) ) );
}
// ProgressionOrder
if ( oSaveNode.GetNode( _T("ProgressionOrder"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("value"), _T("0") );
int nProgOrder = max( 0, min( 4, _wtoi( sValue.GetBuffer() ) ) );
switch( nProgOrder )
{
case 0: pParameters->eProgOrder = poLRCP; break;
case 1: pParameters->eProgOrder = poRLCP; break;
case 2: pParameters->eProgOrder = poRPCL; break;
case 3: pParameters->eProgOrder = poPCRL; break;
case 4: pParameters->eProgOrder = poCPRL; break;
}
}
// Subsampling
if ( oSaveNode.GetNode( _T("Subsampling"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("dx"), _T("1") );
pParameters->nSubSamplingDx = max( 1, min( J2K_MAXSSFTR, _wtoi( sValue.GetBuffer() ) ) );
sValue = oCurNode.GetAttribute( _T("dy"), _T("1") );
pParameters->nSubSamplingDy = max( 1, min( J2K_MAXSSFTR, _wtoi( sValue.GetBuffer() ) ) );
}
// SOPmarker
if ( oSaveNode.GetNode( _T("SOPmarker"), oCurNode ) )
{
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ImageInfo
//pParameters->nCodingStyle |= 0x02;
}
// EPHmarker
if ( oSaveNode.GetNode( _T("EPHmarker"), oCurNode ) )
{
pParameters->nCodingStyle |= 0x04;
}
// ROI
if ( oSaveNode.GetNode( _T("ROI"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("componentindex"), _T("-1") );
pParameters->nROIComponentIndex = max( -1, _wtoi( sValue.GetBuffer() ) );
sValue = oCurNode.GetAttribute( _T("shift"), _T("0") );
pParameters->nROIShift = max( 0, min( 37, _wtoi( sValue.GetBuffer() ) ) );
}
// Comment
if ( oSaveNode.GetNode( _T("Comment"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("value") );
// TO DO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
USES_CONVERSION;
pParameters->sComment = W2A( sValue.GetBuffer() );
}
// Compression
if ( oSaveNode.GetNode( _T("Compression"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("lossless"), _T("1") );
pParameters->nTransformId = _wtoi( sValue.GetBuffer() ) ? 0 : 1;
}
// Rate-Disto
if ( oSaveNode.GetNode( _T("Rate-Disto"), oCurNode ) )
{
sValue = oCurNode.GetText();
wchar_t *wsTemp = sValue.GetBuffer();
while ( swscanf( wsTemp, _T("%f"), &pParameters->afRates[pParameters->nLayersCount] ) == 1 )
{
pParameters->nLayersCount++;
while ( *wsTemp && *wsTemp != _T(',') )
{
wsTemp++;
}
if ( !*wsTemp )
break;
wsTemp++;
}
pParameters->nDistoAlloc = 1;
}
// Fixed-Quality
if ( oSaveNode.GetNode( _T("Fixed-Quality"), oCurNode ) )
{
sValue = oCurNode.GetText();
wchar_t *wsTemp = sValue.GetBuffer();
while ( swscanf( wsTemp, _T("%f"), &pParameters->afDistoratio[pParameters->nLayersCount] ) == 1 )
{
pParameters->nLayersCount++;
while ( *wsTemp && *wsTemp != ',' )
{
wsTemp++;
}
if ( !*wsTemp )
break;
wsTemp++;
}
pParameters->nFixedQuality = 1;
}
// Fixed-Layer
if ( oSaveNode.GetNode( _T("Fixed-Layer"), oCurNode ) )
{
sValue = oCurNode.GetAttribute( _T("layerscount"), _T("1") );
int nLayersCount = max( 1, _wtoi( sValue.GetBuffer() ) );
pParameters->nLayersCount = nLayersCount;
int nResolutionsCount = pParameters->nResolutionsCount;
int nMatrixWidth = nResolutionsCount * 3;
pParameters->pMatrix = (int*)Malloc(0, nLayersCount * nMatrixWidth * sizeof(int) );
sValue = oCurNode.GetText();
wchar_t *wsTemp = sValue.GetBuffer();
for ( int nLayerIndex = 0; nLayerIndex < nLayersCount; nLayerIndex++ )
{
int *pRow = &pParameters->pMatrix[nLayerIndex * nMatrixWidth];
int *pCol = pRow;
pParameters->afRates[nLayerIndex] = 1;
swscanf( wsTemp, _T("%d,"), &pCol[0] );
wsTemp += 2;
if ( pCol[0] > 9 )
wsTemp++;
pCol[1] = 0;
pCol[2] = 0;
for ( int nResolutionIndex = 1; nResolutionIndex < nResolutionsCount; nResolutionIndex++ )
{
pCol += 3;
swscanf( wsTemp, _T("%d,%d,%d"), &pCol[0], &pCol[1], &pCol[2] );
wsTemp += 6;
if ( pCol[0] > 9 )
wsTemp++;
if ( pCol[1] > 9 )
wsTemp++;
if ( pCol[2] > 9 )
wsTemp++;
}
if ( nLayerIndex < nLayersCount - 1 )
wsTemp++;
}
pParameters->nFixedAlloc = 1;
}
}
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> nDistoAlloc, nFixedQuality, nFixedAlloc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( ( pParameters->nDistoAlloc || pParameters->nFixedAlloc || pParameters->nFixedQuality ) && ( !( pParameters->nDistoAlloc ^ pParameters->nFixedAlloc ^ pParameters->nFixedQuality ) ) )
return -1;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( 0 == pParameters->nLayersCount )
{
pParameters->afRates[0] = 0;
pParameters->nLayersCount = 1;
pParameters->nDistoAlloc = 1;
}
if ( pParameters->nXTOsiz > pParameters->nImageOffsetX0 || pParameters->nYTOsiz > pParameters->nImageOffsetY0 )
return -1;
for ( int nIndex = 0; nIndex < pParameters->nPOCsCount; nIndex++ )
{
if ( -1 == pParameters->aoPOC[nIndex].ePpoc )
{
// TO DO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
}
}
return nFormat;
}
public:
STDMETHOD(J2kToInterface)(BSTR bsSrcPath, IUnknown **ppImage, BSTR bsXmlOptions);
STDMETHOD(InterfaceToJ2k)(IUnknown **ppImage, BSTR bsDstPath, BSTR bsXmlOptions);
STDMETHOD(MakeSavePreview)(IUnknown **ppSrcImage, IUnknown **pDstImage, BSTR bsXmlOptions)
{
return S_OK;
}
STDMETHOD(GetFileInfo)(BSTR bsSrcPath, BSTR *pbsXmlFileInfo)
{
return S_OK;
}
STDMETHOD(SetAdditionalParam)(BSTR bsParamName, VARIANT vParamValue)
{
return S_OK;
}
STDMETHOD(GetAdditionalParam)(BSTR bsParamName, VARIANT* pvParamValue)
{
return S_OK;
}
HRESULT Error(long Code)
{
LPCOLESTR lpszDesc;
HRESULT hRes;
switch(Code)
{
case NOERROR: return S_OK;
case BUSY: hRes=AVS_ERROR_BUSY;lpszDesc=c_pszErrorBusy;break;
case MEMORY: hRes=AVS_ERROR_MEMORY;lpszDesc=c_pszErrorMemory;break;
case FILEACCESS: hRes=AVS_ERROR_FILEACCESS;lpszDesc=c_pszErrorFileAccess;break;
case INVALIDARGUMENT: hRes=AVS_ERROR_INVALIDARGUMENT;lpszDesc=c_pszErrorInvalidArgument;break;
case CONTROLNOTINSTALLED: hRes=AVS_ERROR_CONTROLNOTINSTALLED;lpszDesc=c_pszErrorControlNotInstalled;break;
case INDEXOUTOFRANGE: hRes=AVS_ERROR_INDEXOUTOFRANGE;lpszDesc=c_pszErrorIndexOutOfRange;break;
case FILEFORMAT: hRes=AVS_ERROR_FILEFORMAT;lpszDesc=c_pszErrorFileFormat;break;
case UNEXPECTED:
default: hRes=AVS_ERROR_UNEXPECTED;lpszDesc=c_pszErrorUnexpected;break;
}
AtlTrace(L"ERROR %d (%s)", Code, lpszDesc);
return AtlReportError(GetObjectCLSID(), lpszDesc, __uuidof(IJ2kFile), hRes);
}
};