diff --git a/imageio/imageio-jpeg/license.txt b/imageio/imageio-jpeg/license.txt
index 4913b243..53188f88 100644
--- a/imageio/imageio-jpeg/license.txt
+++ b/imageio/imageio-jpeg/license.txt
@@ -1,4 +1,6 @@
-Copyright (c) 2013, Harald Kuhr
+Copyright (c) 2016, Harald Kuhr
+Copyright (C) 2015, Michael Martinez (JPEG Lossless decoder)
+Copyright (C) 2004, Helmut Dersch (Java JPEG decoder)
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AdobeDCT.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AdobeDCT.java
index 19b6dc06..22cbc6c1 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AdobeDCT.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AdobeDCT.java
@@ -40,17 +40,17 @@ import java.io.IOException;
* @author last modified by $Author: haraldk$
* @version $Id: AdobeDCTSegment.java,v 1.0 23.04.12 16:55 haraldk Exp$
*/
-final class AdobeDCT extends AppSegment {
- public static final int Unknown = 0;
- public static final int YCC = 1;
- public static final int YCCK = 2;
+final class AdobeDCT extends Application {
+ static final int Unknown = 0;
+ static final int YCC = 1;
+ static final int YCCK = 2;
final int version;
final int flags0;
final int flags1;
final int transform;
- AdobeDCT(int version, int flags0, int flags1, int transform) {
+ private AdobeDCT(int version, int flags0, int flags1, int transform) {
super(JPEG.APP14, "Adobe", new byte[]{'A', 'd', 'o', 'b', 'e', 0, (byte) version, (byte) (flags0 >> 8), (byte) (flags0 & 0xff), (byte) (flags1 >> 8), (byte) (flags1 & 0xff), (byte) transform});
this.version = version; // 100 or 101
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AppSegment.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AppSegment.java
deleted file mode 100644
index e77472be..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/AppSegment.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.twelvemonkeys.imageio.plugins.jpeg;
-
-import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
-import com.twelvemonkeys.lang.Validate;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * AppSegment.
- *
- * @author Harald Kuhr
- * @author last modified by $Author: harald.kuhr$
- * @version $Id: AppSegment.java,v 1.0 22/08/16 harald.kuhr Exp$
- */
-class AppSegment extends Segment {
-
- final String identifier;
- final byte[] data;
-
- AppSegment(int marker, final String identifier, final byte[] data) {
- super(marker);
-
- this.identifier = Validate.notEmpty(identifier, "identifier");
- this.data = data;
- }
-
- protected AppSegment(int marker, final String identifier) {
- this(marker, identifier, null);
- }
-
- InputStream data() {
- int offset = identifier.length() + 1;
- return new ByteArrayInputStream(data, offset, data.length - offset);
- }
-
- public static AppSegment read(final int marker, final String identifier, final DataInput data, final int length) throws IOException {
- switch (marker) {
- case JPEG.APP0:
- // JFIF
- if ("JFIF".equals(identifier)) {
- return JFIF.read(data, length);
- }
- case JPEG.APP1:
- // JFXX
- if ("JFXX".equals(identifier)) {
- return JFXX.read(data, length);
- }
- // TODO: Exif?
- case JPEG.APP2:
- // ICC_PROFILE
- if ("ICC_PROFILE".equals(identifier)) {
- return ICCProfile.read(data, length);
- }
- case JPEG.APP14:
- // Adobe
- if ("Adobe".equals(identifier)) {
- return AdobeDCT.read(data, length);
- }
-
- default:
- // Generic APPn segment
- byte[] bytes = new byte[length - 2];
- data.readFully(bytes);
- return new AppSegment(marker, identifier, bytes);
- }
- }
-}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Application.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Application.java
new file mode 100644
index 00000000..2a205ba6
--- /dev/null
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Application.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.plugins.jpeg;
+
+import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
+import com.twelvemonkeys.lang.Validate;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Application.
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: harald.kuhr$
+ * @version $Id: Application.java,v 1.0 22/08/16 harald.kuhr Exp$
+ */
+class Application extends Segment {
+
+ final String identifier;
+ final byte[] data;
+
+ Application(int marker, final String identifier, final byte[] data) {
+ super(marker);
+
+ this.identifier = Validate.notEmpty(identifier, "identifier");
+ this.data = data;
+ }
+
+ InputStream data() {
+ int offset = identifier.length() + 1;
+ return new ByteArrayInputStream(data, offset, data.length - offset);
+ }
+
+ @Override
+ public String toString() {
+ return "APP" + (marker & 0x0f) + "/" + identifier + "[length: " + data.length + "]";
+ }
+
+ public static Application read(final int marker, final String identifier, final DataInput data, final int length) throws IOException {
+ switch (marker) {
+ case JPEG.APP0:
+ // JFIF
+ if ("JFIF".equals(identifier)) {
+ return JFIF.read(data, length);
+ }
+ case JPEG.APP1:
+ // JFXX
+ if ("JFXX".equals(identifier)) {
+ return JFXX.read(data, length);
+ }
+ // TODO: Exif?
+ case JPEG.APP2:
+ // ICC_PROFILE
+ if ("ICC_PROFILE".equals(identifier)) {
+ return ICCProfile.read(data, length);
+ }
+ case JPEG.APP14:
+ // Adobe
+ if ("Adobe".equals(identifier)) {
+ return AdobeDCT.read(data, length);
+ }
+
+ default:
+ // Generic APPn segment
+ byte[] bytes = new byte[length - 2];
+ data.readFully(bytes);
+ return new Application(marker, identifier, bytes);
+ }
+ }
+}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Comment.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Comment.java
index 1b4c5c04..50e9ea69 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Comment.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Comment.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
@@ -21,10 +49,15 @@ class Comment extends Segment {
this.comment = comment;
}
+ @Override
+ public String toString() {
+ return "COM[" + comment + "]";
+ }
+
public static Segment read(final DataInput data, final int length) throws IOException {
- byte[] ascii = new byte[length];
+ byte[] ascii = new byte[length - 2];
data.readFully(ascii);
- return new Comment(new String(ascii, StandardCharsets.UTF_8));
+ return new Comment(new String(ascii, StandardCharsets.UTF_8)); // Strictly, it is ASCII, but UTF-8 is compatible
}
}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Frame.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Frame.java
index b3788669..d72dc5f3 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Frame.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Frame.java
@@ -51,7 +51,7 @@ final class Frame extends Segment {
final Component[] components; // Components specifications
- Frame(final int marker, final int samplePrecision, final int lines, final int samplesPerLine, final Component[] components) {
+ private Frame(final int marker, final int samplePrecision, final int lines, final int samplesPerLine, final Component[] components) {
super(marker);
this.samplePrecision = samplePrecision;
@@ -116,7 +116,7 @@ final class Frame extends Segment {
return read(marker, new SubImageInputStream(data, length), length);
}
- static final class Component {
+ public static final class Component {
final int id;
final int hSub; // Horizontal sampling factor
final int vSub; // Vertical sampling factor
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/HuffmanTable.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/HuffmanTable.java
index 8bd4b465..bd53c739 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/HuffmanTable.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/HuffmanTable.java
@@ -1,37 +1,38 @@
/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
+ * Copyright (c) 2016, Harald Kuhr
+ * Copyright (C) 2015, Michael Martinez
+ * Copyright (C) 2004, Helmut Dersch
+ * All rights reserved.
*
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
+import javax.imageio.IIOException;
import javax.imageio.stream.ImageInputStream;
import java.io.DataInput;
import java.io.IOException;
@@ -45,7 +46,7 @@ final class HuffmanTable extends Segment {
public static final int MSB = 0x80000000;
- public HuffmanTable() {
+ private HuffmanTable() {
super(JPEG.DHT);
tc[0][0] = 0;
@@ -109,7 +110,7 @@ final class HuffmanTable extends Segment {
}
if (k >= 256) {
if (k > 256) {
- throw new IOException("Huffman table error");
+ throw new IIOException("JPEG Huffman Table error");
}
k = 0;
@@ -119,9 +120,14 @@ final class HuffmanTable extends Segment {
}
}
- public static Segment read(DataInput data, int length) throws IOException {
- int count = 0;
- count += 2;
+ @Override
+ public String toString() {
+ // TODO: Id and class for tables
+ return "DHT[]";
+ }
+
+ public static Segment read(final DataInput data, final int length) throws IOException {
+ int count = 2;
HuffmanTable table = new HuffmanTable();
@@ -130,12 +136,12 @@ final class HuffmanTable extends Segment {
count++;
int t = temp & 0x0F;
if (t > 3) {
- throw new IOException("Huffman table Id > 3:" + t);
+ throw new IIOException("Unexpected JPEG Huffman Table Id (> 3):" + t);
}
int c = temp >> 4;
if (c > 2) {
- throw new IOException("Huffman table class > 2: " + c);
+ throw new IIOException("Unexpected JPEG Huffman Table class (> 2): " + c);
}
table.th[t] = 1;
@@ -149,7 +155,7 @@ final class HuffmanTable extends Segment {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < table.l[t][c][i]; j++) {
if (count > length) {
- throw new IOException("Huffman table format error [count>Lh]");
+ throw new IIOException("JPEG Huffman Table format error");
}
table.v[t][c][i][j] = data.readUnsignedByte();
count++;
@@ -158,18 +164,9 @@ final class HuffmanTable extends Segment {
}
if (count != length) {
- throw new IOException("Huffman table format error [count!=Lf]");
+ throw new IIOException("JPEG Huffman Table format error, bad segment length: " + length);
}
-// for (int i = 0; i < 4; i++) {
-// for (int j = 0; j < 2; j++) {
-// if (tc[i][j] != 0) {
-// buildHuffTable(HuffTab[i][j], l[i][j], v[i][j]);
-// }
-// }
-// }
-//
-// return 1;
return table;
}
}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/ICCProfile.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/ICCProfile.java
index bdea9621..ba0ae44f 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/ICCProfile.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/ICCProfile.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
@@ -12,12 +40,18 @@ import java.io.IOException;
* @author last modified by $Author: harald.kuhr$
* @version $Id: ICCProfile.java,v 1.0 22/08/16 harald.kuhr Exp$
*/
-final class ICCProfile extends AppSegment {
- protected ICCProfile(final byte[] data) {
+final class ICCProfile extends Application {
+ private ICCProfile(final byte[] data) {
super(JPEG.APP2, "ICC_PROFILE", data);
}
// TODO: Create util method to concat all ICC segments to one and return ICC_Profile (move from JPEGImageReader)
+ // If so, how to deal with warnings from the original code? Throw exceptions instead?
+
+ @Override
+ public String toString() {
+ return "ICC_PROFILE[" + data[0] + "/" + data[1] + " length: " + data.length + "]";
+ }
public static ICCProfile read(DataInput data, int length) throws IOException {
byte[] bytes = new byte[length - 2];
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFIF.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFIF.java
index 832105f2..e20d5289 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFIF.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFIF.java
@@ -32,7 +32,6 @@ import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
import java.io.*;
import java.nio.ByteBuffer;
-import java.util.Arrays;
/**
* JFIFSegment
@@ -41,7 +40,7 @@ import java.util.Arrays;
* @author last modified by $Author: haraldk$
* @version $Id: JFIFSegment.java,v 1.0 23.04.12 16:52 haraldk Exp$
*/
-final class JFIF extends AppSegment {
+final class JFIF extends Application {
final int majorVersion;
final int minorVersion;
final int units;
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFXX.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFXX.java
index 01099fa7..cb19ac87 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFXX.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JFXX.java
@@ -29,9 +29,7 @@
package com.twelvemonkeys.imageio.plugins.jpeg;
import java.io.DataInput;
-import java.io.DataInputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.util.Arrays;
/**
@@ -41,7 +39,7 @@ import java.util.Arrays;
* @author last modified by $Author: haraldk$
* @version $Id: JFXXSegment.java,v 1.0 23.04.12 16:54 haraldk Exp$
*/
-final class JFXX extends AppSegment {
+final class JFXX extends Application {
public static final int JPEG = 0x10;
public static final int INDEXED = 0x11;
public static final int RGB = 0x13;
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10Metadata.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10Metadata.java
index 46ebb233..d3a59730 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10Metadata.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10Metadata.java
@@ -2,13 +2,9 @@ package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.AbstractMetadata;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
-import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
import org.w3c.dom.Node;
import javax.imageio.metadata.IIOMetadataNode;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.util.List;
/**
@@ -95,10 +91,10 @@ class JPEGImage10Metadata extends AbstractMetadata {
Scan scan = (Scan) segment;
IIOMetadataNode sos = new IIOMetadataNode("sos");
sos.setAttribute("numScanComponents", String.valueOf(scan.components.length));
- sos.setAttribute("startSpectralSelection", String.valueOf(scan.selection));
- sos.setAttribute("endSpectralSelection", String.valueOf(scan.spectralEnd));
- sos.setAttribute("approxHigh", String.valueOf(scan.ah));
- sos.setAttribute("approxLow", String.valueOf(scan.al));
+ sos.setAttribute("startSpectralSelection", String.valueOf(scan.spectralSelStart));
+ sos.setAttribute("endSpectralSelection", String.valueOf(scan.spectralSelEnd));
+ sos.setAttribute("approxHigh", String.valueOf(scan.approxHigh));
+ sos.setAttribute("approxLow", String.valueOf(scan.approxLow));
for (Scan.Component component : scan.components) {
IIOMetadataNode spec = new IIOMetadataNode("scanComponentSpec");
@@ -135,7 +131,7 @@ class JPEGImage10Metadata extends AbstractMetadata {
default:
IIOMetadataNode unknown = new IIOMetadataNode("unknown");
unknown.setAttribute("MarkerTag", String.valueOf(segment.marker & 0xFF));
- unknown.setUserObject(((AppSegment) segment).data);
+ unknown.setUserObject(((Application) segment).data);
markerSequence.appendChild(unknown);
break;
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java
index ca2b3728..ac404c0f 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImage10MetadataCleaner.java
@@ -10,10 +10,7 @@ import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import java.awt.color.ICC_Profile;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
import java.io.IOException;
-import java.nio.charset.Charset;
import java.util.List;
/**
@@ -39,7 +36,7 @@ final class JPEGImage10MetadataCleaner {
IIOMetadata cleanMetadata(final IIOMetadata imageMetadata) throws IOException {
// We filter out pretty much everything from the stream..
// Meaning we have to read get *all APP segments* and re-insert into metadata.
- List appSegments = reader.getAppSegments(JPEGImageReader.ALL_APP_MARKERS, null);
+ List appSegments = reader.getAppSegments(JPEGImageReader.ALL_APP_MARKERS, null);
// NOTE: There's a bug in the merging code in JPEGMetadata mergeUnknownNode that makes sure all "unknown" nodes are added twice in certain conditions.... ARGHBL...
// DONE: 1: Work around
@@ -176,7 +173,7 @@ final class JPEGImage10MetadataCleaner {
}
Node next = null;
- for (AppSegment segment : appSegments) {
+ for (Application segment : appSegments) {
// Except real app0JFIF, app0JFXX, app2ICC and app14Adobe, add all the app segments that we filtered away as "unknown" markers
if (segment.marker == JPEG.APP0 && "JFIF".equals(segment.identifier) && hasRealJFIF) {
continue;
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java
index 54a15409..867373f4 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGImageReader.java
@@ -39,7 +39,6 @@ import com.twelvemonkeys.imageio.metadata.exif.TIFF;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegment;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil;
-import com.twelvemonkeys.imageio.plugins.jpeg.lossless.JPEGLosslessDecoderWrapper;
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
import com.twelvemonkeys.lang.Validate;
@@ -110,7 +109,7 @@ public class JPEGImageReader extends ImageReaderBase {
static final int ALL_APP_MARKERS = -1;
/** Segment identifiers for the JPEG segments we care about reading. */
- private static final Map> SEGMENT_IDENTIFIERS = createSegmentIds();
+ private static final Map> SEGMENT_IDENTIFIERS = JPEGSegmentUtil.ALL_SEGMENTS; //createSegmentIds();
private static Map> createSegmentIds() {
Map> map = new LinkedHashMap<>();
@@ -386,7 +385,7 @@ public class JPEGImageReader extends ImageReaderBase {
// TODO: What about stream position?
// TODO: Param handling: Source region, offset, subsampling, destination, destination type, etc....
// Read image as lossless
- return new JPEGLosslessDecoderWrapper().readImage(imageInput);
+ return new JPEGLosslessDecoderWrapper().readImage(segments, imageInput);
}
// We need to apply ICC profile unless the profile is sRGB/default gray (whatever that is)
@@ -592,25 +591,25 @@ public class JPEGImageReader extends ImageReaderBase {
if (adobeDCT != null) {
switch (adobeDCT.transform) {
case AdobeDCT.YCC:
- if (startOfFrame.components.length != 3) {
+ if (startOfFrame.componentsInFrame() != 3) {
// This probably means the Adobe marker is bogus
break;
}
return JPEGColorSpace.YCbCr;
case AdobeDCT.YCCK:
- if (startOfFrame.components.length != 4) {
+ if (startOfFrame.componentsInFrame() != 4) {
// This probably means the Adobe marker is bogus
break;
}
return JPEGColorSpace.YCCK;
case AdobeDCT.Unknown:
- if (startOfFrame.components.length == 1) {
+ if (startOfFrame.componentsInFrame() == 1) {
return JPEGColorSpace.Gray;
}
- else if (startOfFrame.components.length == 3) {
+ else if (startOfFrame.componentsInFrame() == 3) {
return JPEGColorSpace.RGB;
}
- else if (startOfFrame.components.length == 4) {
+ else if (startOfFrame.componentsInFrame() == 4) {
return JPEGColorSpace.CMYK;
}
// Else fall through
@@ -619,7 +618,7 @@ public class JPEGImageReader extends ImageReaderBase {
}
// TODO: We should probably allow component ids out of order (ie. BGR or KMCY)...
- switch (startOfFrame.components.length) {
+ switch (startOfFrame.componentsInFrame()) {
case 1:
return JPEGColorSpace.Gray;
case 2:
@@ -712,7 +711,7 @@ public class JPEGImageReader extends ImageReaderBase {
if (segments == null) {
long start = DEBUG ? System.currentTimeMillis() : 0;
- // TODO: Consider just reading the segments here, for better performance...
+ // TODO: Consider just reading the segments directly, for better performance...
List jpegSegments = readSegments();
List segments = new ArrayList<>(jpegSegments.size());
@@ -761,20 +760,20 @@ public class JPEGImageReader extends ImageReaderBase {
return Collections.emptyList();
}
- List getAppSegments(final int marker, final String identifier) throws IOException {
+ List getAppSegments(final int marker, final String identifier) throws IOException {
initHeader();
- List appSegments = Collections.emptyList();
+ List appSegments = Collections.emptyList();
for (Segment segment : segments) {
- if (segment instanceof AppSegment
+ if (segment instanceof Application
&& (marker == ALL_APP_MARKERS || marker == segment.marker)
- && (identifier == null || identifier.equals(((AppSegment) segment).identifier))) {
+ && (identifier == null || identifier.equals(((Application) segment).identifier))) {
if (appSegments == Collections.EMPTY_LIST) {
appSegments = new ArrayList<>(segments.size());
}
- appSegments.add((AppSegment) segment);
+ appSegments.add((Application) segment);
}
}
@@ -794,26 +793,26 @@ public class JPEGImageReader extends ImageReaderBase {
}
AdobeDCT getAdobeDCT() throws IOException {
- List adobe = getAppSegments(JPEG.APP14, "Adobe");
+ List adobe = getAppSegments(JPEG.APP14, "Adobe");
return adobe.isEmpty() ? null : (AdobeDCT) adobe.get(0);
}
JFIF getJFIF() throws IOException{
- List jfif = getAppSegments(JPEG.APP0, "JFIF");
+ List jfif = getAppSegments(JPEG.APP0, "JFIF");
return jfif.isEmpty() ? null : (JFIF) jfif.get(0);
}
JFXX getJFXX() throws IOException {
- List jfxx = getAppSegments(JPEG.APP0, "JFXX");
+ List jfxx = getAppSegments(JPEG.APP0, "JFXX");
return jfxx.isEmpty() ? null : (JFXX) jfxx.get(0);
}
private CompoundDirectory getExif() throws IOException {
- List exifSegments = getAppSegments(JPEG.APP1, "Exif");
+ List exifSegments = getAppSegments(JPEG.APP1, "Exif");
if (!exifSegments.isEmpty()) {
- AppSegment exif = exifSegments.get(0);
+ Application exif = exifSegments.get(0);
InputStream data = exif.data();
if (data.read() == -1) { // Read pad
@@ -849,13 +848,13 @@ public class JPEGImageReader extends ImageReaderBase {
// TODO: Allow metadata to contain the wrongly indexed profiles, if readable
// NOTE: We ignore any profile with wrong index for reading and image types, just to be on the safe side
- List segments = getAppSegments(JPEG.APP2, "ICC_PROFILE");
+ List segments = getAppSegments(JPEG.APP2, "ICC_PROFILE");
// TODO: Possibly move this logic to the ICCProfile class...
if (segments.size() == 1) {
// Faster code for the common case
- AppSegment segment = segments.get(0);
+ Application segment = segments.get(0);
DataInputStream stream = new DataInputStream(segment.data());
int chunkNumber = stream.readUnsignedByte();
int chunkCount = stream.readUnsignedByte();
@@ -945,7 +944,7 @@ public class JPEGImageReader extends ImageReaderBase {
if (isLossless()) {
// TODO: What about stream position?
// TODO: Param handling: Reading as raster should support source region, subsampling etc.
- return new JPEGLosslessDecoderWrapper().readRaster(imageInput);
+ return new JPEGLosslessDecoderWrapper().readRaster(segments, imageInput);
}
return delegate.readRaster(imageIndex, param);
@@ -1001,9 +1000,9 @@ public class JPEGImageReader extends ImageReaderBase {
}
// Read Exif thumbnails if present
- List exifSegments = getAppSegments(JPEG.APP1, "Exif");
+ List exifSegments = getAppSegments(JPEG.APP1, "Exif");
if (!exifSegments.isEmpty()) {
- AppSegment exif = exifSegments.get(0);
+ Application exif = exifSegments.get(0);
InputStream data = exif.data();
if (data.read() == -1) {
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/JPEGLosslessDecoder.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGLosslessDecoder.java
similarity index 66%
rename from imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/JPEGLosslessDecoder.java
rename to imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGLosslessDecoder.java
index 2fe8d16e..776c6aef 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/JPEGLosslessDecoder.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGLosslessDecoder.java
@@ -1,50 +1,51 @@
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
+ * Copyright (c) 2016, Harald Kuhr
+ * Copyright (C) 2015, Michael Martinez
+ * Copyright (C) 2004, Helmut Dersch
+ * All rights reserved.
*
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
+package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
+import com.twelvemonkeys.lang.Validate;
+import javax.imageio.IIOException;
import javax.imageio.stream.ImageInputStream;
import java.io.IOException;
+import java.util.List;
-public class JPEGLosslessDecoder {
+final class JPEGLosslessDecoder {
private final ImageInputStream input;
- // TODO: Merge these classes with similar classes from the main package
- // (FrameHeader == Frame, ComponentSpec == Frame.Component, ScanHeader == Scan etc)
- private final FrameHeader frame;
+ private final Frame frame;
private final HuffmanTable huffTable;
private final QuantizationTable quantTable;
- private final ScanHeader scan;
+ private Scan scan;
private final int HuffTab[][][] = new int[4][2][MAX_HUFFMAN_SUBTREE * 256];
private final int IDCT_Source[] = new int[64];
@@ -69,36 +70,65 @@ public class JPEGLosslessDecoder {
private int[] outputBlueData;
private static final int IDCT_P[] = {
- 0, 5, 40, 16, 45, 2, 7, 42, 21, 56, 8, 61, 18, 47, 1, 4, 41, 23, 58, 13, 32, 24, 37, 10, 63, 17, 44, 3, 6, 43, 20,
- 57, 15, 34, 29, 48, 53, 26, 39, 9, 60, 19, 46, 22, 59, 12, 33, 31, 50, 55, 25, 36, 11, 62, 14, 35, 28, 49, 52, 27, 38, 30, 51, 54
+ 0, 5, 40, 16, 45, 2, 7, 42,
+ 21, 56, 8, 61, 18, 47, 1, 4,
+ 41, 23, 58, 13, 32, 24, 37, 10,
+ 63, 17, 44, 3, 6, 43, 20, 57,
+ 15, 34, 29, 48, 53, 26, 39, 9,
+ 60, 19, 46, 22, 59, 12, 33, 31,
+ 50, 55, 25, 36, 11, 62, 14, 35,
+ 28, 49, 52, 27, 38, 30, 51, 54
};
private static final int TABLE[] = {
- 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53,
- 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63
+ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63
};
- public static final int RESTART_MARKER_BEGIN = 0xFFD0;
- public static final int RESTART_MARKER_END = 0xFFD7;
- public static final int MAX_HUFFMAN_SUBTREE = 50;
- public static final int MSB = 0x80000000;
+ private static final int RESTART_MARKER_BEGIN = 0xFFD0;
+ private static final int RESTART_MARKER_END = 0xFFD7;
+ private static final int MAX_HUFFMAN_SUBTREE = 50;
+ private static final int MSB = 0x80000000;
- public int getDimX() {
+ int getDimX() {
return xDim;
}
- public int getDimY() {
+ int getDimY() {
return yDim;
}
- public JPEGLosslessDecoder(final ImageInputStream data) {
+ JPEGLosslessDecoder(final List segments, final ImageInputStream data) {
+ Validate.notNull(segments);
+
+ frame = get(segments, Frame.class);
+ scan = get(segments, Scan.class);
+
+ QuantizationTable qt = get(segments, QuantizationTable.class);
+ quantTable = qt != null ? qt : new QuantizationTable(); // For lossless there are no DQTs
+ huffTable = get(segments, HuffmanTable.class); // For non-lossless there can be multiple of DHTs
+ RestartInterval dri = get(segments, RestartInterval.class);
+ restartInterval = dri != null ? dri.interval : 0;
+
input = data;
- frame = new FrameHeader();
- scan = new ScanHeader();
- quantTable = new QuantizationTable();
- huffTable = new HuffmanTable();
}
- public int[][] decode() throws IOException {
+ private T get(final List segments, final Class type) {
+ for (Segment segment : segments) {
+ if (type.isInstance(segment)) {
+ return type.cast(segment);
+ }
+ }
+
+ return null;
+ }
+
+ int[][] decode() throws IOException {
int current, scanNum = 0;
final int pred[] = new int[10];
int[][] outputRef;
@@ -108,108 +138,22 @@ public class JPEGLosslessDecoder {
current = input.readUnsignedShort();
if (current != JPEG.SOI) { // SOI
- throw new IOException("Not a JPEG file");
+ throw new IIOException("Not a JPEG file");
}
- // TODO: Why the two loops?!
+ huffTable.buildHuffTables(HuffTab);
+ quantTable.enhanceTables(TABLE);
current = input.readUnsignedShort();
- while (((current >> 4) != 0x0FFC) || (current == JPEG.DHT)) { // SOF 0~15
- switch (current) {
- case JPEG.DHT: // DHT
- huffTable.read(input, HuffTab);
- break;
- case JPEG.DAC: // DAC
- throw new IOException("Program doesn't support arithmetic coding.");
- case JPEG.DQT:
- quantTable.read(input, TABLE);
- break;
- case JPEG.DRI:
- restartInterval = readNumber();
- break;
- case JPEG.APP0:
- case JPEG.APP1:
- case JPEG.APP2:
- case JPEG.APP3:
- case JPEG.APP4:
- case JPEG.APP5:
- case JPEG.APP6:
- case JPEG.APP7:
- case JPEG.APP8:
- case JPEG.APP9:
- case JPEG.APP10:
- case JPEG.APP11:
- case JPEG.APP12:
- case JPEG.APP13:
- case JPEG.APP14:
- case JPEG.APP15:
- readApp();
- break;
- case JPEG.COM:
- readComment();
- break;
- default:
- if ((current >> 8) != 0xFF) {
- throw new IOException("JPEG Segment marker expected.");
- }
- }
-
- current = input.readUnsignedShort();
- }
-
- if ((current < 0xFFC0) || (current > 0xFFC7)) {
- throw new IOException("ERROR: could not handle arithmetic code!");
- }
-
- frame.read(input);
- current = input.readUnsignedShort();
-
do {
- while (current != 0x0FFDA) { //SOS
- switch (current) {
- case 0xFFC4: //DHT
- huffTable.read(input, HuffTab);
- break;
- case 0xFFCC: //DAC
- throw new IOException("Program doesn't support arithmetic coding. (format throw new IOException)");
- case 0xFFDB:
- quantTable.read(input, TABLE);
- break;
- case 0xFFDD:
- restartInterval = readNumber();
- break;
- case 0xFFE0:
- case 0xFFE1:
- case 0xFFE2:
- case 0xFFE3:
- case 0xFFE4:
- case 0xFFE5:
- case 0xFFE6:
- case 0xFFE7:
- case 0xFFE8:
- case 0xFFE9:
- case 0xFFEA:
- case 0xFFEB:
- case 0xFFEC:
- case 0xFFED:
- case 0xFFEE:
- case 0xFFEF:
- readApp();
- break;
- case 0xFFFE:
- readComment();
- break;
- default:
- if ((current >> 8) != 0xFF) {
- throw new IOException("ERROR: format throw new IOException! (Parser.decode)");
- }
- }
-
+ // Skip until first SOS
+ while (current != JPEG.SOS) {
+ input.skipBytes(input.readUnsignedShort() - 2);
current = input.readUnsignedShort();
}
- final int precision = frame.getPrecision();
+ int precision = frame.samplePrecision;
if (precision == 8) {
mask = 0xFF;
@@ -218,28 +162,29 @@ public class JPEGLosslessDecoder {
mask = 0xFFFF;
}
- final ComponentSpec[] components = frame.getComponents();
+ Frame.Component[] components = frame.components;
- readScan();
- numComp = scan.getNumComponents();
- selection = scan.getSelection();
+ scan = readScan();
+ numComp = scan.components.length;
+ selection = scan.spectralSelStart;
- final ScanComponent[] scanComps = scan.components;
+ final Scan.Component[] scanComps = scan.components;
final int[][] quantTables = quantTable.quantTables;
for (int i = 0; i < numComp; i++) {
- ComponentSpec component = getComponentSpec(components, scanComps[i].getScanCompSel());
- qTab[i] = quantTables[component.quantTableSel];
- nBlock[i] = component.vSamp * component.hSamp;
- dcTab[i] = HuffTab[scanComps[i].getDcTabSel()][0];
- acTab[i] = HuffTab[scanComps[i].getAcTabSel()][1];
+ Frame.Component component = getComponentSpec(components, scanComps[i].scanCompSel);
+ qTab[i] = quantTables[component.qtSel];
+ nBlock[i] = component.vSub * component.hSub;
+ dcTab[i] = HuffTab[scanComps[i].dcTabSel][0];
+ acTab[i] = HuffTab[scanComps[i].acTabSel][1];
}
- xDim = frame.getDimX();
- yDim = frame.getDimY();
+ xDim = frame.samplesPerLine;
+ yDim = frame.lines;
outputRef = new int[numComp][];
+ // TODO: Support 4 components (RGBA/YCCA/CMYK/YCCK), others?
if (numComp == 1) {
outputData = new int[xDim * yDim];
outputRef[0] = outputData;
@@ -314,8 +259,8 @@ public class JPEGLosslessDecoder {
return outputRef;
}
- private ComponentSpec getComponentSpec(ComponentSpec[] components, int sel) {
- for (ComponentSpec component : components) {
+ private Frame.Component getComponentSpec(Frame.Component[] components, int sel) {
+ for (Frame.Component component : components) {
if (component.id == sel) {
return component;
}
@@ -324,8 +269,9 @@ public class JPEGLosslessDecoder {
throw new IllegalArgumentException("No such component id: " + sel);
}
- private int readScan() throws IOException {
- return scan.read(input);
+ private Scan readScan() throws IOException {
+ int length = input.readUnsignedShort();
+ return Scan.read(input, length);
}
private int decode(final int prev[], final int temp[], final int index[]) throws IOException {
@@ -341,11 +287,11 @@ public class JPEGLosslessDecoder {
}
private int decodeSingle(final int prev[], final int temp[], final int index[]) throws IOException {
- // At the beginning of the first line and
- // at the beginning of each restart interval the prediction value of 2P – 1 is used, where P is the input precision.
+ // At the beginning of the first line and
+ // at the beginning of each restart interval the prediction value of 2P – 1 is used, where P is the input precision.
if (restarting) {
restarting = false;
- prev[0] = (1 << (frame.getPrecision() - 1));
+ prev[0] = (1 << (frame.samplePrecision - 1));
}
else {
switch (selection) {
@@ -554,7 +500,7 @@ public class JPEGLosslessDecoder {
index[0] += 8 - (code >> 8);
if (index[0] < 0) {
- throw new IOException("index=" + index[0] + " temp=" + temp[0] + " code=" + code + " in HuffmanValue()");
+ throw new IIOException("index=" + index[0] + " temp=" + temp[0] + " code=" + code + " in HuffmanValue()");
}
if (index[0] < markerIndex) {
@@ -566,7 +512,7 @@ public class JPEGLosslessDecoder {
return code & 0xFF;
}
- private int getn(final int[] PRED, final int n, final int temp[], final int index[]) throws IOException {
+ private int getn(final int[] pred, final int n, final int temp[], final int index[]) throws IOException {
int result;
final int one = 1;
final int n_one = -1;
@@ -578,7 +524,7 @@ public class JPEGLosslessDecoder {
}
if (n == 16) {
- if (PRED[0] >= 0) {
+ if (pred[0] >= 0) {
return -32768;
}
else {
@@ -659,7 +605,7 @@ public class JPEGLosslessDecoder {
return getPreviousY(data);
}
else {
- return (1 << (frame.getPrecision() - 1));
+ return (1 << (frame.samplePrecision - 1));
}
}
@@ -685,18 +631,18 @@ public class JPEGLosslessDecoder {
return (xLoc == (xDim - 1)) && (yLoc == (yDim - 1));
}
- private void output(final int PRED[]) {
+ private void output(final int pred[]) {
if (numComp == 1) {
- outputSingle(PRED);
+ outputSingle(pred);
}
else {
- outputRGB(PRED);
+ outputRGB(pred);
}
}
- private void outputSingle(final int PRED[]) {
+ private void outputSingle(final int pred[]) {
if ((xLoc < xDim) && (yLoc < yDim)) {
- outputData[(yLoc * xDim) + xLoc] = mask & PRED[0];
+ outputData[(yLoc * xDim) + xLoc] = mask & pred[0];
xLoc++;
if (xLoc >= xDim) {
@@ -706,11 +652,11 @@ public class JPEGLosslessDecoder {
}
}
- private void outputRGB(final int PRED[]) {
+ private void outputRGB(final int pred[]) {
if ((xLoc < xDim) && (yLoc < yDim)) {
- outputRedData[(yLoc * xDim) + xLoc] = PRED[0];
- outputGreenData[(yLoc * xDim) + xLoc] = PRED[1];
- outputBlueData[(yLoc * xDim) + xLoc] = PRED[2];
+ outputRedData[(yLoc * xDim) + xLoc] = pred[0];
+ outputGreenData[(yLoc * xDim) + xLoc] = pred[1];
+ outputBlueData[(yLoc * xDim) + xLoc] = pred[2];
xLoc++;
if (xLoc >= xDim) {
@@ -720,34 +666,6 @@ public class JPEGLosslessDecoder {
}
}
- private int readApp() throws IOException {
- int count = 0;
- final int length = input.readUnsignedShort();
- count += 2;
-
- while (count < length) {
- input.readUnsignedByte();
- count++;
- }
-
- return length;
- }
-
- private String readComment() throws IOException {
- final StringBuffer sb = new StringBuffer();
- int count = 0;
-
- final int length = input.readUnsignedShort();
- count += 2;
-
- while (count < length) {
- sb.append((char) input.readUnsignedByte());
- count++;
- }
-
- return sb.toString();
- }
-
private int readNumber() throws IOException {
final int Ld = input.readUnsignedShort();
@@ -758,11 +676,11 @@ public class JPEGLosslessDecoder {
return input.readUnsignedShort();
}
- public int getNumComponents() {
+ int getNumComponents() {
return numComp;
}
- public int getPrecision() {
- return frame.getPrecision();
+ int getPrecision() {
+ return frame.samplePrecision;
}
}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/JPEGLosslessDecoderWrapper.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGLosslessDecoderWrapper.java
similarity index 68%
rename from imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/JPEGLosslessDecoderWrapper.java
rename to imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGLosslessDecoderWrapper.java
index 2a554fdd..6fc0d9c8 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/JPEGLosslessDecoderWrapper.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGLosslessDecoderWrapper.java
@@ -1,4 +1,33 @@
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * Copyright (c) 2016, Herman Kroll
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.plugins.jpeg;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
@@ -6,6 +35,7 @@ import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferUShort;
import java.awt.image.Raster;
import java.io.IOException;
+import java.util.List;
/**
* This class provides the conversion of input data
@@ -22,7 +52,7 @@ import java.io.IOException;
*
* @author Hermann Kroll
*/
-public class JPEGLosslessDecoderWrapper {
+final class JPEGLosslessDecoderWrapper {
/**
* Decodes a JPEG Lossless stream to a {@code BufferedImage}.
@@ -31,17 +61,19 @@ public class JPEGLosslessDecoderWrapper {
* - 8Bit, Grayscale -> BufferedImage.TYPE_BYTE_GRAY
* - 16Bit, Grayscale -> BufferedImage.TYPE_USHORT_GRAY
*
+ * @param segments
* @param input input stream which contains a jpeg lossless data
* @return if successfully a BufferedImage is returned
* @throws IOException is thrown if the decoder failed or a conversion is not supported
*/
- public BufferedImage readImage(final ImageInputStream input) throws IOException {
- JPEGLosslessDecoder decoder = new JPEGLosslessDecoder(input);
+ BufferedImage readImage(final List segments, final ImageInputStream input) throws IOException {
+ JPEGLosslessDecoder decoder = new JPEGLosslessDecoder(segments, input);
int[][] decoded = decoder.decode();
int width = decoder.getDimX();
int height = decoder.getDimY();
+ // Single component, assumed to be Gray
if (decoder.getNumComponents() == 1) {
switch (decoder.getPrecision()) {
case 8:
@@ -52,7 +84,8 @@ public class JPEGLosslessDecoderWrapper {
throw new IOException("JPEG Lossless with " + decoder.getPrecision() + " bit precision and 1 component cannot be decoded");
}
}
- //rgb
+
+ // 3 components, assumed to be RGB
if (decoder.getNumComponents() == 3) {
switch (decoder.getPrecision()) {
case 8:
@@ -66,9 +99,9 @@ public class JPEGLosslessDecoderWrapper {
throw new IOException("JPEG Lossless with " + decoder.getPrecision() + " bit precision and " + decoder.getNumComponents() + " component(s) cannot be decoded");
}
- public Raster readRaster(final ImageInputStream input) throws IOException {
+ Raster readRaster(final List segments, final ImageInputStream input) throws IOException {
// TODO: Can perhaps be implemented faster
- return readImage(input).getRaster();
+ return readImage(segments, input).getRaster();
}
/**
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGProviderInfo.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGProviderInfo.java
index 2865efaf..b571071a 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGProviderInfo.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/JPEGProviderInfo.java
@@ -38,7 +38,7 @@ import com.twelvemonkeys.imageio.spi.ReaderWriterProviderInfo;
* @version $Id: JPEGProviderInfo.java,v 1.0 20/03/15 harald.kuhr Exp$
*/
final class JPEGProviderInfo extends ReaderWriterProviderInfo {
- protected JPEGProviderInfo() {
+ JPEGProviderInfo() {
super(
JPEGProviderInfo.class,
new String[] {"JPEG", "jpeg", "JPG", "jpg"},
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/QuantizationTable.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/QuantizationTable.java
index 2d3a53d5..6b3dacd9 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/QuantizationTable.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/QuantizationTable.java
@@ -1,38 +1,38 @@
/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
+ * Copyright (c) 2016, Harald Kuhr
+ * Copyright (C) 2015, Michael Martinez
+ * Copyright (C) 2004, Helmut Dersch
+ * All rights reserved.
*
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
-import javax.imageio.stream.ImageInputStream;
+import javax.imageio.IIOException;
import java.io.DataInput;
import java.io.IOException;
@@ -41,7 +41,7 @@ final class QuantizationTable extends Segment {
private final int precision[] = new int[4]; // Quantization precision 8 or 16
private final int[] tq = new int[4]; // 1: this table is presented
- protected final int quantTables[][] = new int[4][64]; // Tables
+ final int quantTables[][] = new int[4][64]; // Tables
QuantizationTable() {
super(JPEG.DQT);
@@ -53,7 +53,7 @@ final class QuantizationTable extends Segment {
}
// TODO: Get rid of table param, make it a member?
- protected void enhanceTables(final int[] table) throws IOException {
+ void enhanceTables(final int[] table) throws IOException {
for (int t = 0; t < 4; t++) {
if (tq[t] != 0) {
enhanceQuantizationTable(quantTables[t], table);
@@ -63,24 +63,24 @@ final class QuantizationTable extends Segment {
private void enhanceQuantizationTable(final int qtab[], final int[] table) {
for (int i = 0; i < 8; i++) {
- qtab[table[(0 * 8) + i]] *= 90;
- qtab[table[(4 * 8) + i]] *= 90;
+ qtab[table[ i]] *= 90;
+ qtab[table[(4 * 8) + i]] *= 90;
qtab[table[(2 * 8) + i]] *= 118;
- qtab[table[(6 * 8) + i]] *= 49;
- qtab[table[(5 * 8) + i]] *= 71;
- qtab[table[(1 * 8) + i]] *= 126;
- qtab[table[(7 * 8) + i]] *= 25;
+ qtab[table[(6 * 8) + i]] *= 49;
+ qtab[table[(5 * 8) + i]] *= 71;
+ qtab[table[( 8) + i]] *= 126;
+ qtab[table[(7 * 8) + i]] *= 25;
qtab[table[(3 * 8) + i]] *= 106;
}
for (int i = 0; i < 8; i++) {
- qtab[table[0 + (8 * i)]] *= 90;
- qtab[table[4 + (8 * i)]] *= 90;
+ qtab[table[( 8 * i)]] *= 90;
+ qtab[table[4 + (8 * i)]] *= 90;
qtab[table[2 + (8 * i)]] *= 118;
- qtab[table[6 + (8 * i)]] *= 49;
- qtab[table[5 + (8 * i)]] *= 71;
+ qtab[table[6 + (8 * i)]] *= 49;
+ qtab[table[5 + (8 * i)]] *= 71;
qtab[table[1 + (8 * i)]] *= 126;
- qtab[table[7 + (8 * i)]] *= 25;
+ qtab[table[7 + (8 * i)]] *= 25;
qtab[table[3 + (8 * i)]] *= 106;
}
@@ -89,8 +89,14 @@ final class QuantizationTable extends Segment {
}
}
+ @Override
+ public String toString() {
+ // TODO: Tables...
+ return "DQT[]";
+ }
+
public static QuantizationTable read(final DataInput data, final int length) throws IOException {
- int count = 0; // TODO: Could probably use data.getPosition for this
+ int count = 2;
QuantizationTable table = new QuantizationTable();
while (count < length) {
@@ -99,7 +105,7 @@ final class QuantizationTable extends Segment {
final int t = temp & 0x0F;
if (t > 3) {
- throw new IOException("ERROR: Quantization table ID > 3");
+ throw new IIOException("Unexpected JPEG Quantization Table Id (> 3): " + t);
}
table.precision[t] = temp >> 4;
@@ -111,7 +117,7 @@ final class QuantizationTable extends Segment {
table.precision[t] = 16;
}
else {
- throw new IOException("ERROR: Quantization table precision error");
+ throw new IIOException("Unexpected JPEG Quantization Table precision: " + table.precision[t]);
}
table.tq[t] = 1;
@@ -119,31 +125,27 @@ final class QuantizationTable extends Segment {
if (table.precision[t] == 8) {
for (int i = 0; i < 64; i++) {
if (count > length) {
- throw new IOException("ERROR: Quantization table format error");
+ throw new IIOException("JPEG Quantization Table format error");
}
table.quantTables[t][i] = data.readUnsignedByte();
count++;
}
-
-// table.enhanceQuantizationTable(table.quantTables[t], table);
}
else {
for (int i = 0; i < 64; i++) {
if (count > length) {
- throw new IOException("ERROR: Quantization table format error");
+ throw new IIOException("JPEG Quantization Table format error");
}
table.quantTables[t][i] = data.readUnsignedShort();
count += 2;
}
-
-// table.enhanceQuantizationTable(table.quantTables[t], table);
}
}
if (count != length) {
- throw new IOException("ERROR: Quantization table error [count!=Lq]");
+ throw new IIOException("JPEG Quantization Table error, bad segment length: " + length);
}
return table;
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/RestartInterval.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/RestartInterval.java
new file mode 100644
index 00000000..b4e73a2b
--- /dev/null
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/RestartInterval.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.twelvemonkeys.imageio.plugins.jpeg;
+
+import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
+
+import javax.imageio.IIOException;
+import java.io.DataInput;
+import java.io.IOException;
+
+/**
+ * RestartInterval.
+ *
+ * @author Harald Kuhr
+ * @author last modified by $Author: harald.kuhr$
+ * @version $Id: RestartInterval.java,v 1.0 24/08/16 harald.kuhr Exp$
+ */
+class RestartInterval extends Segment {
+ final int interval;
+
+ private RestartInterval(int interval) {
+ super(JPEG.DRI);
+ this.interval = interval;
+ }
+
+ @Override
+ public String toString() {
+ return "DRI[" + interval + "]";
+ }
+
+ public static RestartInterval read(final DataInput data, final int length) throws IOException {
+ if (length != 4) {
+ throw new IIOException("Unexpected length of DRI segment: " + length);
+ }
+
+ return new RestartInterval(data.readUnsignedShort());
+ }
+}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Scan.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Scan.java
index 5e3612e6..0de93192 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Scan.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Scan.java
@@ -38,28 +38,28 @@ import java.io.IOException;
import java.util.Arrays;
final class Scan extends Segment {
- final int selection; // Start of spectral or predictor selection
- final int spectralEnd; // End of spectral selection
- final int ah;
- final int al;
+ final int spectralSelStart; // Start of spectral or predictor selection
+ final int spectralSelEnd; // End of spectral selection
+ final int approxHigh;
+ final int approxLow;
final Component[] components;
- Scan(final Component[] components, final int selection, final int spectralEnd, final int ah, final int al) {
+ Scan(final Component[] components, final int spectralStart, final int spectralSelEnd, final int approxHigh, final int approxLow) {
super(JPEG.SOS);
this.components = components;
- this.selection = selection;
- this.spectralEnd = spectralEnd;
- this.ah = ah;
- this.al = al;
+ this.spectralSelStart = spectralStart;
+ this.spectralSelEnd = spectralSelEnd;
+ this.approxHigh = approxHigh;
+ this.approxLow = approxLow;
}
@Override
public String toString() {
return String.format(
- "SOS[selection: %d, spectralEnd: %d, ah: %d, al: %d, components: %s]",
- selection, spectralEnd, ah, al, Arrays.toString(components)
+ "SOS[spectralSelStart: %d, spectralSelEnd: %d, approxHigh: %d, approxLow: %d, components: %s]",
+ spectralSelStart, spectralSelEnd, approxHigh, approxLow, Arrays.toString(components)
);
}
@@ -93,7 +93,7 @@ final class Scan extends Segment {
return new Scan(components, selection, spectralEnd, temp >> 4, temp & 0x0F);
}
- final static class Component {
+ public final static class Component {
final int scanCompSel; // Scan component selector
final int acTabSel; // AC table selector
final int dcTabSel; // DC table selector
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Segment.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Segment.java
index bb57b22d..0a0d2b93 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Segment.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Segment.java
@@ -1,3 +1,31 @@
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
package com.twelvemonkeys.imageio.plugins.jpeg;
import com.twelvemonkeys.imageio.metadata.jpeg.JPEG;
@@ -20,15 +48,12 @@ abstract class Segment {
this.marker = Validate.isTrue(marker >> 8 == 0xFF, marker, "Unknown JPEG marker: 0x%04x");
}
- public static Segment read(int marker, String identifier, int length, DataInput data) throws IOException {
- // TODO: Fix length inconsistencies...
-// System.err.print("marker: " + marker);
-// System.err.println(" length: " + length);
+ static Segment read(int marker, String identifier, int length, DataInput data) throws IOException {
switch (marker) {
case JPEG.DHT:
return HuffmanTable.read(data, length);
case JPEG.DQT:
- return QuantizationTable.read(data, length - 2);
+ return QuantizationTable.read(data, length);
case JPEG.SOF0:
case JPEG.SOF1:
case JPEG.SOF2:
@@ -47,6 +72,9 @@ abstract class Segment {
return Scan.read(data, length);
case JPEG.COM:
return Comment.read(data, length);
+ // TODO: JPEG.DAC
+ case JPEG.DRI:
+ return RestartInterval.read(data, length);
case JPEG.APP0:
case JPEG.APP1:
case JPEG.APP2:
@@ -63,8 +91,7 @@ abstract class Segment {
case JPEG.APP13:
case JPEG.APP14:
case JPEG.APP15:
- return AppSegment.read(marker, identifier, data, length);
- // TODO: JPEG.DRI?
+ return Application.read(marker, identifier, data, length);
default:
return Unknown.read(marker, length, data);
}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Unknown.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Unknown.java
index 9c59e504..012eddfd 100644
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Unknown.java
+++ b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/Unknown.java
@@ -1,10 +1,38 @@
+/*
+ * Copyright (c) 2016, Harald Kuhr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name "TwelveMonkeys" nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
package com.twelvemonkeys.imageio.plugins.jpeg;
import java.io.DataInput;
import java.io.IOException;
/**
- * Unknown.
+ * Represents an unknown segment in the JPEG stream.
*
* @author Harald Kuhr
* @author last modified by $Author: harald.kuhr$
@@ -19,9 +47,15 @@ final class Unknown extends Segment {
this.data = data;
}
+ @Override
+ public String toString() {
+ return String.format("Unknown[%04x, length: %d]", marker, data.length);
+ }
+
public static Segment read(int marker, int length, DataInput data) throws IOException {
byte[] bytes = new byte[length - 2];
data.readFully(bytes);
+
return new Unknown(marker, bytes);
}
}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ComponentSpec.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ComponentSpec.java
deleted file mode 100644
index 3df58427..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ComponentSpec.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
- *
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
-public class ComponentSpec {
-
- protected int id;
- protected int hSamp; // Horizontal sampling factor
- protected int quantTableSel; // Quantization table destination selector
- protected int vSamp; // Vertical
-}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/FrameHeader.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/FrameHeader.java
deleted file mode 100644
index 2443426b..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/FrameHeader.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
- *
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
-import javax.imageio.stream.ImageInputStream;
-import java.io.IOException;
-
-public class FrameHeader {
-
- private ComponentSpec components[]; // Components
- private int dimX; // Number of samples per line
- private int dimY; // Number of lines
- private int numComp; // Number of component in the frame
- private int precision; // Sample Precision (from the original image)
-
- public ComponentSpec[] getComponents() {
- return components.clone();
- }
-
- public int getDimX() {
- return dimX;
- }
-
- public int getDimY() {
- return dimY;
- }
-
- public int getNumComponents() {
- return numComp;
- }
-
- public int getPrecision() {
- return precision;
- }
-
- protected int read(final ImageInputStream data) throws IOException {
- int count = 0;
-
- int length = data.readUnsignedShort();
- count += 2;
-
- precision = data.readUnsignedByte();
- count++;
-
- dimY = data.readUnsignedShort();
- count += 2;
-
- dimX = data.readUnsignedShort();
- count += 2;
-
- numComp = data.readUnsignedByte();
- count++;
-
- components = new ComponentSpec[numComp];
-
- for (int i = 0; i < numComp; i++) {
- if (count > length) {
- throw new IOException("ERROR: frame format error");
- }
-
- int cid = data.readUnsignedByte();
- count++;
-
- if (count >= length) {
- throw new IOException("ERROR: frame format error [c>=Lf]");
- }
-
- int temp = data.readUnsignedByte();
- count++;
-
- if (components[i] == null) {
- components[i] = new ComponentSpec();
- }
-
- components[i].id = cid;
- components[i].hSamp = temp >> 4;
- components[i].vSamp = temp & 0x0F;
- components[i].quantTableSel = data.readUnsignedByte();
- count++;
- }
-
- if (count != length) {
- throw new IOException("ERROR: frame format error [Lf!=count]");
- }
-
- return 1;
- }
-}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/HuffmanTable.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/HuffmanTable.java
deleted file mode 100644
index e6517403..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/HuffmanTable.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
- *
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
-import javax.imageio.stream.ImageInputStream;
-import java.io.IOException;
-
-public class HuffmanTable {
-
- private final int l[][][] = new int[4][2][16];
- private final int th[] = new int[4]; // 1: this table is presented
- private final int v[][][][] = new int[4][2][16][200]; // tables
- private final int[][] tc = new int[4][2]; // 1: this table is presented
-
- public static final int MSB = 0x80000000;
-
- public HuffmanTable() {
- tc[0][0] = 0;
- tc[1][0] = 0;
- tc[2][0] = 0;
- tc[3][0] = 0;
- tc[0][1] = 0;
- tc[1][1] = 0;
- tc[2][1] = 0;
- tc[3][1] = 0;
- th[0] = 0;
- th[1] = 0;
- th[2] = 0;
- th[3] = 0;
- }
-
- protected int read(final ImageInputStream data, final int[][][] HuffTab) throws IOException {
- int count = 0;
- final int length = data.readUnsignedShort();
- count += 2;
-
- while (count < length) {
- final int temp = data.readUnsignedByte();
- count++;
- final int t = temp & 0x0F;
- if (t > 3) {
- throw new IOException("ERROR: Huffman table ID > 3");
- }
-
- final int c = temp >> 4;
- if (c > 2) {
- throw new IOException("ERROR: Huffman table [Table class > 2 ]");
- }
-
- th[t] = 1;
- tc[t][c] = 1;
-
- for (int i = 0; i < 16; i++) {
- l[t][c][i] = data.readUnsignedByte();
- count++;
- }
-
- for (int i = 0; i < 16; i++) {
- for (int j = 0; j < l[t][c][i]; j++) {
- if (count > length) {
- throw new IOException("ERROR: Huffman table format error [count>Lh]");
- }
- v[t][c][i][j] = data.readUnsignedByte();
- count++;
- }
- }
- }
-
- if (count != length) {
- throw new IOException("ERROR: Huffman table format error [count!=Lf]");
- }
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 2; j++) {
- if (tc[i][j] != 0) {
- buildHuffTable(HuffTab[i][j], l[i][j], v[i][j]);
- }
- }
- }
-
- return 1;
- }
-
- // Build_HuffTab()
- // Parameter: t table ID
- // c table class ( 0 for DC, 1 for AC )
- // L[i] # of codewords which length is i
- // V[i][j] Huffman Value (length=i)
- // Effect:
- // build up HuffTab[t][c] using L and V.
- private void buildHuffTable(final int tab[], final int L[], final int V[][]) throws IOException {
- int currentTable, temp;
- int k;
- temp = 256;
- k = 0;
-
- for (int i = 0; i < 8; i++) { // i+1 is Code length
- for (int j = 0; j < L[i]; j++) {
- for (int n = 0; n < (temp >> (i + 1)); n++) {
- tab[k] = V[i][j] | ((i + 1) << 8);
- k++;
- }
- }
- }
-
- for (int i = 1; k < 256; i++, k++) {
- tab[k] = i | MSB;
- }
-
- currentTable = 1;
- k = 0;
-
- for (int i = 8; i < 16; i++) { // i+1 is Code length
- for (int j = 0; j < L[i]; j++) {
- for (int n = 0; n < (temp >> (i - 7)); n++) {
- tab[(currentTable * 256) + k] = V[i][j] | ((i + 1) << 8);
- k++;
- }
- if (k >= 256) {
- if (k > 256) {
- throw new IOException("ERROR: Huffman table error(1)!");
- }
- k = 0;
- currentTable++;
- }
- }
- }
- }
-}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/QuantizationTable.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/QuantizationTable.java
deleted file mode 100644
index dbad4683..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/QuantizationTable.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
- *
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
-import javax.imageio.stream.ImageInputStream;
-import java.io.IOException;
-
-public class QuantizationTable {
-
- private final int precision[] = new int[4]; // Quantization precision 8 or 16
- private final int[] tq = new int[4]; // 1: this table is presented
-
- protected final int quantTables[][] = new int[4][64]; // Tables
-
- public QuantizationTable() {
- tq[0] = 0;
- tq[1] = 0;
- tq[2] = 0;
- tq[3] = 0;
- }
-
- protected int read(final ImageInputStream data, final int[] table) throws IOException {
- int count = 0;
- final int length = data.readUnsignedShort();
- count += 2;
-
- while (count < length) {
- final int temp = data.readUnsignedByte();
- count++;
- final int t = temp & 0x0F;
-
- if (t > 3) {
- throw new IOException("ERROR: Quantization table ID > 3");
- }
-
- precision[t] = temp >> 4;
-
- if (precision[t] == 0) {
- precision[t] = 8;
- }
- else if (precision[t] == 1) {
- precision[t] = 16;
- }
- else {
- throw new IOException("ERROR: Quantization table precision error");
- }
-
- tq[t] = 1;
-
- if (precision[t] == 8) {
- for (int i = 0; i < 64; i++) {
- if (count > length) {
- throw new IOException("ERROR: Quantization table format error");
- }
-
- quantTables[t][i] = data.readUnsignedByte();
- count++;
- }
-
- enhanceQuantizationTable(quantTables[t], table);
- }
- else {
- for (int i = 0; i < 64; i++) {
- if (count > length) {
- throw new IOException("ERROR: Quantization table format error");
- }
-
- quantTables[t][i] = data.readUnsignedShort();
- count += 2;
- }
-
- enhanceQuantizationTable(quantTables[t], table);
- }
- }
-
- if (count != length) {
- throw new IOException("ERROR: Quantization table error [count!=Lq]");
- }
-
- return 1;
- }
-
- private void enhanceQuantizationTable(final int qtab[], final int[] table) {
- for (int i = 0; i < 8; i++) {
- qtab[table[(0 * 8) + i]] *= 90;
- qtab[table[(4 * 8) + i]] *= 90;
- qtab[table[(2 * 8) + i]] *= 118;
- qtab[table[(6 * 8) + i]] *= 49;
- qtab[table[(5 * 8) + i]] *= 71;
- qtab[table[(1 * 8) + i]] *= 126;
- qtab[table[(7 * 8) + i]] *= 25;
- qtab[table[(3 * 8) + i]] *= 106;
- }
-
- for (int i = 0; i < 8; i++) {
- qtab[table[0 + (8 * i)]] *= 90;
- qtab[table[4 + (8 * i)]] *= 90;
- qtab[table[2 + (8 * i)]] *= 118;
- qtab[table[6 + (8 * i)]] *= 49;
- qtab[table[5 + (8 * i)]] *= 71;
- qtab[table[1 + (8 * i)]] *= 126;
- qtab[table[7 + (8 * i)]] *= 25;
- qtab[table[3 + (8 * i)]] *= 106;
- }
-
- for (int i = 0; i < 64; i++) {
- qtab[i] >>= 6;
- }
- }
-}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ScanComponent.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ScanComponent.java
deleted file mode 100644
index 94fc6cf9..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ScanComponent.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
- *
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
-public class ScanComponent {
-
- private int acTabSel; // AC table selector
- private int dcTabSel; // DC table selector
- private int scanCompSel; // Scan component selector
-
- public int getAcTabSel() {
- return acTabSel;
- }
-
- public int getDcTabSel() {
- return dcTabSel;
- }
-
- public int getScanCompSel() {
- return scanCompSel;
- }
-
- public void setAcTabSel(final int acTabSel) {
- this.acTabSel = acTabSel;
- }
-
- public void setDcTabSel(final int dcTabSel) {
- this.dcTabSel = dcTabSel;
- }
-
- public void setScanCompSel(final int scanCompSel) {
- this.scanCompSel = scanCompSel;
- }
-}
diff --git a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ScanHeader.java b/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ScanHeader.java
deleted file mode 100644
index be52e20b..00000000
--- a/imageio/imageio-jpeg/src/main/java/com/twelvemonkeys/imageio/plugins/jpeg/lossless/ScanHeader.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2015 Michael Martinez
- * Changes: Added support for selection values 2-7, fixed minor bugs &
- * warnings, split into multiple class files, and general clean up.
- *
- * 08-25-2015: Helmut Dersch agreed to a license change from LGPL to MIT.
- */
-
-/*
- * Copyright (C) Helmut Dersch
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
-
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-package com.twelvemonkeys.imageio.plugins.jpeg.lossless;
-
-import javax.imageio.stream.ImageInputStream;
-import java.io.IOException;
-
-public class ScanHeader {
-
- private int ah;
- private int al;
- private int numComp; // Number of components in the scan
- private int selection; // Start of spectral or predictor selection
- private int spectralEnd; // End of spectral selection
-
- protected ScanComponent components[];
-
- public int getAh() {
- return ah;
- }
-
- public int getAl() {
- return al;
- }
-
- public int getNumComponents() {
- return numComp;
- }
-
- public int getSelection() {
- return selection;
- }
-
- public int getSpectralEnd() {
- return spectralEnd;
- }
-
- public void setAh(final int ah) {
- this.ah = ah;
- }
-
- public void setAl(final int al) {
- this.al = al;
- }
-
- public void setSelection(final int selection) {
- this.selection = selection;
- }
-
- public void setSpectralEnd(final int spectralEnd) {
- this.spectralEnd = spectralEnd;
- }
-
- protected int read(final ImageInputStream data) throws IOException {
- int count = 0;
- final int length = data.readUnsignedShort();
- count += 2;
-
- numComp = data.readUnsignedByte();
- count++;
-
- components = new ScanComponent[numComp];
-
- for (int i = 0; i < numComp; i++) {
- components[i] = new ScanComponent();
-
- if (count > length) {
- throw new IOException("ERROR: scan header format error");
- }
-
- components[i].setScanCompSel(data.readUnsignedByte());
- count++;
-
- final int temp = data.readUnsignedByte();
- count++;
-
- components[i].setDcTabSel(temp >> 4);
- components[i].setAcTabSel(temp & 0x0F);
- }
-
- setSelection(data.readUnsignedByte());
- count++;
-
- setSpectralEnd(data.readUnsignedByte());
- count++;
-
- final int temp = data.readUnsignedByte();
- setAh(temp >> 4);
- setAl(temp & 0x0F);
- count++;
-
- if (count != length) {
- throw new IOException("ERROR: scan header format error [count!=Ns]");
- }
-
- return 1;
- }
-}