From bb5f928008e1990a19b37ff5b0d8dbe22722ba75 Mon Sep 17 00:00:00 2001 From: Apryse Software Date: Tue, 30 Jan 2024 14:40:53 +0000 Subject: [PATCH 01/20] [AFTER RELEASE] pdfOCR 3.0.2 --- .../itext.pdfocr.api.tests/Properties/AssemblyInfo.cs | 6 +++--- .../itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj | 4 ++-- .../Properties/AssemblyInfo.cs | 6 +++--- .../itext.pdfocr.tesseract4.tests.csproj | 4 ++-- itext/itext.pdfocr.api/Properties/AssemblyInfo.cs | 6 +++--- itext/itext.pdfocr.api/itext.pdfocr.api.csproj | 2 +- itext/itext.pdfocr.api/pdfocr-api.nuspec | 6 +++--- itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs | 8 ++++---- .../actions/data/PdfOcrTesseract4ProductData.cs | 2 +- itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec | 6 +++--- port-hash | 2 +- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs index f3eeaa3..b17f4ee 100644 --- a/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs +++ b/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs @@ -15,6 +15,6 @@ [assembly: Guid("d6a6ea97-1f23-448f-b700-eff62971d234")] -[assembly: AssemblyVersion("3.0.2.0")] -[assembly: AssemblyFileVersion("3.0.2.0")] -[assembly: AssemblyInformationalVersion("3.0.2-SNAPSHOT")] +[assembly: AssemblyVersion("3.0.3.0")] +[assembly: AssemblyFileVersion("3.0.3.0")] +[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] diff --git a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj index 1446b4a..9614df6 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj +++ b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj @@ -25,9 +25,9 @@ - + - + diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs index 554a1dd..1f1970e 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs @@ -15,6 +15,6 @@ [assembly: Guid("d6a6ea97-1f23-448f-b700-eff62971d234")] -[assembly: AssemblyVersion("3.0.2.0")] -[assembly: AssemblyFileVersion("3.0.2.0")] -[assembly: AssemblyInformationalVersion("3.0.2-SNAPSHOT")] +[assembly: AssemblyVersion("3.0.3.0")] +[assembly: AssemblyFileVersion("3.0.3.0")] +[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj index 0c21c41..32de2e6 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj @@ -26,9 +26,9 @@ - + - + diff --git a/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs index 0a34927..dbdbe79 100644 --- a/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs @@ -14,9 +14,9 @@ [assembly: Guid("0c4ceb00-9a56-4547-a925-5974a85a6048")] -[assembly: AssemblyVersion("3.0.2.0")] -[assembly: AssemblyFileVersion("3.0.2.0")] -[assembly: AssemblyInformationalVersion("3.0.2-SNAPSHOT")] +[assembly: AssemblyVersion("3.0.3.0")] +[assembly: AssemblyFileVersion("3.0.3.0")] +[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] [assembly: InternalsVisibleTo("itext.pdfocr.api.tests, PublicKey=" + "00240000048000009400000006020000002400005253413100040000010001008b21ed5b3fc1c1" + "1996390981fe22bbe71a39a9e11d3c2cefddd6ee92920fa871f9666ae0fa941af0280d0653df04" + diff --git a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj index 8ef9900..33279d4 100644 --- a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj +++ b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj @@ -30,7 +30,7 @@ - + diff --git a/itext/itext.pdfocr.api/pdfocr-api.nuspec b/itext/itext.pdfocr.api/pdfocr-api.nuspec index a6d90bd..53a098c 100644 --- a/itext/itext.pdfocr.api/pdfocr-api.nuspec +++ b/itext/itext.pdfocr.api/pdfocr-api.nuspec @@ -2,7 +2,7 @@ itext.pdfocr.api - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT iText pdfOcr Apryse Software Apryse Software @@ -18,7 +18,7 @@ - + @@ -30,4 +30,4 @@ - + \ No newline at end of file diff --git a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs index 12e8588..a948523 100644 --- a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs @@ -14,9 +14,9 @@ [assembly: Guid("0c4ceb00-9a56-4547-a925-5974a85a6048")] -[assembly: AssemblyVersion("3.0.2.0")] -[assembly: AssemblyFileVersion("3.0.2.0")] -[assembly: AssemblyInformationalVersion("3.0.2-SNAPSHOT")] +[assembly: AssemblyVersion("3.0.3.0")] +[assembly: AssemblyFileVersion("3.0.3.0")] +[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] [assembly: InternalsVisibleTo("itext.pdfocr.tesseract4.tests, PublicKey=" + "00240000048000009400000006020000002400005253413100040000010001008b21ed5b3fc1c1" + "1996390981fe22bbe71a39a9e11d3c2cefddd6ee92920fa871f9666ae0fa941af0280d0653df04" + @@ -24,4 +24,4 @@ "009746bbdafcb75bcdbcecb7caf1f0f4b6e7d013906ba60b66eb1c8298e4efb052caf6cece4bf1" + "816902cc")] -[assembly: Versions.Attributes.KernelVersion("8.0.3.0")] +[assembly: Versions.Attributes.KernelVersion("8.0.4.0")] diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs index ac074ed..be5ff7e 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs @@ -34,7 +34,7 @@ public class PdfOcrTesseract4ProductData { private const String PDF_OCR_TESSERACT4_PUBLIC_PRODUCT_NAME = "pdfOCR-Tesseract4"; - private const String PDF_OCR_VERSION = "3.0.2-SNAPSHOT"; + private const String PDF_OCR_VERSION = "3.0.3-SNAPSHOT"; private const int PDF_OCR_COPYRIGHT_SINCE = 2000; diff --git a/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec b/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec index 8d436ad..9f1eac6 100644 --- a/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec +++ b/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec @@ -2,7 +2,7 @@ itext.pdfocr.tesseract4 - 3.0.2-SNAPSHOT + 3.0.3-SNAPSHOT iText pdfOcr Apryse Software Apryse Software @@ -18,7 +18,7 @@ - + @@ -38,4 +38,4 @@ - + \ No newline at end of file diff --git a/port-hash b/port-hash index c0e8561..b2f0045 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -713f1d81a78b8ccd722fa0a7eca82e85ce9cf373 +41522a3c1aae4ee690b10fc007cb01fc86ac524f From bbbaf59def28641101f53ea85ba66c27ab7bef27 Mon Sep 17 00:00:00 2001 From: Apryse Software Date: Thu, 18 Apr 2024 17:27:23 +0000 Subject: [PATCH 02/20] Update dependencies --- .../itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj | 4 ++-- .../itext.pdfocr.tesseract4.tests.csproj | 4 ++-- itext/itext.pdfocr.api/itext.pdfocr.api.csproj | 2 +- itext/itext.pdfocr.api/pdfocr-api.nuspec | 2 +- itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs | 2 +- port-hash | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj index 9614df6..b529ad6 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj +++ b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj @@ -25,9 +25,9 @@ - + - + diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj index 32de2e6..9df95f1 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj @@ -26,9 +26,9 @@ - + - + diff --git a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj index 33279d4..a698f62 100644 --- a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj +++ b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj @@ -30,7 +30,7 @@ - + diff --git a/itext/itext.pdfocr.api/pdfocr-api.nuspec b/itext/itext.pdfocr.api/pdfocr-api.nuspec index 53a098c..5a29a0a 100644 --- a/itext/itext.pdfocr.api/pdfocr-api.nuspec +++ b/itext/itext.pdfocr.api/pdfocr-api.nuspec @@ -18,7 +18,7 @@ - + diff --git a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs index a948523..79e4740 100644 --- a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ "009746bbdafcb75bcdbcecb7caf1f0f4b6e7d013906ba60b66eb1c8298e4efb052caf6cece4bf1" + "816902cc")] -[assembly: Versions.Attributes.KernelVersion("8.0.4.0")] +[assembly: Versions.Attributes.KernelVersion("8.0.5.0")] diff --git a/port-hash b/port-hash index c560a4b..11b1c80 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -a31c5052153b3a93224a02e543069d6a425561e8 +fceee3e5d69a7fad03c9b57d1ef00e182664a5a2 From 2f40308ee0412909404160ef6411378446d4aef3 Mon Sep 17 00:00:00 2001 From: Guust Ysebie Date: Wed, 19 Jun 2024 10:57:21 +0200 Subject: [PATCH 03/20] Include package private definitions in docs DEVSIX-8355 --- doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doxyfile b/doxyfile index c3ee5ee..fa9790d 100644 --- a/doxyfile +++ b/doxyfile @@ -485,7 +485,7 @@ EXTRACT_PRIV_VIRTUAL = NO # scope will be included in the documentation. # The default value is: NO. -EXTRACT_PACKAGE = NO +EXTRACT_PACKAGE = YES # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. From 5e90ff4ab7272b6380aceb9e15b5825551159975 Mon Sep 17 00:00:00 2001 From: iText Software Date: Wed, 19 Jun 2024 13:33:17 +0000 Subject: [PATCH 04/20] Update autoported files fceee3e5d69a7fad03c9b57d1ef00e182664a5a2 --- .../itext/pdfocr/ApiTest.cs | 2 ++ .../general/BasicTesseractIntegrationTest.cs | 2 ++ .../ImageFormatIntegrationTest.cs | 4 +++ .../pdfocr/pdfa3u/PdfA3UIntegrationTest.cs | 2 ++ .../pdflayers/PdfLayersIntegrationTest.cs | 2 ++ .../tessdata/TessDataIntegrationTest.cs | 4 +++ .../pdfocr/tesseract4/ImageIntegrationTest.cs | 4 +++ .../pdfocr/tesseract4/TesseractHelperTest.cs | 4 +++ .../itext/pdfocr/tesseract4/UserWordsTest.cs | 4 +++ .../itext/pdfocr/OcrPdfCreatorEventHelper.cs | 4 +++ .../itext/pdfocr/OcrPdfCreatorProperties.cs | 2 ++ .../itext/pdfocr/OcrProcessContext.cs | 2 ++ .../itext/pdfocr/PdfCreatorUtil.cs | 16 ++++++++++++ .../itext/pdfocr/PdfOcrMetaInfoContainer.cs | 2 ++ .../PdfOcrOutputTypeStatisticsAggregator.cs | 4 +++ .../tesseract4/AbstractTesseract4OcrEngine.cs | 26 +++++++++++++++++++ .../tesseract4/ImagePreprocessingUtil.cs | 16 ++++++++++++ .../tesseract4/Tesseract4EventHelper.cs | 4 +++ .../Tesseract4ExecutableOcrEngine.cs | 2 ++ .../Tesseract4FileResultEventHelper.cs | 6 +++++ .../tesseract4/Tesseract4LibOcrEngine.cs | 2 ++ .../pdfocr/tesseract4/Tesseract4MetaInfo.cs | 2 ++ .../Tesseract4OcrEngineProperties.cs | 14 ++++++++++ .../pdfocr/tesseract4/TesseractHelper.cs | 22 ++++++++++++++++ 24 files changed, 152 insertions(+) diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs index f66ea7d..6ed116f 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs @@ -225,11 +225,13 @@ public virtual void TestTaggingNotSupported() { , PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED), e.Message); } +//\cond DO_NOT_DOCUMENT internal class NotImplementedImageRotationHandler : IImageRotationHandler { public virtual ImageData ApplyRotation(ImageData imageData) { throw new Exception("applyRotation is not implemented"); } } +//\endcond private class DummyMetaInfo : IMetaInfo { } diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs index eb96c00..2278714 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs @@ -38,7 +38,9 @@ You should have received a copy of the GNU Affero General Public License namespace iText.Pdfocr.General { public abstract class BasicTesseractIntegrationTest : IntegrationTestHelper { +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond public BasicTesseractIntegrationTest(IntegrationTestHelper.ReaderType type) { tesseractReader = GetTesseractReader(type); diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs index d618cd9..d3133d9 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs @@ -33,9 +33,13 @@ You should have received a copy of the GNU Affero General Public License namespace iText.Pdfocr.Imageformats { public abstract class ImageFormatIntegrationTest : IntegrationTestHelper { +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond +//\cond DO_NOT_DOCUMENT internal String testType; +//\endcond public ImageFormatIntegrationTest(IntegrationTestHelper.ReaderType type) { tesseractReader = GetTesseractReader(type); diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdfa3u/PdfA3UIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdfa3u/PdfA3UIntegrationTest.cs index e204f6f..729c429 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdfa3u/PdfA3UIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdfa3u/PdfA3UIntegrationTest.cs @@ -37,7 +37,9 @@ public abstract class PdfA3UIntegrationTest : IntegrationTestHelper { // path to default rgb color profile private static readonly String DEFAULT_RGB_COLOR_PROFILE_PATH = TEST_DIRECTORY + "profiles/sRGB_CS_profile.icm"; +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond public PdfA3UIntegrationTest(IntegrationTestHelper.ReaderType type) { tesseractReader = GetTesseractReader(type); diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdflayers/PdfLayersIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdflayers/PdfLayersIntegrationTest.cs index 96ac6ad..b913ece 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdflayers/PdfLayersIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/pdflayers/PdfLayersIntegrationTest.cs @@ -31,7 +31,9 @@ You should have received a copy of the GNU Affero General Public License namespace iText.Pdfocr.Pdflayers { public abstract class PdfLayersIntegrationTest : IntegrationTestHelper { +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond public PdfLayersIntegrationTest(IntegrationTestHelper.ReaderType type) { tesseractReader = GetTesseractReader(type); diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationTest.cs index b40c7b0..36a7597 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationTest.cs @@ -39,9 +39,13 @@ public abstract class TessDataIntegrationTest : IntegrationTestHelper { private static readonly ILogger LOGGER = ITextLogManager.GetLogger(typeof(iText.Pdfocr.Tessdata.TessDataIntegrationTest )); +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond +//\cond DO_NOT_DOCUMENT internal String testFileTypeName; +//\endcond private bool isExecutableReaderType; diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImageIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImageIntegrationTest.cs index 249bc6f..705df95 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImageIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImageIntegrationTest.cs @@ -34,9 +34,13 @@ public abstract class ImageIntegrationTest : IntegrationTestHelper { private static readonly ILogger LOGGER = ITextLogManager.GetLogger(typeof(iText.Pdfocr.Tesseract4.ImageIntegrationTest )); +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond +//\cond DO_NOT_DOCUMENT internal String testFileTypeName; +//\endcond private bool isExecutableReaderType; diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/TesseractHelperTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/TesseractHelperTest.cs index 8aa6101..27655d6 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/TesseractHelperTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/TesseractHelperTest.cs @@ -34,9 +34,13 @@ public abstract class TesseractHelperTest : IntegrationTestHelper { private static readonly ILogger LOGGER = ITextLogManager.GetLogger(typeof(iText.Pdfocr.Tesseract4.TesseractHelperTest )); +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond +//\cond DO_NOT_DOCUMENT internal String testFileTypeName; +//\endcond private bool isExecutableReaderType; diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs index b42b87a..b4861d7 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs @@ -29,9 +29,13 @@ You should have received a copy of the GNU Affero General Public License namespace iText.Pdfocr.Tesseract4 { public abstract class UserWordsTest : IntegrationTestHelper { +//\cond DO_NOT_DOCUMENT internal AbstractTesseract4OcrEngine tesseractReader; +//\endcond +//\cond DO_NOT_DOCUMENT internal String testFileTypeName; +//\endcond private bool isExecutableReaderType; diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorEventHelper.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorEventHelper.cs index f5dec9b..f590a6b 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorEventHelper.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorEventHelper.cs @@ -27,15 +27,18 @@ You should have received a copy of the GNU Affero General Public License using iText.Pdfocr.Statistics; namespace iText.Pdfocr { +//\cond DO_NOT_DOCUMENT internal class OcrPdfCreatorEventHelper : AbstractPdfOcrEventHelper { private readonly SequenceId sequenceId; private readonly IMetaInfo metaInfo; +//\cond DO_NOT_DOCUMENT internal OcrPdfCreatorEventHelper(SequenceId sequenceId, IMetaInfo metaInfo) { this.sequenceId = sequenceId; this.metaInfo = metaInfo; } +//\endcond public override void OnEvent(AbstractProductITextEvent @event) { if (@event is AbstractContextBasedITextEvent) { @@ -58,4 +61,5 @@ public override EventConfirmationType GetConfirmationType() { return EventConfirmationType.ON_CLOSE; } } +//\endcond } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorProperties.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorProperties.cs index 75482a5..2c4f11a 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorProperties.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreatorProperties.cs @@ -516,10 +516,12 @@ public virtual iText.Pdfocr.OcrPdfCreatorProperties SetMetaInfo(IMetaInfo metaIn return this; } +//\cond DO_NOT_DOCUMENT /// Returns meta info /// meta info internal virtual IMetaInfo GetMetaInfo() { return metaInfo; } +//\endcond } } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrProcessContext.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrProcessContext.cs index 052fe89..6a7ce81 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrProcessContext.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrProcessContext.cs @@ -48,11 +48,13 @@ public virtual void SetOcrEventHelper(AbstractPdfOcrEventHelper eventHelper) { this.ocrEventHelper = eventHelper; } +//\cond DO_NOT_DOCUMENT /// Set extra OCR process properties. /// extra OCR process properties. internal virtual void SetOcrProcessProperties(IOcrProcessProperties ocrProcessProperties) { this.ocrProcessProperties = ocrProcessProperties; } +//\endcond /// Get extra OCR process properties. /// extra OCR process properties. diff --git a/itext/itext.pdfocr.api/itext/pdfocr/PdfCreatorUtil.cs b/itext/itext.pdfocr.api/itext/pdfocr/PdfCreatorUtil.cs index 00f7448..5e4bc1c 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/PdfCreatorUtil.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/PdfCreatorUtil.cs @@ -37,9 +37,12 @@ You should have received a copy of the GNU Affero General Public License using iText.Pdfocr.Logs; namespace iText.Pdfocr { +//\cond DO_NOT_DOCUMENT internal class PdfCreatorUtil { +//\cond DO_NOT_DOCUMENT /// The Constant to convert pixels to points. internal const float PX_TO_PT = 3f / 4f; +//\endcond /// The Constant for points per inch. private const float POINTS_PER_INCH = 72.0f; @@ -47,6 +50,7 @@ internal class PdfCreatorUtil { /// The logger. private static readonly ILogger LOGGER = ITextLogManager.GetLogger(typeof(PdfCreatorUtil)); +//\cond DO_NOT_DOCUMENT /// /// Calculates font size according to given bbox height, width and selected /// font. @@ -92,7 +96,9 @@ internal static float CalculateFontSize(Document document, String line, String f } return fontSize; } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Calculated real width of a paragraph with given text line, font provider /// and font size. @@ -113,7 +119,9 @@ internal static float GetRealLineWidth(Document document, String line, String fo IRenderer renderer = paragraph.CreateRendererSubTree().SetParent(document.GetRenderer()); return ((ParagraphRenderer)renderer).GetMinMaxWidth().GetMaxWidth(); } +//\endcond +//\cond DO_NOT_DOCUMENT /// Calculates image coordinates on the page. /// size of the page /// size of the image @@ -131,7 +139,9 @@ internal static Point CalculateImageCoordinates(Rectangle size, Rectangle imageS } return new Point(x, y); } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Retrieves /// @@ -189,7 +199,9 @@ internal static IList GetImageData(FileInfo inputImage, IImageRotatio } return images; } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Calculates the size of the PDF document page according to the provided /// . @@ -252,13 +264,16 @@ internal static Rectangle CalculateImageSize(ImageData imageData, ScaleMode scal return requiredSize; } } +//\endcond +//\cond DO_NOT_DOCUMENT /// Converts value from pixels to points. /// input value in pixels /// result value in points internal static float GetPoints(float pixels) { return pixels * PX_TO_PT; } +//\endcond /// Counts number of pages in the provided tiff image. /// @@ -274,4 +289,5 @@ private static int GetNumberOfPageTiff(FileInfo inputImage) { return numOfPages; } } +//\endcond } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/PdfOcrMetaInfoContainer.cs b/itext/itext.pdfocr.api/itext/pdfocr/PdfOcrMetaInfoContainer.cs index 6bdfa92..47cc16e 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/PdfOcrMetaInfoContainer.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/PdfOcrMetaInfoContainer.cs @@ -33,8 +33,10 @@ public PdfOcrMetaInfoContainer(IMetaInfo metaInfo) { this.metaInfo = metaInfo; } +//\cond DO_NOT_DOCUMENT internal virtual IMetaInfo GetMetaInfo() { return metaInfo; } +//\endcond } } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/statistics/PdfOcrOutputTypeStatisticsAggregator.cs b/itext/itext.pdfocr.api/itext/pdfocr/statistics/PdfOcrOutputTypeStatisticsAggregator.cs index 3b2e0dc..6d68c61 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/statistics/PdfOcrOutputTypeStatisticsAggregator.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/statistics/PdfOcrOutputTypeStatisticsAggregator.cs @@ -27,6 +27,7 @@ You should have received a copy of the GNU Affero General Public License using iText.Pdfocr.Exceptions; namespace iText.Pdfocr.Statistics { +//\cond DO_NOT_DOCUMENT /// Statistics aggregator which aggregates types of ocr processing. internal class PdfOcrOutputTypeStatisticsAggregator : AbstractStatisticsAggregator { private const String STRING_FOR_DATA = "data"; @@ -107,8 +108,11 @@ public override void Merge(AbstractStatisticsAggregator aggregator) { } } +//\cond DO_NOT_DOCUMENT internal static String GetKeyForType(PdfOcrOutputType type) { return OCR_OUTPUT_TYPES.Get(type); } +//\endcond } +//\endcond } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/AbstractTesseract4OcrEngine.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/AbstractTesseract4OcrEngine.cs index ad6ad60..3b34b9c 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/AbstractTesseract4OcrEngine.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/AbstractTesseract4OcrEngine.cs @@ -58,7 +58,9 @@ public abstract class AbstractTesseract4OcrEngine : IOcrEngine, IProductAware { (new HashSet(JavaUtil.ArraysAsList(ImageType.BMP, ImageType.PNG, ImageType.TIFF, ImageType. JPEG))); +//\cond DO_NOT_DOCUMENT internal ICollection processedUUID = new HashSet(); +//\endcond /// Set of properties. private Tesseract4OcrEngineProperties tesseract4OcrEngineProperties; @@ -403,6 +405,7 @@ public virtual ProductData GetProductData() { return PdfOcrTesseract4ProductData.GetInstance(); } +//\cond DO_NOT_DOCUMENT /// /// Performs tesseract OCR using command line tool /// or a wrapper for Tesseract OCR API. @@ -437,7 +440,9 @@ internal virtual void DoTesseractOcr(FileInfo inputImage, IList output , int pageNumber, AbstractPdfOcrEventHelper eventHelper) { DoTesseractOcr(inputImage, outputFiles, outputFormat, pageNumber, true, eventHelper); } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Performs tesseract OCR using command line tool /// or a wrapper for Tesseract OCR API. @@ -472,7 +477,9 @@ internal virtual void DoTesseractOcr(FileInfo inputImage, IList output /// event helper internal abstract void DoTesseractOcr(FileInfo inputImage, IList outputFiles, OutputFormat outputFormat , int pageNumber, bool dispatchEvent, AbstractPdfOcrEventHelper eventHelper); +//\endcond +//\cond DO_NOT_DOCUMENT /// Gets path to provided tess data directory. /// /// path to provided tess data directory as @@ -486,7 +493,9 @@ internal virtual String GetTessData() { return GetTesseract4OcrEngineProperties().GetPathToTessData().FullName; } } +//\endcond +//\cond DO_NOT_DOCUMENT internal virtual PdfOcrTesseract4ProductEvent OnEvent(AbstractPdfOcrEventHelper eventHelper) { // usage event PdfOcrTesseract4ProductEvent @event = PdfOcrTesseract4ProductEvent.CreateProcessImageEvent(eventHelper.GetSequenceId @@ -494,11 +503,14 @@ internal virtual PdfOcrTesseract4ProductEvent OnEvent(AbstractPdfOcrEventHelper eventHelper.OnEvent(@event); return @event; } +//\endcond +//\cond DO_NOT_DOCUMENT internal virtual void OnEventStatistics(AbstractPdfOcrEventHelper eventHelper) { eventHelper.OnEvent(new PdfOcrOutputTypeStatisticsEvent(PdfOcrOutputType.DATA, PdfOcrTesseract4ProductData .GetInstance())); } +//\endcond /// Reads data from the provided input image file. /// @@ -619,31 +631,45 @@ private void VerifyImageFormatValidity(FileInfo image) { } } +//\cond DO_NOT_DOCUMENT internal interface ITesseractOcrResult { } +//\endcond +//\cond DO_NOT_DOCUMENT internal class StringTesseractOcrResult : AbstractTesseract4OcrEngine.ITesseractOcrResult { private String data; +//\cond DO_NOT_DOCUMENT internal StringTesseractOcrResult(String data) { this.data = data; } +//\endcond +//\cond DO_NOT_DOCUMENT internal virtual String GetData() { return data; } +//\endcond } +//\endcond +//\cond DO_NOT_DOCUMENT internal class TextInfoTesseractOcrResult : AbstractTesseract4OcrEngine.ITesseractOcrResult { private IDictionary> textInfos; +//\cond DO_NOT_DOCUMENT internal TextInfoTesseractOcrResult(IDictionary> textInfos) { this.textInfos = textInfos; } +//\endcond +//\cond DO_NOT_DOCUMENT internal virtual IDictionary> GetTextInfos() { return this.textInfos; } +//\endcond } +//\endcond } } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/ImagePreprocessingUtil.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/ImagePreprocessingUtil.cs index 1ba18d5..78afc3d 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/ImagePreprocessingUtil.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/ImagePreprocessingUtil.cs @@ -33,6 +33,7 @@ You should have received a copy of the GNU Affero General Public License using iText.Pdfocr.Tesseract4.Logs; namespace iText.Pdfocr.Tesseract4 { +//\cond DO_NOT_DOCUMENT /// Utilities class to work with images. /// /// Utilities class to work with images. @@ -47,6 +48,7 @@ internal class ImagePreprocessingUtil { private ImagePreprocessingUtil() { } +//\cond DO_NOT_DOCUMENT /// Counts number of pages in the provided tiff image. /// /// input image @@ -60,7 +62,9 @@ internal static int GetNumberOfPageTiff(FileInfo inputImage) { raf.Close(); return numOfPages; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Checks whether image format is TIFF. /// /// input image @@ -70,7 +74,9 @@ internal static int GetNumberOfPageTiff(FileInfo inputImage) { internal static bool IsTiffImage(FileInfo inputImage) { return GetImageType(inputImage) == ImageType.TIFF; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Gets the image type. /// /// input image @@ -93,7 +99,9 @@ internal static ImageType GetImageType(FileInfo inputImage) { } return type; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Reads provided image file using stream. /// /// input image @@ -110,7 +118,9 @@ internal static System.Drawing.Bitmap ReadImageFromFile(FileInfo inputFile) { @is.Dispose(); return bi; } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Reads input file as Leptonica /// @@ -131,7 +141,9 @@ internal static System.Drawing.Bitmap ReadAsPixAndConvertToBufferedImage(FileInf Pix pix = TesseractOcrUtil.ReadPixFromFile(inputImage); return TesseractOcrUtil.ConvertPixToImage(pix); } +//\endcond +//\cond DO_NOT_DOCUMENT /// Performs basic image preprocessing using buffered image (if provided). /// /// Performs basic image preprocessing using buffered image (if provided). @@ -166,7 +178,9 @@ internal static Pix PreprocessImage(FileInfo inputFile, int pageNumber, ImagePre } return TesseractOcrUtil.PreprocessPix(pix, imagePreprocessingOptions); } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Reads input image as a /// . @@ -216,5 +230,7 @@ internal static System.Drawing.Bitmap ReadImage(FileInfo inputImage) { } return bufferedImage; } +//\endcond } +//\endcond } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4EventHelper.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4EventHelper.cs index ac9a871..ad8704d 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4EventHelper.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4EventHelper.cs @@ -26,10 +26,13 @@ You should have received a copy of the GNU Affero General Public License using iText.Pdfocr; namespace iText.Pdfocr.Tesseract4 { +//\cond DO_NOT_DOCUMENT /// Helper class for working with events. internal class Tesseract4EventHelper : AbstractPdfOcrEventHelper { +//\cond DO_NOT_DOCUMENT internal Tesseract4EventHelper() { } +//\endcond // do nothing public override void OnEvent(AbstractProductITextEvent @event) { @@ -47,4 +50,5 @@ public override EventConfirmationType GetConfirmationType() { return EventConfirmationType.ON_DEMAND; } } +//\endcond } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs index 59d052f..2082c9f 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs @@ -97,6 +97,7 @@ public void SetPathToExecutable(String path) { pathToExecutable = path; } +//\cond DO_NOT_DOCUMENT /// /// Performs tesseract OCR using command line tool for the selected page /// of input image (by default 1st). @@ -218,6 +219,7 @@ internal override void DoTesseractOcr(FileInfo inputImage, IList outpu } } } +//\endcond /// Sets hocr output format. /// result command as list of strings diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4FileResultEventHelper.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4FileResultEventHelper.cs index b15802a..a2f6511 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4FileResultEventHelper.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4FileResultEventHelper.cs @@ -27,17 +27,22 @@ You should have received a copy of the GNU Affero General Public License using iText.Pdfocr.Tesseract4.Actions.Events; namespace iText.Pdfocr.Tesseract4 { +//\cond DO_NOT_DOCUMENT /// Helper class for working with events. internal class Tesseract4FileResultEventHelper : AbstractPdfOcrEventHelper { private AbstractPdfOcrEventHelper wrappedEventHelper; +//\cond DO_NOT_DOCUMENT internal Tesseract4FileResultEventHelper() : this(null) { } +//\endcond +//\cond DO_NOT_DOCUMENT internal Tesseract4FileResultEventHelper(AbstractPdfOcrEventHelper wrappedEventHelper) { this.wrappedEventHelper = wrappedEventHelper == null ? new Tesseract4EventHelper() : wrappedEventHelper; } +//\endcond public override void OnEvent(AbstractProductITextEvent @event) { if (!IsProcessImageEvent(@event) && !IsConfirmForProcessImageEvent(@event)) { @@ -64,4 +69,5 @@ private static bool IsConfirmForProcessImageEvent(AbstractProductITextEvent @eve ()); } } +//\endcond } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs index 0f66c02..d8f5590 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs @@ -120,6 +120,7 @@ public virtual void InitializeTesseract(OutputFormat outputFormat) { ().GetPageSegMode(), GetTesseract4OcrEngineProperties().GetPathToUserWordsFile()); } +//\cond DO_NOT_DOCUMENT /// /// Performs tesseract OCR using wrapper for Tesseract OCR API for the selected page /// of input image (by default 1st). @@ -215,6 +216,7 @@ internal override void DoTesseractOcr(FileInfo inputImage, IList outpu } } } +//\endcond /// /// Validates Tess Data path, diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4MetaInfo.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4MetaInfo.cs index 2c69b19..2a4d981 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4MetaInfo.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4MetaInfo.cs @@ -23,6 +23,8 @@ You should have received a copy of the GNU Affero General Public License using iText.Commons.Actions.Contexts; namespace iText.Pdfocr.Tesseract4 { +//\cond DO_NOT_DOCUMENT internal class Tesseract4MetaInfo : IMetaInfo { } +//\endcond } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4OcrEngineProperties.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4OcrEngineProperties.cs index b74acff..8210a48 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4OcrEngineProperties.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4OcrEngineProperties.cs @@ -36,12 +36,14 @@ namespace iText.Pdfocr.Tesseract4 { /// . /// public class Tesseract4OcrEngineProperties : OcrEngineProperties { +//\cond DO_NOT_DOCUMENT /// Default suffix for user-word file. /// /// Default suffix for user-word file. /// (e.g. name: 'eng.user-words') /// internal const String DEFAULT_USER_WORDS_SUFFIX = "user-words"; +//\endcond /// Default language for OCR. private const String DEFAULT_LANGUAGE = "eng"; @@ -248,6 +250,7 @@ public iText.Pdfocr.Tesseract4.Tesseract4OcrEngineProperties SetTextPositioning( return this; } +//\cond DO_NOT_DOCUMENT /// /// Using provided list of words there will be created /// temporary file containing words (one per line) which @@ -301,7 +304,9 @@ internal virtual iText.Pdfocr.Tesseract4.Tesseract4OcrEngineProperties SetUserWo } return this; } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Using provided input stream there will be created /// temporary file (with name 'language.user-words') @@ -366,7 +371,9 @@ internal virtual iText.Pdfocr.Tesseract4.Tesseract4OcrEngineProperties SetUserWo } return this; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Returns path to the user words file. /// /// Returns path to the user words file. @@ -383,7 +390,9 @@ internal virtual iText.Pdfocr.Tesseract4.Tesseract4OcrEngineProperties SetUserWo internal String GetPathToUserWordsFile() { return pathToUserWordsFile; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Sets path to the user words file. /// /// Sets path to the user words file. @@ -405,7 +414,9 @@ internal iText.Pdfocr.Tesseract4.Tesseract4OcrEngineProperties SetPathToUserWord ) { return SetPathToUserWordsFile(pathToUserWordsFile, false); } +//\endcond +//\cond DO_NOT_DOCUMENT /// Sets path to the user words file. /// /// path to user words file @@ -424,12 +435,15 @@ internal iText.Pdfocr.Tesseract4.Tesseract4OcrEngineProperties SetPathToUserWord this.isUserWordsFileTemporary = isTempFile; return this; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Indicates if user words file is temporary and has to be removed. /// true if the file is temporary, otherwise false. internal bool IsUserWordsFileTemporary() { return isUserWordsFileTemporary; } +//\endcond /// /// Gets diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractHelper.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractHelper.cs index 5002325..da9940d 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractHelper.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractHelper.cs @@ -97,6 +97,7 @@ public class TesseractHelper { private TesseractHelper() { } +//\cond DO_NOT_DOCUMENT /// /// Parses each hocr file from the provided list, retrieves text, and /// returns data in the format described below. @@ -164,7 +165,9 @@ internal static IDictionary> ParseHocrFile(IList } return imageData; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Get and align (if needed) bbox of the element. internal static Rectangle GetAlignedBBox(iText.StyledXmlParser.Jsoup.Nodes.Element @object, TextPositioning textPositioning, Rectangle pageBbox, IDictionary unparsedBBoxes @@ -180,7 +183,9 @@ internal static Rectangle GetAlignedBBox(iText.StyledXmlParser.Jsoup.Nodes.Eleme } return box; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Parses element bbox. /// element containing bbox /// element containing parent page bbox @@ -216,7 +221,9 @@ internal static Rectangle ParseBBox(iText.StyledXmlParser.Jsoup.Nodes.Node node, ToPoints(bbox[RIGHT_IDX]), pageBBox.GetTop() - ToPoints(bbox[BOTTOM_IDX])); } } +//\endcond +//\cond DO_NOT_DOCUMENT /// Sometimes hOCR file contains broke character bboxes which are equal to page bbox. /// /// Sometimes hOCR file contains broke character bboxes which are equal to page bbox. @@ -246,17 +253,23 @@ internal static void DetectAndFixBrokenBBoxes(iText.StyledXmlParser.Jsoup.Nodes. } } } +//\endcond +//\cond DO_NOT_DOCUMENT /// Converts points to pixels. internal static float ToPixels(float pt) { return pt / PX_TO_PT; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Converts pixels to points. internal static float ToPoints(float px) { return px * PX_TO_PT; } +//\endcond +//\cond DO_NOT_DOCUMENT /// Deletes file using provided path. /// path to the file to be deleted internal static void DeleteFile(String pathToFile) { @@ -275,7 +288,9 @@ internal static void DeleteFile(String pathToFile) { , e.Message)); } } +//\endcond +//\cond DO_NOT_DOCUMENT /// Reads from text file to string. /// /// input @@ -299,7 +314,9 @@ internal static String ReadTxtFile(FileInfo txtFile) { } return content; } +//\endcond +//\cond DO_NOT_DOCUMENT /// /// Writes provided /// @@ -326,7 +343,9 @@ internal static void WriteToTextFile(String path, String data) { throw new PdfOcrInputTesseract4Exception(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_WRITE_TO_FILE, e); } } +//\endcond +//\cond DO_NOT_DOCUMENT /// Runs given command. /// path to the executable /// @@ -337,7 +356,9 @@ internal static void WriteToTextFile(String path, String data) { internal static void RunCommand(String execPath, IList paramsList) { RunCommand(execPath, paramsList, null); } +//\endcond +//\cond DO_NOT_DOCUMENT /// Runs given command from the specific working directory. /// path to the executable /// @@ -361,6 +382,7 @@ internal static void RunCommand(String execPath, IList paramsList, Strin throw new PdfOcrTesseract4Exception(PdfOcrTesseract4ExceptionMessageConstant.TESSERACT_FAILED); } } +//\endcond /// Gets list of text infos from hocr page. private static IList GetTextData(iText.StyledXmlParser.Jsoup.Nodes.Element page, Tesseract4OcrEngineProperties From 3e36a285d6d3a657d396e23c0bf4b5f2afa1c4fc Mon Sep 17 00:00:00 2001 From: Guust Ysebie Date: Thu, 20 Jun 2024 15:39:36 +0200 Subject: [PATCH 05/20] Ignore interal methods in manual files DEVSIX-8355 --- itext/itext.pdfocr.api/PdfOcrExtensions.cs | 3 ++- itext/itext.pdfocr.tesseract4/PdfOcrTesseract4Extensions.cs | 3 ++- .../Properties/KernelVersionAttribute.cs | 2 ++ .../itext/pdfocr/tesseract4/TesseractOcrUtil.cs | 3 +++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/itext/itext.pdfocr.api/PdfOcrExtensions.cs b/itext/itext.pdfocr.api/PdfOcrExtensions.cs index dad4f06..5631ee2 100644 --- a/itext/itext.pdfocr.api/PdfOcrExtensions.cs +++ b/itext/itext.pdfocr.api/PdfOcrExtensions.cs @@ -29,7 +29,7 @@ You should have received a copy of the GNU Affero General Public License using System.Reflection; using iText.Pdfocr; - +//\cond DO_NOT_DOCUMENT internal static class PdfOcrExtensions { public static TValue Get(this IDictionary col, TKey key) @@ -55,3 +55,4 @@ public static bool IsEmpty(this ICollection> collec } } +//\endcond \ No newline at end of file diff --git a/itext/itext.pdfocr.tesseract4/PdfOcrTesseract4Extensions.cs b/itext/itext.pdfocr.tesseract4/PdfOcrTesseract4Extensions.cs index a7d6f31..80aed54 100644 --- a/itext/itext.pdfocr.tesseract4/PdfOcrTesseract4Extensions.cs +++ b/itext/itext.pdfocr.tesseract4/PdfOcrTesseract4Extensions.cs @@ -24,7 +24,7 @@ You should have received a copy of the GNU Affero General Public License using System.Collections.Generic; using System.Reflection; using System.Text; - +//\cond DO_NOT_DOCUMENT internal static class PdfOcrTesseract4Extensions { public static String Name(this Encoding e) @@ -74,3 +74,4 @@ public static Attribute GetCustomAttribute(this Assembly assembly, Type attribut } } +//\endcond \ No newline at end of file diff --git a/itext/itext.pdfocr.tesseract4/Properties/KernelVersionAttribute.cs b/itext/itext.pdfocr.tesseract4/Properties/KernelVersionAttribute.cs index 96767ba..5d0ba4a 100644 --- a/itext/itext.pdfocr.tesseract4/Properties/KernelVersionAttribute.cs +++ b/itext/itext.pdfocr.tesseract4/Properties/KernelVersionAttribute.cs @@ -23,6 +23,7 @@ You should have received a copy of the GNU Affero General Public License using System; namespace Versions.Attributes { + //\cond DO_NOT_DOCUMENT [AttributeUsage(AttributeTargets.Assembly)] internal class KernelVersionAttribute : Attribute { internal string KernelVersion { get; private set; } @@ -31,4 +32,5 @@ internal KernelVersionAttribute(string kernelVersion) { this.KernelVersion = kernelVersion; } } + //\endcond } diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractOcrUtil.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractOcrUtil.cs index 4969cdf..f739009 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractOcrUtil.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/TesseractOcrUtil.cs @@ -38,6 +38,8 @@ You should have received a copy of the GNU Affero General Public License using Tesseract; namespace iText.Pdfocr.Tesseract4 { + + //\cond DO_NOT_DOCUMENT /// /// Utilities class to work with tesseract command line tool and image /// preprocessing using @@ -1046,4 +1048,5 @@ internal static ImageData ApplyRotation(ImageData imageData) } } } + //\endcond } From e024567e1e4be66cb814b6ba410987f96066ec9f Mon Sep 17 00:00:00 2001 From: Andrei Stryhelski Date: Mon, 24 Jun 2024 10:44:56 +0000 Subject: [PATCH 06/20] Migrate junit4 to junit5 DEVSIX-8321 Autoported commit. Original commit hash: [3296d8f] --- .../itext/pdfocr/ApiTest.cs | 12 ++-- .../itext/pdfocr/PdfA3uTest.cs | 22 ++++--- .../itext/pdfocr/PdfCreatorUtilTest.cs | 17 ++--- .../itext/pdfocr/PdfFontTest.cs | 7 +- .../TesseractExecutableIntegrationTest.cs | 34 +++++----- .../general/BasicTesseractIntegrationTest.cs | 64 ++++++++++--------- .../ImageFormatIntegrationTest.cs | 11 ++-- .../tessdata/TessDataIntegrationLibTest.cs | 13 ++-- .../itext/pdfocr/tesseract4/ApiTest.cs | 28 ++++---- .../tesseract4/ImagePreprocessingUtilTest.cs | 11 ++-- .../itext/pdfocr/tesseract4/UserWordsTest.cs | 14 ++-- port-hash | 2 +- 12 files changed, 120 insertions(+), 115 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs index 6ed116f..94940b4 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs @@ -167,7 +167,7 @@ public virtual void TestThaiImageWithNotDefGlyphs() { [NUnit.Framework.Test] public virtual void TestImageRotationHandler() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(Exception), () => { OcrPdfCreatorProperties properties = new OcrPdfCreatorProperties(); properties.SetImageRotationHandler(new ApiTest.NotImplementedImageRotationHandler()); String testName = "testSetAndGetImageRotationHandler"; @@ -176,13 +176,13 @@ public virtual void TestImageRotationHandler() { PdfHelper.CreatePdf(pdfPath, new FileInfo(path), properties); NUnit.Framework.Assert.IsNotNull(properties.GetImageRotationHandler()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo("applyRotation is not implemented")) -; + ); + NUnit.Framework.Assert.AreEqual("applyRotation is not implemented", exception.Message); } [NUnit.Framework.Test] public virtual void TestImageRotationHandlerForTiff() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(Exception), () => { OcrPdfCreatorProperties properties = new OcrPdfCreatorProperties(); properties.SetImageRotationHandler(new ApiTest.NotImplementedImageRotationHandler()); String testName = "testSetAndGetImageRotationHandler"; @@ -191,8 +191,8 @@ public virtual void TestImageRotationHandlerForTiff() { PdfHelper.CreatePdf(pdfPath, new FileInfo(path), properties); NUnit.Framework.Assert.IsNotNull(properties.GetImageRotationHandler()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo("applyRotation is not implemented")) -; + ); + NUnit.Framework.Assert.AreEqual("applyRotation is not implemented", exception.Message); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs index a736190..fba5328 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs @@ -54,7 +54,7 @@ public virtual void TestPdfA3uWithNullIntent() { [NUnit.Framework.Test] public virtual void TestIncompatibleOutputIntentAndFontColorSpaceException() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfException), () => { String testName = "testIncompatibleOutputIntentAndFontColorSpaceException"; String path = PdfHelper.GetDefaultImagePath(); String pdfPath = PdfHelper.GetTargetDirectory() + testName + ".pdf"; @@ -64,8 +64,9 @@ public virtual void TestIncompatibleOutputIntentAndFontColorSpaceException() { PdfHelper.CreatePdfA(pdfPath, new FileInfo(path), ocrPdfCreatorProperties, PdfHelper.GetRGBPdfOutputIntent ()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT + , exception.Message); } [NUnit.Framework.Test] @@ -110,7 +111,7 @@ public virtual void TestPdfCustomMetadata() { [LogMessage(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, Count = 1)] [NUnit.Framework.Test] public virtual void TestNonCompliantThaiPdfA() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrException), () => { String testName = "testNonCompliantThaiPdfA"; String path = PdfHelper.GetThaiImagePath(); String pdfPath = PdfHelper.GetTargetDirectory() + testName + ".pdf"; @@ -120,8 +121,10 @@ public virtual void TestNonCompliantThaiPdfA() { PdfHelper.CreatePdfA(pdfPath, new FileInfo(path), ocrPdfCreatorProperties, PdfHelper.GetRGBPdfOutputIntent ()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, MessageFormatUtil.Format(PdfOcrLogMessageConstant.COULD_NOT_FIND_CORRESPONDING_GLYPH_TO_UNICODE_CHARACTER, 3611)))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT + , MessageFormatUtil.Format(PdfOcrLogMessageConstant.COULD_NOT_FIND_CORRESPONDING_GLYPH_TO_UNICODE_CHARACTER + , 3611)), exception.Message); } [NUnit.Framework.Test] @@ -153,15 +156,16 @@ public virtual void TestCompliantThaiPdfA() { [LogMessage(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, Count = 1)] [NUnit.Framework.Test] public virtual void TestPdfACreateWithoutPdfLangProperty() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrException), () => { String testName = "testPdfACreateWithoutPdfLangProperty"; String path = PdfHelper.GetThaiImagePath(); String pdfPath = PdfHelper.GetTargetDirectory() + testName + ".pdf"; PdfHelper.CreatePdfA(pdfPath, new FileInfo(path), new OcrPdfCreatorProperties(), PdfHelper.GetRGBPdfOutputIntent ()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, PdfOcrLogMessageConstant.PDF_LANGUAGE_PROPERTY_IS_NOT_SET))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT + , PdfOcrLogMessageConstant.PDF_LANGUAGE_PROPERTY_IS_NOT_SET), exception.Message); } } } diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfCreatorUtilTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfCreatorUtilTest.cs index 564aae6..bdf9d12 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfCreatorUtilTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfCreatorUtilTest.cs @@ -20,6 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ +using System; using System.Collections.Generic; using System.IO; using iText.Commons.Utils; @@ -70,21 +71,17 @@ public virtual void GetImageDataFromValidNotTiffTest() { [NUnit.Framework.Test] [LogMessage(PdfOcrLogMessageConstant.CANNOT_READ_INPUT_IMAGE)] public virtual void GetImageDataFromNotExistingImageTest() { - NUnit.Framework.Assert.That(() => { - PdfCreatorUtil.GetImageData(new FileInfo("no such path"), null); - } - , NUnit.Framework.Throws.InstanceOf()) -; + NUnit.Framework.Assert.Catch(typeof(PdfOcrInputException), () => PdfCreatorUtil.GetImageData(new FileInfo( + "no such path"), null)); } [NUnit.Framework.Test] [LogMessage(PdfOcrLogMessageConstant.CANNOT_READ_INPUT_IMAGE)] public virtual void GetImageDataFromInvalidImageTest() { - NUnit.Framework.Assert.That(() => { - PdfCreatorUtil.GetImageData(new FileInfo(PdfHelper.GetImagesTestDirectory() + "corrupted.jpg"), null); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_READ_INPUT_IMAGE))) -; + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrInputException), () => PdfCreatorUtil.GetImageData + (new FileInfo(PdfHelper.GetImagesTestDirectory() + "corrupted.jpg"), null)); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_READ_INPUT_IMAGE + ), exception.Message); } } } diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfFontTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfFontTest.cs index 8fe29c6..5f5ec62 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfFontTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfFontTest.cs @@ -57,7 +57,7 @@ public virtual void TestFontColor() { [LogMessage(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, Count = 1)] [NUnit.Framework.Test] public virtual void TestInvalidFontWithInvalidDefaultFontFamily() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrException), () => { String testName = "testInvalidFontWithInvalidDefaultFontFamily"; String path = PdfHelper.GetDefaultImagePath(); String pdfPath = PdfHelper.GetTargetDirectory() + testName + ".pdf"; @@ -72,8 +72,9 @@ public virtual void TestInvalidFontWithInvalidDefaultFontFamily() { NUnit.Framework.Assert.AreEqual(PdfHelper.DEFAULT_TEXT, result); NUnit.Framework.Assert.AreEqual(ScaleMode.SCALE_TO_FIT, properties.GetScaleMode()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, PdfOcrExceptionMessageConstant.CANNOT_RESOLVE_PROVIDED_FONTS))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT + , PdfOcrExceptionMessageConstant.CANNOT_RESOLVE_PROVIDED_FONTS), exception.Message); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/TesseractExecutableIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/TesseractExecutableIntegrationTest.cs index 16f0783..fc1be83 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/TesseractExecutableIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/TesseractExecutableIntegrationTest.cs @@ -20,6 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ +using System; using System.IO; using iText.Pdfocr.Tesseract4; using iText.Pdfocr.Tesseract4.Exceptions; @@ -32,39 +33,38 @@ public class TesseractExecutableIntegrationTest : IntegrationTestHelper { [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_FIND_PATH_TO_TESSERACT_EXECUTABLE, Count = 1)] [NUnit.Framework.Test] public virtual void TestNullPathToTesseractExecutable() { - NUnit.Framework.Assert.That(() => { - FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); + FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { Tesseract4ExecutableOcrEngine tesseractExecutableReader = new Tesseract4ExecutableOcrEngine(new Tesseract4OcrEngineProperties ()); tesseractExecutableReader.SetPathToExecutable(null); GetTextFromPdf(tesseractExecutableReader, file); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_FIND_PATH_TO_TESSERACT_EXECUTABLE)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_FIND_PATH_TO_TESSERACT_EXECUTABLE + , exception.Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_FIND_PATH_TO_TESSERACT_EXECUTABLE, Count = 1)] [NUnit.Framework.Test] public virtual void TestEmptyPathToTesseractExecutable() { - NUnit.Framework.Assert.That(() => { - FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); - GetTextFromPdf(new Tesseract4ExecutableOcrEngine("", new Tesseract4OcrEngineProperties()), file); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_FIND_PATH_TO_TESSERACT_EXECUTABLE)) -; + FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => GetTextFromPdf + (new Tesseract4ExecutableOcrEngine("", new Tesseract4OcrEngineProperties()), file)); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_FIND_PATH_TO_TESSERACT_EXECUTABLE + , exception.Message); } [LogMessage(Tesseract4LogMessageConstant.COMMAND_FAILED, Count = 1)] [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.TESSERACT_NOT_FOUND, Count = 1)] [NUnit.Framework.Test] public virtual void TestIncorrectPathToTesseractExecutable() { - NUnit.Framework.Assert.That(() => { - FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); - GetTextFromPdf(new Tesseract4ExecutableOcrEngine("path\\to\\executable\\", new Tesseract4OcrEngineProperties - ()), file); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.TESSERACT_NOT_FOUND)) -; + FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => GetTextFromPdf + (new Tesseract4ExecutableOcrEngine("path\\to\\executable\\", new Tesseract4OcrEngineProperties()), file + )); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.TESSERACT_NOT_FOUND, exception.Message + ); } } } diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs index 2278714..f132f24 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs @@ -124,7 +124,7 @@ public virtual void TestImageWithoutText() { [LogMessage(Tesseract4LogMessageConstant.CANNOT_READ_INPUT_IMAGE, Count = 1)] [NUnit.Framework.Test] public virtual void TestInputInvalidImage() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { FileInfo file1 = new FileInfo(TEST_IMAGES_DIRECTORY + "example.txt"); FileInfo file2 = new FileInfo(TEST_IMAGES_DIRECTORY + "example_05_corrupted.bmp"); FileInfo file3 = new FileInfo(TEST_IMAGES_DIRECTORY + "numbers_02.jpg"); @@ -133,8 +133,9 @@ public virtual void TestInputInvalidImage() { OcrPdfCreator ocrPdfCreator = new OcrPdfCreator(tesseractReader); ocrPdfCreator.CreatePdf(JavaUtil.ArraysAsList(file3, file1, file2, file3), GetPdfWriter()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_READ_PROVIDED_IMAGE, new FileInfo(TEST_IMAGES_DIRECTORY + "example.txt").FullName))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_READ_PROVIDED_IMAGE + , new FileInfo(TEST_IMAGES_DIRECTORY + "example.txt").FullName), exception.Message); } [NUnit.Framework.Test] @@ -157,32 +158,34 @@ public virtual void TestNonAsciiImageName() { [NUnit.Framework.Test] public virtual void TestNullPathToTessData() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); tesseractReader.SetTesseract4OcrEngineProperties(tesseractReader.GetTesseract4OcrEngineProperties().SetPathToTessData (null)); GetTextFromPdf(tesseractReader, file, JavaCollectionsUtil.SingletonList("eng")); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_DIRECTORY_IS_INVALID)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_DIRECTORY_IS_INVALID + , exception.Message); } [NUnit.Framework.Test] public virtual void TestPathToTessDataWithoutData() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); tesseractReader.SetTesseract4OcrEngineProperties(tesseractReader.GetTesseract4OcrEngineProperties().SetPathToTessData (new FileInfo("test/"))); GetTextFromPdf(tesseractReader, file, JavaCollectionsUtil.SingletonList("eng")); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_DIRECTORY_IS_INVALID)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_DIRECTORY_IS_INVALID + , exception.Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE)] [NUnit.Framework.Test] public virtual void TestEmptyPathToTessData() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); Tesseract4OcrEngineProperties properties = tesseractReader.GetTesseract4OcrEngineProperties().SetPathToTessData (new FileInfo(".")); @@ -191,56 +194,57 @@ public virtual void TestEmptyPathToTessData() { NUnit.Framework.Assert.AreEqual(new FileInfo("").FullName, tesseractReader.GetTesseract4OcrEngineProperties ().GetPathToTessData().FullName); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, "eng.traineddata", new FileInfo(".").FullName))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE + , "eng.traineddata", new FileInfo(".").FullName), exception.Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, Count = 1)] [NUnit.Framework.Test] public virtual void TestIncorrectLanguage() { - NUnit.Framework.Assert.That(() => { - FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); - GetTextFromPdf(tesseractReader, file, JavaCollectionsUtil.SingletonList("spa_new")); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, "spa_new.traineddata", new FileInfo(LANG_TESS_DATA_DIRECTORY).FullName))) -; + FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => GetTextFromPdf + (tesseractReader, file, JavaCollectionsUtil.SingletonList("spa_new"))); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE + , "spa_new.traineddata", new FileInfo(LANG_TESS_DATA_DIRECTORY).FullName), exception.Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, Count = 1)] [NUnit.Framework.Test] public virtual void TestListOfLanguagesWithOneIncorrectLanguage() { - NUnit.Framework.Assert.That(() => { - FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); - GetTextFromPdf(tesseractReader, file, JavaUtil.ArraysAsList("spa", "spa_new", "spa_old")); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, "spa_new.traineddata", new FileInfo(LANG_TESS_DATA_DIRECTORY).FullName))) -; + FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => GetTextFromPdf + (tesseractReader, file, JavaUtil.ArraysAsList("spa", "spa_new", "spa_old"))); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE + , "spa_new.traineddata", new FileInfo(LANG_TESS_DATA_DIRECTORY).FullName), exception.Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, Count = 1)] [NUnit.Framework.Test] public virtual void TestIncorrectScriptsName() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); tesseractReader.SetTesseract4OcrEngineProperties(tesseractReader.GetTesseract4OcrEngineProperties().SetPathToTessData (new FileInfo(SCRIPT_TESS_DATA_DIRECTORY))); GetTextFromPdf(tesseractReader, file, JavaCollectionsUtil.SingletonList("English")); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, "English.traineddata", new FileInfo(SCRIPT_TESS_DATA_DIRECTORY).FullName))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE + , "English.traineddata", new FileInfo(SCRIPT_TESS_DATA_DIRECTORY).FullName), exception.Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, Count = 1)] [NUnit.Framework.Test] public virtual void TestListOfScriptsWithOneIncorrect() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "spanish_01.jpg"); tesseractReader.SetTesseract4OcrEngineProperties(tesseractReader.GetTesseract4OcrEngineProperties().SetPathToTessData (new FileInfo(SCRIPT_TESS_DATA_DIRECTORY))); GetTextFromPdf(tesseractReader, file, JavaUtil.ArraysAsList("Georgian", "Japanese", "English")); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE, "English.traineddata", new FileInfo(SCRIPT_TESS_DATA_DIRECTORY).FullName))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_LANGUAGE + , "English.traineddata", new FileInfo(SCRIPT_TESS_DATA_DIRECTORY).FullName), exception.Message); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs index d3133d9..d786ac0 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/imageformats/ImageFormatIntegrationTest.cs @@ -228,12 +228,11 @@ public virtual void TestInputMultipagesTIFFWithoutPreprocessing() { [LogMessage(Tesseract4LogMessageConstant.CANNOT_READ_INPUT_IMAGE, Count = 1)] [NUnit.Framework.Test] public virtual void TestInputWrongFormat() { - NUnit.Framework.Assert.That(() => { - FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "wierdwords.gif"); - GetTextFromPdf(tesseractReader, file); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_INPUT_IMAGE_FORMAT, "wierdwords.gif"))) -; + FileInfo file = new FileInfo(TEST_IMAGES_DIRECTORY + "wierdwords.gif"); + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => GetTextFromPdf + (tesseractReader, file)); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.INCORRECT_INPUT_IMAGE_FORMAT + , "wierdwords.gif"), exception.Message); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationLibTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationLibTest.cs index 3c58c5a..9579a4f 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationLibTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tessdata/TessDataIntegrationLibTest.cs @@ -41,14 +41,11 @@ public TessDataIntegrationLibTest() )] [NUnit.Framework.Test] public virtual void TestTessDataWithNonAsciiPath() { - NUnit.Framework.Assert.That(() => { - // Throws exception for the tesseract lib test - DoOcrAndGetTextUsingTessDataByNonAsciiPath(); - NUnit.Framework.Assert.Fail("Should throw exception for the tesseract lib when tess data path contains non ASCII characters" - ); - } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_DIRECTORY_CONTAINS_NON_ASCII_CHARACTERS)) -; + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => + // Throws exception for the tesseract lib test + DoOcrAndGetTextUsingTessDataByNonAsciiPath()); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_DIRECTORY_CONTAINS_NON_ASCII_CHARACTERS + , exception.Message); } #if !NETSTANDARD2_0 diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs index b1f5638..b41c2d0 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs @@ -34,42 +34,45 @@ public class ApiTest : IntegrationTestHelper { [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_IS_NOT_SET)] [NUnit.Framework.Test] public virtual void TestDefaultTessDataPathValidationForLib() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { String path = TEST_IMAGES_DIRECTORY + "numbers_01.jpg"; FileInfo imgFile = new FileInfo(path); Tesseract4LibOcrEngine engine = new Tesseract4LibOcrEngine(new Tesseract4OcrEngineProperties()); engine.DoImageOcr(imgFile); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_IS_NOT_SET)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_IS_NOT_SET, exception + .Message); } [LogMessage(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_IS_NOT_SET)] [NUnit.Framework.Test] public virtual void TestDefaultTessDataPathValidationForExecutable() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { String path = TEST_IMAGES_DIRECTORY + "numbers_01.jpg"; FileInfo imgFile = new FileInfo(path); Tesseract4ExecutableOcrEngine engine = new Tesseract4ExecutableOcrEngine(new Tesseract4OcrEngineProperties ()); engine.DoImageOcr(imgFile); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_IS_NOT_SET)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.PATH_TO_TESS_DATA_IS_NOT_SET, exception + .Message); } [LogMessage(Tesseract4LogMessageConstant.CANNOT_READ_INPUT_IMAGE, Count = 2)] [NUnit.Framework.Test] public virtual void TestDoTesseractOcrForIncorrectImageForExecutable() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { String path = TEST_IMAGES_DIRECTORY + "numbers_01"; FileInfo imgFile = new FileInfo(path); Tesseract4ExecutableOcrEngine engine = new Tesseract4ExecutableOcrEngine(new Tesseract4OcrEngineProperties ().SetPathToTessData(GetTessDataDirectory())); engine.DoTesseractOcr(imgFile, null, OutputFormat.HOCR); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_READ_PROVIDED_IMAGE, new FileInfo(TEST_IMAGES_DIRECTORY + "numbers_01").FullName))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.CANNOT_READ_PROVIDED_IMAGE + , new FileInfo(TEST_IMAGES_DIRECTORY + "numbers_01").FullName), exception.Message); } [LogMessage(Tesseract4LogMessageConstant.CANNOT_READ_INPUT_IMAGE)] @@ -77,15 +80,16 @@ public virtual void TestDoTesseractOcrForIncorrectImageForExecutable() { [LogMessage(Tesseract4LogMessageConstant.TESSERACT_FAILED)] [NUnit.Framework.Test] public virtual void TestOcrResultForSinglePageForNullImage() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { Tesseract4LibOcrEngine tesseract4LibOcrEngine = GetTesseract4LibOcrEngine(); tesseract4LibOcrEngine.SetTesseract4OcrEngineProperties(new Tesseract4OcrEngineProperties().SetPathToTessData (GetTessDataDirectory())); tesseract4LibOcrEngine.InitializeTesseract(OutputFormat.TXT); tesseract4LibOcrEngine.DoTesseractOcr(null, null, OutputFormat.HOCR); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(PdfOcrTesseract4ExceptionMessageConstant.TESSERACT_FAILED)) -; + ); + NUnit.Framework.Assert.AreEqual(PdfOcrTesseract4ExceptionMessageConstant.TESSERACT_FAILED, exception.Message + ); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImagePreprocessingUtilTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImagePreprocessingUtilTest.cs index 03efcff..a74449e 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImagePreprocessingUtilTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ImagePreprocessingUtilTest.cs @@ -41,13 +41,10 @@ public virtual void TestCheckForInvalidTiff() { [LogMessage(Tesseract4LogMessageConstant.CANNOT_READ_INPUT_IMAGE)] [NUnit.Framework.Test] public virtual void TestReadingInvalidImagePath() { - NUnit.Framework.Assert.That(() => { - String path = TEST_IMAGES_DIRECTORY + "numbers_02"; - FileInfo imgFile = new FileInfo(path); - ImagePreprocessingUtil.PreprocessImage(imgFile, 1, new ImagePreprocessingOptions()); - } - , NUnit.Framework.Throws.InstanceOf()) -; + String path = TEST_IMAGES_DIRECTORY + "numbers_02"; + FileInfo imgFile = new FileInfo(path); + NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => ImagePreprocessingUtil.PreprocessImage + (imgFile, 1, new ImagePreprocessingOptions())); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs index b4861d7..0648027 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/UserWordsTest.cs @@ -89,25 +89,27 @@ public virtual void TestCustomUserWordsWithListOfLanguages() { [NUnit.Framework.Test] public virtual void TestUserWordsWithLanguageNotInList() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { String userWords = TEST_DOCUMENTS_DIRECTORY + "userwords.txt"; Tesseract4OcrEngineProperties properties = tesseractReader.GetTesseract4OcrEngineProperties(); properties.SetUserWords("spa", new FileStream(userWords, FileMode.Open, FileAccess.Read)); properties.SetLanguages(new List()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.LANGUAGE_IS_NOT_IN_THE_LIST, "spa"))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.LANGUAGE_IS_NOT_IN_THE_LIST + , "spa"), exception.Message); } [NUnit.Framework.Test] public virtual void TestIncorrectLanguageForUserWordsAsList() { - NUnit.Framework.Assert.That(() => { + Exception exception = NUnit.Framework.Assert.Catch(typeof(PdfOcrTesseract4Exception), () => { Tesseract4OcrEngineProperties properties = tesseractReader.GetTesseract4OcrEngineProperties(); properties.SetUserWords("eng1", JavaUtil.ArraysAsList("word1", "word2")); properties.SetLanguages(new List()); } - , NUnit.Framework.Throws.InstanceOf().With.Message.EqualTo(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.LANGUAGE_IS_NOT_IN_THE_LIST, "eng1"))) -; + ); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrTesseract4ExceptionMessageConstant.LANGUAGE_IS_NOT_IN_THE_LIST + , "eng1"), exception.Message); } [NUnit.Framework.Test] diff --git a/port-hash b/port-hash index 11b1c80..babcc1e 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -fceee3e5d69a7fad03c9b57d1ef00e182664a5a2 +3296d8f07e33b9c5f4946da2d46f1f393329d9e1 From 4192d51af76af547503a74b7718dc1b3beaf34e6 Mon Sep 17 00:00:00 2001 From: Apryse Software Date: Fri, 12 Jul 2024 16:34:59 +0000 Subject: [PATCH 07/20] Update dependencies --- .../itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj | 4 ++-- .../itext.pdfocr.tesseract4.tests.csproj | 4 ++-- itext/itext.pdfocr.api/itext.pdfocr.api.csproj | 2 +- itext/itext.pdfocr.api/pdfocr-api.nuspec | 2 +- itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs | 2 +- port-hash | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj index b529ad6..df5d9bb 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj +++ b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj @@ -25,9 +25,9 @@ - + - + diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj index 9df95f1..df082a6 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj @@ -26,9 +26,9 @@ - + - + diff --git a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj index a698f62..834f981 100644 --- a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj +++ b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj @@ -30,7 +30,7 @@ - + diff --git a/itext/itext.pdfocr.api/pdfocr-api.nuspec b/itext/itext.pdfocr.api/pdfocr-api.nuspec index 5a29a0a..67073a9 100644 --- a/itext/itext.pdfocr.api/pdfocr-api.nuspec +++ b/itext/itext.pdfocr.api/pdfocr-api.nuspec @@ -18,7 +18,7 @@ - + diff --git a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs index 79e4740..2cd3174 100644 --- a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs @@ -24,4 +24,4 @@ "009746bbdafcb75bcdbcecb7caf1f0f4b6e7d013906ba60b66eb1c8298e4efb052caf6cece4bf1" + "816902cc")] -[assembly: Versions.Attributes.KernelVersion("8.0.5.0")] +[assembly: Versions.Attributes.KernelVersion("8.0.6.0")] diff --git a/port-hash b/port-hash index babcc1e..2e7311d 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -3296d8f07e33b9c5f4946da2d46f1f393329d9e1 +82af218fa1c6ee8736807c3116c48882d941c879 From 2c3aa3a5a4bee16927c8a04c313670e47916856b Mon Sep 17 00:00:00 2001 From: Apryse Software Date: Mon, 29 Jul 2024 15:15:14 +0000 Subject: [PATCH 08/20] [AFTER RELEASE] pdfOCR 4.0.0 --- .../itext.pdfocr.api.tests/Properties/AssemblyInfo.cs | 6 +++--- .../itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj | 4 ++-- .../Properties/AssemblyInfo.cs | 6 +++--- .../itext.pdfocr.tesseract4.tests.csproj | 4 ++-- itext/itext.pdfocr.api/Properties/AssemblyInfo.cs | 6 +++--- itext/itext.pdfocr.api/itext.pdfocr.api.csproj | 2 +- itext/itext.pdfocr.api/pdfocr-api.nuspec | 4 ++-- itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs | 8 ++++---- .../actions/data/PdfOcrTesseract4ProductData.cs | 2 +- itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec | 4 ++-- port-hash | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs index b17f4ee..8a5748b 100644 --- a/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs +++ b/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs @@ -15,6 +15,6 @@ [assembly: Guid("d6a6ea97-1f23-448f-b700-eff62971d234")] -[assembly: AssemblyVersion("3.0.3.0")] -[assembly: AssemblyFileVersion("3.0.3.0")] -[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] +[assembly: AssemblyVersion("4.0.0.0")] +[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] diff --git a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj index df5d9bb..0786c84 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj +++ b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj @@ -25,9 +25,9 @@ - + - + diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs index 1f1970e..9486726 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs @@ -15,6 +15,6 @@ [assembly: Guid("d6a6ea97-1f23-448f-b700-eff62971d234")] -[assembly: AssemblyVersion("3.0.3.0")] -[assembly: AssemblyFileVersion("3.0.3.0")] -[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] +[assembly: AssemblyVersion("4.0.0.0")] +[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj index df082a6..06ef731 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj @@ -26,9 +26,9 @@ - + - + diff --git a/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs index dbdbe79..f04e033 100644 --- a/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs @@ -14,9 +14,9 @@ [assembly: Guid("0c4ceb00-9a56-4547-a925-5974a85a6048")] -[assembly: AssemblyVersion("3.0.3.0")] -[assembly: AssemblyFileVersion("3.0.3.0")] -[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] +[assembly: AssemblyVersion("4.0.0.0")] +[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] [assembly: InternalsVisibleTo("itext.pdfocr.api.tests, PublicKey=" + "00240000048000009400000006020000002400005253413100040000010001008b21ed5b3fc1c1" + "1996390981fe22bbe71a39a9e11d3c2cefddd6ee92920fa871f9666ae0fa941af0280d0653df04" + diff --git a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj index 834f981..9deeb66 100644 --- a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj +++ b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj @@ -30,7 +30,7 @@ - + diff --git a/itext/itext.pdfocr.api/pdfocr-api.nuspec b/itext/itext.pdfocr.api/pdfocr-api.nuspec index 67073a9..19a5d7d 100644 --- a/itext/itext.pdfocr.api/pdfocr-api.nuspec +++ b/itext/itext.pdfocr.api/pdfocr-api.nuspec @@ -2,7 +2,7 @@ itext.pdfocr.api - 3.0.3-SNAPSHOT + 4.0.0-SNAPSHOT iText pdfOcr Apryse Software Apryse Software @@ -18,7 +18,7 @@ - + diff --git a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs index 2cd3174..650bcf7 100644 --- a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs @@ -14,9 +14,9 @@ [assembly: Guid("0c4ceb00-9a56-4547-a925-5974a85a6048")] -[assembly: AssemblyVersion("3.0.3.0")] -[assembly: AssemblyFileVersion("3.0.3.0")] -[assembly: AssemblyInformationalVersion("3.0.3-SNAPSHOT")] +[assembly: AssemblyVersion("4.0.0.0")] +[assembly: AssemblyFileVersion("4.0.0.0")] +[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] [assembly: InternalsVisibleTo("itext.pdfocr.tesseract4.tests, PublicKey=" + "00240000048000009400000006020000002400005253413100040000010001008b21ed5b3fc1c1" + "1996390981fe22bbe71a39a9e11d3c2cefddd6ee92920fa871f9666ae0fa941af0280d0653df04" + @@ -24,4 +24,4 @@ "009746bbdafcb75bcdbcecb7caf1f0f4b6e7d013906ba60b66eb1c8298e4efb052caf6cece4bf1" + "816902cc")] -[assembly: Versions.Attributes.KernelVersion("8.0.6.0")] +[assembly: Versions.Attributes.KernelVersion("9.0.0.0")] diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs index be5ff7e..e1253e9 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs @@ -34,7 +34,7 @@ public class PdfOcrTesseract4ProductData { private const String PDF_OCR_TESSERACT4_PUBLIC_PRODUCT_NAME = "pdfOCR-Tesseract4"; - private const String PDF_OCR_VERSION = "3.0.3-SNAPSHOT"; + private const String PDF_OCR_VERSION = "4.0.0-SNAPSHOT"; private const int PDF_OCR_COPYRIGHT_SINCE = 2000; diff --git a/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec b/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec index 9f1eac6..6280689 100644 --- a/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec +++ b/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec @@ -2,7 +2,7 @@ itext.pdfocr.tesseract4 - 3.0.3-SNAPSHOT + 4.0.0-SNAPSHOT iText pdfOcr Apryse Software Apryse Software @@ -18,7 +18,7 @@ - + diff --git a/port-hash b/port-hash index 2e7311d..9d9e021 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -82af218fa1c6ee8736807c3116c48882d941c879 +b8203d0ccb0f88b468fee2582f0b13ff3123c7d3 From 66ef97482df11ba669a5fcd765333a9ce4765717 Mon Sep 17 00:00:00 2001 From: Dmitry Chubrick Date: Tue, 13 Aug 2024 10:34:40 +0000 Subject: [PATCH 09/20] Refactor com.itextpdf.kernel.geom.Point DEVSIX-4753 Autoported commit. Original commit hash: [85113ab] --- itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs | 8 ++++---- port-hash | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs index 2d2dbee..6f9ce2e 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs @@ -755,8 +755,8 @@ private void AddImageToCanvas(ImageData imageData, Rectangle imageSize, PdfCanva else { Point coordinates = PdfCreatorUtil.CalculateImageCoordinates(ocrPdfCreatorProperties.GetPageSize(), imageSize ); - Rectangle rect = new Rectangle((float)coordinates.x, (float)coordinates.y, imageSize.GetWidth(), imageSize - .GetHeight()); + Rectangle rect = new Rectangle((float)coordinates.GetX(), (float)coordinates.GetY(), imageSize.GetWidth(), + imageSize.GetHeight()); pdfCanvas.AddImageFittedIntoRectangle(imageData, rect, false); } if (ocrPdfCreatorProperties.IsTagged()) { @@ -895,8 +895,8 @@ private void AddTextToCanvas(Rectangle imageSize, IList pageText, IDic else { paragraph.SetTextRenderingMode(PdfCanvasConstants.TextRenderingMode.INVISIBLE); } - canvas.ShowTextAligned(paragraph, xOffset + (float)imageCoordinates.x, yOffset + (float)imageCoordinates.y - , TextAlignment.LEFT); + canvas.ShowTextAligned(paragraph, xOffset + (float)imageCoordinates.GetX(), yOffset + (float)imageCoordinates + .GetY(), TextAlignment.LEFT); if (ocrPdfCreatorProperties.IsTagged()) { pdfCanvas.CloseTag(); } diff --git a/port-hash b/port-hash index 9d9e021..62fa6fc 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -b8203d0ccb0f88b468fee2582f0b13ff3123c7d3 +85113ab686849b75b7908fc7d3a507a1202adbb1 From f4e9485c15cd94a76548fc9bea6d474334e2d875 Mon Sep 17 00:00:00 2001 From: Angelina Pavlovets Date: Tue, 20 Aug 2024 01:23:52 +0000 Subject: [PATCH 10/20] Remove deprecated logic in itextcore DEVSIX-8495 Autoported commit. Original commit hash: [e6ae9e7] --- itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs | 2 +- port-hash | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs index fba5328..0a87682 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs @@ -65,7 +65,7 @@ public virtual void TestIncompatibleOutputIntentAndFontColorSpaceException() { ()); } ); - NUnit.Framework.Assert.AreEqual(PdfAConformanceException.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT + NUnit.Framework.Assert.AreEqual(PdfaExceptionMessageConstant.DEVICECMYK_MAY_BE_USED_ONLY_IF_THE_FILE_HAS_A_CMYK_PDFA_OUTPUT_INTENT_OR_DEFAULTCMYK_IN_USAGE_CONTEXT , exception.Message); } diff --git a/port-hash b/port-hash index 62fa6fc..09ae8bb 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -85113ab686849b75b7908fc7d3a507a1202adbb1 +e6ae9e7d92149be55e4d09cefdf57a673bc73855 From 3c96ee22078d5b470e00c22411df1c42b88329c6 Mon Sep 17 00:00:00 2001 From: Nanou Persoons Date: Sun, 25 Aug 2024 23:39:33 +0000 Subject: [PATCH 11/20] Update cmp files after changing default fontselector DEVSIX-8501 Autoported commit. Original commit hash: [1bcb265] --- .../invoice_front_thai_lib_dotnet.pdf | Bin 59120 -> 59154 bytes .../documents/invoice_front_thai_lib_java.pdf | Bin 59108 -> 59143 bytes port-hash | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/resources/itext/pdfocr/documents/invoice_front_thai_lib_dotnet.pdf b/itext.tests/itext.pdfocr.tesseract4.tests/resources/itext/pdfocr/documents/invoice_front_thai_lib_dotnet.pdf index 1f065128d5e3edaab3e90fb9a0085c3ea232f2c0..fcd4b05d17512942a120e52e2d256fa6dd7cc04a 100644 GIT binary patch delta 18174 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 delta 18156 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 diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/resources/itext/pdfocr/documents/invoice_front_thai_lib_java.pdf b/itext.tests/itext.pdfocr.tesseract4.tests/resources/itext/pdfocr/documents/invoice_front_thai_lib_java.pdf index eb6415a97de4e8cd5ac7d85fa245a9041b2efd04..d0d23a2d0614dd193c2a88e98109ffba8e27f2fb 100644 GIT binary patch delta 18164 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 P%7kH*LZ|zM`cwV^*2qjL delta 18124 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 diff --git a/port-hash b/port-hash index 09ae8bb..a94364b 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -e6ae9e7d92149be55e4d09cefdf57a673bc73855 +1bcb265a71ada6a82d5c763bcb93179abe649e33 From e3c0beab5e99e16c27843cd7018d43fcd3d91b3a Mon Sep 17 00:00:00 2001 From: iText Software Date: Tue, 3 Sep 2024 14:23:44 +0000 Subject: [PATCH 12/20] Update port-hash Change throws to IOException for getPdfWriter after FileUtil changes DEVSIX-8403 Autoported commit. Original commit hash: [c82915e] --- port-hash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port-hash b/port-hash index a94364b..db75590 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -1bcb265a71ada6a82d5c763bcb93179abe649e33 +c82915e4a73b151cbb8d24a9dd5322515bf33690 From d1c0d86cb307cb4a910670c0a562368b0e48078a Mon Sep 17 00:00:00 2001 From: Angelina Pavlovets Date: Fri, 6 Sep 2024 14:32:41 +0000 Subject: [PATCH 13/20] Get rid of deprecated OcrPdfCreator#getLogicalTree DEVSIX-8570 Autoported commit. Original commit hash: [a934d79] --- .../itext/pdfocr/ApiTest.cs | 4 +-- .../itext/pdfocr/helpers/CustomOcrEngine.cs | 4 +++ .../helpers/CustomProductAwareOcrEngine.cs | 4 +++ .../TestStructureDetectionOcrEngine.cs | 4 +++ .../itext/pdfocr/tesseract4/ApiTest.cs | 15 ++++++++++ .../itext/pdfocr/IOcrEngine.cs | 10 +++++++ .../itext/pdfocr/OcrPdfCreator.cs | 30 +++++++------------ .../tesseract4/AbstractTesseract4OcrEngine.cs | 7 ++++- .../Tesseract4ExecutableOcrEngine.cs | 1 + .../tesseract4/Tesseract4LibOcrEngine.cs | 2 ++ port-hash | 2 +- 11 files changed, 59 insertions(+), 24 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs index 94940b4..ce2848f 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs @@ -215,14 +215,12 @@ public virtual void TestTableStructureTree() { } [NUnit.Framework.Test] - [LogMessage(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT, LogLevel = LogLevelConstants.ERROR)] public virtual void TestTaggingNotSupported() { String input = PdfHelper.GetImagesTestDirectory() + "numbers_01.jpg"; String pdfPath = PdfHelper.GetTargetDirectory() + "taggingNotSupported.pdf"; Exception e = NUnit.Framework.Assert.Catch(typeof(PdfOcrException), () => PdfHelper.CreatePdf(pdfPath, new FileInfo(input), new OcrPdfCreatorProperties().SetTagged(true))); - NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(PdfOcrExceptionMessageConstant.CANNOT_CREATE_PDF_DOCUMENT - , PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED), e.Message); + NUnit.Framework.Assert.AreEqual(PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED, e.Message); } //\cond DO_NOT_DOCUMENT diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomOcrEngine.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomOcrEngine.cs index 957efe6..00ad5f1 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomOcrEngine.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomOcrEngine.cs @@ -61,6 +61,10 @@ public virtual void CreateTxtFile(IList inputImages, FileInfo txtFile, ) { } + public virtual bool IsTaggingSupported() { + return false; + } + public virtual OcrEngineProperties GetOcrEngineProperties() { return ocrEngineProperties; } diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomProductAwareOcrEngine.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomProductAwareOcrEngine.cs index 0dcca43..20ec990 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomProductAwareOcrEngine.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/CustomProductAwareOcrEngine.cs @@ -50,6 +50,10 @@ public virtual void CreateTxtFile(IList inputImages, FileInfo txtFile, ) { } + public virtual bool IsTaggingSupported() { + return true; + } + public virtual OcrEngineProperties GetOcrEngineProperties() { return null; } diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/TestStructureDetectionOcrEngine.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/TestStructureDetectionOcrEngine.cs index 7970f00..c98ba98 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/TestStructureDetectionOcrEngine.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/TestStructureDetectionOcrEngine.cs @@ -85,5 +85,9 @@ public virtual void CreateTxtFile(IList inputImages, FileInfo txtFile) public virtual void CreateTxtFile(IList inputImages, FileInfo txtFile, OcrProcessContext ocrProcessContext ) { } + + public virtual bool IsTaggingSupported() { + return true; + } } } diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs index b41c2d0..71313f9 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/tesseract4/ApiTest.cs @@ -25,6 +25,7 @@ You should have received a copy of the GNU Affero General Public License using System.IO; using iText.Commons.Utils; using iText.Pdfocr; +using iText.Pdfocr.Exceptions; using iText.Pdfocr.Tesseract4.Exceptions; using iText.Pdfocr.Tesseract4.Logs; using iText.Test.Attributes; @@ -120,5 +121,19 @@ public virtual void TestDetectAndFixBrokenBBoxes() { NUnit.Framework.Assert.AreEqual(385.5, (float)textInfo.GetBboxRect().GetRight(), 0.1); NUnit.Framework.Assert.AreEqual(162.75, (float)textInfo.GetBboxRect().GetTop(), 0.1); } + + [NUnit.Framework.Test] + public virtual void TestTaggingNotSupportedForTesseract4ExecutableOcrEngine() { + Exception e = NUnit.Framework.Assert.Catch(typeof(PdfOcrException), () => new OcrPdfCreator(new Tesseract4ExecutableOcrEngine + (new Tesseract4OcrEngineProperties()), new OcrPdfCreatorProperties().SetTagged(true))); + NUnit.Framework.Assert.AreEqual(PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED, e.Message); + } + + [NUnit.Framework.Test] + public virtual void TestTaggingNotSupportedForTesseract4LibOcrEngine() { + Exception e = NUnit.Framework.Assert.Catch(typeof(PdfOcrException), () => new OcrPdfCreator(new Tesseract4LibOcrEngine + (new Tesseract4OcrEngineProperties()), new OcrPdfCreatorProperties().SetTagged(true))); + NUnit.Framework.Assert.AreEqual(PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED, e.Message); + } } } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/IOcrEngine.cs b/itext/itext.pdfocr.api/itext/pdfocr/IOcrEngine.cs index dc5375f..d909560 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/IOcrEngine.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/IOcrEngine.cs @@ -132,5 +132,15 @@ public interface IOcrEngine { /// file to be created /// ocr processing context void CreateTxtFile(IList inputImages, FileInfo txtFile, OcrProcessContext ocrProcessContext); + + /// Checks whether tagging is supported by the OCR engine. + /// + /// + /// + /// if tagging is supported by the engine, + /// + /// otherwise + /// + bool IsTaggingSupported(); } } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs index 6f9ce2e..4cf0198 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs @@ -113,6 +113,9 @@ public OcrPdfCreator(IOcrEngine ocrEngine) /// /// public OcrPdfCreator(IOcrEngine ocrEngine, OcrPdfCreatorProperties ocrPdfCreatorProperties) { + if (ocrPdfCreatorProperties.IsTagged() && !ocrEngine.IsTaggingSupported()) { + throw new PdfOcrException(PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED); + } SetOcrEngine(ocrEngine); SetOcrPdfCreatorProperties(ocrPdfCreatorProperties); } @@ -630,12 +633,8 @@ private void AddToCanvas(PdfDocument pdfDocument, Rectangle imageSize, IList logicalTree = new List(); // A map of leaf LogicalStructureTreeItem's to TextInfo's attached to these leaves - IDictionary> leavesTextInfos = new Dictionary>(); - bool taggedSupported = GetLogicalTree(pageText, logicalTree, leavesTextInfos); - if (!taggedSupported) { - throw new PdfOcrException(PdfOcrExceptionMessageConstant.TAGGING_IS_NOT_SUPPORTED); - } + IDictionary> leavesTextInfos = GetLogicalTree(pageText, logicalTree + ); pdfDocument.SetTagged(); // Create a map of TextInfo to tag pointers meanwhile creating the required tags. // Tag pointers are later used to put all the required info into canvas (content stream) @@ -765,18 +764,12 @@ private void AddImageToCanvas(ImageData imageData, Rectangle imageSize, PdfCanva } } - /// - /// - /// - /// if tagging supported by the engine. - /// - [System.ObsoleteAttribute(@"In next major version we need to add boolean taggingSupported() method into IOcrEngine and throw exception in OcrPdfCreator constructor if taggingSupported() returns false but OcrPdfCreatorProperties.getTagged returns true." - )] - private static bool GetLogicalTree(IList textInfos, IList logicalStructureTreeItems - , IDictionary> leavesTextInfos) { - bool taggedSupported = false; + private static IDictionary> GetLogicalTree(IList textInfos + , IList logicalStructureTreeItems) { + IDictionary> leavesTextInfos = new Dictionary>(); if (textInfos == null) { - return taggedSupported; + return leavesTextInfos; } foreach (TextInfo textInfo in textInfos) { LogicalStructureTreeItem structTreeItem = textInfo.GetLogicalStructureTreeItem(); @@ -787,7 +780,6 @@ private static bool GetLogicalTree(IList textInfos, IList textInfos, IList /// The implementation of /// . + /// /// This class provides possibilities to perform OCR, to read data from input /// files and to return contained text in the required format. - /// Also there are possibilities to use features of "tesseract" + /// Also, there are possibilities to use features of "tesseract" /// (optical character recognition engine for various operating systems). /// public abstract class AbstractTesseract4OcrEngine : IOcrEngine, IProductAware { @@ -405,6 +406,10 @@ public virtual ProductData GetProductData() { return PdfOcrTesseract4ProductData.GetInstance(); } + public virtual bool IsTaggingSupported() { + return false; + } + //\cond DO_NOT_DOCUMENT /// /// Performs tesseract OCR using command line tool diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs index 2082c9f..751c83e 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4ExecutableOcrEngine.cs @@ -44,6 +44,7 @@ namespace iText.Pdfocr.Tesseract4 { /// The implementation of /// /// for tesseract OCR. + /// /// This class provides possibilities to use features of "tesseract" CL tool /// (optical character recognition engine for various operating systems). /// Please note that it's assumed that "tesseract" has already been diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs index d8f5590..7d509ef 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/Tesseract4LibOcrEngine.cs @@ -44,8 +44,10 @@ namespace iText.Pdfocr.Tesseract4 { /// The implementation of /// /// for tesseract OCR. + /// /// This class provides possibilities to use features of "tesseract" /// using tess4j. + /// /// Please note that this class is not thread-safe, in other words this Tesseract engine cannot /// be used for multithreaded processing. You should create one instance per thread /// diff --git a/port-hash b/port-hash index db75590..f911642 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -c82915e4a73b151cbb8d24a9dd5322515bf33690 +a934d798dd1aaeae01a589cfb297bb1ea585722d From 36c80dcdb526a9e668c1551796ac8ef6cec3b4fa Mon Sep 17 00:00:00 2001 From: Dmitry Chubrick Date: Wed, 18 Sep 2024 12:26:21 +0000 Subject: [PATCH 14/20] Refactor PDF conformance hierarchy * Provide new PdfConformance class which store both PDF/A and PDF/UA * Get rid of "level" word everywhere * Always return not null conformance isntance from PdfDocument * Read conformance from PdfReader even for usual PdfDocument's DEVSIX-8571 Autoported commit. Original commit hash: [b36929b] --- .../itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs | 12 ++++++------ .../itext/pdfocr/PdfA3uTest.cs | 4 ++-- itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs | 3 +-- port-hash | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs index ce2848f..f8be803 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/ApiTest.cs @@ -103,9 +103,9 @@ public virtual void CreatePdfAFileWithFileTest() { String contentBytes = iText.Commons.Utils.JavaUtil.GetStringForBytes(pdf.GetPage(1).GetContentBytes(), System.Text.Encoding .UTF8); NUnit.Framework.Assert.IsTrue(contentBytes.Contains("<00190014001c001400150014>")); - PdfAConformanceLevel cl = pdf.GetReader().GetPdfAConformanceLevel(); - NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_3U.GetConformance(), cl.GetConformance()); - NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_3U.GetPart(), cl.GetPart()); + PdfAConformance cl = pdf.GetReader().GetPdfConformance().GetAConformance(); + NUnit.Framework.Assert.AreEqual(PdfAConformance.PDF_A_3U.GetLevel(), cl.GetLevel()); + NUnit.Framework.Assert.AreEqual(PdfAConformance.PDF_A_3U.GetPart(), cl.GetPart()); } } @@ -120,9 +120,9 @@ public virtual void CreatePdfAFileWithFileNoMetaTest() { String contentBytes = iText.Commons.Utils.JavaUtil.GetStringForBytes(pdf.GetPage(1).GetContentBytes(), System.Text.Encoding .UTF8); NUnit.Framework.Assert.IsTrue(contentBytes.Contains("<00190014001c001400150014>")); - PdfAConformanceLevel cl = pdf.GetReader().GetPdfAConformanceLevel(); - NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_3U.GetConformance(), cl.GetConformance()); - NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_3U.GetPart(), cl.GetPart()); + PdfAConformance cl = pdf.GetReader().GetPdfConformance().GetAConformance(); + NUnit.Framework.Assert.AreEqual(PdfAConformance.PDF_A_3U.GetLevel(), cl.GetLevel()); + NUnit.Framework.Assert.AreEqual(PdfAConformance.PDF_A_3U.GetPart(), cl.GetPart()); } } diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs index 0a87682..ca462eb 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/PdfA3uTest.cs @@ -82,7 +82,7 @@ public virtual void TestPdfA3DefaultMetadata() { PdfDocument pdfDocument = new PdfDocument(new PdfReader(pdfPath)); NUnit.Framework.Assert.AreEqual("en-US", pdfDocument.GetCatalog().GetLang().ToString()); NUnit.Framework.Assert.AreEqual(null, pdfDocument.GetDocumentInfo().GetTitle()); - NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_3U, pdfDocument.GetReader().GetPdfAConformanceLevel + NUnit.Framework.Assert.AreEqual(PdfAConformance.PDF_A_3U, pdfDocument.GetReader().GetPdfConformance().GetAConformance ()); pdfDocument.Close(); } @@ -103,7 +103,7 @@ public virtual void TestPdfCustomMetadata() { PdfDocument pdfDocument = new PdfDocument(new PdfReader(pdfPath)); NUnit.Framework.Assert.AreEqual(locale, pdfDocument.GetCatalog().GetLang().ToString()); NUnit.Framework.Assert.AreEqual(title, pdfDocument.GetDocumentInfo().GetTitle()); - NUnit.Framework.Assert.AreEqual(PdfAConformanceLevel.PDF_A_3U, pdfDocument.GetReader().GetPdfAConformanceLevel + NUnit.Framework.Assert.AreEqual(PdfAConformance.PDF_A_3U, pdfDocument.GetReader().GetPdfConformance().GetAConformance ()); pdfDocument.Close(); } diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs index 4cf0198..6f0d466 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs @@ -660,8 +660,7 @@ private PdfDocument CreatePdfDocument(PdfWriter pdfWriter, PdfOutputIntent pdfOu PdfDocument pdfDocument; bool createPdfA3u = pdfOutputIntent != null; if (createPdfA3u) { - pdfDocument = new PdfADocument(pdfWriter, PdfAConformanceLevel.PDF_A_3U, pdfOutputIntent, documentProperties - ); + pdfDocument = new PdfADocument(pdfWriter, PdfAConformance.PDF_A_3U, pdfOutputIntent, documentProperties); } else { pdfDocument = new PdfDocument(pdfWriter, documentProperties); diff --git a/port-hash b/port-hash index f911642..7907fab 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -a934d798dd1aaeae01a589cfb297bb1ea585722d +b36929b609336a457e5e433836036e9b7ce767ac From b0224bd1fba6cdc4296520798318daa750fc0c89 Mon Sep 17 00:00:00 2001 From: Nanou Persoons Date: Thu, 19 Sep 2024 06:34:38 +0000 Subject: [PATCH 15/20] final modifiers change in core, change to use getters and setters DEVSIX-8225 Autoported commit. Original commit hash: [f1669e2] --- itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs | 2 +- port-hash | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs index 6f0d466..9d28d90 100644 --- a/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs +++ b/itext/itext.pdfocr.api/itext/pdfocr/OcrPdfCreator.cs @@ -1014,7 +1014,7 @@ public override PdfCanvas ShowText(GlyphLine text) { // default value for error message, it'll be updated with the // unicode of the not found glyph String message = PdfOcrLogMessageConstant.COULD_NOT_FIND_CORRESPONDING_GLYPH_TO_UNICODE_CHARACTER; - for (int i = glyphLine.start; i < glyphLine.end; i++) { + for (int i = glyphLine.GetStart(); i < glyphLine.GetEnd(); i++) { if (IsNotDefGlyph(currentFont, glyphLine.Get(i))) { notDefGlyphsExists = true; message = MessageFormatUtil.Format(PdfOcrLogMessageConstant.COULD_NOT_FIND_CORRESPONDING_GLYPH_TO_UNICODE_CHARACTER diff --git a/port-hash b/port-hash index 7907fab..d56d70d 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -b36929b609336a457e5e433836036e9b7ce767ac +f1669e20a0428ea4eea13ca816bbc2413d0a04cc From d1a094dd293582a58511d515c7ebb75fce77f693 Mon Sep 17 00:00:00 2001 From: Guust Ysebie Date: Fri, 6 Sep 2024 12:50:23 +0200 Subject: [PATCH 16/20] Add SECURITY.md DEVSIX-8514 --- SECURITY.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..c09ac3d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,40 @@ +# iText Security Policy + +## Reporting a Vulnerability + +We are committed to maintaining the security of our software. If you discover a security vulnerability, we encourage you to report it to us as soon as possible. + +To report a vulnerability, please visit our [Vulnerability Reporting Page](https://itextpdf.com/report-vulnerability), or email [vulnerability@apryse.com](vulnerability@apryse.com). If you do not receive a response in 2 business days, please follow up as we may not have received your message. + +We follow the procedure of Coordinated Vulnerability Disclosure (CVD) and, to protect the ecosystem, we request that those reporting do the same. Please visit the above page for more information, and follow the steps below to ensure that your report is handled promptly and appropriately: + +1. **Do not disclose the vulnerability publicly** until we have had a chance to address it. +2. **Provide a detailed description** of the vulnerability, including steps to reproduce it, if possible. +3. **Include any relevant information** such as the version of pdfOCR you are using, your operating system, and any other pertinent details. + +## Security Updates and Patches + + When a vulnerability is reported, we will: + +1. **Investigate and verify** the vulnerability. +2. **Develop and test** a fix for the vulnerability. +3. **Release a patch** as soon as possible. + + +## Known Vulnerabilities + +The iText Knowledge Base has a page for known [Common Vulnerabilities and Exposures](https://kb.itextpdf.com/itext/cves) (CVEs), please check it to ensure your vulnerability has not already been disclosed or addressed. + +## Supported product lines + +See [Compatibility Matrix](https://kb.itextpdf.com/itext/compatibility-matrix) + +## Security Best Practices + +To help ensure the security of your applications using pdfOCR, we recommend the following best practices: + +1. **Keep pdfOCR up to date** by regularly checking for and applying updates. +2. **Review and follow** our security guidelines for secure usage. +3. **Monitor your applications** for any unusual activity and investigate any anomalies promptly. + +Thank you for helping us keep iText secure! From dc17d9807979fd65369ded5fb62bd49eb58b54fd Mon Sep 17 00:00:00 2001 From: iText Software Date: Thu, 19 Sep 2024 19:01:01 +0000 Subject: [PATCH 17/20] Update port-hash Add SECURITY.md DEVSIX-8514 Autoported commit. Original commit hash: [d0edac8] Manual files: SECURITY.md --- port-hash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port-hash b/port-hash index d56d70d..43754a4 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -f1669e20a0428ea4eea13ca816bbc2413d0a04cc +d0edac87ac834c996b103317f072b53ec7529d14 From 3bca4830bbb4a7b41df9793cf523f7c1b5d22666 Mon Sep 17 00:00:00 2001 From: iText Software Date: Wed, 9 Oct 2024 09:33:20 +0000 Subject: [PATCH 18/20] Update commons-io dependency version to 2.14.0 to fix CVE DEVSIX-8673 Autoported commit. Original commit hash: [a920f6a] Manual files: pdfocr-tesseract4/pom.xml --- port-hash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port-hash b/port-hash index 43754a4..e394fba 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -d0edac87ac834c996b103317f072b53ec7529d14 +a920f6adfb91e54a7b7c102ee46ff5786b9e24a6 From 9b449c9cf8e1bcf3da814170b99f52b878c40077 Mon Sep 17 00:00:00 2001 From: Dmitry Chubrick Date: Thu, 10 Oct 2024 13:49:20 +0000 Subject: [PATCH 19/20] Change WriterProperties parameters DEVSIX-8623 Autoported commit. Original commit hash: [395badf] --- .../itext.pdfocr.api.tests/itext/pdfocr/helpers/PdfHelper.cs | 5 +++-- .../itext/pdfocr/IntegrationTestHelper.cs | 2 +- .../itext/pdfocr/general/BasicTesseractIntegrationTest.cs | 3 ++- port-hash | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/PdfHelper.cs b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/PdfHelper.cs index ebba8f9..ea26cb9 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/PdfHelper.cs +++ b/itext.tests/itext.pdfocr.api.tests/itext/pdfocr/helpers/PdfHelper.cs @@ -84,12 +84,13 @@ public static String GetTargetDirectory() { /// Create pdfWriter using provided path to destination file. public static PdfWriter GetPdfWriter(String pdfPath) { - return new PdfWriter(pdfPath, new WriterProperties().AddUAXmpMetadata()); + return new PdfWriter(pdfPath, new WriterProperties().AddPdfUaXmpMetadata(PdfUAConformance.PDF_UA_1)); } /// Create pdfWriter. public static PdfWriter GetPdfWriter() { - return new PdfWriter(new MemoryStream(), new WriterProperties().AddUAXmpMetadata()); + return new PdfWriter(new MemoryStream(), new WriterProperties().AddPdfUaXmpMetadata(PdfUAConformance.PDF_UA_1 + )); } /// Creates PDF rgb output intent for tests. diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/IntegrationTestHelper.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/IntegrationTestHelper.cs index 59d313b..20d17d8 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/IntegrationTestHelper.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/IntegrationTestHelper.cs @@ -398,7 +398,7 @@ protected internal virtual String GetTextFromTextFile(FileInfo file) { /// Create pdfWriter using provided path to destination file. protected internal virtual PdfWriter GetPdfWriter(String pdfPath) { - return new PdfWriter(pdfPath, new WriterProperties().AddUAXmpMetadata()); + return new PdfWriter(pdfPath, new WriterProperties().AddPdfUaXmpMetadata(PdfUAConformance.PDF_UA_1)); } /// Gets image name from path. diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs index f132f24..8753fa8 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext/pdfocr/general/BasicTesseractIntegrationTest.cs @@ -327,7 +327,8 @@ private String GetTextFromPage(IList pageText) { /// Create pdfWriter. private PdfWriter GetPdfWriter() { - return new PdfWriter(new ByteArrayOutputStream(), new WriterProperties().AddUAXmpMetadata()); + return new PdfWriter(new ByteArrayOutputStream(), new WriterProperties().AddPdfUaXmpMetadata(PdfUAConformance + .PDF_UA_1)); } } } diff --git a/port-hash b/port-hash index e394fba..a0c3202 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -a920f6adfb91e54a7b7c102ee46ff5786b9e24a6 +395badf33cd52494e7fd07509a2d94a683194519 From 0fc204d7e53a9fa8908ea1539edd1cd3e9ecb9f3 Mon Sep 17 00:00:00 2001 From: Apryse Software Date: Fri, 11 Oct 2024 12:17:26 +0000 Subject: [PATCH 20/20] [RELEASE] pdfOCR 4.0.0 --- doxyfile | 2 +- itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs | 2 +- .../itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj | 4 ++-- .../itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs | 2 +- .../itext.pdfocr.tesseract4.tests.csproj | 4 ++-- itext/itext.pdfocr.api/Properties/AssemblyInfo.cs | 2 +- itext/itext.pdfocr.api/itext.pdfocr.api.csproj | 2 +- itext/itext.pdfocr.api/pdfocr-api.nuspec | 4 ++-- itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs | 2 +- .../tesseract4/actions/data/PdfOcrTesseract4ProductData.cs | 2 +- itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec | 4 ++-- port-hash | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/doxyfile b/doxyfile index fa9790d..d7884f8 100644 --- a/doxyfile +++ b/doxyfile @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "pdfOCR VERSION_PLACEHOLDER API" +PROJECT_NAME = "pdfOCR 4.0.0 API" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version diff --git a/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs index 8a5748b..f474793 100644 --- a/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs +++ b/itext.tests/itext.pdfocr.api.tests/Properties/AssemblyInfo.cs @@ -17,4 +17,4 @@ [assembly: AssemblyVersion("4.0.0.0")] [assembly: AssemblyFileVersion("4.0.0.0")] -[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] +[assembly: AssemblyInformationalVersion("4.0.0")] diff --git a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj index 0786c84..cc7e738 100644 --- a/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj +++ b/itext.tests/itext.pdfocr.api.tests/itext.pdfocr.api.tests.csproj @@ -25,9 +25,9 @@ - + - + diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs index 9486726..516b10a 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs +++ b/itext.tests/itext.pdfocr.tesseract4.tests/Properties/AssemblyInfo.cs @@ -17,4 +17,4 @@ [assembly: AssemblyVersion("4.0.0.0")] [assembly: AssemblyFileVersion("4.0.0.0")] -[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] +[assembly: AssemblyInformationalVersion("4.0.0")] diff --git a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj index 06ef731..740d748 100644 --- a/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj +++ b/itext.tests/itext.pdfocr.tesseract4.tests/itext.pdfocr.tesseract4.tests.csproj @@ -26,9 +26,9 @@ - + - + diff --git a/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs index f04e033..619ffad 100644 --- a/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.api/Properties/AssemblyInfo.cs @@ -16,7 +16,7 @@ [assembly: AssemblyVersion("4.0.0.0")] [assembly: AssemblyFileVersion("4.0.0.0")] -[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] +[assembly: AssemblyInformationalVersion("4.0.0")] [assembly: InternalsVisibleTo("itext.pdfocr.api.tests, PublicKey=" + "00240000048000009400000006020000002400005253413100040000010001008b21ed5b3fc1c1" + "1996390981fe22bbe71a39a9e11d3c2cefddd6ee92920fa871f9666ae0fa941af0280d0653df04" + diff --git a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj index 9deeb66..ff4c0f9 100644 --- a/itext/itext.pdfocr.api/itext.pdfocr.api.csproj +++ b/itext/itext.pdfocr.api/itext.pdfocr.api.csproj @@ -30,7 +30,7 @@ - + diff --git a/itext/itext.pdfocr.api/pdfocr-api.nuspec b/itext/itext.pdfocr.api/pdfocr-api.nuspec index 19a5d7d..e192ba9 100644 --- a/itext/itext.pdfocr.api/pdfocr-api.nuspec +++ b/itext/itext.pdfocr.api/pdfocr-api.nuspec @@ -2,7 +2,7 @@ itext.pdfocr.api - 4.0.0-SNAPSHOT + 4.0.0 iText pdfOcr Apryse Software Apryse Software @@ -18,7 +18,7 @@ - + diff --git a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs index 650bcf7..f393326 100644 --- a/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs +++ b/itext/itext.pdfocr.tesseract4/Properties/AssemblyInfo.cs @@ -16,7 +16,7 @@ [assembly: AssemblyVersion("4.0.0.0")] [assembly: AssemblyFileVersion("4.0.0.0")] -[assembly: AssemblyInformationalVersion("4.0.0-SNAPSHOT")] +[assembly: AssemblyInformationalVersion("4.0.0")] [assembly: InternalsVisibleTo("itext.pdfocr.tesseract4.tests, PublicKey=" + "00240000048000009400000006020000002400005253413100040000010001008b21ed5b3fc1c1" + "1996390981fe22bbe71a39a9e11d3c2cefddd6ee92920fa871f9666ae0fa941af0280d0653df04" + diff --git a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs index e1253e9..4235247 100644 --- a/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs +++ b/itext/itext.pdfocr.tesseract4/itext/pdfocr/tesseract4/actions/data/PdfOcrTesseract4ProductData.cs @@ -34,7 +34,7 @@ public class PdfOcrTesseract4ProductData { private const String PDF_OCR_TESSERACT4_PUBLIC_PRODUCT_NAME = "pdfOCR-Tesseract4"; - private const String PDF_OCR_VERSION = "4.0.0-SNAPSHOT"; + private const String PDF_OCR_VERSION = "4.0.0"; private const int PDF_OCR_COPYRIGHT_SINCE = 2000; diff --git a/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec b/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec index 6280689..528d7b2 100644 --- a/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec +++ b/itext/itext.pdfocr.tesseract4/pdfocr-tesseract4.nuspec @@ -2,7 +2,7 @@ itext.pdfocr.tesseract4 - 4.0.0-SNAPSHOT + 4.0.0 iText pdfOcr Apryse Software Apryse Software @@ -18,7 +18,7 @@ - + diff --git a/port-hash b/port-hash index a0c3202..5591138 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -395badf33cd52494e7fd07509a2d94a683194519 +55a45d5e726da0a60917476f8417bb86c97ebeff