mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-22 00:00:03 -04:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 26d3de45a7 | |||
| 13507ce303 | |||
| a8508dc234 | |||
| b3cf467f0b | |||
| b0e6fbed9f | |||
| c087addb76 | |||
| 250c58cc2e | |||
| c33b3a76f4 | |||
| f14e6823bd | |||
| cae72336a2 |
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys</groupId>
|
<groupId>com.twelvemonkeys</groupId>
|
||||||
<artifactId>twelvemonkeys</artifactId>
|
<artifactId>twelvemonkeys</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.twelvemonkeys.bom</groupId>
|
<groupId>com.twelvemonkeys.bom</groupId>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.common</groupId>
|
<groupId>com.twelvemonkeys.common</groupId>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>common-image</artifactId>
|
<artifactId>common-image</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.common</groupId>
|
<groupId>com.twelvemonkeys.common</groupId>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>common-io</artifactId>
|
<artifactId>common-io</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.common</groupId>
|
<groupId>com.twelvemonkeys.common</groupId>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>common-lang</artifactId>
|
<artifactId>common-lang</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys</groupId>
|
<groupId>com.twelvemonkeys</groupId>
|
||||||
<artifactId>twelvemonkeys</artifactId>
|
<artifactId>twelvemonkeys</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.twelvemonkeys.common</groupId>
|
<groupId>com.twelvemonkeys.common</groupId>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys</groupId>
|
<groupId>com.twelvemonkeys</groupId>
|
||||||
<artifactId>twelvemonkeys</artifactId>
|
<artifactId>twelvemonkeys</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.twelvemonkeys.contrib</groupId>
|
<groupId>com.twelvemonkeys.contrib</groupId>
|
||||||
<artifactId>contrib</artifactId>
|
<artifactId>contrib</artifactId>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-batik</artifactId>
|
<artifactId>imageio-batik</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: Batik Plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: Batik Plugin</name>
|
||||||
|
|||||||
+10
-1
@@ -46,6 +46,7 @@ import org.apache.batik.gvt.renderer.ImageRendererFactory;
|
|||||||
import org.apache.batik.transcoder.*;
|
import org.apache.batik.transcoder.*;
|
||||||
import org.apache.batik.transcoder.image.ImageTranscoder;
|
import org.apache.batik.transcoder.image.ImageTranscoder;
|
||||||
import org.apache.batik.util.ParsedURL;
|
import org.apache.batik.util.ParsedURL;
|
||||||
|
import org.apache.batik.util.SVGConstants;
|
||||||
import org.w3c.dom.DOMImplementation;
|
import org.w3c.dom.DOMImplementation;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.svg.SVGSVGElement;
|
import org.w3c.dom.svg.SVGSVGElement;
|
||||||
@@ -326,7 +327,7 @@ public class SVGImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
// get the 'width' and 'height' attributes of the SVG document
|
// get the 'width' and 'height' attributes of the SVG document
|
||||||
Dimension2D docSize = ctx.getDocumentSize();
|
Dimension2D docSize = ctx.getDocumentSize();
|
||||||
if (docSize != null) {
|
if (docSize != null) {
|
||||||
defaultWidth = (float) docSize.getWidth();
|
defaultWidth = (float) docSize.getWidth();
|
||||||
defaultHeight = (float) docSize.getHeight();
|
defaultHeight = (float) docSize.getHeight();
|
||||||
}
|
}
|
||||||
@@ -334,6 +335,14 @@ public class SVGImageReader extends ImageReaderBase {
|
|||||||
defaultWidth = 200;
|
defaultWidth = 200;
|
||||||
defaultHeight = 200;
|
defaultHeight = 200;
|
||||||
}
|
}
|
||||||
|
SVGSVGElement rootElement = svgDoc.getRootElement();
|
||||||
|
String viewBoxStr = rootElement.getAttributeNS
|
||||||
|
(null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE);
|
||||||
|
if (viewBoxStr.length() != 0) {
|
||||||
|
float[] rect = ViewBox.parseViewBoxAttribute(rootElement, viewBoxStr, null);
|
||||||
|
defaultWidth = rect[2];
|
||||||
|
defaultHeight = rect[3];
|
||||||
|
}
|
||||||
|
|
||||||
// Hack to work around exception above
|
// Hack to work around exception above
|
||||||
if (root != null) {
|
if (root != null) {
|
||||||
|
|||||||
+56
-1
@@ -35,6 +35,7 @@ import org.junit.Ignore;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import javax.imageio.IIOException;
|
import javax.imageio.IIOException;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import javax.imageio.ImageReadParam;
|
import javax.imageio.ImageReadParam;
|
||||||
import javax.imageio.ImageReader;
|
import javax.imageio.ImageReader;
|
||||||
import javax.imageio.event.IIOReadWarningListener;
|
import javax.imageio.event.IIOReadWarningListener;
|
||||||
@@ -43,9 +44,12 @@ import javax.imageio.stream.ImageInputStream;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.ImagingOpException;
|
import java.awt.image.ImagingOpException;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.Buffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -70,7 +74,7 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
|||||||
new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500)),
|
new TestData(getClassLoaderResource("/svg/batikLogo.svg"), new Dimension(450, 500)),
|
||||||
new TestData(getClassLoaderResource("/svg/red-square.svg"), new Dimension(100, 100)),
|
new TestData(getClassLoaderResource("/svg/red-square.svg"), new Dimension(100, 100)),
|
||||||
new TestData(getClassLoaderResource("/svg/blue-square.svg"), new Dimension(100, 100)),
|
new TestData(getClassLoaderResource("/svg/blue-square.svg"), new Dimension(100, 100)),
|
||||||
new TestData(getClassLoaderResource("/svg/Android_robot.svg"), new Dimension(400, 400))
|
new TestData(getClassLoaderResource("/svg/Android_robot.svg"), new Dimension(294, 345))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +103,57 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
|||||||
return Collections.singletonList("image/svg+xml");
|
return Collections.singletonList("image/svg+xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScaleViewBox() throws IOException {
|
||||||
|
URL svgUrl = getClassLoaderResource("/svg/quadrants.svg");
|
||||||
|
|
||||||
|
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
|
||||||
|
|
||||||
|
SVGImageReader reader = createReader();
|
||||||
|
SVGReadParam param = new SVGReadParam();
|
||||||
|
|
||||||
|
int[] sizes = new int[]{16, 32, 64, 128};
|
||||||
|
for (int size : sizes) {
|
||||||
|
try (InputStream svgStream = svgUrl.openStream(); ImageInputStream iis = ImageIO.createImageInputStream(svgStream)) {
|
||||||
|
reader.reset();
|
||||||
|
reader.setInput(iis);
|
||||||
|
|
||||||
|
|
||||||
|
param.setSourceRenderSize(new Dimension(size, size));
|
||||||
|
BufferedImage image = reader.read(0, param);
|
||||||
|
checkQuadrantColors(image);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
reader.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkQuadrantColors(BufferedImage image) {
|
||||||
|
int quadPoint = image.getWidth() / 2;
|
||||||
|
for (int x = 0; x < image.getWidth(); x++) {
|
||||||
|
for (int y = 0; y < image.getHeight(); y++) {
|
||||||
|
int current = image.getRGB(x, y);
|
||||||
|
if (x < quadPoint) {
|
||||||
|
if (y < quadPoint) {
|
||||||
|
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF0000FF, current);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFFFF0000, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (y < quadPoint) {
|
||||||
|
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF00FF00, current);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF000000, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Override
|
@Override
|
||||||
public void testReadWithSizeParam() {
|
public void testReadWithSizeParam() {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" id="blue-square" version="1.1">
|
||||||
|
<g id="layer1">
|
||||||
|
<rect id="rect2985" width="50" height="50" x="0" y="0"
|
||||||
|
style="color:#000000;fill:#0000ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect id="rect2986" width="50" height="50" x="50" y="0"
|
||||||
|
style="color:#000000;fill:#00ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect id="rect2987" width="50" height="50" x="0" y="50"
|
||||||
|
style="color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
<rect id="rect2988" width="50" height="50" x="50" y="50"
|
||||||
|
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-bmp</artifactId>
|
<artifactId>imageio-bmp</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: BMP plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: BMP plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-clippath</artifactId>
|
<artifactId>imageio-clippath</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: Photoshop Path Support</name>
|
<name>TwelveMonkeys :: ImageIO :: Photoshop Path Support</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-core</artifactId>
|
<artifactId>imageio-core</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: Core</name>
|
<name>TwelveMonkeys :: ImageIO :: Core</name>
|
||||||
|
|||||||
Executable → Regular
+80
-7
@@ -31,6 +31,7 @@
|
|||||||
package com.twelvemonkeys.imageio.util;
|
package com.twelvemonkeys.imageio.util;
|
||||||
|
|
||||||
import com.twelvemonkeys.image.ImageUtil;
|
import com.twelvemonkeys.image.ImageUtil;
|
||||||
|
import com.twelvemonkeys.lang.Validate;
|
||||||
|
|
||||||
import javax.imageio.IIOParam;
|
import javax.imageio.IIOParam;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@@ -148,10 +149,9 @@ public final class IIOUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSourceRegion != null) {
|
if (pSourceRegion != null
|
||||||
if (pSourceRegion.x != 0 || pSourceRegion.y != 0 || pSourceRegion.width != pImage.getWidth() || pSourceRegion.height != pImage.getHeight()) {
|
&& (pSourceRegion.x != 0 || pSourceRegion.y != 0 || pSourceRegion.width != pImage.getWidth() || pSourceRegion.height != pImage.getHeight())) {
|
||||||
return pImage.getSubimage(pSourceRegion.x, pSourceRegion.y, pSourceRegion.width, pSourceRegion.height);
|
return pImage.getSubimage(pSourceRegion.x, pSourceRegion.y, pSourceRegion.width, pSourceRegion.height);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pImage;
|
return pImage;
|
||||||
@@ -192,7 +192,7 @@ public final class IIOUtil {
|
|||||||
* The names are all upper-case, and contains no duplicates.
|
* The names are all upper-case, and contains no duplicates.
|
||||||
*
|
*
|
||||||
* @return a normalized array of {@code String}s.
|
* @return a normalized array of {@code String}s.
|
||||||
* @see javax.imageio.ImageIO#getReaderFormatNames()
|
* @see ImageIO#getReaderFormatNames()
|
||||||
*/
|
*/
|
||||||
public static String[] getNormalizedReaderFormatNames() {
|
public static String[] getNormalizedReaderFormatNames() {
|
||||||
return normalizeNames(ImageIO.getReaderFormatNames());
|
return normalizeNames(ImageIO.getReaderFormatNames());
|
||||||
@@ -203,7 +203,7 @@ public final class IIOUtil {
|
|||||||
* The names are all upper-case, and contains no duplicates.
|
* The names are all upper-case, and contains no duplicates.
|
||||||
*
|
*
|
||||||
* @return a normalized array of {@code String}s.
|
* @return a normalized array of {@code String}s.
|
||||||
* @see javax.imageio.ImageIO#getWriterFormatNames()
|
* @see ImageIO#getWriterFormatNames()
|
||||||
*/
|
*/
|
||||||
public static String[] getNormalizedWriterFormatNames() {
|
public static String[] getNormalizedWriterFormatNames() {
|
||||||
return normalizeNames(ImageIO.getWriterFormatNames());
|
return normalizeNames(ImageIO.getWriterFormatNames());
|
||||||
@@ -216,6 +216,79 @@ public final class IIOUtil {
|
|||||||
normalizedNames.add(name.toUpperCase());
|
normalizedNames.add(name.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
return normalizedNames.toArray(new String[normalizedNames.size()]);
|
return normalizedNames.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: RasterUtils? Subsampler?
|
||||||
|
public static void subsampleRow(byte[] srcRow, int srcPos, int srcWidth,
|
||||||
|
byte[] destRow, int destPos,
|
||||||
|
int samplesPerPixel, int bitsPerSample, int samplePeriod) {
|
||||||
|
Validate.isTrue(samplePeriod > 1, "samplePeriod must be > 1"); // Period == 1 could be a no-op...
|
||||||
|
Validate.isTrue(bitsPerSample > 0 && bitsPerSample <= 8 && (bitsPerSample == 1 || bitsPerSample % 2 == 0),
|
||||||
|
"bitsPerSample must be > 0 and <= 8 and a power of 2");
|
||||||
|
Validate.isTrue(samplesPerPixel > 0, "samplesPerPixel must be > 0");
|
||||||
|
Validate.isTrue(samplesPerPixel * bitsPerSample <= 8 || samplesPerPixel * bitsPerSample % 8 == 0,
|
||||||
|
"samplesPerPixel * bitsPerSample must be < 8 or a multiple of 8 ");
|
||||||
|
|
||||||
|
if (bitsPerSample * samplesPerPixel % 8 == 0) {
|
||||||
|
int pixelStride = bitsPerSample * samplesPerPixel / 8;
|
||||||
|
for (int x = 0; x < srcWidth * pixelStride; x += samplePeriod * pixelStride) {
|
||||||
|
// System.arraycopy should be intrinsic, but consider using direct array access for pixelStride == 1
|
||||||
|
System.arraycopy(srcRow, srcPos + x, destRow, destPos + x / samplePeriod, pixelStride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Start bit fiddling...
|
||||||
|
int pixelStride = bitsPerSample * samplesPerPixel;
|
||||||
|
int mask = (1 << pixelStride) - 1;
|
||||||
|
|
||||||
|
for (int x = 0; x < srcWidth; x += samplePeriod) {
|
||||||
|
int dstOff = (destPos + x / samplePeriod) * pixelStride / 8;
|
||||||
|
int srcOff = (srcPos + x) * pixelStride / 8;
|
||||||
|
|
||||||
|
int srcBitPos = 8 - pixelStride - (x * pixelStride) % 8;
|
||||||
|
int srcMask = mask << srcBitPos;
|
||||||
|
|
||||||
|
int dstBitPos = 8 - pixelStride - (x * pixelStride / samplePeriod) % 8;
|
||||||
|
int dstMask = ~(mask << dstBitPos);
|
||||||
|
|
||||||
|
int val = ((srcRow[srcOff] & srcMask) >> srcBitPos);
|
||||||
|
destRow[dstOff] = (byte) ((destRow[dstOff] & dstMask) | val << dstBitPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void subsampleRow(short[] srcRow, int srcPos, int srcWidth,
|
||||||
|
short[] destRow, int destPos,
|
||||||
|
int samplesPerPixel, int bitsPerSample, int samplePeriod) {
|
||||||
|
Validate.isTrue(samplePeriod > 1, "samplePeriod must be > 1"); // Period == 1 could be a no-op...
|
||||||
|
Validate.isTrue(bitsPerSample > 0 && bitsPerSample <= 16 && (bitsPerSample == 1 || bitsPerSample % 2 == 0),
|
||||||
|
"bitsPerSample must be > 0 and <= 16 and a power of 2");
|
||||||
|
Validate.isTrue(samplesPerPixel > 0, "samplesPerPixel must be > 0");
|
||||||
|
Validate.isTrue(samplesPerPixel * bitsPerSample <= 16 || samplesPerPixel * bitsPerSample % 16 == 0,
|
||||||
|
"samplesPerPixel * bitsPerSample must be < 16 or a multiple of 16 ");
|
||||||
|
|
||||||
|
int pixelStride = bitsPerSample * samplesPerPixel / 16;
|
||||||
|
for (int x = 0; x < srcWidth * pixelStride; x += samplePeriod * pixelStride) {
|
||||||
|
// System.arraycopy should be intrinsic, but consider using direct array access for pixelStride == 1
|
||||||
|
System.arraycopy(srcRow, srcPos + x, destRow, destPos + x / samplePeriod, pixelStride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void subsampleRow(int[] srcRow, int srcPos, int srcWidth,
|
||||||
|
int[] destRow, int destPos,
|
||||||
|
int samplesPerPixel, int bitsPerSample, int samplePeriod) {
|
||||||
|
Validate.isTrue(samplePeriod > 1, "samplePeriod must be > 1"); // Period == 1 could be a no-op...
|
||||||
|
Validate.isTrue(bitsPerSample > 0 && bitsPerSample <= 32 && (bitsPerSample == 1 || bitsPerSample % 2 == 0),
|
||||||
|
"bitsPerSample must be > 0 and <= 32 and a power of 2");
|
||||||
|
Validate.isTrue(samplesPerPixel > 0, "samplesPerPixel must be > 0");
|
||||||
|
Validate.isTrue(samplesPerPixel * bitsPerSample <= 32 || samplesPerPixel * bitsPerSample % 32 == 0,
|
||||||
|
"samplesPerPixel * bitsPerSample must be < 32 or a multiple of 32 ");
|
||||||
|
|
||||||
|
int pixelStride = bitsPerSample * samplesPerPixel / 32;
|
||||||
|
for (int x = 0; x < srcWidth * pixelStride; x += samplePeriod * pixelStride) {
|
||||||
|
// System.arraycopy should be intrinsic, but consider using direct array access for pixelStride == 1
|
||||||
|
System.arraycopy(srcRow, srcPos + x, destRow, destPos + x / samplePeriod, pixelStride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+29
-7
@@ -54,6 +54,28 @@ public final class ImageTypeSpecifiers {
|
|||||||
private ImageTypeSpecifiers() {}
|
private ImageTypeSpecifiers() {}
|
||||||
|
|
||||||
public static ImageTypeSpecifier createFromBufferedImageType(final int bufferedImageType) {
|
public static ImageTypeSpecifier createFromBufferedImageType(final int bufferedImageType) {
|
||||||
|
switch (bufferedImageType) {
|
||||||
|
// ImageTypeSpecifier unconditionally uses bits == 32, we'll use a workaround for the USHORT types
|
||||||
|
case BufferedImage.TYPE_USHORT_565_RGB:
|
||||||
|
return createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||||
|
0xF800,
|
||||||
|
0x07E0,
|
||||||
|
0x001F,
|
||||||
|
0x0,
|
||||||
|
DataBuffer.TYPE_USHORT,
|
||||||
|
false);
|
||||||
|
|
||||||
|
case BufferedImage.TYPE_USHORT_555_RGB:
|
||||||
|
return createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||||
|
0x7C00,
|
||||||
|
0x03E0,
|
||||||
|
0x001F,
|
||||||
|
0x0,
|
||||||
|
DataBuffer.TYPE_USHORT,
|
||||||
|
false);
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
return ImageTypeSpecifier.createFromBufferedImageType(bufferedImageType);
|
return ImageTypeSpecifier.createFromBufferedImageType(bufferedImageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,21 +169,21 @@ public final class ImageTypeSpecifiers {
|
|||||||
|
|
||||||
int numEntries = 1 << bits;
|
int numEntries = 1 << bits;
|
||||||
|
|
||||||
byte[] arr = new byte[numEntries];
|
byte[] r = new byte[numEntries];
|
||||||
byte[] arg = new byte[numEntries];
|
byte[] g = new byte[numEntries];
|
||||||
byte[] arb = new byte[numEntries];
|
byte[] b = new byte[numEntries];
|
||||||
|
|
||||||
// Scale array values according to color profile..
|
// Scale array values according to color profile..
|
||||||
for (int i = 0; i < numEntries; i++) {
|
for (int i = 0; i < numEntries; i++) {
|
||||||
float[] gray = new float[]{i / (float) (numEntries - 1)};
|
float[] gray = new float[]{i / (float) (numEntries - 1)};
|
||||||
float[] rgb = colorSpace.toRGB(gray);
|
float[] rgb = colorSpace.toRGB(gray);
|
||||||
|
|
||||||
arr[i] = (byte) (rgb[0] * 255);
|
r[i] = (byte) (rgb[0] * 255);
|
||||||
arg[i] = (byte) (rgb[1] * 255);
|
g[i] = (byte) (rgb[1] * 255);
|
||||||
arb[i] = (byte) (rgb[2]* 255);
|
b[i] = (byte) (rgb[2] * 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorModel colorModel = new IndexColorModel(bits, numEntries, arr, arg, arb);
|
ColorModel colorModel = new IndexColorModel(bits, numEntries, r, g, b);
|
||||||
SampleModel sampleModel = new MultiPixelPackedSampleModel(dataType, 1, 1, bits);
|
SampleModel sampleModel = new MultiPixelPackedSampleModel(dataType, 1, 1, bits);
|
||||||
|
|
||||||
return new ImageTypeSpecifier(colorModel, sampleModel);
|
return new ImageTypeSpecifier(colorModel, sampleModel);
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
package com.twelvemonkeys.imageio.util;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IIOUtilTest
|
||||||
|
*/
|
||||||
|
public class IIOUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2Byte() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {-1, 0, (byte) 0xAA, 0, -1};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {-1, (byte) 0xAA, -1};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length, output, 0, 1, 8, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2ByteStride3() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {-1, -1, -1, 0, 0, 0, (byte) 0xAA, (byte) 0xAA, (byte) 0xAA, 0, 0, 0, -1, -1, -1};
|
||||||
|
byte[] output = new byte[9];
|
||||||
|
byte[] expected = {-1, -1, -1, (byte) 0xAA, (byte) 0xAA, (byte) 0xAA, -1, -1, -1};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length / 3, output, 0, 3, 8, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2Byte1() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0xaa, (byte) 0xaa, (byte) 0xaa};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff, (byte) 0xf0};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length * 8, output, 0, 1, 1, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod3_1Bit() {
|
||||||
|
int period = 3;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0x92, (byte) 0x49, (byte) 0x24};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length * 8, output, 0, 1, 1, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2_2Bit() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0xcc, (byte) 0xcc, (byte) 0xcc};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff, (byte) 0xf0};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length * 4, output, 0, 1, 2, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2_4Bit() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0xf0, (byte) 0xf0, (byte) 0xf0};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff, (byte) 0xf0};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length * 2, output, 0, 1, 4, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2_1Bit2Samples() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0xcc, (byte) 0xcc, (byte) 0xcc};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff, (byte) 0xf0};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length * 4, output, 0, 2, 1, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2_2Bit2Samples() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0xf0, (byte) 0xf0, (byte) 0xf0};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff, (byte) 0xf0};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length * 2, output, 0, 2, 2, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2_4Bit2Samples() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {-1, 0, (byte) 0xAA, 0, -1};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {-1, (byte) 0xAA, -1};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 0, input.length, output, 0, 2, 4, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subsampleRowPeriod2_1BitOffset1() {
|
||||||
|
int period = 2;
|
||||||
|
|
||||||
|
byte[] input = {(byte) 0xaa, (byte) 0xaa, (byte) 0xaa};
|
||||||
|
byte[] output = new byte[divCeil(input.length, period)];
|
||||||
|
byte[] expected = {(byte) 0xff, (byte) 0xf0};
|
||||||
|
|
||||||
|
IIOUtil.subsampleRow(input, 1, input.length * 8, output, 0, 1, 1, period);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int divCeil(int numerator, int denominator) {
|
||||||
|
return (numerator + denominator - 1) / denominator;
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
-6
@@ -61,10 +61,21 @@ public class ImageTypeSpecifiersTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateFromBufferedImageType() {
|
public void testCreateFromBufferedImageType() {
|
||||||
for (int type = BufferedImage.TYPE_INT_RGB; type < BufferedImage.TYPE_BYTE_INDEXED; type++) {
|
for (int type = BufferedImage.TYPE_INT_RGB; type < BufferedImage.TYPE_BYTE_INDEXED; type++) {
|
||||||
assertEquals(
|
ImageTypeSpecifier expected;
|
||||||
ImageTypeSpecifier.createFromBufferedImageType(type),
|
|
||||||
ImageTypeSpecifiers.createFromBufferedImageType(type)
|
switch (type) {
|
||||||
);
|
// Special handling for USHORT_565 and 555, due to bug in ImageTypeSpecifier for these types (DirectColorModel is 32 bits)
|
||||||
|
case BufferedImage.TYPE_USHORT_565_RGB:
|
||||||
|
expected = createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false);
|
||||||
|
break;
|
||||||
|
case BufferedImage.TYPE_USHORT_555_RGB:
|
||||||
|
expected = createPacked(sRGB, DCM_555_RED_MASK, DCM_555_GRN_MASK, DCM_555_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
expected = ImageTypeSpecifier.createFromBufferedImageType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(expected, ImageTypeSpecifiers.createFromBufferedImageType(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +130,7 @@ public class ImageTypeSpecifiersTest {
|
|||||||
|
|
||||||
// Extra: Make sure color models bits is actually 16 (ImageTypeSpecifier equivalent returns 32)
|
// Extra: Make sure color models bits is actually 16 (ImageTypeSpecifier equivalent returns 32)
|
||||||
assertEquals(16, ImageTypeSpecifiers.createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false).getColorModel().getPixelSize());
|
assertEquals(16, ImageTypeSpecifiers.createPacked(sRGB, DCM_565_RED_MASK, DCM_565_GRN_MASK, DCM_565_BLU_MASK, 0, DataBuffer.TYPE_USHORT, false).getColorModel().getPixelSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePacked8() {
|
public void testCreatePacked8() {
|
||||||
@@ -531,6 +542,7 @@ public class ImageTypeSpecifiersTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePackedGrayscale1() {
|
public void testCreatePackedGrayscale1() {
|
||||||
|
// TODO: Fails on Java 11, because IndexColorModel now has an overloaded equals that actually tests the color entries
|
||||||
assertEquals(
|
assertEquals(
|
||||||
ImageTypeSpecifier.createGrayscale(1, DataBuffer.TYPE_BYTE, false),
|
ImageTypeSpecifier.createGrayscale(1, DataBuffer.TYPE_BYTE, false),
|
||||||
ImageTypeSpecifiers.createPackedGrayscale(GRAY, 1, DataBuffer.TYPE_BYTE)
|
ImageTypeSpecifiers.createPackedGrayscale(GRAY, 1, DataBuffer.TYPE_BYTE)
|
||||||
@@ -539,6 +551,7 @@ public class ImageTypeSpecifiersTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePackedGrayscale2() {
|
public void testCreatePackedGrayscale2() {
|
||||||
|
// TODO: Fails on Java 11, because IndexColorModel now has an overloaded equals that actually tests the color entries
|
||||||
assertEquals(
|
assertEquals(
|
||||||
ImageTypeSpecifier.createGrayscale(2, DataBuffer.TYPE_BYTE, false),
|
ImageTypeSpecifier.createGrayscale(2, DataBuffer.TYPE_BYTE, false),
|
||||||
ImageTypeSpecifiers.createPackedGrayscale(GRAY, 2, DataBuffer.TYPE_BYTE)
|
ImageTypeSpecifiers.createPackedGrayscale(GRAY, 2, DataBuffer.TYPE_BYTE)
|
||||||
@@ -546,7 +559,8 @@ public class ImageTypeSpecifiersTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreatePackedGrayscale4() {
|
public void testCreatePackedGrayscale4() throws Exception {
|
||||||
|
// TODO: Fails on Java 11, because IndexColorModel now has an overloaded equals that actually tests the color entries
|
||||||
assertEquals(
|
assertEquals(
|
||||||
ImageTypeSpecifier.createGrayscale(4, DataBuffer.TYPE_BYTE, false),
|
ImageTypeSpecifier.createGrayscale(4, DataBuffer.TYPE_BYTE, false),
|
||||||
ImageTypeSpecifiers.createPackedGrayscale(GRAY, 4, DataBuffer.TYPE_BYTE)
|
ImageTypeSpecifiers.createPackedGrayscale(GRAY, 4, DataBuffer.TYPE_BYTE)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-hdr</artifactId>
|
<artifactId>imageio-hdr</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: HDR plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: HDR plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-icns</artifactId>
|
<artifactId>imageio-icns</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: ICNS plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: ICNS plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-iff</artifactId>
|
<artifactId>imageio-iff</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: IFF plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: IFF plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-jpeg</artifactId>
|
<artifactId>imageio-jpeg</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: JPEG plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: JPEG plugin</name>
|
||||||
|
|||||||
+10
-9
@@ -37,7 +37,7 @@ import javax.imageio.stream.ImageInputStream;
|
|||||||
import javax.imageio.stream.ImageInputStreamImpl;
|
import javax.imageio.stream.ImageInputStreamImpl;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -58,12 +58,12 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
|||||||
// TODO: Rewrite JPEGSegment (from metadata) to store stream pos/length, and be able to replay data, and use instead of Segment?
|
// TODO: Rewrite JPEGSegment (from metadata) to store stream pos/length, and be able to replay data, and use instead of Segment?
|
||||||
// TODO: Support multiple JPEG streams (SOI...EOI, SOI...EOI, ...) in a single file
|
// TODO: Support multiple JPEG streams (SOI...EOI, SOI...EOI, ...) in a single file
|
||||||
|
|
||||||
final private ImageInputStream stream;
|
private final ImageInputStream stream;
|
||||||
final private JPEGSegmentStreamWarningListener warningListener;
|
private final JPEGSegmentStreamWarningListener warningListener;
|
||||||
|
|
||||||
final private ComponentIdSet componentIds = new ComponentIdSet();
|
private final ComponentIdSet componentIds = new ComponentIdSet();
|
||||||
|
|
||||||
private final List<Segment> segments = new ArrayList<Segment>(64);
|
private final List<Segment> segments = new ArrayList<>(64);
|
||||||
private int currentSegment = -1;
|
private int currentSegment = -1;
|
||||||
private Segment segment;
|
private Segment segment;
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
|||||||
processWarningOccured(String.format("Duplicate component ID %d in SOF", id));
|
processWarningOccured(String.format("Duplicate component ID %d in SOF", id));
|
||||||
|
|
||||||
id++;
|
id++;
|
||||||
while (!componentIds.add(id) && componentIds.size() <= 16) {
|
while (componentIds.size() < 4 && !componentIds.add(id) && id < 255) {
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +330,7 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static String asAsciiString(final byte[] data, final int offset, final int length) {
|
static String asAsciiString(final byte[] data, final int offset, final int length) {
|
||||||
return new String(data, offset, length, Charset.forName("ascii"));
|
return new String(data, offset, length, StandardCharsets.US_ASCII);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void streamInit() throws IOException {
|
private void streamInit() throws IOException {
|
||||||
@@ -443,8 +443,9 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"FinalizeDoesntCallSuperFinalize"})
|
@SuppressWarnings({"FinalizeDoesntCallSuperFinalize"})
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() {
|
||||||
// Empty finalizer (for improved performance; no need to call super.finalize() in this case)
|
// Empty finalizer (for improved performance; no need to call super.finalize() in this case)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,7 +586,7 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final class ComponentIdSet {
|
static final class ComponentIdSet {
|
||||||
final int[] values = new int[4]; // The native code don't support more than 4 components
|
final int[] values = new int[4]; // The native code doesn't support more than 4 components
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
boolean add(final int value) {
|
boolean add(final int value) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>imageio-metadata</artifactId>
|
<artifactId>imageio-metadata</artifactId>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-pcx</artifactId>
|
<artifactId>imageio-pcx</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: PCX plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: PCX plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-pdf</artifactId>
|
<artifactId>imageio-pdf</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: PDF plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: PDF plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-pict</artifactId>
|
<artifactId>imageio-pict</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: PICT plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: PICT plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-pnm</artifactId>
|
<artifactId>imageio-pnm</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: PNM plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: PNM plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-psd</artifactId>
|
<artifactId>imageio-psd</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: PSD plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: PSD plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-reference</artifactId>
|
<artifactId>imageio-reference</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: reference test cases</name>
|
<name>TwelveMonkeys :: ImageIO :: reference test cases</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-sgi</artifactId>
|
<artifactId>imageio-sgi</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: SGI plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: SGI plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-tga</artifactId>
|
<artifactId>imageio-tga</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: TGA plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: TGA plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-thumbsdb</artifactId>
|
<artifactId>imageio-thumbsdb</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: Thumbs.db plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: Thumbs.db plugin</name>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
<artifactId>imageio</artifactId>
|
<artifactId>imageio</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>imageio-tiff</artifactId>
|
<artifactId>imageio-tiff</artifactId>
|
||||||
<name>TwelveMonkeys :: ImageIO :: TIFF plugin</name>
|
<name>TwelveMonkeys :: ImageIO :: TIFF plugin</name>
|
||||||
|
|||||||
+15
-13
@@ -48,6 +48,7 @@ import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
|
|||||||
import com.twelvemonkeys.imageio.metadata.xmp.XMPReader;
|
import com.twelvemonkeys.imageio.metadata.xmp.XMPReader;
|
||||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||||
|
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||||
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
|
import com.twelvemonkeys.imageio.util.ProgressListenerBase;
|
||||||
import com.twelvemonkeys.io.FastByteArrayOutputStream;
|
import com.twelvemonkeys.io.FastByteArrayOutputStream;
|
||||||
@@ -82,8 +83,7 @@ import java.util.*;
|
|||||||
import java.util.zip.Inflater;
|
import java.util.zip.Inflater;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
import static com.twelvemonkeys.imageio.util.IIOUtil.createStreamAdapter;
|
import static com.twelvemonkeys.imageio.util.IIOUtil.*;
|
||||||
import static com.twelvemonkeys.imageio.util.IIOUtil.lookupProviderByName;
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -502,7 +502,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
if (cs == ColorSpace.getInstance(ColorSpace.CS_GRAY) && (bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 || bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32)) {
|
if (cs == ColorSpace.getInstance(ColorSpace.CS_GRAY) && (bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 || bitsPerSample == 8 || bitsPerSample == 16 || bitsPerSample == 32)) {
|
||||||
return ImageTypeSpecifiers.createGrayscale(bitsPerSample, dataType);
|
return ImageTypeSpecifiers.createGrayscale(bitsPerSample, dataType);
|
||||||
}
|
}
|
||||||
else if (bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4 ) {
|
else if (bitsPerSample == 1 || bitsPerSample == 2 || bitsPerSample == 4) {
|
||||||
// Use packed format for 1/2/4 bits
|
// Use packed format for 1/2/4 bits
|
||||||
return ImageTypeSpecifiers.createPackedGrayscale(cs, bitsPerSample, dataType);
|
return ImageTypeSpecifiers.createPackedGrayscale(cs, bitsPerSample, dataType);
|
||||||
}
|
}
|
||||||
@@ -1841,6 +1841,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
DataBuffer dataBuffer = tileRowRaster.getDataBuffer();
|
DataBuffer dataBuffer = tileRowRaster.getDataBuffer();
|
||||||
int bands = dataBuffer.getNumBanks();
|
int bands = dataBuffer.getNumBanks();
|
||||||
boolean banded = bands > 1;
|
boolean banded = bands > 1;
|
||||||
|
int bitsPerSample = getBitsPerSample();
|
||||||
|
|
||||||
switch (tileRowRaster.getTransferType()) {
|
switch (tileRowRaster.getTransferType()) {
|
||||||
case DataBuffer.TYPE_BYTE:
|
case DataBuffer.TYPE_BYTE:
|
||||||
@@ -1870,9 +1871,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
// Subsample horizontal
|
// Subsample horizontal
|
||||||
if (xSub != 1) {
|
if (xSub != 1) {
|
||||||
for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + colsInTile) / xSub) * numBands; x += numBands) {
|
IIOUtil.subsampleRow(rowDataByte, srcRegion.x * numBands, colsInTile,
|
||||||
System.arraycopy(rowDataByte, x * xSub, rowDataByte, x, numBands);
|
rowDataByte, srcRegion.x * numBands / xSub, numBands, bitsPerSample, xSub);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
|
destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
|
||||||
@@ -1913,9 +1913,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
// Subsample horizontal
|
// Subsample horizontal
|
||||||
if (xSub != 1) {
|
if (xSub != 1) {
|
||||||
for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + colsInTile) / xSub) * numBands; x += numBands) {
|
subsampleRow(rowDataShort, srcRegion.x * numBands, colsInTile,
|
||||||
System.arraycopy(rowDataShort, x * xSub, rowDataShort, x, numBands);
|
rowDataShort, srcRegion.x * numBands / xSub, numBands, bitsPerSample, xSub);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
|
destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
|
||||||
@@ -1950,9 +1949,8 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
// Subsample horizontal
|
// Subsample horizontal
|
||||||
if (xSub != 1) {
|
if (xSub != 1) {
|
||||||
for (int x = srcRegion.x / xSub * numBands; x < ((srcRegion.x + colsInTile) / xSub) * numBands; x += numBands) {
|
subsampleRow(rowDataInt, srcRegion.x * numBands, colsInTile,
|
||||||
System.arraycopy(rowDataInt, x * xSub, rowDataInt, x, numBands);
|
rowDataInt, srcRegion.x * numBands / xSub, numBands, bitsPerSample, xSub);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
|
destChannel.setDataElements(startCol / xSub, (row - srcRegion.y) / ySub, srcChannel);
|
||||||
@@ -1998,6 +1996,9 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new AssertionError("Unsupported data type: " + tileRowRaster.getTransferType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2294,7 +2295,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
case TIFFBaseline.COMPRESSION_NONE:
|
case TIFFBaseline.COMPRESSION_NONE:
|
||||||
return stream;
|
return stream;
|
||||||
case TIFFBaseline.COMPRESSION_PACKBITS:
|
case TIFFBaseline.COMPRESSION_PACKBITS:
|
||||||
return new DecoderStream(createFillOrderStream(fillOrder, stream), new PackBitsDecoder(), 1024);
|
return new DecoderStream(createFillOrderStream(fillOrder, stream), new PackBitsDecoder(), 256);
|
||||||
case TIFFExtension.COMPRESSION_LZW:
|
case TIFFExtension.COMPRESSION_LZW:
|
||||||
// NOTE: Needs large buffer for compatibility with certain encoders
|
// NOTE: Needs large buffer for compatibility with certain encoders
|
||||||
return new DecoderStream(createFillOrderStream(fillOrder, stream), LZWDecoder.create(LZWDecoder.isOldBitReversedStream(stream)), Math.max(width * bands, 4096));
|
return new DecoderStream(createFillOrderStream(fillOrder, stream), LZWDecoder.create(LZWDecoder.isOldBitReversedStream(stream)), Math.max(width * bands, 4096));
|
||||||
@@ -2469,6 +2470,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canReadRaster() {
|
public boolean canReadRaster() {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+23
@@ -708,6 +708,29 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadWithSubsampleParamPixelsBinary() throws IOException {
|
||||||
|
ImageReader reader = createReader();
|
||||||
|
TestData data = new TestData(getClassLoaderResource("/tiff/ccitt/group3_2d.tif"), new Dimension(6, 4));
|
||||||
|
reader.setInput(data.getInputStream());
|
||||||
|
|
||||||
|
ImageReadParam param = reader.getDefaultReadParam();
|
||||||
|
|
||||||
|
BufferedImage image = null;
|
||||||
|
BufferedImage subsampled = null;
|
||||||
|
try {
|
||||||
|
image = reader.read(0, param);
|
||||||
|
|
||||||
|
param.setSourceSubsampling(2, 2, 0, 0);
|
||||||
|
subsampled = reader.read(0, param);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
failBecause("Image could not be read", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSubsampledImageDataEquals("Subsampled image data does not match expected", image, subsampled, param);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadWithSubsampleParamPixelsJPEG() throws IOException {
|
public void testReadWithSubsampleParamPixelsJPEG() throws IOException {
|
||||||
// Tiled "new style" JPEG
|
// Tiled "new style" JPEG
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys</groupId>
|
<groupId>com.twelvemonkeys</groupId>
|
||||||
<artifactId>twelvemonkeys</artifactId>
|
<artifactId>twelvemonkeys</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<groupId>com.twelvemonkeys</groupId>
|
<groupId>com.twelvemonkeys</groupId>
|
||||||
<artifactId>twelvemonkeys</artifactId>
|
<artifactId>twelvemonkeys</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>Twelvemonkeys</name>
|
<name>Twelvemonkeys</name>
|
||||||
|
|
||||||
@@ -84,9 +84,9 @@
|
|||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:git:https://github.com/haraldk/TwelveMonkeys</connection>
|
<connection>scm:git:https://github.com/haraldk/TwelveMonkeys</connection>
|
||||||
<developerConnection>scm:git:ssh://github.com/haraldk/TwelveMonkeys</developerConnection>
|
<developerConnection>scm:git:ssh://git@github.com/haraldk/TwelveMonkeys</developerConnection>
|
||||||
<url>https://github.com/haraldk/TwelveMonkeys</url>
|
<url>https://github.com/haraldk/TwelveMonkeys</url>
|
||||||
<tag>twelvemonkeys-3.4.2</tag>
|
<tag>twelvemonkeys-3.4</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -80,11 +80,5 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
<version>1.2.14</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
-183
@@ -1,183 +0,0 @@
|
|||||||
package com.twelvemonkeys.servlet.log4j;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
|
||||||
import javax.servlet.Servlet;
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log4JContextWrapper
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
|
||||||
* @version $Id: log4j/Log4JContextWrapper.java#1 $
|
|
||||||
*/
|
|
||||||
final class Log4JContextWrapper implements ServletContext {
|
|
||||||
// TODO: Move to sandbox
|
|
||||||
|
|
||||||
// TODO: This solution sucks...
|
|
||||||
// How about starting to create some kind of pluggable decorator system,
|
|
||||||
// something along the lines of AOP mixins/interceptor pattern..
|
|
||||||
// Probably using a dynamic Proxy, delegating to the mixins and or the
|
|
||||||
// wrapped object based on configuration.
|
|
||||||
// This way we could simply call ServletUtil.decorate(ServletContext):ServletContext
|
|
||||||
// And the context would be decorated with all configured mixins at once,
|
|
||||||
// requiring less boilerplate delegation code, and less layers of wrapping
|
|
||||||
// (alternatively we could decorate the Servlet/FilterConfig objects).
|
|
||||||
// See the ServletUtil.createWrapper methods for some hints..
|
|
||||||
|
|
||||||
|
|
||||||
// Something like this:
|
|
||||||
public static ServletContext wrap(final ServletContext pContext, final Object[] pDelegates, final ClassLoader pLoader) {
|
|
||||||
ClassLoader cl = pLoader != null ? pLoader : Thread.currentThread().getContextClassLoader();
|
|
||||||
|
|
||||||
// TODO: Create a "static" mapping between methods in the ServletContext
|
|
||||||
// and the corresponding delegate
|
|
||||||
|
|
||||||
// TODO: Resolve super-invokations, to delegate to next delegate in
|
|
||||||
// chain, and finally invoke pContext
|
|
||||||
|
|
||||||
return (ServletContext) Proxy.newProxyInstance(cl, new Class[] {ServletContext.class}, new InvocationHandler() {
|
|
||||||
public Object invoke(Object pProxy, Method pMethod, Object[] pArgs) throws Throwable {
|
|
||||||
// TODO: Test if any of the delegates should receive, if so invoke
|
|
||||||
|
|
||||||
// Else, invoke on original object
|
|
||||||
return pMethod.invoke(pContext, pArgs);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ServletContext context;
|
|
||||||
|
|
||||||
private final Logger logger;
|
|
||||||
|
|
||||||
Log4JContextWrapper(ServletContext pContext) {
|
|
||||||
context = pContext;
|
|
||||||
|
|
||||||
// TODO: We want a logger per servlet, not per servlet context, right?
|
|
||||||
logger = Logger.getLogger(pContext.getServletContextName());
|
|
||||||
|
|
||||||
// TODO: Automatic init/config of Log4J using context parameter for log4j.xml?
|
|
||||||
// See Log4JInit.java
|
|
||||||
|
|
||||||
// TODO: Automatic config of properties in the context wrapper?
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void log(final Exception pException, final String pMessage) {
|
|
||||||
log(pMessage, pException);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add more logging methods to interface info/warn/error?
|
|
||||||
// TODO: Implement these mehtods in GenericFilter/GenericServlet?
|
|
||||||
|
|
||||||
public void log(String pMessage) {
|
|
||||||
// TODO: Get logger for caller..
|
|
||||||
// Should be possible using some stack peek hack, but that's slow...
|
|
||||||
// Find a good way...
|
|
||||||
// Maybe just pass it into the constuctor, and have one wrapper per servlet
|
|
||||||
logger.info(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void log(String pMessage, Throwable pCause) {
|
|
||||||
// TODO: Get logger for caller..
|
|
||||||
|
|
||||||
logger.error(pMessage, pCause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getAttribute(String pMessage) {
|
|
||||||
return context.getAttribute(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Enumeration getAttributeNames() {
|
|
||||||
return context.getAttributeNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServletContext getContext(String pMessage) {
|
|
||||||
return context.getContext(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInitParameter(String pMessage) {
|
|
||||||
return context.getInitParameter(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Enumeration getInitParameterNames() {
|
|
||||||
return context.getInitParameterNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMajorVersion() {
|
|
||||||
return context.getMajorVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMimeType(String pMessage) {
|
|
||||||
return context.getMimeType(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinorVersion() {
|
|
||||||
return context.getMinorVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RequestDispatcher getNamedDispatcher(String pMessage) {
|
|
||||||
return context.getNamedDispatcher(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRealPath(String pMessage) {
|
|
||||||
return context.getRealPath(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RequestDispatcher getRequestDispatcher(String pMessage) {
|
|
||||||
return context.getRequestDispatcher(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public URL getResource(String pMessage) throws MalformedURLException {
|
|
||||||
return context.getResource(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputStream getResourceAsStream(String pMessage) {
|
|
||||||
return context.getResourceAsStream(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set getResourcePaths(String pMessage) {
|
|
||||||
return context.getResourcePaths(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getServerInfo() {
|
|
||||||
return context.getServerInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Servlet getServlet(String pMessage) throws ServletException {
|
|
||||||
//noinspection deprecation
|
|
||||||
return context.getServlet(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getServletContextName() {
|
|
||||||
return context.getServletContextName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Enumeration getServletNames() {
|
|
||||||
//noinspection deprecation
|
|
||||||
return context.getServletNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Enumeration getServlets() {
|
|
||||||
//noinspection deprecation
|
|
||||||
return context.getServlets();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAttribute(String pMessage) {
|
|
||||||
context.removeAttribute(pMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttribute(String pMessage, Object pExtension) {
|
|
||||||
context.setAttribute(pMessage, pExtension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-8
@@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.twelvemonkeys</groupId>
|
<groupId>com.twelvemonkeys</groupId>
|
||||||
<artifactId>twelvemonkeys</artifactId>
|
<artifactId>twelvemonkeys</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.4.4-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@@ -57,13 +57,6 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>log4j</groupId>
|
|
||||||
<artifactId>log4j</artifactId>
|
|
||||||
<version>1.2.14</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-fileupload</groupId>
|
<groupId>commons-fileupload</groupId>
|
||||||
<artifactId>commons-fileupload</artifactId>
|
<artifactId>commons-fileupload</artifactId>
|
||||||
|
|||||||
Reference in New Issue
Block a user