diff --git a/common/common-image/src/main/java/com/twelvemonkeys/image/Magick.java b/common/common-image/src/main/java/com/twelvemonkeys/image/Magick.java
deleted file mode 100755
index b348e22e..00000000
--- a/common/common-image/src/main/java/com/twelvemonkeys/image/Magick.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2008, 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 of the copyright holder 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 HOLDER 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.image;
-
-/**
- * Magick
- *
- * @author Harald Kuhr
- * @author last modified by $Author: haku $
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/Magick.java#1 $
- */
-final class Magick {
- static final boolean DEBUG = useDebug();
-
- private static boolean useDebug() {
- try {
- return "TRUE".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.image.magick.debug"));
- }
- catch (Throwable t) {
- // Most probably in case of a SecurityManager
- return false;
- }
- }
-
- private Magick() {}
-}
diff --git a/common/common-image/src/main/java/com/twelvemonkeys/image/MagickAccelerator.java b/common/common-image/src/main/java/com/twelvemonkeys/image/MagickAccelerator.java
deleted file mode 100755
index ed0753e9..00000000
--- a/common/common-image/src/main/java/com/twelvemonkeys/image/MagickAccelerator.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2008, 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 of the copyright holder 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 HOLDER 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.image;
-
-import com.twelvemonkeys.lang.SystemUtil;
-import magick.MagickImage;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-
-/**
- * This class accelerates certain graphics operations, using
- * JMagick and ImageMagick, if available.
- * If those libraries are not installed, this class silently does nothing.
- *
- * Set the system property {@code "com.twelvemonkeys.image.accel"} to
- * {@code false}, to disable, even if JMagick is installed.
- * Set the system property {@code "com.twelvemonkeys.image.magick.debug"} to
- *
- *
- * @author Harald Kuhr
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/MagickAccelerator.java#3 $
- */
-final class MagickAccelerator {
-
- private static final boolean DEBUG = Magick.DEBUG;
- private static final boolean USE_MAGICK = useMagick();
-
- private static final int RESAMPLE_OP = 0;
-
- private static Class[] nativeOp = new Class[1];
-
- static {
- try {
- nativeOp[RESAMPLE_OP] = Class.forName("com.twelvemonkeys.image.ResampleOp");
- }
- catch (ClassNotFoundException e) {
- System.err.println("Could not find class: " + e);
- }
- }
-
- private static boolean useMagick() {
- try {
- boolean available = SystemUtil.isClassAvailable("magick.MagickImage");
-
- if (DEBUG && !available) {
- System.err.print("ImageMagick bindings not available.");
- }
-
- boolean useMagick =
- available && !"FALSE".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.image.accel"));
-
- if (DEBUG) {
- System.err.println(
- useMagick
- ? "Will use ImageMagick bindings to accelerate image resampling operations."
- : "Will not use ImageMagick to accelerate image resampling operations."
- );
- }
-
- return useMagick;
- }
- catch (Throwable t) {
- // Most probably in case of a SecurityManager
- System.err.println("Could not enable ImageMagick bindings: " + t);
- return false;
- }
- }
-
- private static int getNativeOpIndex(Class pOpClass) {
- for (int i = 0; i < nativeOp.length; i++) {
- if (pOpClass == nativeOp[i]) {
- return i;
- }
- }
-
- return -1;
- }
-
- public static BufferedImage filter(BufferedImageOp pOperation, BufferedImage pInput, BufferedImage pOutput) {
- if (!USE_MAGICK) {
- return null;
- }
-
- BufferedImage result = null;
- switch (getNativeOpIndex(pOperation.getClass())) {
- case RESAMPLE_OP:
- ResampleOp resample = (ResampleOp) pOperation;
- result = resampleMagick(pInput, resample.width, resample.height, resample.filterType);
-
- // NOTE: If output parameter is non-null, we have to return that
- // image, instead of result
- if (pOutput != null) {
- //pOutput.setData(result.getRaster()); // Fast, but less compatible
- // NOTE: For some reason, this is sometimes super-slow...?
- ImageUtil.drawOnto(pOutput, result);
- result = pOutput;
- }
-
- break;
-
- default:
- // Simply fall through, allowing acceleration to be added later
- break;
-
- }
-
- return result;
- }
-
- private static BufferedImage resampleMagick(BufferedImage pSrc, int pWidth, int pHeight, int pFilterType) {
- // Convert to Magick, scale and convert back
- MagickImage image = null;
- MagickImage scaled = null;
- try {
- image = MagickUtil.toMagick(pSrc);
-
- long start = 0;
- if (DEBUG) {
- start = System.currentTimeMillis();
- }
-
- // NOTE: setFilter affects zoomImage, NOT scaleImage
- image.setFilter(pFilterType);
- scaled = image.zoomImage(pWidth, pHeight);
- //scaled = image.scaleImage(pWidth, pHeight); // AREA_AVERAGING
-
- if (DEBUG) {
- long time = System.currentTimeMillis() - start;
- System.out.println("Filtered: " + time + " ms");
- }
-
- return MagickUtil.toBuffered(scaled);
- }
- //catch (MagickException e) {
- catch (Exception e) {
- // NOTE: Stupid workaround: If MagickException is caught, a
- // NoClassDefFoundError is thrown, when MagickException class is
- // unavailable...
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- }
-
- throw new ImageConversionException(e.getMessage(), e);
- }
- finally {
- // NOTE: ImageMagick might be unstable after a while, if image data
- // is not deallocated. The GC/finalize method handles this, but in
- // special circumstances, it's not triggered often enough.
- if (image != null) {
- image.destroyImages();
- }
- if (scaled != null) {
- scaled.destroyImages();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/common/common-image/src/main/java/com/twelvemonkeys/image/MagickUtil.java b/common/common-image/src/main/java/com/twelvemonkeys/image/MagickUtil.java
deleted file mode 100755
index a5a316ea..00000000
--- a/common/common-image/src/main/java/com/twelvemonkeys/image/MagickUtil.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (c) 2008, 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 of the copyright holder 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 HOLDER 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.image;
-
-import magick.ImageType;
-import magick.MagickException;
-import magick.MagickImage;
-import magick.PixelPacket;
-
-import java.awt.*;
-import java.awt.color.ColorSpace;
-import java.awt.color.ICC_ColorSpace;
-import java.awt.color.ICC_Profile;
-import java.awt.image.*;
-
-/**
- * Utility for converting JMagick {@code MagickImage}s to standard Java
- * {@code BufferedImage}s and back.
- *
- * NOTE: This class is considered an implementation detail and not part of
- * the public API. This class is subject to change without further notice.
- * You have been warned. :-)
- *
- *
- * @author Harald Kuhr
- * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/MagickUtil.java#4 $
- */
-public final class MagickUtil {
- // IMPORTANT NOTE: Disaster happens if any of these constants are used outside this class
- // because you then have a dependency on MagickException (this is due to Java class loading
- // and initialization magic).
- // Do not use outside this class. If the constants need to be shared, move to Magick or ImageUtil.
-
- /** Color Model usesd for bilevel (B/W) */
- private static final IndexColorModel CM_MONOCHROME = MonochromeColorModel.getInstance();
-
- /** Color Model usesd for raw ABGR */
- private static final ColorModel CM_COLOR_ALPHA =
- new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8, 8, 8, 8},
- true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
-
- /** Color Model usesd for raw BGR */
- private static final ColorModel CM_COLOR_OPAQUE =
- new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8, 8, 8},
- false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
-
- /** Color Model usesd for raw RGB */
- //private static final ColorModel CM_COLOR_RGB = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
-
- /** Color Model usesd for raw GRAY + ALPHA */
- private static final ColorModel CM_GRAY_ALPHA =
- new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
- true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
-
- /** Color Model usesd for raw GRAY */
- private static final ColorModel CM_GRAY_OPAQUE =
- new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
- false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
-
- /** Band offsets for raw ABGR */
- private static final int[] BAND_OFF_TRANS = new int[] {3, 2, 1, 0};
-
- /** Band offsets for raw BGR */
- private static final int[] BAND_OFF_OPAQUE = new int[] {2, 1, 0};
-
- /** The point at {@code 0, 0} */
- private static final Point LOCATION_UPPER_LEFT = new Point(0, 0);
-
- private static final boolean DEBUG = Magick.DEBUG;
-
- // Only static members and methods
- private MagickUtil() {}
-
- /**
- * Converts a {@code MagickImage} to a {@code BufferedImage}.
- *
- * The conversion depends on {@code pImage}'s {@code ImageType}:
- *
- *
- * - {@code ImageType.BilevelType}
- * - {@code BufferedImage} of type {@code TYPE_BYTE_BINARY}
- *
- * - {@code ImageType.GrayscaleType}
- * - {@code BufferedImage} of type {@code TYPE_BYTE_GRAY}
- * - {@code ImageType.GrayscaleMatteType}
- * - {@code BufferedImage} of type {@code TYPE_USHORT_GRAY}
- *
- * - {@code ImageType.PaletteType}
- * - {@code BufferedImage} of type {@code TYPE_BYTE_BINARY} (for images
- * with a palette of <= 16 colors) or {@code TYPE_BYTE_INDEXED}
- * - {@code ImageType.PaletteMatteType}
- * - {@code BufferedImage} of type {@code TYPE_BYTE_BINARY} (for images
- * with a palette of <= 16 colors) or {@code TYPE_BYTE_INDEXED}
- *
- * - {@code ImageType.TrueColorType}
- * - {@code BufferedImage} of type {@code TYPE_3BYTE_BGR}
- * - {@code ImageType.TrueColorPaletteType}
- * - {@code BufferedImage} of type {@code TYPE_4BYTE_ABGR}
- *
- *
- * @param pImage the original {@code MagickImage}
- * @return a new {@code BufferedImage}
- *
- * @throws IllegalArgumentException if {@code pImage} is {@code null}
- * or if the {@code ImageType} is not one mentioned above.
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- public static BufferedImage toBuffered(MagickImage pImage) throws MagickException {
- if (pImage == null) {
- throw new IllegalArgumentException("image == null");
- }
-
- long start = 0L;
- if (DEBUG) {
- start = System.currentTimeMillis();
- }
-
- BufferedImage image = null;
- try {
- switch (pImage.getImageType()) {
- case ImageType.BilevelType:
- image = bilevelToBuffered(pImage);
- break;
- case ImageType.GrayscaleType:
- image = grayToBuffered(pImage, false);
- break;
- case ImageType.GrayscaleMatteType:
- image = grayToBuffered(pImage, true);
- break;
- case ImageType.PaletteType:
- image = paletteToBuffered(pImage, false);
- break;
- case ImageType.PaletteMatteType:
- image = paletteToBuffered(pImage, true);
- break;
- case ImageType.TrueColorType:
- image = rgbToBuffered(pImage, false);
- break;
- case ImageType.TrueColorMatteType:
- image = rgbToBuffered(pImage, true);
- break;
- case ImageType.ColorSeparationType:
- image = cmykToBuffered(pImage, false);
- break;
- case ImageType.ColorSeparationMatteType:
- image = cmykToBuffered(pImage, true);
- break;
- case ImageType.OptimizeType:
- default:
- throw new IllegalArgumentException("Unknown JMagick image type: " + pImage.getImageType());
- }
-
- }
- finally {
- if (DEBUG) {
- long time = System.currentTimeMillis() - start;
- System.out.println("Converted JMagick image type: " + pImage.getImageType() + " to BufferedImage: " + image);
- System.out.println("Conversion to BufferedImage: " + time + " ms");
- }
- }
-
- return image;
- }
-
- /**
- * Converts a {@code BufferedImage} to a {@code MagickImage}.
- *
- * The conversion depends on {@code pImage}'s {@code ColorModel}:
- *
- *
- * - {@code IndexColorModel} with 1 bit b/w
- * - {@code MagickImage} of type {@code ImageType.BilevelType}
- * - {@code IndexColorModel} > 1 bit,
- * - {@code MagickImage} of type {@code ImageType.PaletteType}
- * or {@code MagickImage} of type {@code ImageType.PaletteMatteType}
- * depending on ColorModel.getAlpha()
- *
- * - {@code ColorModel.getColorSpace().getType() == ColorSpace.TYPE_GRAY}
- * - {@code MagickImage} of type {@code ImageType.GrayscaleType}
- * or {@code MagickImage} of type {@code ImageType.GrayscaleMatteType}
- * depending on ColorModel.getAlpha()
- *
- * - {@code ColorModel.getColorSpace().getType() == ColorSpace.TYPE_RGB}
- * - {@code MagickImage} of type {@code ImageType.TrueColorType}
- * or {@code MagickImage} of type {@code ImageType.TrueColorPaletteType}
- *
- *
- * @param pImage the original {@code BufferedImage}
- * @return a new {@code MagickImage}
- *
- * @throws IllegalArgumentException if {@code pImage} is {@code null}
- * or if the {@code ColorModel} is not one mentioned above.
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- public static MagickImage toMagick(BufferedImage pImage) throws MagickException {
- if (pImage == null) {
- throw new IllegalArgumentException("image == null");
- }
-
- long start = 0L;
- if (DEBUG) {
- start = System.currentTimeMillis();
- }
-
- try {
- ColorModel cm = pImage.getColorModel();
- if (cm instanceof IndexColorModel) {
- // Handles both BilevelType, PaletteType and PaletteMatteType
- return indexedToMagick(pImage, (IndexColorModel) cm, cm.hasAlpha());
- }
-
- switch (cm.getColorSpace().getType()) {
- case ColorSpace.TYPE_GRAY:
- // Handles GrayType and GrayMatteType
- return grayToMagick(pImage, cm.hasAlpha());
- case ColorSpace.TYPE_RGB:
- // Handles TrueColorType and TrueColorMatteType
- return rgbToMagic(pImage, cm.hasAlpha());
- case ColorSpace.TYPE_CMY:
- case ColorSpace.TYPE_CMYK:
- case ColorSpace.TYPE_HLS:
- case ColorSpace.TYPE_HSV:
- // Other types not supported yet
- default:
- throw new IllegalArgumentException("Unknown buffered image type: " + pImage);
- }
- }
- finally {
- if (DEBUG) {
- long time = System.currentTimeMillis() - start;
- System.out.println("Conversion to MagickImage: " + time + " ms");
- }
- }
- }
-
- private static MagickImage rgbToMagic(BufferedImage pImage, boolean pAlpha) throws MagickException {
- MagickImage image = new MagickImage();
-
- BufferedImage buffered = ImageUtil.toBuffered(pImage, pAlpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
-
- // Need to get data of sub raster, not the full data array, this is
- // just a convenient way
- Raster raster;
- if (buffered.getRaster().getParent() != null) {
- raster = buffered.getData(new Rectangle(buffered.getWidth(), buffered.getHeight()));
- }
- else {
- raster = buffered.getRaster();
- }
-
- image.constituteImage(buffered.getWidth(), buffered.getHeight(), pAlpha ? "ABGR" : "BGR",
- ((DataBufferByte) raster.getDataBuffer()).getData());
-
- return image;
- }
-
- private static MagickImage grayToMagick(BufferedImage pImage, boolean pAlpha) throws MagickException {
- MagickImage image = new MagickImage();
-
- // TODO: Make a fix for TYPE_USHORT_GRAY
- // The code below does not seem to work (JMagick issues?)...
- /*
- if (pImage.getType() == BufferedImage.TYPE_USHORT_GRAY) {
- short[] data = ((DataBufferUShort) pImage.getRaster().getDataBuffer()).getData();
- int[] intData = new int[data.length];
- for (int i = 0; i < data.length; i++) {
- intData[i] = (data[i] & 0xffff) * 0xffff;
- }
- image.constituteImage(pImage.getWidth(), pImage.getHeight(), "I", intData);
-
- System.out.println("storageClass: " + image.getStorageClass());
- System.out.println("depth: " + image.getDepth());
- System.out.println("imageType: " + image.getImageType());
- }
- else {
- */
- BufferedImage buffered = ImageUtil.toBuffered(pImage, pAlpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_BYTE_GRAY);
-
- // Need to get data of sub raster, not the full data array, this is
- // just a convenient way
- Raster raster;
- if (buffered.getRaster().getParent() != null) {
- raster = buffered.getData(new Rectangle(buffered.getWidth(), buffered.getHeight()));
- }
- else {
- raster = buffered.getRaster();
- }
-
- image.constituteImage(buffered.getWidth(), buffered.getHeight(), pAlpha ? "ABGR" : "I", ((DataBufferByte) raster.getDataBuffer()).getData());
- //}
-
- return image;
- }
-
- private static MagickImage indexedToMagick(BufferedImage pImage, IndexColorModel pColorModel, boolean pAlpha) throws MagickException {
- MagickImage image = rgbToMagic(pImage, pAlpha);
-
- int mapSize = pColorModel.getMapSize();
- image.setNumberColors(mapSize);
-
- return image;
- }
-
- /*
- public static MagickImage toMagick(BufferedImage pImage) throws MagickException {
- if (pImage == null) {
- throw new IllegalArgumentException("image == null");
- }
-
- final int width = pImage.getWidth();
- final int height = pImage.getHeight();
-
- // int ARGB -> byte RGBA conversion
- // NOTE: This is ImageMagick Q16 compatible raw RGBA format with 16 bits/sample...
- // For a Q8 build, we could probably go with half the space...
- // NOTE: This is close to insanity, as it wastes extreme ammounts of memory
- final int[] argb = new int[width];
- final byte[] raw16 = new byte[width * height * 8];
- for (int y = 0; y < height; y++) {
- // Fetch one line of ARGB data
- pImage.getRGB(0, y, width, 1, argb, 0, width);
-
- for (int x = 0; x < width; x++) {
- int pixel = (x + (y * width)) * 8;
- raw16[pixel ] = (byte) ((argb[x] >> 16) & 0xff); // R
- raw16[pixel + 2] = (byte) ((argb[x] >> 8) & 0xff); // G
- raw16[pixel + 4] = (byte) ((argb[x] ) & 0xff); // B
- raw16[pixel + 6] = (byte) ((argb[x] >> 24) & 0xff); // A
- }
- }
-
- // Create magick image
- ImageInfo info = new ImageInfo();
- info.setMagick("RGBA"); // Raw RGBA samples
- info.setSize(width + "x" + height); // String?!?
-
- MagickImage image = new MagickImage(info);
- image.setImageAttribute("depth", "8");
-
- // Set pixel data in 16 bit raw RGBA format
- image.blobToImage(info, raw16);
-
- return image;
- }
- */
-
- /**
- * Converts a bi-level {@code MagickImage} to a {@code BufferedImage}, of
- * type {@code TYPE_BYTE_BINARY}.
- *
- * @param pImage the original {@code MagickImage}
- * @return a new {@code BufferedImage}
- *
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- private static BufferedImage bilevelToBuffered(MagickImage pImage) throws MagickException {
- // As there is no way to get the binary representation of the image,
- // convert to gray, and the create a binary image from it
- BufferedImage temp = grayToBuffered(pImage, false);
-
- BufferedImage image = new BufferedImage(temp.getWidth(), temp.getHeight(), BufferedImage.TYPE_BYTE_BINARY, CM_MONOCHROME);
-
- ImageUtil.drawOnto(image, temp);
-
- return image;
- }
-
- /**
- * Converts a gray {@code MagickImage} to a {@code BufferedImage}, of
- * type {@code TYPE_USHORT_GRAY} or {@code TYPE_BYTE_GRAY}.
- *
- * @param pImage the original {@code MagickImage}
- * @param pAlpha keep alpha channel
- * @return a new {@code BufferedImage}
- *
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- private static BufferedImage grayToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
- Dimension size = pImage.getDimension();
- int length = size.width * size.height;
- int bands = pAlpha ? 2 : 1;
- byte[] pixels = new byte[length * bands];
-
- // TODO: Make a fix for 16 bit TYPE_USHORT_GRAY?!
- // Note: The ordering AI or I corresponds to BufferedImage
- // TYPE_CUSTOM and TYPE_BYTE_GRAY respectively
- pImage.dispatchImage(0, 0, size.width, size.height, pAlpha ? "AI" : "I", pixels);
-
- // Init databuffer with array, to avoid allocation of empty array
- DataBuffer buffer = new DataBufferByte(pixels, pixels.length);
-
- int[] bandOffsets = pAlpha ? new int[] {1, 0} : new int[] {0};
-
- WritableRaster raster =
- Raster.createInterleavedRaster(buffer, size.width, size.height,
- size.width * bands, bands, bandOffsets, LOCATION_UPPER_LEFT);
-
- return new BufferedImage(pAlpha ? CM_GRAY_ALPHA : CM_GRAY_OPAQUE, raster, pAlpha, null);
- }
-
- /**
- * Converts a palette-based {@code MagickImage} to a
- * {@code BufferedImage}, of type {@code TYPE_BYTE_BINARY} (for images
- * with a palette of <= 16 colors) or {@code TYPE_BYTE_INDEXED}.
- *
- * @param pImage the original {@code MagickImage}
- * @param pAlpha keep alpha channel
- * @return a new {@code BufferedImage}
- *
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- private static BufferedImage paletteToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
- // Create indexcolormodel for the image
- IndexColorModel cm;
-
- try {
- cm = createIndexColorModel(pImage.getColormap(), pAlpha);
- }
- catch (MagickException e) {
- // NOTE: Some MagickImages incorrecly (?) reports to be paletteType,
- // but does not have a colormap, this is a workaround.
- return rgbToBuffered(pImage, pAlpha);
- }
-
- // As there is no way to get the indexes of an indexed image, convert to
- // RGB, and the create an indexed image from it
- BufferedImage temp = rgbToBuffered(pImage, pAlpha);
-
- BufferedImage image;
- if (cm.getMapSize() <= 16) {
- image = new BufferedImage(temp.getWidth(), temp.getHeight(), BufferedImage.TYPE_BYTE_BINARY, cm);
- }
- else {
- image = new BufferedImage(temp.getWidth(), temp.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, cm);
- }
-
- // Create transparent background for images containing alpha
- if (pAlpha) {
- Graphics2D g = image.createGraphics();
- try {
- g.setComposite(AlphaComposite.Clear);
- g.fillRect(0, 0, temp.getWidth(), temp.getHeight());
- }
- finally {
- g.dispose();
- }
- }
-
- // NOTE: This is (surprisingly) much faster than using g2d.drawImage()..
- // (Tests shows 20-30ms, vs. 600-700ms on the same image)
- BufferedImageOp op = new CopyDither(cm);
- op.filter(temp, image);
-
- return image;
- }
-
- /**
- * Creates an {@code IndexColorModel} from an array of
- * {@code PixelPacket}s.
- *
- * @param pColormap the original colormap as a {@code PixelPacket} array
- * @param pAlpha keep alpha channel
- *
- * @return a new {@code IndexColorModel}
- */
- public static IndexColorModel createIndexColorModel(PixelPacket[] pColormap, boolean pAlpha) {
- int[] colors = new int[pColormap.length];
-
- // TODO: Verify if this is correct for alpha...?
- int trans = pAlpha ? colors.length - 1 : -1;
-
- //for (int i = 0; i < pColormap.length; i++) {
- for (int i = pColormap.length - 1; i != 0; i--) {
- PixelPacket color = pColormap[i];
- if (pAlpha) {
- colors[i] = (0xff - (color.getOpacity() & 0xff)) << 24 |
- (color.getRed() & 0xff) << 16 |
- (color.getGreen() & 0xff) << 8 |
- (color.getBlue() & 0xff);
- }
- else {
- colors[i] = (color.getRed() & 0xff) << 16 |
- (color.getGreen() & 0xff) << 8 |
- (color.getBlue() & 0xff);
- }
- }
-
- return new InverseColorMapIndexColorModel(8, colors.length, colors, 0, pAlpha, trans, DataBuffer.TYPE_BYTE);
- }
-
- /**
- * Converts an (A)RGB {@code MagickImage} to a {@code BufferedImage}, of
- * type {@code TYPE_4BYTE_ABGR} or {@code TYPE_3BYTE_BGR}.
- *
- * @param pImage the original {@code MagickImage}
- * @param pAlpha keep alpha channel
- * @return a new {@code BufferedImage}
- *
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- private static BufferedImage rgbToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
- Dimension size = pImage.getDimension();
- int length = size.width * size.height;
- int bands = pAlpha ? 4 : 3;
- byte[] pixels = new byte[length * bands];
-
- // TODO: If we do multiple dispatches (one per line, typically), we could provide listener
- // feedback. But it's currently a lot slower than fetching all the pixels in one go.
-
- // Note: The ordering ABGR or BGR corresponds to BufferedImage
- // TYPE_4BYTE_ABGR and TYPE_3BYTE_BGR respectively
- pImage.dispatchImage(0, 0, size.width, size.height, pAlpha ? "ABGR" : "BGR", pixels);
-
- // Init databuffer with array, to avoid allocation of empty array
- DataBuffer buffer = new DataBufferByte(pixels, pixels.length);
-
- int[] bandOffsets = pAlpha ? BAND_OFF_TRANS : BAND_OFF_OPAQUE;
-
- WritableRaster raster =
- Raster.createInterleavedRaster(buffer, size.width, size.height,
- size.width * bands, bands, bandOffsets, LOCATION_UPPER_LEFT);
-
- return new BufferedImage(pAlpha ? CM_COLOR_ALPHA : CM_COLOR_OPAQUE, raster, pAlpha, null);
- }
-
-
-
-
- /**
- * Converts an {@code MagickImage} to a {@code BufferedImage} which holds an CMYK ICC profile
- *
- * @param pImage the original {@code MagickImage}
- * @param pAlpha keep alpha channel
- * @return a new {@code BufferedImage}
- *
- * @throws MagickException if an exception occurs during conversion
- *
- * @see BufferedImage
- */
- private static BufferedImage cmykToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
- Dimension size = pImage.getDimension();
- int length = size.width * size.height;
-
- // Retreive the ICC profile
- ICC_Profile profile = ICC_Profile.getInstance(pImage.getColorProfile().getInfo());
- ColorSpace cs = new ICC_ColorSpace(profile);
-
- int bands = cs.getNumComponents() + (pAlpha ? 1 : 0);
-
- int[] bits = new int[bands];
- for (int i = 0; i < bands; i++) {
- bits[i] = 8;
- }
-
- ColorModel cm = pAlpha ?
- new ComponentColorModel(cs, bits, true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE) :
- new ComponentColorModel(cs, bits, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
-
- byte[] pixels = new byte[length * bands];
-
- // TODO: If we do multiple dispatches (one per line, typically), we could provide listener
- // feedback. But it's currently a lot slower than fetching all the pixels in one go.
- // TODO: handle more generic cases if profile is not CMYK
- // TODO: Test "ACMYK"
- pImage.dispatchImage(0, 0, size.width, size.height, pAlpha ? "ACMYK" : "CMYK", pixels);
-
- // Init databuffer with array, to avoid allocation of empty array
- DataBuffer buffer = new DataBufferByte(pixels, pixels.length);
-
- // TODO: build array from bands variable, here it just works for CMYK
- // The values has not been tested with an alpha picture actually...
- int[] bandOffsets = pAlpha ? new int[] {0, 1, 2, 3, 4} : new int[] {0, 1, 2, 3};
-
- WritableRaster raster =
- Raster.createInterleavedRaster(buffer, size.width, size.height,
- size.width * bands, bands, bandOffsets, LOCATION_UPPER_LEFT);
-
- return new BufferedImage(cm, raster, pAlpha, null);
-
- }
-}
diff --git a/common/common-image/src/main/java/com/twelvemonkeys/image/ResampleOp.java b/common/common-image/src/main/java/com/twelvemonkeys/image/ResampleOp.java
index d61d220d..0ddc7eab 100644
--- a/common/common-image/src/main/java/com/twelvemonkeys/image/ResampleOp.java
+++ b/common/common-image/src/main/java/com/twelvemonkeys/image/ResampleOp.java
@@ -55,9 +55,7 @@
package com.twelvemonkeys.image;
import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
+import java.awt.geom.*;
import java.awt.image.*;
/**
@@ -103,15 +101,6 @@ import java.awt.image.*;
* BufferedImage scaled = new ResampleOp(w, h).filter(temp, null);
*
*
- * For maximum performance, this class will use native code, through
- * JMagick, when available.
- * Otherwise, the class will silently fall back to pure Java mode.
- * Native code may be disabled globally, by setting the system property
- * {@code com.twelvemonkeys.image.accel} to {@code false}.
- * To allow debug of the native code, set the system property
- * {@code com.twelvemonkeys.image.magick.debug} to {@code true}.
- *
- *
* This {@code BufferedImageOp} is based on C example code found in
* Graphics Gems III,
* Filtered Image Rescaling, by Dale Schumacher (with additional improvments by
@@ -139,9 +128,6 @@ import java.awt.image.*;
// TODO: Consider using AffineTransformOp for more operations!?
public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
- // NOTE: These MUST correspond to ImageMagick filter types, for the
- // MagickAccelerator to work consistently (see magick.FilterType).
-
/**
* Undefined interpolation, filter method will use default filter.
*/
@@ -295,11 +281,10 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
new Value(KEY_RESAMPLE_INTERPOLATION, "Blackman-Sinc", FILTER_BLACKMAN_SINC);
// Member variables
- // Package access, to allow access from MagickAccelerator
- int width;
- int height;
+ private final int width;
+ private final int height;
- int filterType;
+ private final int filterType;
/**
* RendereingHints.Key implementation, works only with Value values.
@@ -547,16 +532,6 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
// Fall through
}
- // Try to use native ImageMagick code
- BufferedImage result = MagickAccelerator.filter(this, input, output);
- if (result != null) {
- return result;
- }
-
- // Otherwise, continue in pure Java mode
-
- // TODO: What if output != null and wrong size? Create new? Render on only a part? Document?
-
// If filter type != POINT or BOX and input has IndexColorModel, convert
// to true color, with alpha reflecting that of the original color model.
BufferedImage temp;
@@ -571,7 +546,7 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
// Create or convert output to a suitable image
// TODO: OPTIMIZE: Don't really need to convert all types to same as input
- result = output != null && temp.getType() != BufferedImage.TYPE_CUSTOM ? /*output*/ ImageUtil.toBuffered(output, temp.getType()) : createCompatibleDestImage(temp, null);
+ BufferedImage result = output != null && temp.getType() != BufferedImage.TYPE_CUSTOM ? /*output*/ ImageUtil.toBuffered(output, temp.getType()) : createCompatibleDestImage(temp, null);
resample(temp, result, filter);
@@ -1280,12 +1255,12 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
/*
* image rescaling routine
*/
- class Contributor {
+ static class Contributor {
int pixel;
double weight;
}
- class ContributorList {
+ static class ContributorList {
int n;/* number of contributors (may be < p.length) */
Contributor[] p;/* pointer to list of contributions */
}
diff --git a/common/common-image/todo.txt b/common/common-image/todo.txt
deleted file mode 100644
index c8ed52d1..00000000
--- a/common/common-image/todo.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-TODO:
- Remove compile-time dependency on JMagick:
- - Extract interface for MagickAccelerator
- - Move implementation to separate module
- - Instantiate impl via reflection
-DONE:
\ No newline at end of file