From cc45ab05fd447db6d6e25798c321f5c853f9aad0 Mon Sep 17 00:00:00 2001 From: "Ilya.Kirillov" Date: Mon, 18 May 2015 14:40:54 +0000 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B8=D1=81=D1=85=D0=BE=D0=B4=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BA=D1=80=D0=BE=D1=81=D1=81=D0=BF=D0=BB=D0=B0=D1=82?= =?UTF-8?q?=D1=84=D0=BE=D1=80=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=B1?= =?UTF-8?q?=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82=D0=B5=D0=BA=D0=B8=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=87=D1=82=D0=B5=D0=BD=D0=B8=D1=8F=20DjVu=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62606 954022d7-b5bf-4e40-9824-e11837661b57 --- .gitattributes | 2 + DjVuFile/DjVu.cpp | 59 + DjVuFile/DjVu.h | 30 + DjVuFile/DjVuFile.pro | 133 + DjVuFile/DjVuFile.sln | 50 + DjVuFile/DjVuFile.vcxproj | 262 ++ DjVuFile/DjVuFileImplementation.cpp | 675 +++++ DjVuFile/DjVuFileImplementation.h | 57 + DjVuFile/DjVuFileTest/DjVuFileTest.cpp | 72 + DjVuFile/DjVuFileTest/DjVuFileTest.vcxproj | 173 ++ DjVuFile/DjVuFileTest/ReadMe.txt | 40 + DjVuFile/DjVuFileTest/stdafx.cpp | 8 + DjVuFile/DjVuFileTest/stdafx.h | 23 + DjVuFile/DjVuFileTest/targetver.h | 8 + DjVuFile/ReadMe.txt | 29 + DjVuFile/libdjvu/Arrays.cpp | 307 +++ DjVuFile/libdjvu/Arrays.h | 987 +++++++ DjVuFile/libdjvu/BSByteStream.cpp | 467 ++++ DjVuFile/libdjvu/BSByteStream.h | 277 ++ DjVuFile/libdjvu/BSEncodeByteStream.cpp | 1012 +++++++ DjVuFile/libdjvu/ByteStream.cpp | 1385 ++++++++++ DjVuFile/libdjvu/ByteStream.h | 411 +++ DjVuFile/libdjvu/DataPool.cpp | 1837 +++++++++++++ DjVuFile/libdjvu/DataPool.h | 631 +++++ DjVuFile/libdjvu/DjVmDir.cpp | 851 ++++++ DjVuFile/libdjvu/DjVmDir.h | 457 ++++ DjVuFile/libdjvu/DjVmDir0.cpp | 171 ++ DjVuFile/libdjvu/DjVmDir0.h | 219 ++ DjVuFile/libdjvu/DjVmDoc.cpp | 665 +++++ DjVuFile/libdjvu/DjVmDoc.h | 276 ++ DjVuFile/libdjvu/DjVmNav.cpp | 340 +++ DjVuFile/libdjvu/DjVmNav.h | 151 + DjVuFile/libdjvu/DjVuAnno.cpp | 1602 +++++++++++ DjVuFile/libdjvu/DjVuAnno.h | 297 ++ DjVuFile/libdjvu/DjVuDocEditor.cpp | 2199 +++++++++++++++ DjVuFile/libdjvu/DjVuDocEditor.h | 464 ++++ DjVuFile/libdjvu/DjVuDocument.cpp | 1995 ++++++++++++++ DjVuFile/libdjvu/DjVuDocument.h | 1086 ++++++++ DjVuFile/libdjvu/DjVuDumpHelper.cpp | 360 +++ DjVuFile/libdjvu/DjVuDumpHelper.h | 128 + DjVuFile/libdjvu/DjVuErrorList.cpp | 176 ++ DjVuFile/libdjvu/DjVuErrorList.h | 196 ++ DjVuFile/libdjvu/DjVuFile.cpp | 2872 ++++++++++++++++++++ DjVuFile/libdjvu/DjVuFile.h | 855 ++++++ DjVuFile/libdjvu/DjVuFileCache.cpp | 274 ++ DjVuFile/libdjvu/DjVuFileCache.h | 294 ++ DjVuFile/libdjvu/DjVuGlobal.cpp | 257 ++ DjVuFile/libdjvu/DjVuGlobal.h | 404 +++ DjVuFile/libdjvu/DjVuGlobalMemory.cpp | 308 +++ DjVuFile/libdjvu/DjVuImage.cpp | 1504 ++++++++++ DjVuFile/libdjvu/DjVuImage.h | 451 +++ DjVuFile/libdjvu/DjVuInfo.cpp | 210 ++ DjVuFile/libdjvu/DjVuInfo.h | 194 ++ DjVuFile/libdjvu/DjVuMessage.cpp | 624 +++++ DjVuFile/libdjvu/DjVuMessage.h | 137 + DjVuFile/libdjvu/DjVuMessageLite.cpp | 481 ++++ DjVuFile/libdjvu/DjVuMessageLite.h | 229 ++ DjVuFile/libdjvu/DjVuNavDir.cpp | 239 ++ DjVuFile/libdjvu/DjVuNavDir.h | 194 ++ DjVuFile/libdjvu/DjVuPalette.cpp | 614 +++++ DjVuFile/libdjvu/DjVuPalette.h | 362 +++ DjVuFile/libdjvu/DjVuPort.cpp | 714 +++++ DjVuFile/libdjvu/DjVuPort.h | 521 ++++ DjVuFile/libdjvu/DjVuText.cpp | 981 +++++++ DjVuFile/libdjvu/DjVuText.h | 283 ++ DjVuFile/libdjvu/DjVuToPS.cpp | 2584 ++++++++++++++++++ DjVuFile/libdjvu/DjVuToPS.h | 427 +++ DjVuFile/libdjvu/GBitmap.cpp | 1687 ++++++++++++ DjVuFile/libdjvu/GBitmap.h | 677 +++++ DjVuFile/libdjvu/GContainer.cpp | 824 ++++++ DjVuFile/libdjvu/GContainer.h | 1368 ++++++++++ DjVuFile/libdjvu/GException.cpp | 286 ++ DjVuFile/libdjvu/GException.h | 361 +++ DjVuFile/libdjvu/GIFFManager.cpp | 665 +++++ DjVuFile/libdjvu/GIFFManager.h | 396 +++ DjVuFile/libdjvu/GMapAreas.cpp | 1120 ++++++++ DjVuFile/libdjvu/GMapAreas.h | 607 +++++ DjVuFile/libdjvu/GOS.cpp | 380 +++ DjVuFile/libdjvu/GOS.h | 163 ++ DjVuFile/libdjvu/GPixmap.cpp | 1734 ++++++++++++ DjVuFile/libdjvu/GPixmap.h | 545 ++++ DjVuFile/libdjvu/GRect.cpp | 480 ++++ DjVuFile/libdjvu/GRect.h | 358 +++ DjVuFile/libdjvu/GScaler.cpp | 713 +++++ DjVuFile/libdjvu/GScaler.h | 323 +++ DjVuFile/libdjvu/GSmartPointer.cpp | 226 ++ DjVuFile/libdjvu/GSmartPointer.h | 528 ++++ DjVuFile/libdjvu/GString.cpp | 2750 +++++++++++++++++++ DjVuFile/libdjvu/GString.h | 1678 ++++++++++++ DjVuFile/libdjvu/GThreads.cpp | 1898 +++++++++++++ DjVuFile/libdjvu/GThreads.h | 653 +++++ DjVuFile/libdjvu/GURL.cpp | 1910 +++++++++++++ DjVuFile/libdjvu/GURL.h | 448 +++ DjVuFile/libdjvu/GUnicode.cpp | 791 ++++++ DjVuFile/libdjvu/IFFByteStream.cpp | 572 ++++ DjVuFile/libdjvu/IFFByteStream.h | 317 +++ DjVuFile/libdjvu/IW44EncodeCodec.cpp | 1799 ++++++++++++ DjVuFile/libdjvu/IW44Image.cpp | 1948 +++++++++++++ DjVuFile/libdjvu/IW44Image.h | 763 ++++++ DjVuFile/libdjvu/JB2EncodeCodec.cpp | 566 ++++ DjVuFile/libdjvu/JB2Image.cpp | 1456 ++++++++++ DjVuFile/libdjvu/JB2Image.h | 814 ++++++ DjVuFile/libdjvu/JPEGDecoder.cpp | 567 ++++ DjVuFile/libdjvu/JPEGDecoder.h | 157 ++ DjVuFile/libdjvu/MMRDecoder.cpp | 963 +++++++ DjVuFile/libdjvu/MMRDecoder.h | 240 ++ DjVuFile/libdjvu/MMX.cpp | 215 ++ DjVuFile/libdjvu/MMX.h | 196 ++ DjVuFile/libdjvu/UnicodeByteStream.cpp | 370 +++ DjVuFile/libdjvu/UnicodeByteStream.h | 201 ++ DjVuFile/libdjvu/XMLParser.cpp | 1133 ++++++++ DjVuFile/libdjvu/XMLParser.h | 125 + DjVuFile/libdjvu/XMLTags.cpp | 419 +++ DjVuFile/libdjvu/XMLTags.h | 244 ++ DjVuFile/libdjvu/ZPCodec.cpp | 1294 +++++++++ DjVuFile/libdjvu/ZPCodec.h | 749 +++++ DjVuFile/libdjvu/atomic.cpp | 412 +++ DjVuFile/libdjvu/atomic.h | 105 + DjVuFile/libdjvu/debug.cpp | 305 +++ DjVuFile/libdjvu/debug.h | 302 ++ DjVuFile/libdjvu/libdjvu.vcproj | 571 ++++ 121 files changed, 76953 insertions(+) create mode 100644 DjVuFile/DjVu.cpp create mode 100644 DjVuFile/DjVu.h create mode 100644 DjVuFile/DjVuFile.pro create mode 100644 DjVuFile/DjVuFile.sln create mode 100644 DjVuFile/DjVuFile.vcxproj create mode 100644 DjVuFile/DjVuFileImplementation.cpp create mode 100644 DjVuFile/DjVuFileImplementation.h create mode 100644 DjVuFile/DjVuFileTest/DjVuFileTest.cpp create mode 100644 DjVuFile/DjVuFileTest/DjVuFileTest.vcxproj create mode 100644 DjVuFile/DjVuFileTest/ReadMe.txt create mode 100644 DjVuFile/DjVuFileTest/stdafx.cpp create mode 100644 DjVuFile/DjVuFileTest/stdafx.h create mode 100644 DjVuFile/DjVuFileTest/targetver.h create mode 100644 DjVuFile/ReadMe.txt create mode 100644 DjVuFile/libdjvu/Arrays.cpp create mode 100644 DjVuFile/libdjvu/Arrays.h create mode 100644 DjVuFile/libdjvu/BSByteStream.cpp create mode 100644 DjVuFile/libdjvu/BSByteStream.h create mode 100644 DjVuFile/libdjvu/BSEncodeByteStream.cpp create mode 100644 DjVuFile/libdjvu/ByteStream.cpp create mode 100644 DjVuFile/libdjvu/ByteStream.h create mode 100644 DjVuFile/libdjvu/DataPool.cpp create mode 100644 DjVuFile/libdjvu/DataPool.h create mode 100644 DjVuFile/libdjvu/DjVmDir.cpp create mode 100644 DjVuFile/libdjvu/DjVmDir.h create mode 100644 DjVuFile/libdjvu/DjVmDir0.cpp create mode 100644 DjVuFile/libdjvu/DjVmDir0.h create mode 100644 DjVuFile/libdjvu/DjVmDoc.cpp create mode 100644 DjVuFile/libdjvu/DjVmDoc.h create mode 100644 DjVuFile/libdjvu/DjVmNav.cpp create mode 100644 DjVuFile/libdjvu/DjVmNav.h create mode 100644 DjVuFile/libdjvu/DjVuAnno.cpp create mode 100644 DjVuFile/libdjvu/DjVuAnno.h create mode 100644 DjVuFile/libdjvu/DjVuDocEditor.cpp create mode 100644 DjVuFile/libdjvu/DjVuDocEditor.h create mode 100644 DjVuFile/libdjvu/DjVuDocument.cpp create mode 100644 DjVuFile/libdjvu/DjVuDocument.h create mode 100644 DjVuFile/libdjvu/DjVuDumpHelper.cpp create mode 100644 DjVuFile/libdjvu/DjVuDumpHelper.h create mode 100644 DjVuFile/libdjvu/DjVuErrorList.cpp create mode 100644 DjVuFile/libdjvu/DjVuErrorList.h create mode 100644 DjVuFile/libdjvu/DjVuFile.cpp create mode 100644 DjVuFile/libdjvu/DjVuFile.h create mode 100644 DjVuFile/libdjvu/DjVuFileCache.cpp create mode 100644 DjVuFile/libdjvu/DjVuFileCache.h create mode 100644 DjVuFile/libdjvu/DjVuGlobal.cpp create mode 100644 DjVuFile/libdjvu/DjVuGlobal.h create mode 100644 DjVuFile/libdjvu/DjVuGlobalMemory.cpp create mode 100644 DjVuFile/libdjvu/DjVuImage.cpp create mode 100644 DjVuFile/libdjvu/DjVuImage.h create mode 100644 DjVuFile/libdjvu/DjVuInfo.cpp create mode 100644 DjVuFile/libdjvu/DjVuInfo.h create mode 100644 DjVuFile/libdjvu/DjVuMessage.cpp create mode 100644 DjVuFile/libdjvu/DjVuMessage.h create mode 100644 DjVuFile/libdjvu/DjVuMessageLite.cpp create mode 100644 DjVuFile/libdjvu/DjVuMessageLite.h create mode 100644 DjVuFile/libdjvu/DjVuNavDir.cpp create mode 100644 DjVuFile/libdjvu/DjVuNavDir.h create mode 100644 DjVuFile/libdjvu/DjVuPalette.cpp create mode 100644 DjVuFile/libdjvu/DjVuPalette.h create mode 100644 DjVuFile/libdjvu/DjVuPort.cpp create mode 100644 DjVuFile/libdjvu/DjVuPort.h create mode 100644 DjVuFile/libdjvu/DjVuText.cpp create mode 100644 DjVuFile/libdjvu/DjVuText.h create mode 100644 DjVuFile/libdjvu/DjVuToPS.cpp create mode 100644 DjVuFile/libdjvu/DjVuToPS.h create mode 100644 DjVuFile/libdjvu/GBitmap.cpp create mode 100644 DjVuFile/libdjvu/GBitmap.h create mode 100644 DjVuFile/libdjvu/GContainer.cpp create mode 100644 DjVuFile/libdjvu/GContainer.h create mode 100644 DjVuFile/libdjvu/GException.cpp create mode 100644 DjVuFile/libdjvu/GException.h create mode 100644 DjVuFile/libdjvu/GIFFManager.cpp create mode 100644 DjVuFile/libdjvu/GIFFManager.h create mode 100644 DjVuFile/libdjvu/GMapAreas.cpp create mode 100644 DjVuFile/libdjvu/GMapAreas.h create mode 100644 DjVuFile/libdjvu/GOS.cpp create mode 100644 DjVuFile/libdjvu/GOS.h create mode 100644 DjVuFile/libdjvu/GPixmap.cpp create mode 100644 DjVuFile/libdjvu/GPixmap.h create mode 100644 DjVuFile/libdjvu/GRect.cpp create mode 100644 DjVuFile/libdjvu/GRect.h create mode 100644 DjVuFile/libdjvu/GScaler.cpp create mode 100644 DjVuFile/libdjvu/GScaler.h create mode 100644 DjVuFile/libdjvu/GSmartPointer.cpp create mode 100644 DjVuFile/libdjvu/GSmartPointer.h create mode 100644 DjVuFile/libdjvu/GString.cpp create mode 100644 DjVuFile/libdjvu/GString.h create mode 100644 DjVuFile/libdjvu/GThreads.cpp create mode 100644 DjVuFile/libdjvu/GThreads.h create mode 100644 DjVuFile/libdjvu/GURL.cpp create mode 100644 DjVuFile/libdjvu/GURL.h create mode 100644 DjVuFile/libdjvu/GUnicode.cpp create mode 100644 DjVuFile/libdjvu/IFFByteStream.cpp create mode 100644 DjVuFile/libdjvu/IFFByteStream.h create mode 100644 DjVuFile/libdjvu/IW44EncodeCodec.cpp create mode 100644 DjVuFile/libdjvu/IW44Image.cpp create mode 100644 DjVuFile/libdjvu/IW44Image.h create mode 100644 DjVuFile/libdjvu/JB2EncodeCodec.cpp create mode 100644 DjVuFile/libdjvu/JB2Image.cpp create mode 100644 DjVuFile/libdjvu/JB2Image.h create mode 100644 DjVuFile/libdjvu/JPEGDecoder.cpp create mode 100644 DjVuFile/libdjvu/JPEGDecoder.h create mode 100644 DjVuFile/libdjvu/MMRDecoder.cpp create mode 100644 DjVuFile/libdjvu/MMRDecoder.h create mode 100644 DjVuFile/libdjvu/MMX.cpp create mode 100644 DjVuFile/libdjvu/MMX.h create mode 100644 DjVuFile/libdjvu/UnicodeByteStream.cpp create mode 100644 DjVuFile/libdjvu/UnicodeByteStream.h create mode 100644 DjVuFile/libdjvu/XMLParser.cpp create mode 100644 DjVuFile/libdjvu/XMLParser.h create mode 100644 DjVuFile/libdjvu/XMLTags.cpp create mode 100644 DjVuFile/libdjvu/XMLTags.h create mode 100644 DjVuFile/libdjvu/ZPCodec.cpp create mode 100644 DjVuFile/libdjvu/ZPCodec.h create mode 100644 DjVuFile/libdjvu/atomic.cpp create mode 100644 DjVuFile/libdjvu/atomic.h create mode 100644 DjVuFile/libdjvu/debug.cpp create mode 100644 DjVuFile/libdjvu/debug.h create mode 100644 DjVuFile/libdjvu/libdjvu.vcproj diff --git a/.gitattributes b/.gitattributes index 5ef4a93263..ac3d140cea 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7281,6 +7281,8 @@ DesktopEditor/raster/Metafile svnc_tsvn_003alogminsize=5 svn_global_002dignores DesktopEditor/raster/Metafile/Common svnc_tsvn_003alogminsize=5 DesktopEditor/raster/Metafile/Emf svnc_tsvn_003alogminsize=5 DesktopEditor/raster/Metafile/Wmf svnc_tsvn_003alogminsize=5 +DjVuFile/DjVuFileTest svnc_tsvn_003alogminsize=5 +DjVuFile/libdjvu svnc_tsvn_003alogminsize=5 DoctRenderer/COMMON/Dlls/AVSGraphics.dll svn_mime_002dtype=application%2Foctet-stream DoctRenderer/COMMON/Dlls/AVSOfficeFOFile.dll svn_mime_002dtype=application%2Foctet-stream DoctRenderer/COMMON/Joiner/bin/Debug/Joiner.exe svn_mime_002dtype=application%2Foctet-stream diff --git a/DjVuFile/DjVu.cpp b/DjVuFile/DjVu.cpp new file mode 100644 index 0000000000..14c57bc1ae --- /dev/null +++ b/DjVuFile/DjVu.cpp @@ -0,0 +1,59 @@ +#include "DjVu.h" +#include "DjVuFileImplementation.h" + +class CApplicationFonts; + +CDjVuFile::CDjVuFile() +{ + m_pImplementation = new CDjVuFileImplementation(); +} +CDjVuFile::~CDjVuFile() +{ + if (m_pImplementation) + delete m_pImplementation; +} +bool CDjVuFile::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXMLOptions) +{ + if (m_pImplementation) + return m_pImplementation->LoadFromFile(wsSrcFileName, wsXMLOptions); + + return false; +} +void CDjVuFile::Close() +{ + if (m_pImplementation) + m_pImplementation->Close(); +} +std::wstring CDjVuFile::GetTempDirectory() const +{ + if (m_pImplementation) + return m_pImplementation->GetTempDirectory(); + + return L""; +} +void CDjVuFile::SetTempDirectory(const std::wstring& wsDirectory) +{ + if (m_pImplementation) + m_pImplementation->SetTempDirectory(wsDirectory); +} +int CDjVuFile::GetPagesCount() const +{ + if (m_pImplementation) + return m_pImplementation->GetPagesCount(); + return 0; +} +void CDjVuFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const +{ + if (m_pImplementation) + m_pImplementation->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); +} +void CDjVuFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) +{ + if (m_pImplementation) + m_pImplementation->DrawPageOnRenderer(pRenderer, nPageIndex, pBreak); +} +void CDjVuFile::ConvertToRaster(CApplicationFonts* pAppFonts, int nPageIndex, const std::wstring& wsDstPath, int nImageType) +{ + if (m_pImplementation) + m_pImplementation->ConvertToRaster(pAppFonts, nPageIndex, wsDstPath, nImageType); +} diff --git a/DjVuFile/DjVu.h b/DjVuFile/DjVu.h new file mode 100644 index 0000000000..4581f7f365 --- /dev/null +++ b/DjVuFile/DjVu.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "../DesktopEditor/graphics/IRenderer.h" + + +// Работаем через класс CDjVuFileImplementation, чтобы когда цеплялся данный h-файл, ничего лишнего не инклюдилось +class CDjVuFileImplementation; +class CApplicationFonts; + +class CDjVuFile +{ +private: + + CDjVuFileImplementation* m_pImplementation; + +public: + + CDjVuFile(); + ~CDjVuFile(); + + bool LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXmlOptions = L""); + void Close(); + std::wstring GetTempDirectory() const; + void SetTempDirectory(const std::wstring& wsDirectory); + int GetPagesCount() const; + void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const; + void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); + void ConvertToRaster(CApplicationFonts* pAppFonts, int nPageIndex, const std::wstring& wsDstPath, int nImageType); +}; \ No newline at end of file diff --git a/DjVuFile/DjVuFile.pro b/DjVuFile/DjVuFile.pro new file mode 100644 index 0000000000..e8f0f91139 --- /dev/null +++ b/DjVuFile/DjVuFile.pro @@ -0,0 +1,133 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-05-18T16:30:42 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = DjVuFile +TEMPLATE = lib +CONFIG += staticlib + +DEFINES += UNICODE +DEFINES += _UNICODE +DEFINES += _USE_LIBXML2_READER_ +DEFINES += LIBXML_READER_ENABLED + +SOURCES += djvufile.cpp \ + libdjvu/Arrays.cpp \ + libdjvu/atomic.cpp \ + libdjvu/BSByteStream.cpp \ + libdjvu/BSEncodeByteStream.cpp \ + libdjvu/ByteStream.cpp \ + libdjvu/DataPool.cpp \ + libdjvu/debug.cpp \ + libdjvu/DjVmDir.cpp \ + libdjvu/DjVmDir0.cpp \ + libdjvu/DjVmDoc.cpp \ + libdjvu/DjVmNav.cpp \ + libdjvu/DjVuAnno.cpp \ + libdjvu/DjVuDocEditor.cpp \ + libdjvu/DjVuDocument.cpp \ + libdjvu/DjVuDumpHelper.cpp \ + libdjvu/DjVuErrorList.cpp \ + libdjvu/DjVuFile.cpp \ + libdjvu/DjVuFileCache.cpp \ + libdjvu/DjVuGlobal.cpp \ + libdjvu/DjVuGlobalMemory.cpp \ + libdjvu/DjVuImage.cpp \ + libdjvu/DjVuInfo.cpp \ + libdjvu/DjVuMessage.cpp \ + libdjvu/DjVuMessageLite.cpp \ + libdjvu/DjVuNavDir.cpp \ + libdjvu/DjVuPalette.cpp \ + libdjvu/DjVuPort.cpp \ + libdjvu/DjVuText.cpp \ + libdjvu/DjVuToPS.cpp \ + libdjvu/GBitmap.cpp \ + libdjvu/GContainer.cpp \ + libdjvu/GException.cpp \ + libdjvu/GIFFManager.cpp \ + libdjvu/GMapAreas.cpp \ + libdjvu/GOS.cpp \ + libdjvu/GPixmap.cpp \ + libdjvu/GRect.cpp \ + libdjvu/GScaler.cpp \ + libdjvu/GSmartPointer.cpp \ + libdjvu/GString.cpp \ + libdjvu/GThreads.cpp \ + libdjvu/GUnicode.cpp \ + libdjvu/GURL.cpp \ + libdjvu/IFFByteStream.cpp \ + libdjvu/IW44EncodeCodec.cpp \ + libdjvu/IW44Image.cpp \ + libdjvu/JB2EncodeCodec.cpp \ + libdjvu/JB2Image.cpp \ + libdjvu/JPEGDecoder.cpp \ + libdjvu/MMRDecoder.cpp \ + libdjvu/MMX.cpp \ + libdjvu/UnicodeByteStream.cpp \ + libdjvu/XMLParser.cpp \ + libdjvu/XMLTags.cpp \ + libdjvu/ZPCodec.cpp \ + DjVu.cpp \ + DjVuFileImplementation.cpp + +HEADERS += djvufile.h \ + libdjvu/Arrays.h \ + libdjvu/atomic.h \ + libdjvu/BSByteStream.h \ + libdjvu/ByteStream.h \ + libdjvu/DataPool.h \ + libdjvu/debug.h \ + libdjvu/DjVmDir.h \ + libdjvu/DjVmDir0.h \ + libdjvu/DjVmDoc.h \ + libdjvu/DjVmNav.h \ + libdjvu/DjVuAnno.h \ + libdjvu/DjVuDocEditor.h \ + libdjvu/DjVuDocument.h \ + libdjvu/DjVuDumpHelper.h \ + libdjvu/DjVuErrorList.h \ + libdjvu/DjVuFile.h \ + libdjvu/DjVuFileCache.h \ + libdjvu/DjVuGlobal.h \ + libdjvu/DjVuImage.h \ + libdjvu/DjVuInfo.h \ + libdjvu/DjVuMessage.h \ + libdjvu/DjVuMessageLite.h \ + libdjvu/DjVuNavDir.h \ + libdjvu/DjVuPalette.h \ + libdjvu/DjVuPort.h \ + libdjvu/DjVuText.h \ + libdjvu/DjVuToPS.h \ + libdjvu/GBitmap.h \ + libdjvu/GContainer.h \ + libdjvu/GException.h \ + libdjvu/GIFFManager.h \ + libdjvu/GMapAreas.h \ + libdjvu/GOS.h \ + libdjvu/GPixmap.h \ + libdjvu/GRect.h \ + libdjvu/GScaler.h \ + libdjvu/GSmartPointer.h \ + libdjvu/GString.h \ + libdjvu/GThreads.h \ + libdjvu/GURL.h \ + libdjvu/IFFByteStream.h \ + libdjvu/IW44Image.h \ + libdjvu/JB2Image.h \ + libdjvu/JPEGDecoder.h \ + libdjvu/MMRDecoder.h \ + libdjvu/MMX.h \ + libdjvu/UnicodeByteStream.h \ + libdjvu/XMLParser.h \ + libdjvu/XMLTags.h \ + libdjvu/ZPCodec.h \ + DjVu.h \ + DjVuFileImplementation.h +unix { + target.path = /usr/lib + INSTALLS += target +} diff --git a/DjVuFile/DjVuFile.sln b/DjVuFile/DjVuFile.sln new file mode 100644 index 0000000000..7ba8b9eb94 --- /dev/null +++ b/DjVuFile/DjVuFile.sln @@ -0,0 +1,50 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30723.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DjVuFile", "DjVuFile.vcxproj", "{712534D7-B84A-4D84-93C9-3BF3F98F4BF5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DjVuFileTest", "DjVuFileTest\DjVuFileTest.vcxproj", "{6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}" + ProjectSection(ProjectDependencies) = postProject + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5} = {712534D7-B84A-4D84-93C9-3BF3F98F4BF5} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Debug|Win32.ActiveCfg = Debug|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Debug|Win32.Build.0 = Debug|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Debug|x64.ActiveCfg = Debug|x64 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Debug|x64.Build.0 = Debug|x64 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Release|Mixed Platforms.Build.0 = Release|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Release|Win32.ActiveCfg = Release|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Release|Win32.Build.0 = Release|Win32 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Release|x64.ActiveCfg = Release|x64 + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5}.Release|x64.Build.0 = Release|x64 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Debug|Win32.ActiveCfg = Debug|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Debug|Win32.Build.0 = Debug|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Debug|x64.ActiveCfg = Debug|x64 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Debug|x64.Build.0 = Debug|x64 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Release|Mixed Platforms.Build.0 = Release|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Release|Win32.ActiveCfg = Release|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Release|Win32.Build.0 = Release|Win32 + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788}.Release|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DjVuFile/DjVuFile.vcxproj b/DjVuFile/DjVuFile.vcxproj new file mode 100644 index 0000000000..75bf41f146 --- /dev/null +++ b/DjVuFile/DjVuFile.vcxproj @@ -0,0 +1,262 @@ +п»ї + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {712534D7-B84A-4D84-93C9-3BF3F98F4BF5} + Win32Proj + DjVuFile + + + + StaticLibrary + true + v120 + Unicode + + + StaticLibrary + true + v120 + Unicode + + + StaticLibrary + false + v120 + true + Unicode + + + StaticLibrary + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES + true + 4267;4244 + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\Common\DocxFormat\Source\XML\libxml2\XML\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\agg-2.4\include;%(AdditionalIncludeDirectories) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES + true + 4267; + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DjVuFile/DjVuFileImplementation.cpp b/DjVuFile/DjVuFileImplementation.cpp new file mode 100644 index 0000000000..206709056d --- /dev/null +++ b/DjVuFile/DjVuFileImplementation.cpp @@ -0,0 +1,675 @@ +#include "DjVuFileImplementation.h" + +#include "../DesktopEditor/common/File.h" +#include "../DesktopEditor/common/Directory.h" +#include "../DesktopEditor/graphics/IRenderer.h" +#include "../DesktopEditor/raster/BgraFrame.h" +#include "../DesktopEditor/graphics/Image.h" +#include "../DesktopEditor/common/String.h" + +#include "../DesktopEditor/fontengine/FontManager.h" +#include "../DesktopEditor/fontengine/ApplicationFonts.h" +#include "../DesktopEditor/raster/BgraFrame.h" +#include "../DesktopEditor/graphics/GraphicsRenderer.h" + +#define VER_DPI 96 +#define HOR_DPI 96 + +#include + +namespace NSDjvu +{ + static GUTF8String MakeUTF8String(const std::wstring& wsText) + { + int nSize; + +#ifdef _UNICODE + LPCWSTR pszUnicodeText = wsText.c_str(); +#else + nSize = ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strText, -1, NULL, 0); + if (nSize == 0) + return ""; + + LPWSTR pszUnicodeText = new WCHAR[nSize]; + ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)strText, -1, pszUnicodeText, nSize); +#endif + + nSize = ::WideCharToMultiByte(CP_UTF8, 0, pszUnicodeText, -1, NULL, 0, NULL, NULL); + if (nSize == 0) + { +#ifndef _UNICODE + delete[] pszUnicodeText; +#endif + return ""; + } + + LPSTR pszTextUTF8 = new CHAR[nSize]; + ::WideCharToMultiByte(CP_UTF8, 0, pszUnicodeText, -1, pszTextUTF8, nSize, NULL, NULL); + + GUTF8String utf8String(pszTextUTF8); + delete[] pszTextUTF8; + +#ifndef _UNICODE + delete[] pszUnicodeText; +#endif + + return utf8String; + + //std::string sText = NSFile::CUtf8Converter::GetUtf8StringFromUnicode(wsText); + //GUTF8String utf8String(sText.c_str()); + //return utf8String; + } + static CString MakeCString(GUTF8String& strText) + { + int nSize; + + LPSTR pszUtf8Text = strText.getbuf(); + + //nSize = ::WideCharToMultiByte(CP_UTF8, 0, pszUtf8Text, -1, NULL, 0, NULL, NULL); + nSize = ::MultiByteToWideChar(CP_UTF8, 0, pszUtf8Text, -1, NULL, 0); + + if (nSize == 0) + { + return _T(""); + } + + LPWSTR pszUnicodeText = new WCHAR[nSize]; + ::MultiByteToWideChar(CP_UTF8, 0, pszUtf8Text, -1, pszUnicodeText, nSize); + + CString String(pszUnicodeText); + delete[] pszUnicodeText; + + return String; + } + static int GetInteger(const std::wstring& wsString) + { + if (wsString.size() < 1) + return 0; + + try + { + return _ttoi(wsString.c_str()); + } + catch (...) + { + } + + try + { + return static_cast(_wtoi64(wsString.c_str())); + } + catch (...) + { + return 0; + } + } +} + +CDjVuFileImplementation::CDjVuFileImplementation() +{ + m_pDoc = NULL; + std::wstring wsTempPath = NSFile::CFileBinary::GetTempPathW(); + wsTempPath += L"DJVU\\"; + m_wsTempDirectory = wsTempPath; + NSDirectory::CreateDirectory(m_wsTempDirectory); +} +CDjVuFileImplementation::~CDjVuFileImplementation() +{ + NSDirectory::DeleteDirectory(m_wsTempDirectory); +} +bool CDjVuFileImplementation::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXMLOptions) +{ + m_pDoc = NULL; + try + { + GUTF8String utf8; + GURL url = GURL::Filename::UTF8(NSDjvu::MakeUTF8String(wsSrcFileName)); + m_pDoc = DjVuDocument::create(url); + m_pDoc->wait_get_pages_num(); + } + catch (...) + { + return false; + } + + return true; +} +void CDjVuFileImplementation::Close() +{ +} +std::wstring CDjVuFileImplementation::GetTempDirectory() const +{ + return m_wsTempDirectory; +} +void CDjVuFileImplementation::SetTempDirectory(const std::wstring& wsDirectory) +{ + NSDirectory::DeleteDirectory(m_wsTempDirectory); + + m_wsTempDirectory = wsDirectory; + m_wsTempDirectory += L"\\DJVU\\"; + NSDirectory::CreateDirectory(m_wsTempDirectory); +} +int CDjVuFileImplementation::GetPagesCount() const +{ + if (!m_pDoc) + return 0; + + return m_pDoc->get_pages_num(); +} +void CDjVuFileImplementation::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const +{ + if (!m_pDoc) + { + *pdWidth = 0; + *pdHeight = 0; + + *pdDpiX = 96; + *pdDpiY = 96; + } + + GP pPage = m_pDoc->get_page(nPageIndex); + + pPage->wait_for_complete_decode(); + pPage->set_rotate(0); + + *pdWidth = pPage->get_real_width(); + *pdHeight = pPage->get_real_height(); + + *pdDpiX = pPage->get_dpi(); + *pdDpiY = pPage->get_dpi(); +} +void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) +{ + if (!m_pDoc) + return; + + try + { + GP pPage = m_pDoc->get_page(nPageIndex); + pPage->wait_for_complete_decode(); + pPage->set_rotate(0); + + long lRendererType = c_nUnknownRenderer; + pRenderer->get_Type(&lRendererType); + if (false)//c_nGrRenderer == lRendererType) + { + CreateGrFrame(pRenderer, pPage, pBreak); + } + else + { + XmlUtils::CXmlNode text = ParseText(pPage); + CreateFrame(pRenderer, pPage, nPageIndex, text); + } + } + catch (...) + { + // белая страница + } +} +void CDjVuFileImplementation::ConvertToRaster(CApplicationFonts* pAppFonts, int nPageIndex, const std::wstring& wsDstPath, int nImageType) +{ + CFontManager *pFontManager = pAppFonts->GenerateFontManager(); + CFontsCache* pFontCache = new CFontsCache(); + pFontCache->SetStreams(pAppFonts->GetStreams()); + pFontManager->SetOwnerCache(pFontCache); + + CGraphicsRenderer oRenderer; + oRenderer.SetFontManager(pFontManager); + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiX); + + int nWidth = (int)dWidth * 96 / dPageDpiX; + int nHeight = (int)dHeight * 96 / dPageDpiX; + + BYTE* pBgraData = new BYTE[nWidth * nHeight * 4]; + if (!pBgraData) + return; + + memset(pBgraData, 0xff, nWidth * nHeight * 4); + CBgraFrame oFrame; + oFrame.put_Data(pBgraData); + oFrame.put_Width(nWidth); + oFrame.put_Height(nHeight); + oFrame.put_Stride(-4 * nWidth); + + oRenderer.CreateFromBgraFrame(&oFrame); + oRenderer.SetSwapRGB(false); + oRenderer.put_Width(dWidth); + oRenderer.put_Height(dHeight); + + bool bBreak = false; + DrawPageOnRenderer(&oRenderer, nPageIndex, &bBreak); + + oFrame.SaveFile(wsDstPath, nImageType); + RELEASEINTERFACE(pFontManager); +} +void CDjVuFileImplementation::CreateFrame(IRenderer* pRenderer, GP& pPage, int nPage, XmlUtils::CXmlNode& text) +{ + int nWidth = pPage->get_real_width(); + int nHeight = pPage->get_real_height(); + + int nDpi = pPage->get_dpi(); + + double dPixToMM = 25.4; + + double dRendDpiX = 0; + double dRendDpiY = 0; + + pRenderer->get_DpiX(&dRendDpiX); + pRenderer->get_DpiY(&dRendDpiY); + + if (0 >= dRendDpiX) + dRendDpiX = 72.0; + if (0 >= dRendDpiY) + dRendDpiY = 72.0; + + double dRendWidth = 0; + double dRendHeight = 0; + + pRenderer->get_Width(&dRendWidth); + pRenderer->get_Height(&dRendHeight); + + if (0 >= dRendWidth) + dRendWidth = 200; + if (0 >= dRendHeight) + dRendHeight = 300; + + LONG lImageWidth = (LONG)(dRendDpiX * dRendWidth / dPixToMM); + LONG lImageHeight = (LONG)(dRendDpiY * dRendHeight / dPixToMM); + + long lRendererType = c_nUnknownRenderer; + pRenderer->get_Type(&lRendererType); + if (c_nPDFWriter == lRendererType) + { + lImageWidth = pPage->get_real_width(); + lImageHeight = pPage->get_real_height(); + } + else if (c_nHtmlRendrerer == lRendererType) + { + // TODO: Нужно реализовать функцию + // pRenderer->GetMaxImageSize(); + //VARIANT var; + //renderer->GetAdditionalParam(L"MaxImageSize", &var); + //LONG lMaxWidth = var.lVal; + //if ((lImageWidth > lMaxWidth) || (lImageHeight > lMaxWidth)) + //{ + // double dAspect = (double)(lImageWidth) / lImageHeight; + // if (lImageWidth > lImageHeight) + // { + // lImageWidth = lMaxWidth; + // lImageHeight = (LONG)(lImageHeight / dAspect); + // } + // else + // { + // lImageHeight = lMaxWidth; + // lImageWidth = (LONG)(dAspect * lImageHeight); + // } + //} + } + + BYTE* pBufferDst = new BYTE[4 * lImageHeight * lImageWidth]; + if (!pBufferDst) + return; + + Aggplus::CImage oImage; + oImage.Create(pBufferDst, lImageWidth, lImageHeight, 4 * lImageWidth); + if (pPage->is_legal_photo() || pPage->is_legal_compound()) + { + GRect oRectAll(0, 0, lImageWidth, lImageHeight); + GP pImage = pPage->get_pixmap(oRectAll, oRectAll); + + BYTE* pBuffer = pBufferDst; + for (int j = lImageHeight - 1; j >= 0; --j) + { + GPixel* pLine = pImage->operator [](j); + + for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) + { + pBuffer[0] = pLine->b; + pBuffer[1] = pLine->g; + pBuffer[2] = pLine->r; + pBuffer[3] = 255; + } + } + } + else if (pPage->is_legal_bilevel()) + { + GRect oRectAll(0, 0, lImageWidth, lImageHeight); + GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); + int nPaletteEntries = pBitmap->get_grays(); + + DWORD* palette = new DWORD[nPaletteEntries]; + + // Create palette for the bitmap + int color = 0xff0000; + int decrement = color / (nPaletteEntries - 1); + for (int i = 0; i < nPaletteEntries; ++i) + { + BYTE level = (BYTE)(color >> 16); + palette[i] = (0xFF000000 | level << 16 | level << 8 | level); + color -= decrement; + } + + DWORD* pBuffer = (DWORD*)pBufferDst; + for (int j = lImageHeight - 1; j >= 0; --j) + { + BYTE* pLine = pBitmap->operator [](j); + + for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine) + { + if (*pLine < nPaletteEntries) + { + *pBuffer = palette[*pLine]; + } + else + { + *pBuffer = palette[0]; + } + } + } + + RELEASEARRAYOBJECTS(palette); + } + else + { + // белый фрейм?? + //memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight); + GRect oRectAll(0, 0, lImageWidth, lImageHeight); + GP pImage = pPage->get_pixmap(oRectAll, oRectAll); + + if (NULL != pImage) + { + BYTE* pBuffer = pBufferDst; + for (int j = lImageHeight - 1; j >= 0; --j) + { + GPixel* pLine = pImage->operator [](j); + + for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) + { + pBuffer[0] = pLine->b; + pBuffer[1] = pLine->g; + pBuffer[2] = pLine->r; + pBuffer[3] = 255; + } + } + } + else + { + GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); + + if (NULL != pBitmap) + { + int nPaletteEntries = pBitmap->get_grays(); + + DWORD* palette = new DWORD[nPaletteEntries]; + + // Create palette for the bitmap + int color = 0xff0000; + int decrement = color / (nPaletteEntries - 1); + for (int i = 0; i < nPaletteEntries; ++i) + { + BYTE level = (BYTE)(color >> 16); + palette[i] = (0xFF000000 | level << 16 | level << 8 | level); + color -= decrement; + } + + DWORD* pBuffer = (DWORD*)pBufferDst; + for (int j = lImageHeight - 1; j >= 0; --j) + { + BYTE* pLine = pBitmap->operator [](j); + + for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine) + { + if (*pLine < nPaletteEntries) + { + *pBuffer = palette[*pLine]; + } + else + { + *pBuffer = palette[0]; + } + } + } + + RELEASEARRAYOBJECTS(palette); + } + } + } + + pRenderer->BeginCommand(c_nPageType); + + if (c_nGrRenderer != lRendererType && c_nHtmlRendrerer != lRendererType && c_nHtmlRendrerer2 != lRendererType) + { + TextToRenderer(pRenderer, text, dPixToMM / nDpi); + } + + pRenderer->DrawImage((IGrObject*)&oImage, 0, 0, dRendWidth, dRendHeight); + pRenderer->EndCommand(c_nPageType); +} +void CDjVuFileImplementation::CreateGrFrame(IRenderer* pRenderer, GP& pPage, bool* pBreak) +{ + int nWidth = pPage->get_real_width(); + int nHeight = pPage->get_real_height(); + + BYTE* pBufferDst = NULL; + LONG lImageWidth = 0; + LONG lImageHeight = 0; + + // TODO: Реализовать для графического рендерера + + //VARIANT var; + //renderer->GetAdditionalParam(L"Pixels", &var); + //pBufferDst = (BYTE*)var.lVal; + + //renderer->GetAdditionalParam(L"PixelsWidth", &var); + //lImageWidth = var.lVal; + //renderer->GetAdditionalParam(L"PixelsHeight", &var); + //lImageHeight = var.lVal; + + volatile bool* pCancel = pBreak; + + if ((NULL != pCancel) && (TRUE == *pCancel)) + return; + + if (pPage->is_legal_photo() || pPage->is_legal_compound()) + { + GRect oRectAll(0, 0, lImageWidth, lImageHeight); + GP pImage = pPage->get_pixmap(oRectAll, oRectAll); + + BYTE* pBuffer = pBufferDst; + for (int j = 0; j < lImageHeight; ++j) + { + GPixel* pLine = pImage->operator [](j); + + if ((NULL != pCancel) && (TRUE == *pCancel)) + return; + + for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) + { + pBuffer[0] = pLine->b; + pBuffer[1] = pLine->g; + pBuffer[2] = pLine->r; + pBuffer[3] = 255; + } + } + } + else if (pPage->is_legal_bilevel()) + { + GRect oRectAll(0, 0, lImageWidth, lImageHeight); + GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); + int nPaletteEntries = pBitmap->get_grays(); + + DWORD* palette = new DWORD[nPaletteEntries]; + + // Create palette for the bitmap + int color = 0xff0000; + int decrement = color / (nPaletteEntries - 1); + for (int i = 0; i < nPaletteEntries; ++i) + { + BYTE level = (BYTE)(color >> 16); + palette[i] = (0xFF000000 | level << 16 | level << 8 | level); + color -= decrement; + } + + DWORD* pBuffer = (DWORD*)pBufferDst; + for (int j = 0; j < lImageHeight; ++j) + { + BYTE* pLine = pBitmap->operator [](j); + + if ((NULL != pCancel) && (TRUE == *pCancel)) + return; + + for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine) + { + if (*pLine < nPaletteEntries) + { + *pBuffer = palette[*pLine]; + } + else + { + *pBuffer = palette[0]; + } + } + } + + RELEASEARRAYOBJECTS(palette); + } + else + { + // белый фрейм?? + //memset(pBufferDst, 0xFF, 4 * lImageWidth * lImageHeight); + GRect oRectAll(0, 0, lImageWidth, lImageHeight); + GP pImage = pPage->get_pixmap(oRectAll, oRectAll); + + if (NULL != pImage) + { + BYTE* pBuffer = pBufferDst; + for (int j = 0; j < lImageHeight; ++j) + { + GPixel* pLine = pImage->operator [](j); + + if ((NULL != pCancel) && (TRUE == *pCancel)) + return; + + for (int i = 0; i < lImageWidth; ++i, pBuffer += 4, ++pLine) + { + pBuffer[0] = pLine->b; + pBuffer[1] = pLine->g; + pBuffer[2] = pLine->r; + pBuffer[3] = 255; + } + } + + return; + } + + GP pBitmap = pPage->get_bitmap(oRectAll, oRectAll, 4); + + if (NULL != pBitmap) + { + int nPaletteEntries = pBitmap->get_grays(); + + DWORD* palette = new DWORD[nPaletteEntries]; + + // Create palette for the bitmap + int color = 0xff0000; + int decrement = color / (nPaletteEntries - 1); + for (int i = 0; i < nPaletteEntries; ++i) + { + BYTE level = (BYTE)(color >> 16); + palette[i] = (0xFF000000 | level << 16 | level << 8 | level); + color -= decrement; + } + + DWORD* pBuffer = (DWORD*)pBufferDst; + for (int j = 0; j < lImageHeight; ++j) + { + BYTE* pLine = pBitmap->operator [](j); + + if ((NULL != pCancel) && (TRUE == *pCancel)) + return; + + for (int i = 0; i < lImageWidth; ++i, ++pBuffer, ++pLine) + { + if (*pLine < nPaletteEntries) + { + *pBuffer = palette[*pLine]; + } + else + { + *pBuffer = palette[0]; + } + } + } + + RELEASEARRAYOBJECTS(palette); + } + } +} +XmlUtils::CXmlNode CDjVuFileImplementation::ParseText(GP pPage) +{ + XmlUtils::CXmlNode paragraph; + const GP text(DjVuText::create()); + const GP text_str(pPage->get_text()); + if (text_str) + { + text->decode(text_str); + GUTF8String pageText = text->get_xmlText(pPage->get_height()); + XmlUtils::CXmlNode hiddenText; + XmlUtils::CXmlNode pageColumn; + XmlUtils::CXmlNode region; + hiddenText.FromXmlString(NSDjvu::MakeCString(pageText)); + hiddenText.GetNode(_T("PAGECOLUMN"), pageColumn); + pageColumn.GetNode(_T("REGION"), region); + region.GetNode(_T("PARAGRAPH"), paragraph); + } + return paragraph; +} +void CDjVuFileImplementation::TextToRenderer(IRenderer* pRenderer, XmlUtils::CXmlNode oTextNode, double dKoef, bool isView) +{ + // Выставим шрифт пустой (чтобы растягивать по всему ректу) + pRenderer->put_FontName(L"AVSEmptyFont"); + CString csText = oTextNode.GetXml(); + XmlUtils::CXmlNodes oLinesNodes; + oTextNode.GetNodes(L"LINE", oLinesNodes); + for (int nLineIndex = 0; nLineIndex < oLinesNodes.GetCount(); ++nLineIndex) + { + XmlUtils::CXmlNode oLineNode; + oLinesNodes.GetAt(nLineIndex, oLineNode); + XmlUtils::CXmlNodes oWordsNodes; + oLineNode.GetNodes(L"WORD", oWordsNodes); + for (int nWordIndex = 0; nWordIndex < oWordsNodes.GetCount(); ++nWordIndex) + { + XmlUtils::CXmlNode oWordNode; + oWordsNodes.GetAt(nWordIndex, oWordNode); + CString csWord = oWordNode.GetText(); + CString csCoords = oWordNode.GetAttribute(L"coords"); + double arrCoords[4]; + ParseCoords(csCoords.GetBuffer(), arrCoords, dKoef); + DrawText(pRenderer, arrCoords, csWord.GetBuffer()); + } + } +} +void CDjVuFileImplementation::DrawText(IRenderer* pRenderer, double* pdCoords, const std::wstring& wsText) +{ + pRenderer->put_FontSize(pdCoords[1] - pdCoords[3]); + pRenderer->CommandDrawText(wsText, + (float)(pdCoords[0]), + (float)(pdCoords[3]), + (float)(pdCoords[2] - pdCoords[0]), + (float)(pdCoords[1] - pdCoords[3]), + (float)(pdCoords[1] - pdCoords[3])); +} +void CDjVuFileImplementation::ParseCoords(const std::wstring& wsCoordsStr, double* pdCoords, double dKoef) +{ + std::vector vCoords = NSString::Split(wsCoordsStr, L','); + if (vCoords.size() >= 4) + { + for (int nIndex = 0; nIndex < 4; nIndex++) + { + pdCoords[nIndex] = NSDjvu::GetInteger(vCoords.at(nIndex)) * dKoef; + } + } +} \ No newline at end of file diff --git a/DjVuFile/DjVuFileImplementation.h b/DjVuFile/DjVuFileImplementation.h new file mode 100644 index 0000000000..31e8b31ad4 --- /dev/null +++ b/DjVuFile/DjVuFileImplementation.h @@ -0,0 +1,57 @@ +#pragma once + +#include "libdjvu/DjVuDocument.h" +#include "libdjvu/DjVuImage.h" +#include "libdjvu/GBitmap.h" +#include "libdjvu/GScaler.h" +#include "libdjvu/IFFByteStream.h" +#include "libdjvu/BSByteStream.h" +#include "libdjvu/DataPool.h" +#include "libdjvu/DjVuText.h" +#include "libdjvu/DjVmNav.h" + +#define ZIP_NO_COMPRESSION 0 +#define ZIP_BEST_SPEED 1 +#define ZIP_BEST_COMPRESSION 9 +#define ZIP_DEFAULT_COMPRESSION (-1) + +#define UNICODE +#define _UNICODE +#define _USE_LIBXML2_READER_ +#define LIBXML_READER_ENABLED +#include "../Common/DocxFormat/Source/XML/xmlutils.h" + +#include "../DesktopEditor/graphics/IRenderer.h" + +class CApplicationFonts; + +class CDjVuFileImplementation +{ +private: + + std::wstring m_wsTempDirectory; + GP m_pDoc; + +public: + + CDjVuFileImplementation(); + ~CDjVuFileImplementation(); + + bool LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXmlOptions = L""); + void Close(); + std::wstring GetTempDirectory() const; + void SetTempDirectory(const std::wstring& wsDirectory); + int GetPagesCount() const; + void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) const; + void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); + void ConvertToRaster(CApplicationFonts* pAppFonts, int nPageIndex, const std::wstring& wsDstPath, int nImageType); + +private: + + void CreateFrame(IRenderer* pRenderer, GP& pImage, int nPage, XmlUtils::CXmlNode& text); + void CreateGrFrame(IRenderer* pRenderer, GP& pImage, bool* pBreak); + XmlUtils::CXmlNode ParseText(GP pPage); + void TextToRenderer(IRenderer* pRenderer, XmlUtils::CXmlNode text, double koef, bool isView = true); + void DrawText(IRenderer* pRenderer, double* pdCoords, const std::wstring& wsText); + void ParseCoords(const std::wstring& wsCoordsStr, double* pdCoords, double dKoef); +}; diff --git a/DjVuFile/DjVuFileTest/DjVuFileTest.cpp b/DjVuFile/DjVuFileTest/DjVuFileTest.cpp new file mode 100644 index 0000000000..988e41ea8d --- /dev/null +++ b/DjVuFile/DjVuFileTest/DjVuFileTest.cpp @@ -0,0 +1,72 @@ +// DjVuFileTest.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "../DjVu.h" + +#include +#include +#include "windows.h" + +#include "../../DesktopEditor/fontengine/ApplicationFonts.h" + +std::vector GetAllFilesInFolder(std::wstring wsFolder, std::wstring wsExt) +{ + std::vector vwsNames; + + std::wstring wsSearchPath = wsFolder; + wsSearchPath.append(L"*."); + wsSearchPath.append(wsExt); + + WIN32_FIND_DATA oFindData; + HANDLE hFind = ::FindFirstFile(wsSearchPath.c_str(), &oFindData); + if (hFind != INVALID_HANDLE_VALUE) + { + do + { + if (!(oFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + vwsNames.push_back(oFindData.cFileName); + } + } while (::FindNextFile(hFind, &oFindData)); + ::FindClose(hFind); + } + return vwsNames; +} +void ConvertFolder(CDjVuFile& oReader, std::wstring wsFolderPath) +{ + CApplicationFonts oFonts; + oFonts.Initialize(); + + oReader.Close(); + + std::vector vFiles = GetAllFilesInFolder(wsFolderPath, L"djvu"); + for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) + { + std::wstring wsFilePath = wsFolderPath; + wsFilePath.append(vFiles.at(nIndex)); + std::wstring wsFilePathName = (wsFilePath.substr(0, wsFilePath.size() - 4)); + if (oReader.LoadFromFile(wsFilePath.c_str())) + { + int nPagesCount = oReader.GetPagesCount(); + + for (int nPageIndex = 0; nPageIndex < nPagesCount; nPageIndex++) + { + std::wstring wsDstFilePath = wsFilePathName + L"_" + std::to_wstring(nPageIndex) + L".png"; + oReader.ConvertToRaster(&oFonts, nPageIndex, wsDstFilePath.c_str(), 4); + printf("%d of %d %S page %d / %d\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str(), nPageIndex, nPagesCount); + } + oReader.Close(); + } + else + { + printf("%d of %d %S error\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); + } + } +} + +void main() +{ + CDjVuFile oFile; + ConvertFolder(oFile, L"D:/Test Files//"); +} diff --git a/DjVuFile/DjVuFileTest/DjVuFileTest.vcxproj b/DjVuFile/DjVuFileTest/DjVuFileTest.vcxproj new file mode 100644 index 0000000000..3e9e0f95c8 --- /dev/null +++ b/DjVuFile/DjVuFileTest/DjVuFileTest.vcxproj @@ -0,0 +1,173 @@ +п»ї + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {6D3BC8A8-93A8-468E-90CE-BCEAC28B8788} + Win32Proj + DjVuFileTest + + + + Application + true + v120 + Unicode + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES + true + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\agg-2.4\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES;UNICODE;_UNICODE;_USE_LIBXML2_READER_;LIBXML_READER_ENABLED + true + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\agg-2.4\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\Common\DocxFormat\Source\XML\libxml2\XML\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES + true + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;HAVE_NAMESPACES + true + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + NotUsing + + + NotUsing + + + NotUsing + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/DjVuFile/DjVuFileTest/ReadMe.txt b/DjVuFile/DjVuFileTest/ReadMe.txt new file mode 100644 index 0000000000..a7f7056edd --- /dev/null +++ b/DjVuFile/DjVuFileTest/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + CONSOLE APPLICATION : DjVuFileTest Project Overview +======================================================================== + +AppWizard has created this DjVuFileTest application for you. + +This file contains a summary of what you will find in each of the files that +make up your DjVuFileTest application. + + +DjVuFileTest.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +DjVuFileTest.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +DjVuFileTest.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named DjVuFileTest.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/DjVuFile/DjVuFileTest/stdafx.cpp b/DjVuFile/DjVuFileTest/stdafx.cpp new file mode 100644 index 0000000000..82331d82a1 --- /dev/null +++ b/DjVuFile/DjVuFileTest/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// DjVuFileTest.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/DjVuFile/DjVuFileTest/stdafx.h b/DjVuFile/DjVuFileTest/stdafx.h new file mode 100644 index 0000000000..df30986d85 --- /dev/null +++ b/DjVuFile/DjVuFileTest/stdafx.h @@ -0,0 +1,23 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + +#ifdef _DEBUG +#pragma comment(lib, "../../Common/DocxFormat/Source/XML/libxml2/win_build/x64/Debug/libxml2.lib") +#pragma comment(lib, "../x64/Debug/DjVuFile.lib") +#pragma comment(lib, "../../DesktopEditor/Qt_build/graphics/project/debug/graphics.lib") +#else +#pragma comment(lib, "../x64/Release/DjVuFile.lib") +#pragma comment(lib, "../../DesktopEditor/Qt_build/graphics/project/release/graphics.lib") +#endif + +// TODO: reference additional headers your program requires here diff --git a/DjVuFile/DjVuFileTest/targetver.h b/DjVuFile/DjVuFileTest/targetver.h new file mode 100644 index 0000000000..90e767bfce --- /dev/null +++ b/DjVuFile/DjVuFileTest/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/DjVuFile/ReadMe.txt b/DjVuFile/ReadMe.txt new file mode 100644 index 0000000000..5d3bb3b061 --- /dev/null +++ b/DjVuFile/ReadMe.txt @@ -0,0 +1,29 @@ +======================================================================== + STATIC LIBRARY : DjVuFile Project Overview +======================================================================== + +AppWizard has created this DjVuFile library project for you. + +No source files were created as part of your project. + + +DjVuFile.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +DjVuFile.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/DjVuFile/libdjvu/Arrays.cpp b/DjVuFile/libdjvu/Arrays.cpp new file mode 100644 index 0000000000..8173d7d40f --- /dev/null +++ b/DjVuFile/libdjvu/Arrays.cpp @@ -0,0 +1,307 @@ +//C- -*- C++ -*- +//C- ------------------------------------------------------------------- +//C- DjVuLibre-3.5 +//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. +//C- Copyright (c) 2001 AT&T +//C- +//C- This software is subject to, and may be distributed under, the +//C- GNU General Public License, either Version 2 of the license, +//C- or (at your option) any later version. The license should have +//C- accompanied the software or you may obtain a copy of the license +//C- from the Free Software Foundation at http://www.fsf.org . +//C- +//C- This program is distributed in the hope that it will be useful, +//C- but WITHOUT ANY WARRANTY; without even the implied warranty of +//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//C- GNU General Public License for more details. +//C- +//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from +//C- Lizardtech Software. Lizardtech Software has authorized us to +//C- replace the original DjVu(r) Reference Library notice by the following +//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): +//C- +//C- ------------------------------------------------------------------ +//C- | DjVu (r) Reference Library (v. 3.5) +//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. +//C- | The DjVu Reference Library is protected by U.S. Pat. No. +//C- | 6,058,214 and patents pending. +//C- | +//C- | This software is subject to, and may be distributed under, the +//C- | GNU General Public License, either Version 2 of the license, +//C- | or (at your option) any later version. The license should have +//C- | accompanied the software or you may obtain a copy of the license +//C- | from the Free Software Foundation at http://www.fsf.org . +//C- | +//C- | The computer code originally released by LizardTech under this +//C- | license and unmodified by other parties is deemed "the LIZARDTECH +//C- | ORIGINAL CODE." Subject to any third party intellectual property +//C- | claims, LizardTech grants recipient a worldwide, royalty-free, +//C- | non-exclusive license to make, use, sell, or otherwise dispose of +//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the +//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU +//C- | General Public License. This grant only confers the right to +//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to +//C- | the extent such infringement is reasonably necessary to enable +//C- | recipient to make, have made, practice, sell, or otherwise dispose +//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to +//C- | any greater extent that may be necessary to utilize further +//C- | modifications or combinations. +//C- | +//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY +//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF +//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +//C- +------------------------------------------------------------------ +// +// $Id: Arrays.cpp,v 1.9 2007/03/25 20:48:29 leonb Exp $ +// $Name: $ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#if NEED_GNUG_PRAGMAS +# pragma implementation +#endif + +#include "Arrays.h" +#include "GException.h" + + +#ifdef HAVE_NAMESPACES +namespace DJVU { +# ifdef NOT_DEFINED // Just to fool emacs c++ mode +} +#endif +#endif + +ArrayRep::ArrayRep(int xelsize, + void (* xdestroy)(void *, int, int), + void (* xinit1)(void *, int, int), + void (* xinit2)(void *, int, int, const void *, int, int), + void (* xcopy)(void *, int, int, const void *, int, int), + void (* xinsert)(void *, int, int, const void *, int)) : + data(0), minlo(0), maxhi(-1), lobound(0), hibound(-1), + elsize(xelsize), destroy(xdestroy), init1(xinit1), + init2(xinit2), copy(xcopy), insert(xinsert) +{ +} + +ArrayRep::ArrayRep(int xelsize, + void (* xdestroy)(void *, int, int), + void (* xinit1)(void *, int, int), + void (* xinit2)(void *, int, int, const void *, int, int), + void (* xcopy)(void *, int, int, const void *, int, int), + void (* xinsert)(void *, int, int, const void *, int), + int hi) : data(0), minlo(0), maxhi(-1), + lobound(0), hibound(-1), elsize(xelsize), destroy(xdestroy), init1(xinit1), + init2(xinit2), copy(xcopy), insert(xinsert) +{ + resize(0, hi); +} + +ArrayRep::ArrayRep(int xelsize, + void (* xdestroy)(void *, int, int), + void (* xinit1)(void *, int, int), + void (* xinit2)(void *, int, int, const void *, int, int), + void (* xcopy)(void *, int, int, const void *, int, int), + void (* xinsert)(void *, int, int, const void *, int), + int lo, int hi) : data(0), minlo(0), maxhi(-1), + lobound(0), hibound(-1), elsize(xelsize), destroy(xdestroy), init1(xinit1), + init2(xinit2), copy(xcopy), insert(xinsert) +{ + resize(lo,hi); +} + +ArrayRep::ArrayRep(const ArrayRep & arr) : data(0), minlo(0), maxhi(-1), + lobound(0), hibound(-1), elsize(arr.elsize), destroy(arr.destroy), + init1(arr.init1), init2(arr.init2), copy(arr.copy), insert(arr.insert) +{ + resize(arr.lobound, arr.hibound); + arr.copy(data, lobound-minlo, hibound-minlo, + arr.data, arr.lobound-arr.minlo, arr.hibound-arr.minlo); +} + +ArrayRep::~ArrayRep() +{ + destroy(data, lobound-minlo, hibound-minlo); + operator delete(data); + data=0; +} + +ArrayRep & +ArrayRep::operator= (const ArrayRep & rep) +{ + if (&rep == this) return *this; + empty(); + resize(rep.lobound, rep.hibound); + copy(data, lobound-minlo, hibound-minlo, + rep.data, rep.lobound-rep.minlo, rep.hibound-rep.minlo); + return *this; +} + +void +ArrayRep::resize(int lo, int hi) +{ + int nsize = hi - lo + 1; + // Validation + if (nsize < 0) + G_THROW( ERR_MSG("arrays.resize") ); + // Destruction + if (nsize == 0) + { + destroy(data, lobound-minlo, hibound-minlo); + operator delete(data); + data = 0; + lobound = minlo = lo; + hibound = maxhi = hi; + return; + } + // Simple extension + if (lo >= minlo && hi <= maxhi) + { + init1(data, lo-minlo, lobound-1-minlo); + destroy(data, lobound-minlo, lo-1-minlo); + init1(data, hibound+1-minlo, hi-minlo); + destroy(data, hi+1-minlo, hibound-minlo); + lobound = lo; + hibound = hi; + return; + } + // General case + int nminlo = minlo; + int nmaxhi = maxhi; + if (nminlo > nmaxhi) + nminlo = nmaxhi = lo; + while (nminlo > lo) { + int incr = nmaxhi - nminlo; + nminlo -= (incr < 8 ? 8 : (incr > 32768 ? 32768 : incr)); + } + while (nmaxhi < hi) { + int incr = nmaxhi - nminlo; + nmaxhi += (incr < 8 ? 8 : (incr > 32768 ? 32768 : incr)); + } + // allocate + int bytesize=elsize*(nmaxhi-nminlo+1); + void * ndata; + GPBufferBase gndata(ndata,bytesize,1); + memset(ndata, 0, bytesize); + // initialize + init1(ndata, lo-nminlo, lobound-1-nminlo); + init2(ndata, lobound-nminlo, hibound-nminlo, + data, lobound-minlo, hibound-minlo); + init1(ndata, hibound+1-nminlo, hi-nminlo); + destroy(data, lobound-minlo, hibound-minlo); + + // free and replace + void *tmp=data; + data = ndata; + ndata=tmp; + + minlo = nminlo; + maxhi = nmaxhi; + lobound = lo; + hibound = hi; +} + +void +ArrayRep::shift(int disp) +{ + lobound += disp; + hibound += disp; + minlo += disp; + maxhi += disp; +} + +void +ArrayRep::del(int n, unsigned int howmany) +{ + if (howmany == 0) + return; + if ((int)(n + howmany) > hibound +1) + G_THROW( ERR_MSG("arrays.ill_arg") ); + copy(data, n-minlo, hibound-howmany-minlo, + data, n+howmany-minlo, hibound-minlo); + destroy(data, hibound+1-howmany-minlo, hibound-minlo); + hibound = hibound - howmany; +} + +void +ArrayRep::ins(int n, const void * what, unsigned int howmany) +{ + int nhi = hibound + howmany; + if (howmany == 0) return; + if (maxhi < nhi) + { + int nmaxhi = maxhi; + while (nmaxhi < nhi) + nmaxhi += (nmaxhi < 8 ? 8 : (nmaxhi > 32768 ? 32768 : nmaxhi)); + int bytesize = elsize*(nmaxhi-minlo+1); + void *ndata; + GPBufferBase gndata(ndata,bytesize,1); + memset(ndata, 0, bytesize); + copy(ndata, lobound-minlo, hibound-minlo, + data, lobound-minlo, hibound-minlo); + destroy(data, lobound-minlo, hibound-minlo); + void *tmp=data; + data=ndata; + tmp=data; + maxhi = nmaxhi; + } + + insert(data, hibound+1-minlo, n-minlo, what, howmany); + hibound=nhi; +} + + + +#ifdef HAVE_NAMESPACES +} +# ifndef NOT_USING_DJVU_NAMESPACE +using namespace DJVU; +# endif +#endif + + +// --------------------------------------- +// BEGIN HACK +// --------------------------------------- +// Included here to avoid dependency +// from ByteStream.o to Arrays.o + +#ifndef DO_NOT_MOVE_GET_DATA_TO_ARRAYS_CPP +#include "ByteStream.h" + +#ifdef HAVE_NAMESPACES +namespace DJVU { +# ifdef NOT_DEFINED // Just to fool emacs c++ mode +} +#endif +#endif +TArray +ByteStream::get_data(void) +{ + const int s=size(); + if(s > 0) + { + TArray data(0, s-1); + readat((char*)data, s, 0); + return data; + }else + { + TArray data(0, -1); + return data; + } +} + +#ifdef HAVE_NAMESPACES +} +# ifndef NOT_USING_DJVU_NAMESPACE +using namespace DJVU; +# endif +#endif +#endif + +// --------------------------------------- +// END HACK +// --------------------------------------- + diff --git a/DjVuFile/libdjvu/Arrays.h b/DjVuFile/libdjvu/Arrays.h new file mode 100644 index 0000000000..78ee740743 --- /dev/null +++ b/DjVuFile/libdjvu/Arrays.h @@ -0,0 +1,987 @@ +//C- -*- C++ -*- +//C- ------------------------------------------------------------------- +//C- DjVuLibre-3.5 +//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. +//C- Copyright (c) 2001 AT&T +//C- +//C- This software is subject to, and may be distributed under, the +//C- GNU General Public License, either Version 2 of the license, +//C- or (at your option) any later version. The license should have +//C- accompanied the software or you may obtain a copy of the license +//C- from the Free Software Foundation at http://www.fsf.org . +//C- +//C- This program is distributed in the hope that it will be useful, +//C- but WITHOUT ANY WARRANTY; without even the implied warranty of +//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//C- GNU General Public License for more details. +//C- +//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from +//C- Lizardtech Software. Lizardtech Software has authorized us to +//C- replace the original DjVu(r) Reference Library notice by the following +//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu): +//C- +//C- ------------------------------------------------------------------ +//C- | DjVu (r) Reference Library (v. 3.5) +//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. +//C- | The DjVu Reference Library is protected by U.S. Pat. No. +//C- | 6,058,214 and patents pending. +//C- | +//C- | This software is subject to, and may be distributed under, the +//C- | GNU General Public License, either Version 2 of the license, +//C- | or (at your option) any later version. The license should have +//C- | accompanied the software or you may obtain a copy of the license +//C- | from the Free Software Foundation at http://www.fsf.org . +//C- | +//C- | The computer code originally released by LizardTech under this +//C- | license and unmodified by other parties is deemed "the LIZARDTECH +//C- | ORIGINAL CODE." Subject to any third party intellectual property +//C- | claims, LizardTech grants recipient a worldwide, royalty-free, +//C- | non-exclusive license to make, use, sell, or otherwise dispose of +//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the +//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU +//C- | General Public License. This grant only confers the right to +//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to +//C- | the extent such infringement is reasonably necessary to enable +//C- | recipient to make, have made, practice, sell, or otherwise dispose +//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to +//C- | any greater extent that may be necessary to utilize further +//C- | modifications or combinations. +//C- | +//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY +//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF +//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +//C- +------------------------------------------------------------------ +// +// $Id: Arrays.h,v 1.13 2007/05/19 03:07:33 leonb Exp $ +// $Name: $ + +#ifndef _ARRAYS_H_ +#define _ARRAYS_H_ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#if NEED_GNUG_PRAGMAS +# pragma interface +#endif + +#include "GException.h" +#include "GSmartPointer.h" +#include + +#ifdef HAVE_NAMESPACES +namespace DJVU { +# ifdef NOT_DEFINED // Just to fool emacs c++ mode +} +#endif +#endif + + + +/** @name Arrays.h + + Files #"Arrays.h"# and #"Arrays.cpp"# implement three array template classes. + Class \Ref{TArray} implements an array of objects of trivial types + such as #char#, #int#, #float#, etc. It is faster than general implementation + for any type done in \Ref{DArray} because it does not cope with + element's constructors, destructors and copy operators. Although + implemented as a template, which makes it possible to incorrectly use + \Ref{TArray} with non-trivial classes, it should not be done. + + A lot of things is shared by these three arrays. That is why there are + more base classes: + \begin{itemize} + \item \Ref{ArrayBase} defines functions independent of the elements type + \item \Ref{ArrayBaseT} template class defining functions shared by + \Ref{DArray} and \Ref{TArray} + \end{itemize} + + The main difference between \Ref{GArray} (now obsolete) and these ones + is the copy-on-demand strategy, which allows you to copy array objects + without copying the real data. It's the same thing, which has been + implemented in \Ref{GString} long ago: as long as you don't try to modify + the underlying data, it may be shared between several copies of array + objects. As soon as you attempt to make any changes, a private copy + is created automatically and transparently for you - the procedure, that + we call "copy-on-demand". + + Also, please note that now there is no separate class, which does fast + sorting. Both \Ref{TArray} (dynamic array for trivial types) and + \Ref{DArray} (dynamic array for arbitrary types) can sort their elements. + + {\bf Historical comments} --- Leon chose to implement his own arrays because + the STL classes were not universally available and the compilers were + rarely able to deal with such a template galore. Later it became clear + that there is no really good reason why arrays should be derived from + containers. It was also suggested to create separate arrays implementation + for simple classes and do the copy-on-demand strategy, which would allow + to assign array objects without immediate copying of their elements. + + At this point \Ref{DArray} and \Ref{TArray} should only be used when + it is critical to have the copy-on-demand feature. The \Ref{GArray} + implementation is a lot more efficient. + + @memo Template array classes. + @author + Andrei Erofeev -- Copy-on-demand implementation. + @version + #$Id: Arrays.h,v 1.13 2007/05/19 03:07:33 leonb Exp $# */ +//@{ + +// Auxiliary classes: Will be used in place of GPBase and GPEnabled objects +class _ArrayRep +{ + friend class _ArrayBase; +public: + _ArrayRep(void) : count(0) {} + _ArrayRep(const _ArrayRep &) {} + virtual ~_ArrayRep(void) {} + + _ArrayRep & operator=(const _ArrayRep &) { return *this; } + + int get_count(void) const { return count; } +private: + int count; + + void ref(void) { count++; } + void unref(void) { if (--count==0) delete this; } +}; + +class _ArrayBase +{ +public: + _ArrayBase(void) : rep(0) {} + _ArrayBase(const _ArrayBase & ab) : rep(0) + { + if (ab.rep) ab.rep->ref(); + rep=ab.rep; + } + _ArrayBase(_ArrayRep * ar) : rep(0) + { + if (ar) ar->ref(); + rep=ar; + } + virtual ~_ArrayBase(void) + { + if (rep) { rep->unref(); rep=0; } + } + + _ArrayRep * get(void) const { return rep; } + _ArrayBase & assign(_ArrayRep * ar) + { + if (ar) ar->ref(); + if (rep) rep->unref(); + rep=ar; + return *this; + } + _ArrayBase & operator=(const _ArrayBase & ab) { return assign(ab.rep); } + bool operator==(const _ArrayBase & ab) { return rep==ab.rep; } +private: + _ArrayRep * rep; +}; + +// Internal "Array repository" holding the pointer to the actual data, +// data bounds, etc. It copes with data elements with the help of five +// static functions which pointers are supposed to be passed to the +// constructor. +class DJVUAPI ArrayRep : public _ArrayRep +{ +public: + ArrayRep(int elsize, + void (* xdestroy)(void *, int, int), + void (* xinit1)(void *, int, int), + void (* xinit2)(void *, int, int, const void *, int, int), + void (* xcopy)(void *, int, int, const void *, int, int), + void (* xinsert)(void *, int, int, const void *, int)); + ArrayRep(int elsize, + void (* xdestroy)(void *, int, int), + void (* xinit1)(void *, int, int), + void (* xinit2)(void *, int, int, const void *, int, int), + void (* xcopy)(void *, int, int, const void *, int, int), + void (* xinsert)(void *, int, int, const void *, int), + int hibound); + ArrayRep(int elsize, + void (* xdestroy)(void *, int, int), + void (* xinit1)(void *, int, int), + void (* xinit2)(void *, int, int, const void *, int, int), + void (* xcopy)(void *, int, int, const void *, int, int), + void (* xinsert)(void *, int, int, const void *, int), + int lobound, int hibound); + ArrayRep(const ArrayRep & rep); + + virtual ~ArrayRep(); + + // Following is the standard interface to DArray. DArray will call these + // functions to access data. + int size() const; + int lbound() const; + int hbound() const; + + void empty(); + void touch(int n); + void resize(int lobound, int hibound); + void shift(int disp); + void del(int n, unsigned int howmany=1); + + // ins() is an exception. It does it job only partially. + // The derived class is supposed to finish insertion. + void ins(int n, const void * what, unsigned int howmany); + + ArrayRep & operator=(const ArrayRep & rep); + + // All data is public because DArray... classes will need access to it + void *data; + int minlo; + int maxhi; + int lobound; + int hibound; + int elsize; +private: + // These functions can't be virtual as they're called from + // constructors and destructors :(( + // destroy(): should destroy elements in data[] array from 'lo' to 'hi' + void (* destroy)(void * data, int lo, int hi); + // init1(): should initialize elements in data[] from 'lo' to 'hi' + // using default constructors + void (* init1)(void * data, int lo, int hi); + // init2(): should initialize elements in data[] from 'lo' to 'hi' + // using corresponding elements from src[] (copy constructor) + void (* init2)(void * data, int lo, int hi, + const void * src, int src_lo, int src_hi); + // copy(): should copy elements from src[] to dst[] (copy operator) + void (* copy)(void * dst, int dst_lo, int dst_hi, + const void * src, int src_lo, int src_hi); + // insert(): should insert '*what' at position 'where' 'howmany' times + // into array data[] having 'els' initialized elements + void (* insert)(void * data, int els, int where, const void * what, + int howmany); +}; + +inline int +ArrayRep::size() const +{ + return hibound - lobound + 1; +} + +inline int +ArrayRep::lbound() const +{ + return lobound; +} + +inline int +ArrayRep::hbound() const +{ + return hibound; +} + +inline void +ArrayRep::empty() +{ + resize(0, -1); +} + +inline void +ArrayRep::touch(int n) +{ + if (hibound < lobound) + { + resize(n,n); + } else + { + int nlo = lobound; + int nhi = hibound; + if (n < nlo) nlo = n; + if (n > nhi) nhi = n; + resize(nlo, nhi); + } +} + +/** Dynamic array base class. + This is an auxiliary base class for \Ref{DArray} and \Ref{TArray} + implementing some shared functions independent of the type of array + elements. It's not supposed to be constructed by hands. Use \Ref{DArray} + and \Ref{TArray} instead. + */ + +class DJVUAPI ArrayBase : protected _ArrayBase +{ +protected: + void check(void); + void detach(void); + + ArrayBase(void) {}; +public: + /// Returns the number of elements in the array + int size() const; + /** Returns the lower bound of the valid subscript range. */ + int lbound() const; + /** Returns the upper bound of the valid subscript range. */ + int hbound() const; + /** Erases the array contents. All elements in the array are destroyed. + The valid subscript range is set to the empty range. */ + void empty(); + /** Extends the subscript range so that is contains #n#. + This function does nothing if #n# is already int the valid subscript range. + If the valid range was empty, both the lower bound and the upper bound + are set to #n#. Otherwise the valid subscript range is extended + to encompass #n#. This function is very handy when called before setting + an array element: + \begin{verbatim} + int lineno=1; + DArray a; + while (! end_of_file()) { + a.touch[lineno]; + a[lineno++] = read_a_line(); + } + \end{verbatim} + */ + void touch(int n); + /** Resets the valid subscript range to #0#---#hibound#. + This function may destroy some array elements and may construct + new array elements with the null constructor. Setting #hibound# to + #-1# resets the valid subscript range to the empty range. + @param hibound upper bound of the new subscript range. */ + void resize(int hibound); + /** Resets the valid subscript range to #lobound#---#hibound#. + This function may destroy some array elements and may construct + new array elements with the null constructor. Setting #lobound# to #0# and + #hibound# to #-1# resets the valid subscript range to the empty range. + @param lobound lower bound of the new subscript range. + @param hibound upper bound of the new subscript range. */ + void resize(int lobound, int hibound); + /** Shifts the valid subscript range. Argument #disp# is added to both + bounds of the valid subscript range. Array elements previously + located at subscript #x# will now be located at subscript #x+disp#. */ + void shift(int disp); + /** Deletes array elements. The array elements corresponding to + subscripts #n#...#n+howmany-1# are destroyed. All array elements + previously located at subscripts greater or equal to #n+howmany# + are moved to subscripts starting with #n#. The new subscript upper + bound is reduced in order to account for this shift. + @param n subscript of the first element to delete. + @param howmany number of elements to delete. */ + void del(int n, unsigned int howmany=1); + + virtual ~ArrayBase(void) {}; +}; + +inline void +ArrayBase::detach(void) +{ + ArrayRep * new_rep=new ArrayRep(*(ArrayRep *) get()); + assign(new_rep); +} + +inline void +ArrayBase::check(void) +{ + if (get()->get_count()>1) detach(); +} + +inline int +ArrayBase::size() const +{ + return ((const ArrayRep *) get())->size(); +} + +inline int +ArrayBase::lbound() const +{ + return ((const ArrayRep *) get())->lobound; +} + +inline int +ArrayBase::hbound() const +{ + return ((const ArrayRep *) get())->hibound; +} + +inline void +ArrayBase::empty() +{ + check(); + ((ArrayRep *) get())->empty(); +} + +inline void +ArrayBase::resize(int lo, int hi) +{ + check(); + ((ArrayRep *) get())->resize(lo, hi); +} + +inline void +ArrayBase::resize(int hi) +{ + resize(0, hi); +} + +inline void +ArrayBase::touch(int n) +{ + check(); + ((ArrayRep *) get())->touch(n); +} + +inline void +ArrayBase::shift(int disp) +{ + check(); + ((ArrayRep *) get())->shift(disp); +} + +inline void +ArrayBase::del(int n, unsigned int howmany) +{ + check(); + + ((ArrayRep *) get())->del(n, howmany); +} + +/** Dynamic array template base class. + This is an auxiliary template base class for \Ref{DArray} and \Ref{TArray} + implementing some shared functions which {\em depend} on the type of + the array elements (this is contrary to \Ref{ArrayBase}). + It's not supposed to be constructed by hands. Use \Ref{DArray} and + \Ref{TArray} instead. + */ + +template +class ArrayBaseT : public ArrayBase +{ +public: + virtual ~ArrayBaseT(void) {}; + + /** Returns a reference to the array element for subscript #n#. This + reference can be used for both reading (as "#a[n]#") and writing (as + "#a[n]=v#") an array element. This operation will not extend the valid + subscript range: an exception \Ref{GException} is thrown if argument #n# + is not in the valid subscript range. */ + TYPE& operator[](int n); + /** Returns a constant reference to the array element for subscript #n#. + This reference can only be used for reading (as "#a[n]#") an array + element. This operation will not extend the valid subscript range: an + exception \Ref{GException} is thrown if argument #n# is not in the valid + subscript range. This variant of #operator[]# is necessary when dealing + with a #const DArray#. */ + const TYPE& operator[](int n) const; + + /** Returns a pointer for reading or writing the array elements. This + pointer can be used to access the array elements with the same + subscripts and the usual bracket syntax. This pointer remains valid as + long as the valid subscript range is unchanged. If you change the + subscript range, you must stop using the pointers returned by prior + invocation of this conversion operator. */ + operator TYPE* (); + /** Returns a pointer for reading (but not modifying) the array elements. + This pointer can be used to access the array elements with the same + subscripts and the usual bracket syntax. This pointer remains valid as + long as the valid subscript range is unchanged. If you change the + subscript range, you must stop using the pointers returned by prior + invocation of this conversion operator. */ + operator const TYPE* () const; + + /** Insert new elements into an array. This function inserts + #howmany# elements at position #n# into the array. The initial value #val# + is copied into the new elements. All array elements previously located at subscripts + #n# and higher are moved to subscripts #n+howmany# and higher. The upper bound of the + valid subscript range is increased in order to account for this shift. + @param n subscript of the first inserted element. + @param val initial value of the new elements. + @param howmany number of elements to insert. */ + void ins(int n, const TYPE &val, unsigned int howmany=1); + + /** Sort array elements. Sort all array elements in ascending order. Array + elements are compared using the less-or-equal comparison operator for + type #TYPE#. */ + void sort(); + /** Sort array elements in subscript range #lo# to #hi#. Sort all array + elements whose subscripts are in range #lo#..#hi# in ascending order. + The other elements of the array are left untouched. An exception is + thrown if arguments #lo# and #hi# are not in the valid subscript range. + Array elements are compared using the less-or-equal comparison operator + for type #TYPE#. + @param lo low bound for the subscripts of the elements to sort. + @param hi high bound for the subscripts of the elements to sort. */ + void sort(int lo, int hi); +protected: + ArrayBaseT(void) {}; +private: + // Callbacks called from ArrayRep + static void destroy(void * data, int lo, int hi); + static void init1(void * data, int lo, int hi); + static void init2(void * data, int lo, int hi, + const void * src, int src_lo, int src_hi); + static void copy(void * dst, int dst_lo, int dst_hi, + const void * src, int src_lo, int src_hi); + static void insert(void * data, int els, int where, + const void * what, int howmany); +}; + +template inline +ArrayBaseT::operator TYPE* () +{ + check(); + + ArrayRep * rep=(ArrayRep *) get(); + return &((TYPE *) rep->data)[-rep->minlo]; +} + +template inline +ArrayBaseT::operator const TYPE* () const +{ + const ArrayRep * rep=(const ArrayRep *) get(); + return &((const TYPE *) rep->data)[-rep->minlo]; +} + +template inline TYPE& +ArrayBaseT::operator[](int n) +{ + check(); + + ArrayRep * rep=(ArrayRep *) get(); + if (nlobound || n>rep->hibound) + G_THROW( ERR_MSG("arrays.ill_sub") ); + return ((TYPE *) rep->data)[n - rep->minlo]; +} + +template inline const TYPE& +ArrayBaseT::operator[](int n) const +{ + const ArrayRep * rep=(const ArrayRep *) get(); + if (nlobound || n>rep->hibound) + G_THROW( ERR_MSG("arrays.ill_sub") ); + return ((const TYPE *) rep->data)[n - rep->minlo]; +} + +template inline void +ArrayBaseT::ins(int n, const TYPE &val, unsigned int howmany) +{ + check(); + + ((ArrayRep *) get())->ins(n, &val, howmany); +} + +template void +ArrayBaseT::sort() +{ + sort(lbound(), hbound()); +} + +template void +ArrayBaseT::sort(int lo, int hi) +{ + if (hi <= lo) + return; + // Test for insertion sort (optimize!) + if (hi <= lo + 20) + { + for (int i=lo+1; i<=hi; i++) + { + int j = i; + TYPE tmp = (*this)[i]; + while ((--j>=lo) && !((*this)[j]<=tmp)) + (*this)[j+1] = (*this)[j]; + (*this)[j+1] = tmp; + } + return; + } + // -- determine suitable quick-sort pivot + TYPE tmp = (*this)[lo]; + TYPE pivot = (*this)[(lo+hi)/2]; + if (pivot <= tmp) + { tmp = pivot; pivot=(*this)[lo]; } + if ((*this)[hi] <= tmp) + { pivot = tmp; } + else if ((*this)[hi] <= pivot) + { pivot = (*this)[hi]; } + // -- partition set + int h = hi; + int l = lo; + while (l < h) + { + while (! (pivot <= (*this)[l])) l++; + while (! ((*this)[h] <= pivot)) h--; + if (l < h) + { + tmp = (*this)[l]; + (*this)[l] = (*this)[h]; + (*this)[h] = tmp; + l = l+1; + h = h-1; + } + } + // -- recursively restart + sort(lo, h); + sort(l, hi); +} + +/** Dynamic array for simple types. + Template class #TArray# implements an array of + elements of {\em simple} type #TYPE#. {\em Simple} means that the type + may be #char#, #int#, #float# etc. The limitation is imposed by the + way in which the #TArray# is working with its elements: it's not trying + to execute elements' constructors, destructors or copy operators. It's + just doing bitwise copy. Except for this it's pretty much the same as + \Ref{DArray}. + + Please note that most of the methods are implemented in the base classes + \Ref{ArrayBase} and \Ref{ArrayBaseT}. +*/ + +template +class TArray : public ArrayBaseT { +public: + /** Constructs an empty array. The valid subscript range is initially + empty. Member function #touch# and #resize# provide convenient ways + to enlarge the subscript range. */ + TArray(); + /** Constructs an array with subscripts in range 0 to #hibound#. + The subscript range can be subsequently modified with member functions + #touch# and #resize#. + @param hibound upper bound of the initial subscript range. */ + TArray(int hibound); + /** Constructs an array with subscripts in range #lobound# to #hibound#. + The subscript range can be subsequently modified with member functions + #touch# and #resize#. + @param lobound lower bound of the initial subscript range. + @param hibound upper bound of the initial subscript range. */ + TArray(int lobound, int hibound); + + virtual ~TArray() {}; +private: + // Callbacks called from ArrayRep + static void destroy(void * data, int lo, int hi); + static void init1(void * data, int lo, int hi); + static void init2(void * data, int lo, int hi, + const void * src, int src_lo, int src_hi); + static void insert(void * data, int els, int where, + const void * what, int howmany); +}; + +template void +TArray::destroy(void * data, int lo, int hi) +{ +} + +template void +TArray::init1(void * data, int lo, int hi) +{ +} + +template void +TArray::init2(void * data, int lo, int hi, + const void * src, int src_lo, int src_hi) +{ + if (data && src) + { + int els=hi-lo+1; + if (els>src_hi-src_lo+1) els=src_hi-src_lo+1; + if (els>0) + memmove((void *) &((TYPE *) data)[lo], + (void *) &((TYPE *) src)[src_lo], els*sizeof(TYPE)); + }; +} + +// inline removed +template void +TArray::insert(void * data, int els, int where, + const void * what, int howmany) +{ + memmove(((TYPE *) data)+where+howmany, + ((TYPE *) data)+where, sizeof(TYPE)*(els-where)); + for(int i=0;i +TArray::TArray () +{ + this->assign(new ArrayRep(sizeof(TYPE), destroy, init1, + init2, init2, insert)); +} + +template +TArray::TArray(int hi) +{ + this->assign(new ArrayRep(sizeof(TYPE), destroy, init1, + init2, init2, insert, hi)); +} + +template +TArray::TArray(int lo, int hi) +{ + this->assign(new ArrayRep(sizeof(TYPE), destroy, init1, + init2, init2, insert, lo, hi)); +} + +//inline removal ends + +/** Dynamic array for general types. + Template class #DArray# implements an array of + elements of type #TYPE#. Each element is identified by an integer + subscript. The valid subscripts range is defined by dynamically + adjustable lower- and upper-bounds. Besides accessing and setting + elements, member functions are provided to insert or delete elements at + specified positions. + + This template class must be able to access + \begin{itemize} + \item a null constructor #TYPE::TYPE()#, + \item a copy constructor #TYPE::TYPE(const TYPE &)#, + \item and a copy operator #TYPE & operator=(const TYPE &)#. + \end{itemize} + + The class offers "copy-on-demand" policy, which means that when you + copy the array object, array elements will stay intact as long as you + don't try to modify them. As soon as you make an attempt to change + array contents, the copying is done automatically and transparently + for you - the procedure that we call "copy-on-demand". This is the main + difference between this class and \Ref{GArray} (now obsolete) + + Please note that most of the methods are implemented in the base classes + \Ref{ArrayBase} and \Ref{ArrayBaseT}. +*/ + +template +class DArray : public ArrayBaseT { +public: + /** Constructs an empty array. The valid subscript range is initially + empty. Member function #touch# and #resize# provide convenient ways + to enlarge the subscript range. */ + DArray(void); + /** Constructs an array with subscripts in range 0 to #hibound#. + The subscript range can be subsequently modified with member functions + #touch# and #resize#. + @param hibound upper bound of the initial subscript range. */ + DArray(const int hibound); + /** Constructs an array with subscripts in range #lobound# to #hibound#. + The subscript range can be subsequently modified with member functions + #touch# and #resize#. + @param lobound lower bound of the initial subscript range. + @param hibound upper bound of the initial subscript range. */ + DArray(const int lobound, const int hibound); + + virtual ~DArray() {}; +private: + // Callbacks called from ArrayRep + static void destroy(void * data, int lo, int hi); + static void init1(void * data, int lo, int hi); + static void init2(void * data, int lo, int hi, + const void * src, int src_lo, int src_hi); + static void copy(void * dst, int dst_lo, int dst_hi, + const void * src, int src_lo, int src_hi); + static void insert(void * data, int els, int where, + const void * what, int howmany); +}; + +template void +DArray::destroy(void * data, int lo, int hi) +{ + if (data) + for(int i=lo;i<=hi;i++) + ((TYPE *) data)[i].TYPE::~TYPE(); +} + +template void +DArray::init1(void * data, int lo, int hi) +{ + if (data) + for(int i=lo;i<=hi;i++) + new ((void *) &((TYPE *) data)[i]) TYPE; +} + +template void +DArray::init2(void * data, int lo, int hi, + const void * src, int src_lo, int src_hi) +{ + if (data && src) + { + int i, j; + for(i=lo, j=src_lo;i<=hi && j<=src_hi;i++, j++) + new ((void *) &((TYPE *) data)[i]) TYPE(((TYPE *) src)[j]); + }; +} + +template void +DArray::copy(void * dst, int dst_lo, int dst_hi, + const void * src, int src_lo, int src_hi) +{ + if (dst && src) + { + int i, j; + for(i=dst_lo, j=src_lo;i<=dst_hi && j<=src_hi;i++, j++) + ((TYPE *) dst)[i]=((TYPE *) src)[j]; + }; +} + +template inline void +DArray::insert(void * data, int els, int where, + const void * what, int howmany) +{ + // Now do the insertion + TYPE * d=(TYPE *) data; + + int i; + for (i=els+howmany-1; i>=els; i--) + { + if (i-where >= (int)howmany) + new ((void*) &d[i]) TYPE (d[i-howmany]); + else + new ((void*) &d[i]) TYPE (*(TYPE *) what); + } + + for (i=els-1; i>=where; i--) + { + if (i-where >= (int)howmany) + d[i] = d[i-howmany]; + else + d[i] = *(TYPE *) what; + } +} + +template inline +DArray::DArray () +{ + this->assign(new ArrayRep(sizeof(TYPE), destroy, init1, + init2, copy, insert)); +} + +template inline +DArray::DArray(const int hi) +{ + this->assign(new ArrayRep(sizeof(TYPE), destroy, init1, + init2, copy, insert, hi)); +} + +template inline +DArray::DArray(const int lo, const int hi) +{ + this->assign(new ArrayRep(sizeof(TYPE), destroy, init1, + init2, copy, insert, lo, hi)); +} + +/** Dynamic array for \Ref{GPBase}d classes. + + There are many situations when it's necessary to create arrays of + \Ref{GP} pointers. For example, #DArray ># or #DArray >#. + This would result in compilation of two instances of \Ref{DArray} because + from the viewpoint of the compiler there are two different classes used + as array elements: #GP# and #GP