1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.dcx;
18
19 import static org.apache.commons.imaging.common.BinaryFunctions.read4Bytes;
20
21 import java.awt.Dimension;
22 import java.awt.image.BufferedImage;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.PrintWriter;
27 import java.nio.ByteOrder;
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import org.apache.commons.imaging.ImageFormat;
32 import org.apache.commons.imaging.ImageFormats;
33 import org.apache.commons.imaging.ImageInfo;
34 import org.apache.commons.imaging.ImageParser;
35 import org.apache.commons.imaging.ImageReadException;
36 import org.apache.commons.imaging.ImageWriteException;
37 import org.apache.commons.imaging.common.BinaryOutputStream;
38 import org.apache.commons.imaging.common.ImageMetadata;
39 import org.apache.commons.imaging.common.bytesource.ByteSource;
40 import org.apache.commons.imaging.common.bytesource.ByteSourceInputStream;
41 import org.apache.commons.imaging.formats.pcx.PcxImageParser;
42 import org.apache.commons.imaging.formats.pcx.PcxImagingParameters;
43
44 public class DcxImageParser extends ImageParser<PcxImagingParameters> {
45
46 private static final String DEFAULT_EXTENSION = ImageFormats.DCX.getDefaultExtension();
47 private static final String[] ACCEPTED_EXTENSIONS = ImageFormats.DCX.getExtensions();
48
49 public DcxImageParser() {
50 super.setByteOrder(ByteOrder.LITTLE_ENDIAN);
51 }
52
53 @Override
54 public PcxImagingParameters getDefaultParameters() {
55 return new PcxImagingParameters();
56 }
57
58 @Override
59 public String getName() {
60 return "Dcx-Custom";
61 }
62
63 @Override
64 public String getDefaultExtension() {
65 return DEFAULT_EXTENSION;
66 }
67
68 @Override
69 protected String[] getAcceptedExtensions() {
70 return ACCEPTED_EXTENSIONS;
71 }
72
73 @Override
74 protected ImageFormat[] getAcceptedTypes() {
75 return new ImageFormat[] { ImageFormats.DCX };
76 }
77
78
79 @Override
80 public ImageMetadata getMetadata(final ByteSource byteSource, final PcxImagingParameters params)
81 throws ImageReadException, IOException {
82 return null;
83 }
84
85
86 @Override
87 public ImageInfo getImageInfo(final ByteSource byteSource, final PcxImagingParameters params)
88 throws ImageReadException, IOException {
89 return null;
90 }
91
92
93 @Override
94 public Dimension getImageSize(final ByteSource byteSource, final PcxImagingParameters params)
95 throws ImageReadException, IOException {
96 return null;
97 }
98
99
100 @Override
101 public byte[] getICCProfileBytes(final ByteSource byteSource, final PcxImagingParameters params)
102 throws ImageReadException, IOException {
103 return null;
104 }
105
106 private static class DcxHeader {
107
108 public static final int DCX_ID = 0x3ADE68B1;
109 public final int id;
110 public final long[] pageTable;
111
112 DcxHeader(final int id, final long[] pageTable) {
113 this.id = id;
114 this.pageTable = pageTable;
115 }
116
117 public void dump(final PrintWriter pw) {
118 pw.println("DcxHeader");
119 pw.println("Id: 0x" + Integer.toHexString(id));
120 pw.println("Pages: " + pageTable.length);
121 pw.println();
122 }
123 }
124
125 private DcxHeader readDcxHeader(final ByteSource byteSource)
126 throws ImageReadException, IOException {
127 try (InputStream is = byteSource.getInputStream()) {
128 final int id = read4Bytes("Id", is, "Not a Valid DCX File", getByteOrder());
129 final List<Long> pageTable = new ArrayList<>(1024);
130 for (int i = 0; i < 1024; i++) {
131 final long pageOffset = 0xFFFFffffL & read4Bytes("PageTable", is,
132 "Not a Valid DCX File", getByteOrder());
133 if (pageOffset == 0) {
134 break;
135 }
136 pageTable.add(pageOffset);
137 }
138
139 if (id != DcxHeader.DCX_ID) {
140 throw new ImageReadException(
141 "Not a Valid DCX File: file id incorrect");
142 }
143 if (pageTable.size() == 1024) {
144 throw new ImageReadException(
145 "DCX page table not terminated by zero entry");
146 }
147
148 final Object[] objects = pageTable.toArray();
149 final long[] pages = new long[objects.length];
150 for (int i = 0; i < objects.length; i++) {
151 pages[i] = ((Long) objects[i]);
152 }
153
154 return new DcxHeader(id, pages);
155 }
156 }
157
158 @Override
159 public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource)
160 throws ImageReadException, IOException {
161 readDcxHeader(byteSource).dump(pw);
162 return true;
163 }
164
165 @Override
166 public final BufferedImage getBufferedImage(final ByteSource byteSource,
167 final PcxImagingParameters params) throws ImageReadException, IOException {
168 final List<BufferedImage> list = getAllBufferedImages(byteSource);
169 if (list.isEmpty()) {
170 return null;
171 }
172 return list.get(0);
173 }
174
175 @Override
176 public List<BufferedImage> getAllBufferedImages(final ByteSource byteSource)
177 throws ImageReadException, IOException {
178 final DcxHeader dcxHeader = readDcxHeader(byteSource);
179 final List<BufferedImage> images = new ArrayList<>();
180 final PcxImageParser/PcxImageParser.html#PcxImageParser">PcxImageParser pcxImageParser = new PcxImageParser();
181 for (final long element : dcxHeader.pageTable) {
182 try (InputStream stream = byteSource.getInputStream(element)) {
183 final ByteSourceInputStreamurce/ByteSourceInputStream.html#ByteSourceInputStream">ByteSourceInputStream pcxSource = new ByteSourceInputStream(
184 stream, null);
185 final BufferedImage image = pcxImageParser.getBufferedImage(
186 pcxSource, new PcxImagingParameters());
187 images.add(image);
188 }
189 }
190 return images;
191 }
192
193 @Override
194 public void writeImage(final BufferedImage src, final OutputStream os, final PcxImagingParameters params)
195 throws ImageWriteException, IOException {
196 final int headerSize = 4 + 1024 * 4;
197
198 final BinaryOutputStreamon/BinaryOutputStream.html#BinaryOutputStream">BinaryOutputStream bos = new BinaryOutputStream(os,
199 ByteOrder.LITTLE_ENDIAN);
200 bos.write4Bytes(DcxHeader.DCX_ID);
201
202 bos.write4Bytes(headerSize);
203 for (int i = 0; i < 1023; i++) {
204 bos.write4Bytes(0);
205 }
206 final PcxImageParser/PcxImageParser.html#PcxImageParser">PcxImageParser pcxImageParser = new PcxImageParser();
207 pcxImageParser.writeImage(src, bos, params);
208 }
209 }