Files
DocumentServer-v-9.2.0/core/DesktopEditor/raster/Jp2/J2kFile.cpp
T
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

761 lines
26 KiB
C++

#include "J2kFile.h"
#include "J2kIncludes.h"
#include "Utils.h"
namespace Jpeg2000
{
void* Malloc(size_t nSize)
{
void *pMemBlock = malloc(nSize);
if (!pMemBlock)
{
// TODO: print error "Memory !!\n")
}
else
{
memset(pMemBlock, 0x00, nSize);
}
return pMemBlock;
}
int check_j2000_type(BYTE* pBuffer, int nSize)
{
if (!pBuffer)
return 0;
int type = 0;
if ((32 <= nSize) && (0x00 == pBuffer[0] && 0x00 == pBuffer[1] && 0x00 == pBuffer[2] && 0x0c == pBuffer[3]
&& 0x6a == pBuffer[4] && 0x50 == pBuffer[5] && 0x20 == pBuffer[6] && 0x20 == pBuffer[7]
&& 0x0d == pBuffer[8] && 0x0a == pBuffer[9] && 0x87 == pBuffer[10] && 0x0a == pBuffer[11]
&& 0x00 == pBuffer[12] && 0x00 == pBuffer[13] && 0x00 == pBuffer[14] /*&& (0x14 == pBuffer[15] || 0x18 == pBuffer[15] )*/
&& 0x66 == pBuffer[16] && 0x74 == pBuffer[17] && 0x79 == pBuffer[18] && 0x70 == pBuffer[19]
&& 0x6a == pBuffer[20] && 0x70 == pBuffer[21] && 0x32 == pBuffer[22] && 0x20 == pBuffer[23]
&& 0x00 == pBuffer[24] && 0x00 == pBuffer[25] && 0x00 == pBuffer[26] && 0x00 == pBuffer[27]
/*&& 0x6a == pBuffer[28] && 0x70 == pBuffer[29] && 0x32 == pBuffer[30] && 0x20 == pBuffer[31]*/))
{
type = 1;
}
if ((4 <= nSize) && (0xff == pBuffer[0] && 0x4f == pBuffer[1] && 0xff == pBuffer[2] && 0x51 == pBuffer[3]))
{
type = 2;
}
if ((32 <= nSize) && (0x00 == pBuffer[0] && 0x00 == pBuffer[1] && 0x00 == pBuffer[2] && 0x0c == pBuffer[3]
&& 0x6a == pBuffer[4] && 0x50 == pBuffer[5] && 0x20 == pBuffer[6] && 0x20 == pBuffer[7]
&& 0x0d == pBuffer[8] && 0x0a == pBuffer[9] && 0x87 == pBuffer[10] && 0x0a == pBuffer[11]
&& 0x00 == pBuffer[12] && 0x00 == pBuffer[13] && 0x00 == pBuffer[14] && 0x18 == pBuffer[15]
&& 0x66 == pBuffer[16] && 0x74 == pBuffer[17] && 0x79 == pBuffer[18] && 0x70 == pBuffer[19]
&& 0x6d == pBuffer[20] && 0x6a == pBuffer[21] && 0x70 == pBuffer[22] && 0x32 == pBuffer[23]
&& 0x00 == pBuffer[24] && 0x00 == pBuffer[25] && 0x00 == pBuffer[26] && 0x00 == pBuffer[27]
&& 0x6d == pBuffer[28] && 0x6a == pBuffer[29] && 0x70 == pBuffer[30] && 0x32 == pBuffer[31]))
{
type = 3;
}
return type;
}
int check_j2000_type(FILE* pFile)
{
if (!pFile)
return 0;
BYTE *pBuffer = new BYTE[1024];
if (!pBuffer)
return 0;
size_t nBytesRead = fread(pBuffer, 1, 1024, pFile);
int type = check_j2000_type(pBuffer, nBytesRead);
delete[] pBuffer;
fseek(pFile, 0, SEEK_SET);
return type;
}
// CJ2kFile
bool ImageToFrame(Image* pImage, CBgraFrame* pFrame, bool isBGRA)
{
int nWidth = pImage->pComponents[0].nWidth;
int nHeight = pImage->pComponents[0].nHeight;
int nBufferSize = 4 /*pImage->nCsiz*/ * nWidth * nHeight;
if (nBufferSize < 1)
return false;
pFrame->put_Width(nWidth);
pFrame->put_Height(nHeight);
pFrame->put_Stride(4 * nWidth);
BYTE* pData = new BYTE[nBufferSize];
if (!pData)
return false;
pFrame->put_Data(pData);
unsigned char* pBufferPtr = (unsigned char*)pData;
unsigned char indR = isBGRA ? 2 : 0;
unsigned char indG = 1;
unsigned char indB = isBGRA ? 0 : 2;
Jpeg2000::ImageComponent* pComponents = pImage->pComponents;
// Пишем данные в pBufferPtr
if (pImage->nCsiz == 3 && pImage->pComponents[0].nXRsiz == pImage->pComponents[1].nXRsiz && pImage->pComponents[1].nXRsiz == pImage->pComponents[2].nXRsiz
&& pImage->pComponents[0].nYRsiz == pImage->pComponents[1].nYRsiz && pImage->pComponents[1].nYRsiz == pImage->pComponents[2].nYRsiz
&& pImage->pComponents[0].nPrecision == pImage->pComponents[1].nPrecision && pImage->pComponents[1].nPrecision == pImage->pComponents[2].nPrecision)
{
int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2);
int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2);
int nValue = nWidth * (nResH - 1);
for (int j = 0; j < nResH; ++j)
{
for (int i = 0; i < nResW; ++i)
{
pBufferPtr[indR] = pComponents[0].pData[nValue + i];
pBufferPtr[indG] = pComponents[1].pData[nValue + i];
pBufferPtr[indB] = pComponents[2].pData[nValue + i];
pBufferPtr[3] = 255;
pBufferPtr += 4;
}
nValue -= nWidth;
}
}
else if (pImage->nCsiz >= 4 && pImage->pComponents[0].nXRsiz == pImage->pComponents[1].nXRsiz && pImage->pComponents[1].nXRsiz == pImage->pComponents[2].nXRsiz && pImage->pComponents[2].nXRsiz == pImage->pComponents[3].nXRsiz
&& pImage->pComponents[0].nYRsiz == pImage->pComponents[1].nYRsiz && pImage->pComponents[1].nYRsiz == pImage->pComponents[2].nYRsiz && pImage->pComponents[2].nYRsiz == pImage->pComponents[3].nYRsiz
&& pImage->pComponents[0].nPrecision == pImage->pComponents[1].nPrecision && pImage->pComponents[1].nPrecision == pImage->pComponents[2].nPrecision && pImage->pComponents[2].nPrecision == pImage->pComponents[3].nPrecision)
{
int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2);
int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2);
int nValue = nWidth * (nResH - 1);
for (int j = 0; j < nResH; ++j)
{
for (int i = 0; i < nResW; ++i)
{
pBufferPtr[indR] = pComponents[0].pData[nValue + i];
pBufferPtr[indG] = pComponents[1].pData[nValue + i];
pBufferPtr[indB] = pComponents[2].pData[nValue + i];
pBufferPtr[3] = pComponents[3].pData[nValue + i];
pBufferPtr += 4;
}
nValue -= nWidth;
}
}
else // Grayscale
{
int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2);
int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2);
int nValue = nWidth * (nResH - 1);
for (int j = 0; j < nResH; ++j)
{
for (int i = 0; i < nResW; ++i)
{
pBufferPtr[0] = pComponents[0].pData[nValue + i];
pBufferPtr[1] = pBufferPtr[0];
pBufferPtr[2] = pBufferPtr[0];
pBufferPtr[3] = 255;
pBufferPtr += 4;
}
nValue -= nWidth;
}
}
return true;
}
bool CJ2kFile::Open(CBgraFrame* pFrame, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions, bool isBGRA)
{
Image *pImage = NULL;
DecoderParams oParameters;
// Установим стандартные значения параметров
ApplyDecoderOptions(&oParameters, wsXmlOptions);
///////////////////////////////////////////////////////////////////////////////////
NSFile::CFileBinary oFile;
if (!oFile.OpenFile(wsSrcPath))
return false;
int type = check_j2000_type(oFile.GetFileNative());
oFile.CloseFile();
bool bOpenResult = false;
if (!bOpenResult && type == 1)
bOpenResult = (NULL != (pImage = Jp2ToImage(wsSrcPath, &oParameters)));
if (!bOpenResult && type == 2)
bOpenResult = (NULL != (pImage = J2kToImage(wsSrcPath, &oParameters)));
if (!bOpenResult && type == 3)
bOpenResult = (NULL != (pImage = Mj2ToImage(wsSrcPath, &oParameters)));
if (!bOpenResult && type == 4)
bOpenResult = (NULL != (pImage = JptToImage(wsSrcPath, &oParameters)));
if (!bOpenResult)
{
Image_Destroy(pImage);
return false;
}
bool bFrame = ImageToFrame(pImage, pFrame, isBGRA);
Image_Destroy(pImage);
return bFrame;
}
bool CJ2kFile::Open(CBgraFrame* pFrame, BYTE* pBuffer, int nSize, const std::wstring& wsXmlOptions, bool isBGRA)
{
Image *pImage = NULL;
DecoderParams oParameters;
// Установим стандартные значения параметров
ApplyDecoderOptions(&oParameters, wsXmlOptions);
///////////////////////////////////////////////////////////////////////////////////
int type = check_j2000_type(pBuffer, nSize);
bool bOpenResult = false;
if (!bOpenResult && type == 1)
bOpenResult = (NULL != (pImage = Jp2ToImage(pBuffer, nSize, &oParameters)));
if (!bOpenResult && type == 2)
bOpenResult = (NULL != (pImage = J2kToImage(pBuffer, nSize, &oParameters)));
if (!bOpenResult && type == 3)
bOpenResult = (NULL != (pImage = Mj2ToImage(pBuffer, nSize, &oParameters)));
if (!bOpenResult && type == 4)
bOpenResult = (NULL != (pImage = JptToImage(pBuffer, nSize, &oParameters)));
if (!bOpenResult)
{
Image_Destroy(pImage);
return false;
}
bool bFrame = ImageToFrame(pImage, pFrame, isBGRA);
Image_Destroy(pImage);
return bFrame;
}
bool CJ2kFile::Open(BYTE** ppData, int& nComponentsCount, int& nWidth, int& nHeight, const std::wstring& wsSrcPath, const std::wstring& wsXmlOptions)
{
Image *pImage = NULL;
DecoderParams oParameters;
// Установим стандартные значения параметров
ApplyDecoderOptions(&oParameters, wsXmlOptions);
///////////////////////////////////////////////////////////////////////////////////
NSFile::CFileBinary oFile;
if (!oFile.OpenFile(wsSrcPath))
return false;
DWORD nFileSize = oFile.GetFileSize();
int type = check_j2000_type(oFile.GetFileNative());
oFile.CloseFile();
bool bOpenResult = false;
if (!bOpenResult && type == 1)
bOpenResult = (NULL != (pImage = Jp2ToImage(wsSrcPath, &oParameters)));
if (!bOpenResult && type == 2)
bOpenResult = (NULL != (pImage = J2kToImage(wsSrcPath, &oParameters)));
if (!bOpenResult && type == 3)
bOpenResult = (NULL != (pImage = Mj2ToImage(wsSrcPath, &oParameters)));
if (!bOpenResult && type == 4)
bOpenResult = (NULL != (pImage = JptToImage(wsSrcPath, &oParameters)));
if (!bOpenResult)
{
Image_Destroy(pImage);
return false;
}
nWidth = pImage->pComponents[0].nWidth;
nHeight = pImage->pComponents[0].nHeight;
int nBufferSize = pImage->nCsiz * nWidth * nHeight;
if (nBufferSize < 1 || pImage->nCsiz <= 0)
{
Image_Destroy(pImage);
return false;
}
*ppData = new BYTE[nBufferSize];
if (!(*ppData))
{
Image_Destroy(pImage);
return false;
}
unsigned char* pBufferPtr = (unsigned char*)(*ppData);
long nCreatedBufferSize = nBufferSize;
nComponentsCount = pImage->nCsiz;
// Пишем данные в pBufferPtr
for (int nComponent = 1; nComponent < nComponentsCount; nComponent++)
{
if (pImage->pComponents[0].nXRsiz != pImage->pComponents[nComponent].nXRsiz
|| pImage->pComponents[0].nYRsiz != pImage->pComponents[nComponent].nYRsiz
|| pImage->pComponents[0].nPrecision != pImage->pComponents[nComponent].nPrecision)
{
delete[](*ppData);
Image_Destroy(pImage);
return false;
}
}
int nResW = CeilDivPow2(pImage->pComponents[0].nWidth, pImage->pComponents[0].nFactorDiv2);
int nResH = CeilDivPow2(pImage->pComponents[0].nHeight, pImage->pComponents[0].nFactorDiv2);
for (int nIndex = 0; nIndex < nResW * nResH; nIndex++)
{
for (int nComponent = 0; nComponent < nComponentsCount; nComponent++)
{
pBufferPtr[nComponent] = pImage->pComponents[nComponent].pData[nWidth * nResH - ((nIndex) / (nResW)+1) * nWidth + (nIndex) % (nResW)];
}
pBufferPtr += nComponentsCount;
}
Image_Destroy(pImage);
return true;
}
bool CJ2kFile::Save(CBgraFrame* pFrame, const std::wstring& wsDstPath, const std::wstring& wsXmlOptions)
{
// TODO: Запись не реализована, надо доделать.
return false;
if (!pFrame)
return false;
LONG lWidth = pFrame->get_Width();
LONG lHeight = pFrame->get_Height();
BYTE* pSourceBuffer = pFrame->get_Data();
LONG lBufferSize = 4 * lWidth * lHeight;
// Далее обрабатываем Xml с параметрами компрессии
EncoderParams oParameters;
int nFormat = ApplyEncoderOptions(&oParameters, wsXmlOptions);
// TODO: Добавить возможность записи альфа-канала
ImageComponentParams aComponentParams[3]; // Пока пусть будет максимально три компоненты (RGB)
Image *pImage = NULL;
int nComponentsCount = oParameters.nComponentsCount;
memset(&aComponentParams[0], 0, sizeof(ImageComponentParams));
for (int nIndex = 0; nIndex < nComponentsCount; nIndex++)
{
aComponentParams[nIndex].nPrecision = 8;
aComponentParams[nIndex].nBPP = 8;
aComponentParams[nIndex].nSigned = 0;
aComponentParams[nIndex].nXRsiz = oParameters.nSubSamplingDx;
aComponentParams[nIndex].nYRsiz = oParameters.nSubSamplingDy;
aComponentParams[nIndex].nWidth = (int)lWidth;
aComponentParams[nIndex].nHeight = (int)lHeight;
}
// Создаем структуру Image
pImage = Image_Create(nComponentsCount, &aComponentParams[0], csRGB);
if (!pImage)
return false;
pImage->nXOsiz = oParameters.nImageOffsetX0;
pImage->nYOsiz = oParameters.nImageOffsetY0;
pImage->nXsiz = (!pImage->nXOsiz) ? (lWidth - 1) * oParameters.nSubSamplingDx + 1 : pImage->nXOsiz + (lWidth - 1) * oParameters.nSubSamplingDy + 1;
pImage->nYsiz = (!pImage->nYOsiz) ? (lHeight - 1) * oParameters.nSubSamplingDy + 1 : pImage->nYOsiz + (lHeight - 1) * oParameters.nSubSamplingDy + 1;
if (3 == nComponentsCount)
{
int nIndex = 0;
for (int nY = 0; nY < (int)lHeight; nY++)
{
for (int nX = 0; nX < (int)lWidth; nX++, pSourceBuffer += 4)
{
pImage->pComponents[0].pData[nIndex] = pSourceBuffer[2];
pImage->pComponents[1].pData[nIndex] = pSourceBuffer[1];
pImage->pComponents[2].pData[nIndex] = pSourceBuffer[0];
nIndex++;
}
}
}
else if (1 == nComponentsCount)
{
int nIndex = 0;
for (int nY = 0; nY < (int)lHeight; nY++)
{
for (int nX = 0; nX < (int)lWidth; nX++, pSourceBuffer += 4)
{
pImage->pComponents[0].pData[nIndex] = pSourceBuffer[0];
nIndex++;
}
}
}
else
{
Image_Destroy(pImage);
return false;
}
bool bRes = false;
switch (nFormat)
{
case 0: bRes = ImageToJ2k(pImage, wsDstPath, &oParameters); break;
case 1: bRes = ImageToJ2p(pImage, wsDstPath, &oParameters); break;
case -1:
default: bRes = false;
}
Image_Destroy(pImage);
return bRes;
}
void CJ2kFile::ApplyDecoderOptions(void *pParametersV, const std::wstring& sXml)
{
DecoderParams* pParameters = (DecoderParams*)pParametersV;
memset(pParameters, 0, sizeof(DecoderParams));
pParameters->eLimitDecoding = declimNoLimitation;
pParameters->nReduce = 0;
pParameters->nLayer = 0;
// TODO: Сделать чтение параметров декодирования
//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());
// }
// }
// }
//}
}
long CJ2kFile::ApplyEncoderOptions(void *pParametersV, const std::wstring& sXml)
{
EncoderParams* pParameters = (EncoderParams*)pParameters;
int nFormat = 0; // J2k
// Сначала выставляем стандартные значения параметров
memset(pParameters, 0, sizeof(EncoderParams));
pParameters->nComponentsCount = 3;
pParameters->nResolutionsCount = 6;
pParameters->nCodeBlockHeightInit = 64;
pParameters->nCodeBlockWidthInit = 64;
pParameters->eProgOrder = poLRCP;
pParameters->nROIComponentIndex = -1; // Нет ROI
pParameters->nSubSamplingDx = 1;
pParameters->nSubSamplingDy = 1;
pParameters->bTileSizeOn = false;
pParameters->sComment = (char*)"Manufactured by Online Media Technologies Ltd.";
// TODO: Сделать чтение параметров кодирования
//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))
// {
// // Пока отключим, потом надо будет добавить - для этого нужно выделять память для стрктуры 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: Неправильное копирование строки
// 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;
// }
// }
// }
//}
// Проверим кооректность введенных параметров
// Параметры nDistoAlloc, nFixedQuality, nFixedAlloc нельзя использовать вместе
if ((pParameters->nDistoAlloc || pParameters->nFixedAlloc || pParameters->nFixedQuality) && (!(pParameters->nDistoAlloc ^ pParameters->nFixedAlloc ^ pParameters->nFixedQuality)))
return -1;
// Если параметры не заданы, тогда по умолчанию ставим компрессию без потерь
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: Выдать ошибку, что порядок не задан
}
}
return nFormat;
}
}