Author: damjan Date: Wed Jun 27 18:42:22 2012 New Revision: 1354661 URL: http://svn.apache.org/viewvc?rev=1354661&view=rev Log: Add a pixel density test, and fix pixel density implementations in PCX, DCX and ICO formats.
Modified: commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/dcx/DcxImageParser.java commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/roundtrip/RoundtripTest.java Modified: commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/dcx/DcxImageParser.java URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/dcx/DcxImageParser.java?rev=1354661&r1=1354660&r2=1354661&view=diff ============================================================================== --- commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/dcx/DcxImageParser.java (original) +++ commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/dcx/DcxImageParser.java Wed Jun 27 18:42:22 2012 @@ -33,6 +33,7 @@ import org.apache.commons.imaging.ImageI import org.apache.commons.imaging.ImageParser; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.PixelDensity; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.IImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -217,6 +218,17 @@ public class DcxImageParser extends Imag .remove(PcxConstants.PARAM_KEY_PCX_COMPRESSION); pcxParams.put(PcxConstants.PARAM_KEY_PCX_COMPRESSION, value); } + + if (params.containsKey(PARAM_KEY_PIXEL_DENSITY)) { + Object value = params.remove(PARAM_KEY_PIXEL_DENSITY); + if (value != null) { + if (!(value instanceof PixelDensity)) + throw new ImageWriteException( + "Invalid pixel density parameter"); + pcxParams.put(PARAM_KEY_PIXEL_DENSITY, (PixelDensity) value); + } + } + if (params.size() > 0) { Object firstKey = params.keySet().iterator().next(); Modified: commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java?rev=1354661&r1=1354660&r2=1354661&view=diff ============================================================================== --- commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java (original) +++ commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java Wed Jun 27 18:42:22 2012 @@ -36,6 +36,7 @@ import org.apache.commons.imaging.ImageP import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.Imaging; +import org.apache.commons.imaging.PixelDensity; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.IImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -719,6 +720,8 @@ public class IcoImageParser extends Imag // clear format key. if (params.containsKey(PARAM_KEY_FORMAT)) params.remove(PARAM_KEY_FORMAT); + + PixelDensity pixelDensity = (PixelDensity) params.remove(PARAM_KEY_PIXEL_DENSITY); if (params.size() > 0) { Object firstKey = params.keySet().iterator().next(); @@ -785,8 +788,8 @@ public class IcoImageParser extends Imag bos.write2Bytes(bitCount); bos.write4Bytes(0); // compression bos.write4Bytes(0); // image size - bos.write4Bytes(0); // x pixels per meter - bos.write4Bytes(0); // y pixels per meter + bos.write4Bytes(pixelDensity == null ? 0 : (int)Math.round(pixelDensity.horizontalDensityMetres())); // x pixels per meter + bos.write4Bytes(pixelDensity == null ? 0 : (int)Math.round(pixelDensity.horizontalDensityMetres())); // y pixels per meter bos.write4Bytes(0); // colors used, 0 = (1 << bitCount) (ignored) bos.write4Bytes(0); // colors important Modified: commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java?rev=1354661&r1=1354660&r2=1354661&view=diff ============================================================================== --- commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java (original) +++ commons/proper/imaging/trunk/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java Wed Jun 27 18:42:22 2012 @@ -72,8 +72,7 @@ public class PcxWriter implements PcxCon if (!(value instanceof PixelDensity)) throw new ImageWriteException( "Invalid pixel density parameter"); - pixelDensity = (PixelDensity) params - .remove(PARAM_KEY_PIXEL_DENSITY); + pixelDensity = (PixelDensity) value; } } if (pixelDensity == null) { Modified: commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/roundtrip/RoundtripTest.java URL: http://svn.apache.org/viewvc/commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/roundtrip/RoundtripTest.java?rev=1354661&r1=1354660&r2=1354661&view=diff ============================================================================== --- commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/roundtrip/RoundtripTest.java (original) +++ commons/proper/imaging/trunk/src/test/java/org/apache/commons/imaging/roundtrip/RoundtripTest.java Wed Jun 27 18:42:22 2012 @@ -24,11 +24,13 @@ import java.util.HashMap; import java.util.Map; import org.apache.commons.imaging.ImageFormat; +import org.apache.commons.imaging.ImageInfo; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.Imaging; import org.apache.commons.imaging.ImagingConstants; import org.apache.commons.imaging.ImagingTest; +import org.apache.commons.imaging.PixelDensity; import org.apache.commons.imaging.common.RgbBufferedImageFactory; import org.apache.commons.imaging.util.Debug; import org.apache.commons.imaging.util.IoUtils; @@ -46,53 +48,56 @@ public class RoundtripTest extends Imagi public final boolean canWrite; public final int colorSupport; public final boolean identicalSecondWrite; + public final boolean preservesResolution; public FormatInfo(ImageFormat format, boolean canRead, boolean canWrite, int colorSupport, - final boolean identicalSecondWrite) { + final boolean identicalSecondWrite, + final boolean preservesResolution) { this.canRead = canRead; this.canWrite = canWrite; this.colorSupport = colorSupport; this.format = format; this.identicalSecondWrite = identicalSecondWrite; + this.preservesResolution = preservesResolution; } } private static final FormatInfo FORMAT_INFOS[] = { // new FormatInfo(ImageFormat.IMAGE_FORMAT_PNG, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_GIF, true, true, - COLOR_LIMITED_INDEX, true), // + COLOR_LIMITED_INDEX, true, false), // new FormatInfo(ImageFormat.IMAGE_FORMAT_ICO, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_TIFF, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_JPEG, true, false, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_BMP, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, false), // new FormatInfo(ImageFormat.IMAGE_FORMAT_PSD, true, false, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_PBM, true, true, - COLOR_BITMAP, true), // + COLOR_BITMAP, true, false), // new FormatInfo(ImageFormat.IMAGE_FORMAT_PGM, true, true, - COLOR_GRAYSCALE, true), // + COLOR_GRAYSCALE, true, false), // new FormatInfo(ImageFormat.IMAGE_FORMAT_PPM, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, false), // // new FormatInfo(ImageFormat.IMAGE_FORMAT_PNM, true, true, // COLOR_FULL_RGB, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_TGA, false, false, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_WBMP, true, true, - COLOR_BITMAP, true), // + COLOR_BITMAP, true, false), // new FormatInfo(ImageFormat.IMAGE_FORMAT_PCX, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_DCX, true, true, - COLOR_FULL_RGB, true), // + COLOR_FULL_RGB, true, true), // new FormatInfo(ImageFormat.IMAGE_FORMAT_XBM, true, true, - COLOR_BITMAP, false), // + COLOR_BITMAP, false, false), // new FormatInfo(ImageFormat.IMAGE_FORMAT_XPM, true, true, - COLOR_FULL_RGB, false), // + COLOR_FULL_RGB, false, false), // }; private BufferedImage createArgbBitmapImage(int width, int height) { @@ -378,6 +383,40 @@ public class RoundtripTest extends Imagi } } } + + public void testPixelDensityRoundtrip() throws IOException, + ImageReadException, ImageWriteException { + BufferedImage testImage = createFullColorImage(2, 2); + for (FormatInfo formatInfo : FORMAT_INFOS) { + if (!formatInfo.canRead || !formatInfo.canWrite || !formatInfo.preservesResolution) + continue; + + Debug.debug("pixel density test: " + formatInfo.format.name); + + File temp1 = createTempFile("pixeldensity.", "." + + formatInfo.format.extension); + + Map params = new HashMap(); + PixelDensity pixelDensity = PixelDensity.createFromPixelsPerInch(75, 150); + params.put(ImagingConstants.PARAM_KEY_PIXEL_DENSITY, pixelDensity); + Imaging.writeImage(testImage, temp1, formatInfo.format, params); + + ImageInfo imageInfo = Imaging.getImageInfo(temp1); + if (imageInfo == null) + continue; + int xReadDPI = imageInfo.getPhysicalWidthDpi(); + int yReadDPI = imageInfo.getPhysicalHeightDpi(); + // allow a 5% margin of error in storage and conversion + assertTrue("horizontal pixel density stored wrongly for " + formatInfo.format + + " in=" + pixelDensity.horizontalDensityInches() + ", out=" + xReadDPI, + Math.abs((xReadDPI - pixelDensity.horizontalDensityInches()) / + pixelDensity.horizontalDensityInches()) <= 0.05); + assertTrue("vertical pixel density stored wrongly for " + formatInfo.format + + " in=" + pixelDensity.verticalDensityInches() + ", out=" + yReadDPI, + Math.abs((yReadDPI - pixelDensity.verticalDensityInches()) / + pixelDensity.verticalDensityInches()) <= 0.05); + } + } private void roundtrip(FormatInfo formatInfo, BufferedImage testImage, String tempPrefix, boolean imageExact) throws IOException,