Skip to content

Commit c84e37c

Browse files
committed
Add additional stream filters to apply
* ASCII85Decode * ASCIIHexDecode * RunLengthDecode
1 parent da93df8 commit c84e37c

File tree

7 files changed

+601
-0
lines changed

7 files changed

+601
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2025 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
address: sales@itextpdf.com
42+
*/
43+
package com.itextpdf.rups.io.encoders;
44+
45+
import com.itextpdf.kernel.pdf.IStreamCompressionStrategy;
46+
import com.itextpdf.kernel.pdf.PdfName;
47+
import com.itextpdf.kernel.pdf.PdfObject;
48+
import com.itextpdf.kernel.pdf.PdfStream;
49+
50+
import java.io.OutputStream;
51+
52+
public class ASCII85CompressionStrategy implements IStreamCompressionStrategy {
53+
@Override
54+
public PdfName getFilterName() {
55+
return PdfName.ASCII85Decode;
56+
}
57+
58+
@Override
59+
public PdfObject getDecodeParams() {
60+
return null;
61+
}
62+
63+
@Override
64+
public OutputStream createNewOutputStream(OutputStream original, PdfStream stream) {
65+
return new ASCII85OutputStream(original);
66+
}
67+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2025 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
address: sales@itextpdf.com
42+
*/
43+
package com.itextpdf.rups.io.encoders;
44+
45+
import com.itextpdf.io.source.IFinishable;
46+
47+
import java.io.FilterOutputStream;
48+
import java.io.IOException;
49+
import java.io.OutputStream;
50+
import java.util.Arrays;
51+
import java.util.concurrent.atomic.AtomicBoolean;
52+
53+
public class ASCII85OutputStream extends FilterOutputStream implements IFinishable {
54+
private static final int OFFSET = 33;
55+
private static final int BASE = 85;
56+
private static final int INPUT_LENGTH = 4;
57+
private static final int OUTPUT_LENGTH = 5;
58+
private static final byte ALL_ZEROS_MARKER = 'z';
59+
private static final byte[] EOD = new byte[] {'~', '>'};
60+
61+
private final byte[] buffer = new byte[OUTPUT_LENGTH];
62+
private int inputOr = 0;
63+
private int inputCursor = 0;
64+
65+
private final AtomicBoolean finished = new AtomicBoolean(false);
66+
67+
public ASCII85OutputStream(OutputStream out) {
68+
super(out);
69+
}
70+
71+
@Override
72+
public void write(int b) throws IOException {
73+
final int value = b & 0xFF;
74+
buffer[inputCursor] = (byte) value;
75+
inputOr |= value;
76+
++inputCursor;
77+
writeBufferIfFull();
78+
}
79+
80+
@Override
81+
public void write(byte[] b, int off, int len) throws IOException {
82+
for (int i = off; i < off + len; ++i) {
83+
write(b[i]);
84+
}
85+
}
86+
87+
@Override
88+
public void close() throws IOException {
89+
finish();
90+
super.close();
91+
}
92+
93+
@Override
94+
public void finish() throws IOException {
95+
if (finished.getAndSet(true)) {
96+
return;
97+
}
98+
// Writing the remainder
99+
if (inputCursor > 0) {
100+
Arrays.fill(buffer, inputCursor, INPUT_LENGTH, (byte) 0);
101+
convertBuffer();
102+
out.write(buffer, 0, inputCursor + 1);
103+
resetBuffer();
104+
}
105+
out.write(EOD);
106+
flush();
107+
}
108+
109+
private void writeBufferIfFull() throws IOException {
110+
if (inputCursor < INPUT_LENGTH) {
111+
return;
112+
}
113+
// Special case, if all zeros
114+
if (inputOr == 0) {
115+
out.write(ALL_ZEROS_MARKER);
116+
} else {
117+
convertBuffer();
118+
out.write(buffer);
119+
}
120+
resetBuffer();
121+
}
122+
123+
private void resetBuffer() {
124+
inputOr = 0;
125+
inputCursor = 0;
126+
}
127+
128+
private void convertBuffer() {
129+
long num = ((buffer[0] & 0xFFL) << 24)
130+
| ((buffer[1] & 0xFFL) << 16)
131+
| ((buffer[2] & 0xFFL) << 8)
132+
| (buffer[3] & 0xFFL);
133+
for (int i = OUTPUT_LENGTH - 1; i >= 0; --i) {
134+
buffer[i] = (byte) (OFFSET + (num % BASE));
135+
num /= BASE;
136+
}
137+
}
138+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2025 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
address: sales@itextpdf.com
42+
*/
43+
package com.itextpdf.rups.io.encoders;
44+
45+
import com.itextpdf.kernel.pdf.IStreamCompressionStrategy;
46+
import com.itextpdf.kernel.pdf.PdfName;
47+
import com.itextpdf.kernel.pdf.PdfObject;
48+
import com.itextpdf.kernel.pdf.PdfStream;
49+
50+
import java.io.OutputStream;
51+
52+
public class ASCIIHexCompressionStrategy implements IStreamCompressionStrategy {
53+
@Override
54+
public PdfName getFilterName() {
55+
return PdfName.ASCIIHexDecode;
56+
}
57+
58+
@Override
59+
public PdfObject getDecodeParams() {
60+
return null;
61+
}
62+
63+
@Override
64+
public OutputStream createNewOutputStream(OutputStream original, PdfStream stream) {
65+
return new ASCIIHexOutputStream(original);
66+
}
67+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2025 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
APRYSE GROUP. APRYSE GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
address: sales@itextpdf.com
42+
*/
43+
package com.itextpdf.rups.io.encoders;
44+
45+
import com.itextpdf.io.source.IFinishable;
46+
47+
import java.io.FilterOutputStream;
48+
import java.io.IOException;
49+
import java.io.OutputStream;
50+
import java.util.concurrent.atomic.AtomicBoolean;
51+
52+
public class ASCIIHexOutputStream extends FilterOutputStream implements IFinishable {
53+
private static final byte EOD = '>';
54+
private static final byte[] CHAR_MAP = {
55+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
56+
};
57+
58+
private final AtomicBoolean finished = new AtomicBoolean(false);
59+
60+
public ASCIIHexOutputStream(OutputStream out) {
61+
super(out);
62+
}
63+
64+
@Override
65+
public void write(int b) throws IOException {
66+
final int value = (b & 0xFF);
67+
out.write(CHAR_MAP[value >> 4]);
68+
out.write(CHAR_MAP[value & 0x0F]);
69+
}
70+
71+
@Override
72+
public void write(byte[] b, int off, int len) throws IOException {
73+
for (int i = off; i < off + len; ++i) {
74+
write(b[i]);
75+
}
76+
}
77+
78+
@Override
79+
public void close() throws IOException {
80+
finish();
81+
super.close();
82+
}
83+
84+
@Override
85+
public void finish() throws IOException {
86+
if (finished.getAndSet(true)) {
87+
return;
88+
}
89+
out.write(EOD);
90+
flush();
91+
}
92+
}

0 commit comments

Comments
 (0)