Added saving arbitrary bytes from an EMF file to XML, Refactoring

This commit is contained in:
Kirill Poljakov
2021-04-28 23:38:55 +03:00
parent aad4c38574
commit c2cb1fd828
5 changed files with 155 additions and 38 deletions

View File

@ -1,4 +1,5 @@
#include "CXmlOutput.h"
#include "../../common/Base64.h"
namespace MetaFile
{
@ -97,6 +98,18 @@ namespace MetaFile
m_oXmlWriter.WriteNode(wsNameNode, std::to_wstring(unValueNode));
}
void CXmlOutput::WriteNode(const std::wstring &wsNameNode, const BYTE *pValueNode, unsigned int unSizeValue)
{
int nSize = NSBase64::Base64EncodeGetRequiredLength(unSizeValue);
unsigned char* ucValue = new unsigned char[nSize];
NSBase64::Base64Encode(pValueNode, unSizeValue, ucValue, &nSize);
std::wstring wsValue(ucValue, ucValue + nSize);
m_oXmlWriter.WriteNode(wsNameNode, wsValue);
delete[] ucValue;
}
void CXmlOutput::WriteNode(const std::wstring &wsNameNode, double dValueNode)
{
m_oXmlWriter.WriteNode(wsNameNode, dValueNode);
@ -114,15 +127,16 @@ namespace MetaFile
void CXmlOutput::WriteNode(const std::wstring &wsNameNode, std::vector<XmlArgument> arArguments)
{
m_oXmlWriter.WriteNodeBegin(wsNameNode, !arArguments.empty());
m_oXmlWriter.WriteNodeBegin(wsNameNode, true);
if (!arArguments.empty())
{
for (unsigned int i = 0; i < arArguments.size(); ++i)
WriteAttribute(arArguments[i].wsName, arArguments[i].wsValue);
m_oXmlWriter.WriteNodeEnd(wsNameNode, true, true);
}
m_oXmlWriter.WriteNodeEnd(wsNameNode, true, true);
}
void CXmlOutput::WriteNode(const std::wstring &wsNameNode, const TEmfRectL &oTEmfRectL, std::vector<XmlArgument> arArguments)

View File

@ -43,6 +43,7 @@ namespace MetaFile
void WriteNode(const std::wstring& wsNameNode, unsigned short usValueNode);
void WriteNode(const std::wstring& wsNameNode, unsigned char ucValueNode);
void WriteNode(const std::wstring& wsNameNode, unsigned int unValueNode);
void WriteNode(const std::wstring& wsNameNode, const BYTE* pValueNode, unsigned int unSizeValue);
void WriteNode(const std::wstring& wsNameNode, double dValueNode);
void WriteNode(const std::wstring& wsNameNode, short shValueNode);
void WriteNode(const std::wstring& wsNameNode, int nValueNode);

View File

@ -382,7 +382,7 @@ static const struct ActionNamesEmf
if (NULL != m_pOutputXml)
{
m_pOutputXml->WriteNodeEnd(L"EMF");
m_pOutputXml->SaveToFile(NSFile::GetProcessDirectory() + L"/tests.xml");
m_pOutputXml->SaveToFile(NSFile::GetProcessDirectory() + L"/test.xml");
}
}
}
@ -761,7 +761,15 @@ static const struct ActionNamesEmf
m_pOutputXml->WriteNode(L"Device", m_oHeader.oDevice);
m_pOutputXml->WriteNode(L"Millimeters", m_oHeader.oMillimeters);
//TODO: не хватает сохранения остальных записей, которые не используются
unsigned int unSize = m_ulRecordSize - 80;
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
delete[] pData;
}
m_pOutputXml->WriteNodeEnd(L"EMR_HEADER");
}
@ -801,9 +809,21 @@ static const struct ActionNamesEmf
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNode(L"EMR_ALPHABLEND", oBitmap, {XmlArgument(L"Id", EMR_ALPHABLEND),
XmlArgument(L"Size", m_ulRecordSize)});
//TODO: не хватает записи переменной BitmapBuffer
m_pOutputXml->WriteNodeBegin(L"EMR_ALPHABLEND", {XmlArgument(L"Id", EMR_ALPHABLEND),
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"", oBitmap);
unsigned int unSize = m_ulRecordSize - sizeof (TEmfAlphaBlend);
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
delete[] pData;
}
m_pOutputXml->WriteNodeEnd(L"EMR_ALPHABLEND");
}
BYTE* pBgraBuffer = NULL;
@ -852,9 +872,21 @@ static const struct ActionNamesEmf
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNode(L"EMR_STRETCHDIBITS", oBitmap, {XmlArgument(L"Id", EMR_STRETCHDIBITS),
XmlArgument(L"Size", m_ulRecordSize)});
//TODO: не хватает записи переменной BitmapBuffer
m_pOutputXml->WriteNodeBegin(L"EMR_STRETCHDIBITS", {XmlArgument(L"Id", EMR_STRETCHDIBITS),
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"", oBitmap);
unsigned int unSize = m_ulRecordSize - sizeof (TEmfStretchDIBITS);
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
delete[] pData;
}
m_pOutputXml->WriteNodeEnd(L"EMR_STRETCHDIBITS");
}
BYTE* pBgraBuffer = NULL;
@ -879,9 +911,21 @@ static const struct ActionNamesEmf
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNode(L"EMR_BITBLT", oBitmap, {XmlArgument(L"Id", EMR_BITBLT),
XmlArgument(L"Size", m_ulRecordSize)});
//TODO: не хватает записи переменной BitmapBuffer
m_pOutputXml->WriteNodeBegin(L"EMR_BITBLT", {XmlArgument(L"Id", EMR_BITBLT),
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"", oBitmap);
unsigned int unSize = m_ulRecordSize - 92;
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
delete[] pData;
}
m_pOutputXml->WriteNodeEnd(L"EMR_BITBLT");
}
BYTE* pBgraBuffer = NULL;
@ -984,9 +1028,21 @@ static const struct ActionNamesEmf
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNode(L"EMR_SETDIBITSTODEVICE", oBitmap, {XmlArgument(L"Id", EMR_SETDIBITSTODEVICE),
XmlArgument(L"Size", m_ulRecordSize)});
//TODO: не хватает записи переменной BitmapBuffer
m_pOutputXml->WriteNodeBegin(L"EMR_SETDIBITSTODEVICE", {XmlArgument(L"Id", EMR_SETDIBITSTODEVICE),
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"", oBitmap);
unsigned int unSize = m_ulRecordSize - sizeof (TEmfSetDiBitsToDevice);
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
delete[] pData;
}
m_pOutputXml->WriteNodeEnd(L"EMR_SETDIBITSTODEVICE");
}
BYTE* pBgraBuffer = NULL;
@ -1007,9 +1063,21 @@ static const struct ActionNamesEmf
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNode(L"EMR_STRETCHBLT", oBitmap, {XmlArgument(L"Id", EMR_STRETCHBLT),
XmlArgument(L"Size", m_ulRecordSize)});
//TODO: не хватает записи переменной BitmapBuffer
m_pOutputXml->WriteNodeBegin(L"EMR_STRETCHBLT", {XmlArgument(L"Id", EMR_STRETCHBLT),
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"", oBitmap);
unsigned int unSize = m_ulRecordSize - 100;
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
delete[] pData;
}
m_pOutputXml->WriteNodeEnd(L"EMR_STRETCHBLT");
}
BYTE* pBgraBuffer = NULL;
@ -1281,7 +1349,6 @@ static const struct ActionNamesEmf
{
m_pOutputXml->WriteNodeBegin(L"EMR_EXTCREATEPEN", {XmlArgument(L"Id", EMR_EXTCREATEPEN),
XmlArgument(L"Size", m_ulRecordSize)});
m_oStream.SeekBack(16);
m_pOutputXml->WriteNode(L"ihPen", ulPenIndex);
m_pOutputXml->WriteNode(L"offBmi", m_oStream.ReadULong());
m_pOutputXml->WriteNode(L"cbBmi", m_oStream.ReadULong());
@ -1367,17 +1434,22 @@ static const struct ActionNamesEmf
}
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNodeEnd(L"LogPenEx");
if (current_size > 0 && current_size < INT_MAX)
{
BYTE *pData = new BYTE[current_size];
m_oStream.ReadBytes(pData, current_size);
m_oStream.SeekBack(current_size);
m_pOutputXml->WriteNode(L"Buffer", pData, current_size);
}
m_pOutputXml->WriteNodeEnd(L"EMR_EXTCREATEPEN");
}
// Пропускаем часть с картинкой, если она была
m_oStream.Skip(current_size);
if (m_pOutput && NULL != m_pOutputXml)
{
//TODO: не хватает сохранения
m_pOutputXml->WriteNodeEnd(L"EMR_EXTCREATEPEN");
}
m_oPlayer.RegisterObject(ulPenIndex, (CEmfObjectBase*)pPen);
}
void CEmfFile::Read_EMR_CREATEPEN()
@ -1687,8 +1759,18 @@ static const struct ActionNamesEmf
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"ihBrush", ulBrushIndex);
m_pOutputXml->WriteNode(L"", oDibBrush);
m_pOutputXml->WriteNodeBegin(L"DeviceIndependentBitmap");
//TODO: не хватает сохранения переменной DeviceIndependentBitmap
unsigned int unSize = m_ulRecordSize - 24;
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
}
m_pOutputXml->WriteNodeEnd(L"EMR_CREATEDIBPATTERNBRUSHPT");
}
if (ReadImage(oDibBrush.offBmi, oDibBrush.cbBmi, oDibBrush.offBits, oDibBrush.cbBits, sizeof(TEmfDibPatternBrush) + 12, &pBgraBuffer, &ulWidth, &ulHeight))
@ -1701,12 +1783,6 @@ static const struct ActionNamesEmf
m_oPlayer.RegisterObject(ulBrushIndex, (CEmfObjectBase*)pBrush);
}
if (m_pOutput && NULL != m_pOutputXml)
{
m_pOutputXml->WriteNodeEnd(L"DeviceIndependentBitmap");
m_pOutputXml->WriteNodeEnd(L"EMR_CREATEDIBPATTERNBRUSHPT");
}
}
void CEmfFile::Read_EMR_SELECTCLIPPATH()
{
@ -1803,7 +1879,17 @@ static const struct ActionNamesEmf
XmlArgument(L"Size", m_ulRecordSize)});
m_pOutputXml->WriteNode(L"RgnDataSize", ulRgnDataSize);
m_pOutputXml->WriteNode(L"RegionMode", ulRegionMode);
//TODO: не хватает сохранения переменной RgnData, которая в реализации пропускается
unsigned int unSize = m_ulRecordSize - 8;
if (unSize > 0)
{
BYTE *pData = new BYTE[unSize];
m_oStream.ReadBytes(pData, unSize);
m_oStream.SeekBack(unSize);
m_pOutputXml->WriteNode(L"Buffer", pData, unSize);
}
m_pOutputXml->WriteNodeEnd(L"EMR_EXTSELECTCLIPRGN");
}

View File

@ -53,6 +53,8 @@ namespace MetaFile
{
m_pPath = NULL;
m_pDC = m_oPlayer.GetDC();
m_pOutputXml = NULL;
}
~CEmfFile()

View File

@ -115,6 +115,7 @@ void MainWindow::ReadXmlNode(XmlUtils::CXmlNode& oXmlNode, unsigned int unLevel)
}
XmlUtils::CXmlNodes oXmlChilds;
bool bEndNode = false;
if (oXmlNode.GetChilds(oXmlChilds))
{
@ -128,9 +129,22 @@ void MainWindow::ReadXmlNode(XmlUtils::CXmlNode& oXmlNode, unsigned int unLevel)
AddIndent(unLevel);
}
else
oTextCursor.insertText(QString::fromStdWString(oXmlNode.GetText()), m_oStandardTextFormat);
{
std::wstring wsText = oXmlNode.GetText();
oTextCursor.insertText(QString::fromStdWString(L"</" + oXmlNode.GetName() + L">\n"), oTextCharFormat);
if (wsText.empty())
{
oTextCursor.deletePreviousChar();
oTextCursor.insertText("/>\n", oTextCharFormat);
bEndNode = true;
}
else
oTextCursor.insertText(QString::fromStdWString(oXmlNode.GetText()), m_oStandardTextFormat);
}
if (!bEndNode)
oTextCursor.insertText(QString::fromStdWString(L"</" + oXmlNode.GetName() + L">\n"), oTextCharFormat);
}