djvu structure

This commit is contained in:
Kulikova Svetlana
2021-07-23 18:18:18 +03:00
parent 6ad4a538eb
commit d652e3c32f
11 changed files with 434 additions and 17 deletions

View File

@ -71,6 +71,10 @@ WASM_EXPORT BYTE* XPS_GetStructure(CGraphicsFileDrawing* pGraphics)
{ {
return pGraphics->GetXPSStructure(); return pGraphics->GetXPSStructure();
} }
WASM_EXPORT BYTE* DJVU_GetStructure(CGraphicsFileDrawing* pGraphics)
{
return pGraphics->GetDJVUStructure();
}
WASM_EXPORT void XPS_Delete(BYTE* pData) WASM_EXPORT void XPS_Delete(BYTE* pData)
{ {
RELEASEARRAYOBJECTS(pData); RELEASEARRAYOBJECTS(pData);
@ -216,9 +220,29 @@ int main()
resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG); resFrame->SaveFile(NSFile::GetProcessDirectory() + L"/res.png", _CXIMAGE_FORMAT_PNG);
resFrame->ClearNoAttack(); resFrame->ClearNoAttack();
BYTE* pStructure = DJVU_GetStructure(test);
DWORD nLength = GetLength(pStructure);
DWORD i = 4;
nLength -= 4;
while (i < nLength)
{
DWORD nPathLength = GetLength(pStructure + i);
i += 4;
std::cout << "Page " << nPathLength << ", ";
nPathLength = GetLength(pStructure + i);
i += 4;
std::cout << "Level " << nPathLength << ", ";
nPathLength = GetLength(pStructure + i);
i += 4;
std::string oDs = std::string((char*)(pStructure + i), nPathLength);
std::wcout << L"Description "<< UTF8_TO_U(oDs) << std::endl;
i += nPathLength;
}
XPS_Close(test); XPS_Close(test);
RELEASEARRAYOBJECTS(info); RELEASEARRAYOBJECTS(info);
RELEASEARRAYOBJECTS(res); RELEASEARRAYOBJECTS(res);
RELEASEARRAYOBJECTS(pStructure);
RELEASEOBJECT(resFrame); RELEASEOBJECT(resFrame);
return 0; return 0;
#endif #endif

View File

@ -82,6 +82,10 @@ public:
{ {
return ((CXpsFile*)pReader)->GetStructure(); return ((CXpsFile*)pReader)->GetStructure();
} }
BYTE* GetDJVUStructure()
{
return ((CDjVuFile*)pReader)->GetStructure();
}
}; };
#endif // _WASM_GRAPHICS_ #endif // _WASM_GRAPHICS_

View File

@ -105,3 +105,9 @@ void CDjVuFile::ConvertToPdf(const std::wstring& wsDstPath)
if (m_pImplementation) if (m_pImplementation)
m_pImplementation->ConvertToPdf(wsDstPath); m_pImplementation->ConvertToPdf(wsDstPath);
} }
BYTE* CDjVuFile::GetStructure()
{
if (m_pImplementation)
return m_pImplementation->GetStructure();
return NULL;
}

View File

@ -71,4 +71,5 @@ public:
virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1); virtual void ConvertToRaster(int nPageIndex, const std::wstring& path, int nImageType, const int nRasterW = -1, const int nRasterH = -1);
void ConvertToPdf(const std::wstring& path); void ConvertToPdf(const std::wstring& path);
BYTE* GetStructure();
}; };

View File

@ -336,6 +336,169 @@ void CDjVuFileImplementation::ConvertToPdf(const std::wstring& wsD
oPdf.SaveToFile(wsDstPath); oPdf.SaveToFile(wsDstPath);
} }
class CData
{
protected:
unsigned char* m_pData;
size_t m_lSize;
unsigned char* m_pDataCur;
size_t m_lSizeCur;
public:
CData()
{
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = m_lSize;
}
virtual ~CData()
{
Clear();
}
inline void AddSize(size_t nSize)
{
if (NULL == m_pData)
{
m_lSize = 1000;
if (nSize > m_lSize)
m_lSize = nSize;
m_pData = (unsigned char*)malloc(m_lSize * sizeof(unsigned char));
m_lSizeCur = 0;
m_pDataCur = m_pData;
return;
}
if ((m_lSizeCur + nSize) > m_lSize)
{
while ((m_lSizeCur + nSize) > m_lSize)
m_lSize *= 2;
unsigned char* pRealloc = (unsigned char*)realloc(m_pData, m_lSize * sizeof(unsigned char));
if (NULL != pRealloc)
{
m_pData = pRealloc;
m_pDataCur = m_pData + m_lSizeCur;
}
else
{
unsigned char* pMalloc = (unsigned char*)malloc(m_lSize * sizeof(unsigned char));
memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(unsigned char));
free(m_pData);
m_pData = pMalloc;
m_pDataCur = m_pData + m_lSizeCur;
}
}
}
public:
void AddInt(unsigned int value)
{
AddSize(4);
memcpy(m_pDataCur, &value, sizeof(unsigned int));
m_pDataCur += 4;
m_lSizeCur += 4;
}
void WriteString(unsigned char* value, unsigned int len)
{
AddSize(len + 4);
memcpy(m_pDataCur, &len, sizeof(unsigned int));
m_pDataCur += 4;
m_lSizeCur += 4;
memcpy(m_pDataCur, value, len);
m_pDataCur += len;
m_lSizeCur += len;
}
unsigned char* GetBuffer()
{
return m_pData;
}
void Clear()
{
if (m_pData) free(m_pData);
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
void ClearWithoutAttack()
{
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
void ClearNoAttack()
{
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
unsigned int GetSize()
{
return (unsigned int)m_lSizeCur;
}
void SkipLen()
{
AddInt(0);
}
void WriteLen()
{
unsigned int len = (unsigned int)m_lSizeCur;
memcpy(m_pData, &len, sizeof(unsigned int));
}
};
void getBookmars(const GP<DjVmNav>& nav, int& pos, int count, CData& out, int level)
{
while (count > 0 && pos < nav->getBookMarkCount())
{
GP<DjVmNav::DjVuBookMark> gpBookMark;
nav->getBookMark(gpBookMark, pos++);
GUTF8String str = gpBookMark->url;
int endpos;
DWORD nPage = str.toULong(1, endpos);
if (endpos == (int)str.length())
{
out.AddInt(nPage);
out.AddInt(level);
GUTF8String description = gpBookMark->displayname;
out.WriteString((BYTE*)description.getbuf(), description.length());
}
getBookmars(nav, pos, gpBookMark->count, out, level + 1);
count--;
}
}
BYTE* CDjVuFileImplementation::GetStructure()
{
GP<DjVmNav> nav = m_pDoc->get_djvm_nav();
if (!nav)
return NULL;
int pos = 0;
int count = nav->getBookMarkCount();
if (count <= 0)
return NULL;
CData oRes;
oRes.SkipLen();
getBookmars(nav, pos, count, oRes, 1);
oRes.WriteLen();
BYTE* bRes = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return bRes;
}
void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text) void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pPage, int nPage, XmlUtils::CXmlNode& text)
{ {
int nWidth = pPage->get_real_width(); int nWidth = pPage->get_real_width();

View File

@ -79,6 +79,7 @@ public:
BYTE* ConvertToPixels(int nPageIndex, const int& nRasterW = -1, const int& nRasterH = -1); BYTE* ConvertToPixels(int nPageIndex, const int& nRasterW = -1, const int& nRasterH = -1);
void ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int& nRasterW = -1, const int& nRasterH = -1); void ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType, const int& nRasterW = -1, const int& nRasterH = -1);
void ConvertToPdf(const std::wstring& wsDstPath); void ConvertToPdf(const std::wstring& wsDstPath);
BYTE* GetStructure();
private: private:

View File

@ -370,6 +370,12 @@ window.onload = function()
{ {
this.isRepaint = true; this.isRepaint = true;
}; };
this.getStructure = function()
{
var res = this.file.structure();
return res;
};
this._paint = function() this._paint = function()
{ {

View File

@ -74,6 +74,8 @@
} }
} }
//string_utf8
//module //module
/** /**
@ -124,6 +126,41 @@
{ {
return Module["_DJVU_GetPixmap"](this.nativeFile, pageIndex, width, height); return Module["_DJVU_GetPixmap"](this.nativeFile, pageIndex, width, height);
}; };
CFile.prototype.structure = function()
{
var res = [];
var str = Module["_DJVU_GetStructure"](this.nativeFile);
var lenArray = new Int32Array(Module["HEAP8"].buffer, str, 4);
if (lenArray == null)
return res;
var len = lenArray[0];
len -= 4;
if (len <= 0)
return res;
var buffer = new Uint8Array(Module["HEAP8"].buffer, str + 4, len);
var index = 0;
var Line = -1;
var prevY = -1;
while (index < len)
{
var lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24;
index += 4;
var _Page = lenRec;
lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24;
index += 4;
var _Level = lenRec;
lenRec = buffer[index] | buffer[index + 1] << 8 | buffer[index + 2] << 16 | buffer[index + 3] << 24;
index += 4;
var _Description = "".fromUtf8(buffer, index, lenRec);
index += lenRec;
res.push({ page : _Page, level : _Level, Y : 0, description : _Description});
}
Module["_DJVU_Delete"](str);
return res;
};
CFile.prototype.close = function() CFile.prototype.close = function()
{ {
Module["_DJVU_Close"](this.nativeFile); Module["_DJVU_Close"](this.nativeFile);
@ -141,4 +178,4 @@
window["AscViewer"].DjVuFile = CFile; window["AscViewer"].DjVuFile = CFile;
})(window, undefined); })(window, undefined);

View File

@ -15,6 +15,128 @@ class CDjvuFile
public: public:
GP<DjVuDocument> m_doc; GP<DjVuDocument> m_doc;
}; };
class CData
{
protected:
unsigned char* m_pData;
size_t m_lSize;
unsigned char* m_pDataCur;
size_t m_lSizeCur;
public:
CData()
{
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = m_lSize;
}
virtual ~CData()
{
Clear();
}
inline void AddSize(size_t nSize)
{
if (NULL == m_pData)
{
m_lSize = 1000;
if (nSize > m_lSize)
m_lSize = nSize;
m_pData = (unsigned char*)malloc(m_lSize * sizeof(unsigned char));
m_lSizeCur = 0;
m_pDataCur = m_pData;
return;
}
if ((m_lSizeCur + nSize) > m_lSize)
{
while ((m_lSizeCur + nSize) > m_lSize)
m_lSize *= 2;
unsigned char* pRealloc = (unsigned char*)realloc(m_pData, m_lSize * sizeof(unsigned char));
if (NULL != pRealloc)
{
m_pData = pRealloc;
m_pDataCur = m_pData + m_lSizeCur;
}
else
{
unsigned char* pMalloc = (unsigned char*)malloc(m_lSize * sizeof(unsigned char));
memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(unsigned char));
free(m_pData);
m_pData = pMalloc;
m_pDataCur = m_pData + m_lSizeCur;
}
}
}
public:
void AddInt(unsigned int value)
{
AddSize(4);
memcpy(m_pDataCur, &value, sizeof(unsigned int));
m_pDataCur += 4;
m_lSizeCur += 4;
}
void WriteString(unsigned char* value, unsigned int len)
{
AddSize(len + 4);
memcpy(m_pDataCur, &len, sizeof(unsigned int));
m_pDataCur += 4;
m_lSizeCur += 4;
memcpy(m_pDataCur, value, len);
m_pDataCur += len;
m_lSizeCur += len;
}
unsigned char* GetBuffer()
{
return m_pData;
}
void Clear()
{
if (m_pData) free(m_pData);
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
void ClearWithoutAttack()
{
m_pData = NULL;
m_lSize = 0;
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
void ClearNoAttack()
{
m_pDataCur = m_pData;
m_lSizeCur = 0;
}
unsigned int GetSize()
{
return (unsigned int)m_lSizeCur;
}
void SkipLen()
{
AddInt(0);
}
void WriteLen()
{
unsigned int len = (unsigned int)m_lSizeCur;
memcpy(m_pData, &len, sizeof(unsigned int));
}
};
extern "C" extern "C"
{ {
@ -22,6 +144,7 @@ extern "C"
void DJVU_Close(CDjvuFile* file); void DJVU_Close(CDjvuFile* file);
int* DJVU_GetInfo(CDjvuFile* file); int* DJVU_GetInfo(CDjvuFile* file);
unsigned char* DJVU_GetPixmap(CDjvuFile* file, int page_index, int w, int h); unsigned char* DJVU_GetPixmap(CDjvuFile* file, int page_index, int w, int h);
unsigned char* DJVU_GetStructure(CDjvuFile* file);
void DJVU_Delete(unsigned char* pData); void DJVU_Delete(unsigned char* pData);
} }
@ -198,6 +321,48 @@ unsigned char* DJVU_GetPixmap(CDjvuFile* file, int page_index, int w, int h)
return pixmap; return pixmap;
} }
void getBookmars(const GP<DjVmNav>& nav, int& pos, int count, CData& out, int level)
{
while (count > 0 && pos < nav->getBookMarkCount())
{
GP<DjVmNav::DjVuBookMark> gpBookMark;
nav->getBookMark(gpBookMark, pos++);
GUTF8String str = gpBookMark->url;
int endpos;
unsigned long nPage = str.toULong(1, endpos);
if (endpos == (int)str.length())
{
out.AddInt(nPage);
out.AddInt(level);
GUTF8String description = gpBookMark->displayname;
out.WriteString((unsigned char*)description.getbuf(), description.length());
}
getBookmars(nav, pos, gpBookMark->count, out, level + 1);
count--;
}
}
unsigned char* DJVU_GetStructure(CDjvuFile* file)
{
GP<DjVmNav> nav = file->m_doc->get_djvm_nav();
if (!nav)
return NULL;
int pos = 0;
int count = nav->getBookMarkCount();
if (count <= 0)
return NULL;
CData oRes;
oRes.SkipLen();
getBookmars(nav, pos, count, oRes, 1);
oRes.WriteLen();
unsigned char* bRes = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return bRes;
}
void DJVU_Delete(unsigned char* pData) void DJVU_Delete(unsigned char* pData)
{ {
delete [] pData; delete [] pData;
@ -205,6 +370,8 @@ void DJVU_Delete(unsigned char* pData)
#ifdef WASM_MODE_DEBUG #ifdef WASM_MODE_DEBUG
#include <stdio.h> #include <stdio.h>
#include <string>
#include <iostream>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
FILE* f = fopen("D:\\1.djvu", "rb"); FILE* f = fopen("D:\\1.djvu", "rb");
@ -231,6 +398,27 @@ int main(int argc, char *argv[])
} }
delete [] info; delete [] info;
unsigned char* pStructure = DJVU_GetStructure(file);
unsigned nLength = pStructure[0] | pStructure[1] << 8 | pStructure[2] << 16 | pStructure[3] << 24;
unsigned i = 4;
nLength -= 4;
while (i < nLength)
{
unsigned nPathLength = (pStructure + i)[0] | (pStructure + i)[1] << 8 | (pStructure + i)[2] << 16 | (pStructure + i)[3] << 24;
i += 4;
std::cout << "Page " << nPathLength << ", ";
nPathLength = (pStructure + i)[0] | (pStructure + i)[1] << 8 | (pStructure + i)[2] << 16 | (pStructure + i)[3] << 24;
i += 4;
std::cout << "Level " << nPathLength << ", ";
nPathLength = (pStructure + i)[0] | (pStructure + i)[1] << 8 | (pStructure + i)[2] << 16 | (pStructure + i)[3] << 24;
i += 4;
std::string oDs = std::string((char*)(pStructure + i), nPathLength);
std::cout << "Description " << oDs << std::endl;
i += nPathLength;
}
delete [] pStructure;
} }
return 0; return 0;

View File

@ -35,6 +35,7 @@ exported_functions = ["_malloc",
"_DJVU_Close", "_DJVU_Close",
"_DJVU_GetInfo", "_DJVU_GetInfo",
"_DJVU_GetPixmap", "_DJVU_GetPixmap",
"_DJVU_GetStructure",
"_DJVU_Delete"] "_DJVU_Delete"]
libDjVu_src_path = "../libdjvu/" libDjVu_src_path = "../libdjvu/"
@ -82,7 +83,9 @@ base.replaceInFile("./djvu.js", "function getBinaryPromise(){", "function getBin
djvu_js_content = base.readFile("./djvu.js") djvu_js_content = base.readFile("./djvu.js")
engine_base_js_content = base.readFile("./djvu_base.js") engine_base_js_content = base.readFile("./djvu_base.js")
string_utf8_content = base.readFile("./../../Common/js/string_utf8.js")
engine_js_content = engine_base_js_content.replace("//module", djvu_js_content) engine_js_content = engine_base_js_content.replace("//module", djvu_js_content)
engine_js_content = engine_js_content.replace("//string_utf8", string_utf8_content)
# write new version # write new version
base.writeFile("./deploy/djvu/djvu.js", engine_js_content) base.writeFile("./deploy/djvu/djvu.js", engine_js_content)

View File

@ -73,22 +73,6 @@ namespace XPS
m_pDataCur = m_pData; m_pDataCur = m_pData;
m_lSizeCur = m_lSize; m_lSizeCur = m_lSize;
} }
CData(size_t nLen)
{
m_lSize = nLen;
m_pData = (unsigned char*)malloc(m_lSize * sizeof(unsigned char));
m_lSizeCur = 0;
m_pDataCur = m_pData;
}
CData(unsigned char* value, unsigned int len)
{
m_lSize = len;
m_pData = value;
m_lSizeCur = m_lSize;
m_pDataCur = m_pData + m_lSizeCur;
}
virtual ~CData() virtual ~CData()
{ {
Clear(); Clear();