+++ /dev/null
-/*\r
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium\r
- * Copyright (c) 2002-2007, Professor Benoit Macq\r
- * Copyright (c) 2002-2007, Patrick Piscaglia, Telemis s.a.\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */ \r
-package org.openJpeg;\r
-\r
-import java.util.Vector;\r
-\r
-/** This class decodes one J2K codestream into an image (width + height + depth + pixels[], \r
- * using the OpenJPEG.org library.\r
- * To be able to log messages, the called must register a IJavaJ2KDecoderLogger object.\r
- */\r
-public class OpenJPEGJavaDecoder {\r
-\r
- public interface IJavaJ2KDecoderLogger {\r
- public void logDecoderMessage(String message);\r
- public void logDecoderError(String message);\r
- }\r
- \r
- private static boolean isInitialized = false;\r
- \r
- // ===== decompression parameters =============>\r
- // These value may be changed for each image\r
- private String[] decoder_arguments = null;\r
- /** number of resolutions decompositions */\r
- private int nbResolutions = -1;\r
- /** the quality layers */\r
- private int[] layers = null;\r
-\r
- /** Contains the 8 bpp version of the image. May NOT be filled together with image16 or image24.<P>\r
- * We store in Java the 8 or 16 bpp version of the image while the decoder uses a 32 bpp version, because <UL>\r
- * <LI> the storage capacity required is smaller\r
- * <LI> the transfer Java <-- C will be faster\r
- * <LI> the conversion byte/short ==> int will be done faster by the C\r
- * </UL>*/\r
- private byte[] image8 = null;\r
- /** Contains the 16 bpp version of the image. May NOT be filled together with image8 or image24*/\r
- private short[] image16 = null;\r
- /** Contains the 24 bpp version of the image. May NOT be filled together with image8 or image16 */\r
- private int[] image24 = null;\r
- /** Holds the J2K compressed bytecode to decode */\r
- private byte compressedStream[] = null;\r
- /** Holds the compressed version of the index file, to be used by the decoder */\r
- private byte compressedIndex[] = null;\r
- /** Width and Height of the image */\r
- private int width = -1;\r
- private int height = -1;\r
- private int depth = -1;\r
- /** This parameter is never used in Java but is read by the C library to know the number of resolutions to skip when decoding, \r
- * i.e. if there are 5 resolutions and skipped=1 ==> decode until resolution 4. */\r
- private int skippedResolutions = 0;\r
- \r
- private Vector<IJavaJ2KDecoderLogger> loggers = new Vector();\r
-\r
-\r
- public OpenJPEGJavaDecoder(String openJPEGlibraryFullPathAndName, IJavaJ2KDecoderLogger messagesAndErrorsLogger) throws ExceptionInInitializerError\r
- {\r
- this(openJPEGlibraryFullPathAndName);\r
- loggers.addElement(messagesAndErrorsLogger);\r
- }\r
-\r
- public OpenJPEGJavaDecoder(String openJPEGlibraryFullPathAndName) throws ExceptionInInitializerError\r
- {\r
- if (!isInitialized) {\r
- try {\r
- System.load(openJPEGlibraryFullPathAndName);\r
- isInitialized = true;\r
- } catch (Throwable t) {\r
- throw new ExceptionInInitializerError("OpenJPEG Java Decoder: probably impossible to find the C library");\r
- }\r
- }\r
- }\r
- \r
- public void addLogger(IJavaJ2KDecoderLogger messagesAndErrorsLogger) {\r
- loggers.addElement(messagesAndErrorsLogger);\r
- }\r
- \r
- public void removeLogger(IJavaJ2KDecoderLogger messagesAndErrorsLogger) {\r
- loggers.removeElement(messagesAndErrorsLogger);\r
- }\r
- \r
- public int decodeJ2KtoImage() {\r
- if ((image16 == null || (image16 != null && image16.length != width*height)) && (depth==-1 || depth==16)) {\r
- image16 = new short[width*height];\r
- logMessage("OpenJPEGJavaDecoder.decompressImage: image16 length = " + image16.length + " (" + width + " x " + height + ") ");\r
- }\r
- if ((image8 == null || (image8 != null && image8.length != width*height)) && (depth==-1 || depth==8)) {\r
- image8 = new byte[width*height];\r
- logMessage("OpenJPEGJavaDecoder.decompressImage: image8 length = " + image8.length + " (" + width + " x " + height + ") ");\r
- }\r
- if ((image24 == null || (image24 != null && image24.length != width*height)) && (depth==-1 || depth==24)) {\r
- image24 = new int[width*height];\r
- logMessage("OpenJPEGJavaDecoder.decompressImage: image24 length = " + image24.length + " (" + width + " x " + height + ") ");\r
- }\r
- \r
- String[] arguments = new String[0 + (decoder_arguments != null ? decoder_arguments.length : 0)];\r
- int offset = 0;\r
- if (decoder_arguments != null) {\r
- for (int i=0; i<decoder_arguments.length; i++) {\r
- arguments[i+offset] = decoder_arguments[i];\r
- }\r
- }\r
-\r
- return internalDecodeJ2KtoImage(arguments);\r
- }\r
- \r
- /** \r
- * Decode the j2k stream given in the codestream byte[] and fills the image8, image16 or image24 array, according to the bit depth.\r
- */\r
- private native int internalDecodeJ2KtoImage(String[] parameters);\r
-\r
- /** Image depth in bpp */\r
- public int getDepth() {\r
- return depth;\r
- }\r
-\r
- /** Image depth in bpp */\r
- public void setDepth(int depth) {\r
- this.depth = depth;\r
- }\r
-\r
- /** Image height in pixels */\r
- public int getHeight() {\r
- return height;\r
- }\r
-\r
- /** Image height in pixels */\r
- public void setHeight(int height) {\r
- this.height = height;\r
- }\r
-\r
- /** Number of resolutions contained in the image */\r
- public int getNbResolutions() {\r
- return nbResolutions;\r
- }\r
-\r
- /** Number of resolutions contained in the image */\r
- public void setNbResolutions(int nbResolutions) {\r
- this.nbResolutions = nbResolutions;\r
- }\r
-\r
- /** Width of the image in pixels */\r
- public int getWidth() {\r
- return width;\r
- }\r
-\r
- /** Width of the image in pixels */\r
- public void setWidth(int width) {\r
- this.width = width;\r
- }\r
-\r
- /** Contains the decompressed version of the image, if the depth in is [9,16] bpp.\r
- * Returns NULL otherwise.\r
- */\r
- public short[] getImage16() {\r
- return image16;\r
- }\r
-\r
- /** Contains the decompressed version of the image, if the depth in is [17,24] bpp and the image is in color.\r
- * Returns NULL otherwise.\r
- */\r
- public int[] getImage24() {\r
- return image24;\r
- }\r
-\r
- /** Contains the decompressed version of the image, if the depth in is [1,8] bpp.\r
- * Returns NULL otherwise.\r
- */\r
- public byte[] getImage8() {\r
- return image8;\r
- }\r
-\r
- /** Sets the compressed version of the index file for this image.\r
- * This index file is used by the decompressor\r
- */\r
- public void setCompressedIndex(byte[] compressedIndex) {\r
- this.compressedIndex = compressedIndex;\r
- }\r
-\r
- /** Sets the codestream to be decoded */\r
- public void setCompressedStream(byte[] compressedStream) {\r
- this.compressedStream = compressedStream;\r
- }\r
-\r
- /** @return the compressed code stream length, or -1 if not defined */\r
- public long getCodestreamLength() {\r
- if (compressedStream == null)\r
- return -1;\r
- else return compressedStream.length;\r
- }\r
- \r
- /** This method is called either directly or by the C methods */\r
- public void logMessage(String message) {\r
- for (IJavaJ2KDecoderLogger logger:loggers)\r
- logger.logDecoderMessage(message);\r
- }\r
- \r
- /** This method is called either directly or by the C methods */\r
- public void logError(String error) {\r
- for (IJavaJ2KDecoderLogger logger:loggers)\r
- logger.logDecoderError(error);\r
- }\r
-\r
- public void reset() {\r
- nbResolutions = -1;\r
- layers = null;\r
- image8 = null;\r
- image16 = null;\r
- image24 = null;\r
- compressedStream = null;\r
- compressedIndex = null;\r
- width = -1;\r
- height = -1;\r
- depth = -1;\r
- }\r
-\r
- public void setSkippedResolutions(int numberOfSkippedResolutions) {\r
- skippedResolutions = numberOfSkippedResolutions;\r
- }\r
-\r
- /** Contains all the decoding arguments other than the input/output file */\r
- public void setDecoderArguments(String[] argumentsForTheDecoder) {\r
- decoder_arguments = argumentsForTheDecoder;\r
- }\r
-\r
-\r
-}\r
+++ /dev/null
-/*\r
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium\r
- * Copyright (c) 2002-2007, Professor Benoit Macq\r
- * Copyright (c) 2002-2007, Patrick Piscaglia, Telemis s.a.\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */ \r
-package org.openJpeg;\r
-\r
-import java.io.File;\r
-import java.util.Vector;\r
-\r
-/** This class encodes one image into the J2K format, \r
- * using the OpenJPEG.org library.\r
- * To be able to log messages, the called must register a IJavaJ2KEncoderLogger object.\r
- */\r
-public class OpenJPEGJavaEncoder {\r
-\r
- public interface IJavaJ2KEncoderLogger {\r
- public void logEncoderMessage(String message);\r
- public void logEncoderError(String message);\r
- }\r
- \r
- private static boolean isInitialized = false;\r
- \r
- // ===== Compression parameters =============>\r
- // These value may be changed for each image\r
- private String[] encoder_arguments = null;\r
- /** number of resolutions decompositions */\r
- private int nbResolutions = -1;\r
- /** the quality layers, expressed as compression rate */\r
- private float[] ratioLayers = null;\r
- /** the quality layers, expressed as PSNR values. This variable, if defined, has priority over the ratioLayers variable */\r
- private float[] psnrLayers = null;\r
- \r
- /** Contains the 8 bpp version of the image. May NOT be filled together with image16 or image24.<P>\r
- * We store the 8 or 16 bpp version of the original image while the encoder uses a 32 bpp version, because <UL>\r
- * <LI> the storage capacity required is smaller\r
- * <LI> the transfer Java --> C will be faster\r
- * <LI> the conversion byte/short ==> int will be done faster by the C\r
- * </UL>*/\r
- private byte[] image8 = null;\r
- /** Contains the 16 bpp version of the image. May NOT be filled together with image8 or image24*/\r
- private short[] image16 = null;\r
- /** Contains the 24 bpp version of the image. May NOT be filled together with image8 or image16 */\r
- private int[] image24 = null;\r
- /** Holds the result of the compression, i.e. the J2K compressed bytecode */\r
- private byte compressedStream[] = null;\r
- /** Holds the compressed stream length, which may be smaller than compressedStream.length if this byte[] is pre-allocated */\r
- private long compressedStreamLength = -1;\r
- /** Holds the compressed version of the index file, returned by the encoder */\r
- private byte compressedIndex[] = null;\r
- /** Width and Height of the image */\r
- private int width = -1;\r
- private int height = -1;\r
- private int depth = -1;\r
- /** Tile size. We suppose the same size for the horizontal and vertical tiles.\r
- * If size == -1 ==> no tiling */\r
- private int tileSize = -1;\r
- // <===== Compression parameters =============\r
- \r
- private Vector<IJavaJ2KEncoderLogger> loggers = new Vector();\r
-\r
- public OpenJPEGJavaEncoder(String openJPEGlibraryFullPathAndName, IJavaJ2KEncoderLogger messagesAndErrorsLogger) throws ExceptionInInitializerError\r
- {\r
- this(openJPEGlibraryFullPathAndName);\r
- loggers.addElement(messagesAndErrorsLogger);\r
- }\r
-\r
- public OpenJPEGJavaEncoder(String openJPEGlibraryFullPathAndName) throws ExceptionInInitializerError\r
- {\r
- if (!isInitialized) {\r
- try {\r
- String absolutePath = (new File(openJPEGlibraryFullPathAndName)).getCanonicalPath();\r
- System.load(absolutePath);\r
- isInitialized = true;\r
- } catch (Throwable t) {\r
- t.printStackTrace();\r
- throw new ExceptionInInitializerError("OpenJPEG Java Encoder: probably impossible to find the C library");\r
- }\r
- }\r
- }\r
- \r
- public void addLogger(IJavaJ2KEncoderLogger messagesAndErrorsLogger) {\r
- loggers.addElement(messagesAndErrorsLogger);\r
- }\r
- \r
- public void removeLogger(IJavaJ2KEncoderLogger messagesAndErrorsLogger) {\r
- loggers.removeElement(messagesAndErrorsLogger);\r
- }\r
- \r
- /** This method compresses the given image.<P>\r
- * It returns the compressed J2K codestream into the compressedStream byte[].<P>\r
- * It also returns the compression index as a compressed form, into the compressedIndex byte[].<P>\r
- * One of the image8, image16 or image24 arrays must be correctly initialized and filled.<P>\r
- * The width, height and depth variables must be correctly filled.<P>\r
- * The nbResolutions, nbLayers and if needed the float[] psnrLayers or ratioLayers must also be filled before calling this method.\r
- */\r
- public void encodeImageToJ2K() {\r
- // Need to allocate / reallocate the compressed stream buffer ? (size = max possible size = original image size)\r
- if (compressedStream== null || (compressedStream.length != width*height*depth/8)) {\r
- logMessage("OpenJPEGJavaEncoder.encodeImageToJ2K: (re-)allocating " + (width*height*depth/8) + " bytes for the compressedStream");\r
- compressedStream = new byte[width*height*depth/8];\r
- }\r
- // Arguments = \r
- // - number of resolutions "-n 5" : 2\r
- // - size of tile "-t 512,512" : 2\r
- // \r
- // Image width, height, depth and pixels are directly fetched by C from the Java class\r
- int nbArgs = 2 + (tileSize == -1 ? 0 : 2) + (encoder_arguments != null ? encoder_arguments.length : 0);\r
- if (psnrLayers != null && psnrLayers.length>0 && psnrLayers[0] != 0)\r
- // If psnrLayers is defined and doesn't just express "lossless"\r
- nbArgs += 2;\r
- else if (ratioLayers != null && ratioLayers.length>0 && ratioLayers[0]!=0.0)\r
- nbArgs += 2;\r
- String[] arguments = new String[nbArgs];\r
- int offset = 0;\r
- arguments[offset] = "-n"; arguments[offset+1] = "" + nbResolutions; offset += 2;\r
- if (tileSize!= -1) {\r
- arguments[offset++] = "-t"; \r
- arguments[offset++] = "" + tileSize + "," + tileSize;\r
- }\r
- // If PSNR layers are defined, use them to encode the images\r
- if (psnrLayers != null && psnrLayers.length>0 && psnrLayers[0]!=-1) {\r
- arguments[offset++] = "-q";\r
- String s = "";\r
- for (int i=0; i<psnrLayers.length; i++)\r
- s += psnrLayers[i] + ",";\r
- arguments[offset++] = s.substring(0, s.length()-1);\r
- } else if (ratioLayers != null && ratioLayers.length>0 && ratioLayers[0]!=0.0) {\r
- // Specify quality ratioLayers, as compression ratios\r
- arguments[offset++] = "-r";\r
- String s = "";\r
- for (int i=0; i<ratioLayers.length; i++)\r
- s += ratioLayers[i] + ",";\r
- arguments[offset++] = s.substring(0, s.length()-1);\r
- }\r
- if (encoder_arguments != null) {\r
- for (int i=0; i<encoder_arguments.length; i++) {\r
- arguments[i+offset] = encoder_arguments[i];\r
- }\r
- }\r
- logMessage("Encoder additional arguments = " + arrayToString(arguments));\r
- long startTime = (new java.util.Date()).getTime();\r
- compressedStreamLength = internalEncodeImageToJ2K(arguments);\r
- logMessage("compression time = " + ((new java.util.Date()).getTime() - startTime) + " msec");\r
- }\r
- \r
- /** \r
- * Fills the compressedStream byte[] and the compressedIndex byte[]\r
- * @return the codestream length.\r
- */\r
- private native long internalEncodeImageToJ2K(String[] parameters);\r
-\r
- /** Image depth in bpp */\r
- public int getDepth() {\r
- return depth;\r
- }\r
-\r
- /** Image depth in bpp */\r
- public void setDepth(int depth) {\r
- this.depth = depth;\r
- }\r
-\r
- /** Image height in pixels */\r
- public int getHeight() {\r
- return height;\r
- }\r
-\r
- /** Image height in pixels */\r
- public void setHeight(int height) {\r
- this.height = height;\r
- }\r
-\r
- /** This method must be called in depth in [9,16].\r
- * @param an array of shorts, containing width*height values\r
- */\r
- public void setImage16(short[] image16) {\r
- this.image16 = image16;\r
- }\r
-\r
- /** This method must be called in depth in [17,24] for RGB images.\r
- * @param an array of int, containing width*height values\r
- */\r
- public void setImage24(int[] image24) {\r
- this.image24 = image24;\r
- }\r
-\r
- /** This method must be called in depth in [1,8].\r
- * @param an array of bytes, containing width*height values\r
- */\r
- public void setImage8(byte[] image8) {\r
- this.image8 = image8;\r
- }\r
-\r
- /** Return the ratioLayers, i.e. the compression ratio for each quality layer.\r
- * If the last value is 0.0, last layer is lossless compressed.\r
- */\r
- public float[] getRatioLayers() {\r
- return ratioLayers;\r
- }\r
-\r
- /**\r
- * sets the quality layers.\r
- * At least one level.\r
- * Each level is expressed as a compression ratio (float).\r
- * If the last value is 0.0, the last layer will be losslessly compressed\r
- */\r
- public void setRatioLayers(float[] layers) {\r
- this.ratioLayers = layers;\r
- }\r
-\r
- /** Return the PSNR Layers, i.e. the target PSNR for each quality layer.\r
- * If the last value is -1, last layer is lossless compressed.\r
- */\r
- public float[] getPsnrLayers() {\r
- return psnrLayers;\r
- }\r
-\r
- /**\r
- * sets the quality layers.\r
- * At least one level.\r
- * Each level is expressed as a target PSNR (float).\r
- * If the last value is -1, the last layer will be losslessly compressed\r
- */\r
- public void setPsnrLayers(float[] layers) {\r
- this.psnrLayers = layers;\r
- }\r
-\r
- /** Set the number of resolutions that must be created */\r
- public void setNbResolutions(int nbResolutions) {\r
- this.nbResolutions = nbResolutions;\r
- }\r
-\r
- public int getWidth() {\r
- return width;\r
- }\r
-\r
- /** Width of the image, in pixels */\r
- public void setWidth(int width) {\r
- this.width = width;\r
- }\r
-\r
- /** Return the compressed index file.\r
- * Syntax: TODO PP:\r
- */\r
- public byte[] getCompressedIndex() {\r
- return compressedIndex;\r
- }\r
- \r
- public void setCompressedIndex(byte[] index) {\r
- compressedIndex = index;\r
- }\r
-\r
- public byte[] getCompressedStream() {\r
- return compressedStream;\r
- }\r
-\r
- public void reset() {\r
- nbResolutions = -1;\r
- ratioLayers = null;\r
- psnrLayers = null;\r
- image8 = null;\r
- image16 = null;\r
- image24 = null;\r
- compressedStream = null;\r
- compressedIndex = null;\r
- width = -1;\r
- height = -1;\r
- depth = -1;\r
- }\r
-\r
- public short[] getImage16() {\r
- return image16;\r
- }\r
-\r
- public int[] getImage24() {\r
- return image24;\r
- }\r
-\r
- public byte[] getImage8() {\r
- return image8;\r
- }\r
- \r
- /** Sets the size of the tiles. We assume square tiles */\r
- public void setTileSize(int tileSize) {\r
- this.tileSize = tileSize;\r
- }\r
- \r
- /** Contains all the encoding arguments other than the input/output file, compression ratio, tile size */\r
- public void setEncoderArguments(String[] argumentsForTheEncoder) {\r
- encoder_arguments = argumentsForTheEncoder;\r
- }\r
-\r
- public void logMessage(String message) {\r
- for (IJavaJ2KEncoderLogger logger:loggers)\r
- logger.logEncoderMessage(message);\r
- }\r
- \r
- public void logError(String error) {\r
- for (IJavaJ2KEncoderLogger logger:loggers)\r
- logger.logEncoderError(error);\r
- }\r
-\r
- public long getCompressedStreamLength() {\r
- return compressedStreamLength;\r
- }\r
- \r
- private String arrayToString(String[] array) {\r
- if (array == null)\r
- return "NULL";\r
- StringBuffer sb = new StringBuffer();\r
- for (int i=0; i<array.length; i++)\r
- sb.append(array[i]).append(" ");\r
- sb.delete(sb.length()-1, sb.length());\r
- return sb.toString();\r
- }\r
-}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium\r
+ * Copyright (c) 2002-2007, Professor Benoit Macq\r
+ * Copyright (c) 2002-2007, Patrick Piscaglia, Telemis s.a.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */ \r
+package org.openJpeg;\r
+\r
+import java.util.Vector;\r
+\r
+/** This class decodes one J2K codestream into an image (width + height + depth + pixels[], \r
+ * using the OpenJPEG.org library.\r
+ * To be able to log messages, the called must register a IJavaJ2KDecoderLogger object.\r
+ */\r
+public class OpenJPEGJavaDecoder {\r
+\r
+ public interface IJavaJ2KDecoderLogger {\r
+ public void logDecoderMessage(String message);\r
+ public void logDecoderError(String message);\r
+ }\r
+ \r
+ private static boolean isInitialized = false;\r
+ \r
+ // ===== decompression parameters =============>\r
+ // These value may be changed for each image\r
+ private String[] decoder_arguments = null;\r
+ /** number of resolutions decompositions */\r
+ private int nbResolutions = -1;\r
+ /** the quality layers */\r
+ private int[] layers = null;\r
+\r
+ /** Contains the 8 bpp version of the image. May NOT be filled together with image16 or image24.<P>\r
+ * We store in Java the 8 or 16 bpp version of the image while the decoder uses a 32 bpp version, because <UL>\r
+ * <LI> the storage capacity required is smaller\r
+ * <LI> the transfer Java <-- C will be faster\r
+ * <LI> the conversion byte/short ==> int will be done faster by the C\r
+ * </UL>*/\r
+ private byte[] image8 = null;\r
+ /** Contains the 16 bpp version of the image. May NOT be filled together with image8 or image24*/\r
+ private short[] image16 = null;\r
+ /** Contains the 24 bpp version of the image. May NOT be filled together with image8 or image16 */\r
+ private int[] image24 = null;\r
+ /** Holds the J2K compressed bytecode to decode */\r
+ private byte compressedStream[] = null;\r
+ /** Holds the compressed version of the index file, to be used by the decoder */\r
+ private byte compressedIndex[] = null;\r
+ /** Width and Height of the image */\r
+ private int width = -1;\r
+ private int height = -1;\r
+ private int depth = -1;\r
+ /** This parameter is never used in Java but is read by the C library to know the number of resolutions to skip when decoding, \r
+ * i.e. if there are 5 resolutions and skipped=1 ==> decode until resolution 4. */\r
+ private int skippedResolutions = 0;\r
+ \r
+ private Vector<IJavaJ2KDecoderLogger> loggers = new Vector();\r
+\r
+\r
+ public OpenJPEGJavaDecoder(String openJPEGlibraryFullPathAndName, IJavaJ2KDecoderLogger messagesAndErrorsLogger) throws ExceptionInInitializerError\r
+ {\r
+ this(openJPEGlibraryFullPathAndName);\r
+ loggers.addElement(messagesAndErrorsLogger);\r
+ }\r
+\r
+ public OpenJPEGJavaDecoder(String openJPEGlibraryFullPathAndName) throws ExceptionInInitializerError\r
+ {\r
+ if (!isInitialized) {\r
+ try {\r
+ System.load(openJPEGlibraryFullPathAndName);\r
+ isInitialized = true;\r
+ } catch (Throwable t) {\r
+ throw new ExceptionInInitializerError("OpenJPEG Java Decoder: probably impossible to find the C library");\r
+ }\r
+ }\r
+ }\r
+ \r
+ public void addLogger(IJavaJ2KDecoderLogger messagesAndErrorsLogger) {\r
+ loggers.addElement(messagesAndErrorsLogger);\r
+ }\r
+ \r
+ public void removeLogger(IJavaJ2KDecoderLogger messagesAndErrorsLogger) {\r
+ loggers.removeElement(messagesAndErrorsLogger);\r
+ }\r
+ \r
+ public int decodeJ2KtoImage() {\r
+ if ((image16 == null || (image16 != null && image16.length != width*height)) && (depth==-1 || depth==16)) {\r
+ image16 = new short[width*height];\r
+ logMessage("OpenJPEGJavaDecoder.decompressImage: image16 length = " + image16.length + " (" + width + " x " + height + ") ");\r
+ }\r
+ if ((image8 == null || (image8 != null && image8.length != width*height)) && (depth==-1 || depth==8)) {\r
+ image8 = new byte[width*height];\r
+ logMessage("OpenJPEGJavaDecoder.decompressImage: image8 length = " + image8.length + " (" + width + " x " + height + ") ");\r
+ }\r
+ if ((image24 == null || (image24 != null && image24.length != width*height)) && (depth==-1 || depth==24)) {\r
+ image24 = new int[width*height];\r
+ logMessage("OpenJPEGJavaDecoder.decompressImage: image24 length = " + image24.length + " (" + width + " x " + height + ") ");\r
+ }\r
+ \r
+ String[] arguments = new String[0 + (decoder_arguments != null ? decoder_arguments.length : 0)];\r
+ int offset = 0;\r
+ if (decoder_arguments != null) {\r
+ for (int i=0; i<decoder_arguments.length; i++) {\r
+ arguments[i+offset] = decoder_arguments[i];\r
+ }\r
+ }\r
+\r
+ return internalDecodeJ2KtoImage(arguments);\r
+ }\r
+ \r
+ /** \r
+ * Decode the j2k stream given in the codestream byte[] and fills the image8, image16 or image24 array, according to the bit depth.\r
+ */\r
+ private native int internalDecodeJ2KtoImage(String[] parameters);\r
+\r
+ /** Image depth in bpp */\r
+ public int getDepth() {\r
+ return depth;\r
+ }\r
+\r
+ /** Image depth in bpp */\r
+ public void setDepth(int depth) {\r
+ this.depth = depth;\r
+ }\r
+\r
+ /** Image height in pixels */\r
+ public int getHeight() {\r
+ return height;\r
+ }\r
+\r
+ /** Image height in pixels */\r
+ public void setHeight(int height) {\r
+ this.height = height;\r
+ }\r
+\r
+ /** Number of resolutions contained in the image */\r
+ public int getNbResolutions() {\r
+ return nbResolutions;\r
+ }\r
+\r
+ /** Number of resolutions contained in the image */\r
+ public void setNbResolutions(int nbResolutions) {\r
+ this.nbResolutions = nbResolutions;\r
+ }\r
+\r
+ /** Width of the image in pixels */\r
+ public int getWidth() {\r
+ return width;\r
+ }\r
+\r
+ /** Width of the image in pixels */\r
+ public void setWidth(int width) {\r
+ this.width = width;\r
+ }\r
+\r
+ /** Contains the decompressed version of the image, if the depth in is [9,16] bpp.\r
+ * Returns NULL otherwise.\r
+ */\r
+ public short[] getImage16() {\r
+ return image16;\r
+ }\r
+\r
+ /** Contains the decompressed version of the image, if the depth in is [17,24] bpp and the image is in color.\r
+ * Returns NULL otherwise.\r
+ */\r
+ public int[] getImage24() {\r
+ return image24;\r
+ }\r
+\r
+ /** Contains the decompressed version of the image, if the depth in is [1,8] bpp.\r
+ * Returns NULL otherwise.\r
+ */\r
+ public byte[] getImage8() {\r
+ return image8;\r
+ }\r
+\r
+ /** Sets the compressed version of the index file for this image.\r
+ * This index file is used by the decompressor\r
+ */\r
+ public void setCompressedIndex(byte[] compressedIndex) {\r
+ this.compressedIndex = compressedIndex;\r
+ }\r
+\r
+ /** Sets the codestream to be decoded */\r
+ public void setCompressedStream(byte[] compressedStream) {\r
+ this.compressedStream = compressedStream;\r
+ }\r
+\r
+ /** @return the compressed code stream length, or -1 if not defined */\r
+ public long getCodestreamLength() {\r
+ if (compressedStream == null)\r
+ return -1;\r
+ else return compressedStream.length;\r
+ }\r
+ \r
+ /** This method is called either directly or by the C methods */\r
+ public void logMessage(String message) {\r
+ for (IJavaJ2KDecoderLogger logger:loggers)\r
+ logger.logDecoderMessage(message);\r
+ }\r
+ \r
+ /** This method is called either directly or by the C methods */\r
+ public void logError(String error) {\r
+ for (IJavaJ2KDecoderLogger logger:loggers)\r
+ logger.logDecoderError(error);\r
+ }\r
+\r
+ public void reset() {\r
+ nbResolutions = -1;\r
+ layers = null;\r
+ image8 = null;\r
+ image16 = null;\r
+ image24 = null;\r
+ compressedStream = null;\r
+ compressedIndex = null;\r
+ width = -1;\r
+ height = -1;\r
+ depth = -1;\r
+ }\r
+\r
+ public void setSkippedResolutions(int numberOfSkippedResolutions) {\r
+ skippedResolutions = numberOfSkippedResolutions;\r
+ }\r
+\r
+ /** Contains all the decoding arguments other than the input/output file */\r
+ public void setDecoderArguments(String[] argumentsForTheDecoder) {\r
+ decoder_arguments = argumentsForTheDecoder;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium\r
+ * Copyright (c) 2002-2007, Professor Benoit Macq\r
+ * Copyright (c) 2002-2007, Patrick Piscaglia, Telemis s.a.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */ \r
+package org.openJpeg;\r
+\r
+import java.io.File;\r
+import java.util.Vector;\r
+\r
+/** This class encodes one image into the J2K format, \r
+ * using the OpenJPEG.org library.\r
+ * To be able to log messages, the called must register a IJavaJ2KEncoderLogger object.\r
+ */\r
+public class OpenJPEGJavaEncoder {\r
+\r
+ public interface IJavaJ2KEncoderLogger {\r
+ public void logEncoderMessage(String message);\r
+ public void logEncoderError(String message);\r
+ }\r
+ \r
+ private static boolean isInitialized = false;\r
+ \r
+ // ===== Compression parameters =============>\r
+ // These value may be changed for each image\r
+ private String[] encoder_arguments = null;\r
+ /** number of resolutions decompositions */\r
+ private int nbResolutions = -1;\r
+ /** the quality layers, expressed as compression rate */\r
+ private float[] ratioLayers = null;\r
+ /** the quality layers, expressed as PSNR values. This variable, if defined, has priority over the ratioLayers variable */\r
+ private float[] psnrLayers = null;\r
+ \r
+ /** Contains the 8 bpp version of the image. May NOT be filled together with image16 or image24.<P>\r
+ * We store the 8 or 16 bpp version of the original image while the encoder uses a 32 bpp version, because <UL>\r
+ * <LI> the storage capacity required is smaller\r
+ * <LI> the transfer Java --> C will be faster\r
+ * <LI> the conversion byte/short ==> int will be done faster by the C\r
+ * </UL>*/\r
+ private byte[] image8 = null;\r
+ /** Contains the 16 bpp version of the image. May NOT be filled together with image8 or image24*/\r
+ private short[] image16 = null;\r
+ /** Contains the 24 bpp version of the image. May NOT be filled together with image8 or image16 */\r
+ private int[] image24 = null;\r
+ /** Holds the result of the compression, i.e. the J2K compressed bytecode */\r
+ private byte compressedStream[] = null;\r
+ /** Holds the compressed stream length, which may be smaller than compressedStream.length if this byte[] is pre-allocated */\r
+ private long compressedStreamLength = -1;\r
+ /** Holds the compressed version of the index file, returned by the encoder */\r
+ private byte compressedIndex[] = null;\r
+ /** Width and Height of the image */\r
+ private int width = -1;\r
+ private int height = -1;\r
+ private int depth = -1;\r
+ /** Tile size. We suppose the same size for the horizontal and vertical tiles.\r
+ * If size == -1 ==> no tiling */\r
+ private int tileSize = -1;\r
+ // <===== Compression parameters =============\r
+ \r
+ private Vector<IJavaJ2KEncoderLogger> loggers = new Vector();\r
+\r
+ public OpenJPEGJavaEncoder(String openJPEGlibraryFullPathAndName, IJavaJ2KEncoderLogger messagesAndErrorsLogger) throws ExceptionInInitializerError\r
+ {\r
+ this(openJPEGlibraryFullPathAndName);\r
+ loggers.addElement(messagesAndErrorsLogger);\r
+ }\r
+\r
+ public OpenJPEGJavaEncoder(String openJPEGlibraryFullPathAndName) throws ExceptionInInitializerError\r
+ {\r
+ if (!isInitialized) {\r
+ try {\r
+ String absolutePath = (new File(openJPEGlibraryFullPathAndName)).getCanonicalPath();\r
+ System.load(absolutePath);\r
+ isInitialized = true;\r
+ } catch (Throwable t) {\r
+ t.printStackTrace();\r
+ throw new ExceptionInInitializerError("OpenJPEG Java Encoder: probably impossible to find the C library");\r
+ }\r
+ }\r
+ }\r
+ \r
+ public void addLogger(IJavaJ2KEncoderLogger messagesAndErrorsLogger) {\r
+ loggers.addElement(messagesAndErrorsLogger);\r
+ }\r
+ \r
+ public void removeLogger(IJavaJ2KEncoderLogger messagesAndErrorsLogger) {\r
+ loggers.removeElement(messagesAndErrorsLogger);\r
+ }\r
+ \r
+ /** This method compresses the given image.<P>\r
+ * It returns the compressed J2K codestream into the compressedStream byte[].<P>\r
+ * It also returns the compression index as a compressed form, into the compressedIndex byte[].<P>\r
+ * One of the image8, image16 or image24 arrays must be correctly initialized and filled.<P>\r
+ * The width, height and depth variables must be correctly filled.<P>\r
+ * The nbResolutions, nbLayers and if needed the float[] psnrLayers or ratioLayers must also be filled before calling this method.\r
+ */\r
+ public void encodeImageToJ2K() {\r
+ // Need to allocate / reallocate the compressed stream buffer ? (size = max possible size = original image size)\r
+ if (compressedStream== null || (compressedStream.length != width*height*depth/8)) {\r
+ logMessage("OpenJPEGJavaEncoder.encodeImageToJ2K: (re-)allocating " + (width*height*depth/8) + " bytes for the compressedStream");\r
+ compressedStream = new byte[width*height*depth/8];\r
+ }\r
+ // Arguments = \r
+ // - number of resolutions "-n 5" : 2\r
+ // - size of tile "-t 512,512" : 2\r
+ // \r
+ // Image width, height, depth and pixels are directly fetched by C from the Java class\r
+ int nbArgs = 2 + (tileSize == -1 ? 0 : 2) + (encoder_arguments != null ? encoder_arguments.length : 0);\r
+ if (psnrLayers != null && psnrLayers.length>0 && psnrLayers[0] != 0)\r
+ // If psnrLayers is defined and doesn't just express "lossless"\r
+ nbArgs += 2;\r
+ else if (ratioLayers != null && ratioLayers.length>0 && ratioLayers[0]!=0.0)\r
+ nbArgs += 2;\r
+ String[] arguments = new String[nbArgs];\r
+ int offset = 0;\r
+ arguments[offset] = "-n"; arguments[offset+1] = "" + nbResolutions; offset += 2;\r
+ if (tileSize!= -1) {\r
+ arguments[offset++] = "-t"; \r
+ arguments[offset++] = "" + tileSize + "," + tileSize;\r
+ }\r
+ // If PSNR layers are defined, use them to encode the images\r
+ if (psnrLayers != null && psnrLayers.length>0 && psnrLayers[0]!=-1) {\r
+ arguments[offset++] = "-q";\r
+ String s = "";\r
+ for (int i=0; i<psnrLayers.length; i++)\r
+ s += psnrLayers[i] + ",";\r
+ arguments[offset++] = s.substring(0, s.length()-1);\r
+ } else if (ratioLayers != null && ratioLayers.length>0 && ratioLayers[0]!=0.0) {\r
+ // Specify quality ratioLayers, as compression ratios\r
+ arguments[offset++] = "-r";\r
+ String s = "";\r
+ for (int i=0; i<ratioLayers.length; i++)\r
+ s += ratioLayers[i] + ",";\r
+ arguments[offset++] = s.substring(0, s.length()-1);\r
+ }\r
+ if (encoder_arguments != null) {\r
+ for (int i=0; i<encoder_arguments.length; i++) {\r
+ arguments[i+offset] = encoder_arguments[i];\r
+ }\r
+ }\r
+ logMessage("Encoder additional arguments = " + arrayToString(arguments));\r
+ long startTime = (new java.util.Date()).getTime();\r
+ compressedStreamLength = internalEncodeImageToJ2K(arguments);\r
+ logMessage("compression time = " + ((new java.util.Date()).getTime() - startTime) + " msec");\r
+ }\r
+ \r
+ /** \r
+ * Fills the compressedStream byte[] and the compressedIndex byte[]\r
+ * @return the codestream length.\r
+ */\r
+ private native long internalEncodeImageToJ2K(String[] parameters);\r
+\r
+ /** Image depth in bpp */\r
+ public int getDepth() {\r
+ return depth;\r
+ }\r
+\r
+ /** Image depth in bpp */\r
+ public void setDepth(int depth) {\r
+ this.depth = depth;\r
+ }\r
+\r
+ /** Image height in pixels */\r
+ public int getHeight() {\r
+ return height;\r
+ }\r
+\r
+ /** Image height in pixels */\r
+ public void setHeight(int height) {\r
+ this.height = height;\r
+ }\r
+\r
+ /** This method must be called in depth in [9,16].\r
+ * @param an array of shorts, containing width*height values\r
+ */\r
+ public void setImage16(short[] image16) {\r
+ this.image16 = image16;\r
+ }\r
+\r
+ /** This method must be called in depth in [17,24] for RGB images.\r
+ * @param an array of int, containing width*height values\r
+ */\r
+ public void setImage24(int[] image24) {\r
+ this.image24 = image24;\r
+ }\r
+\r
+ /** This method must be called in depth in [1,8].\r
+ * @param an array of bytes, containing width*height values\r
+ */\r
+ public void setImage8(byte[] image8) {\r
+ this.image8 = image8;\r
+ }\r
+\r
+ /** Return the ratioLayers, i.e. the compression ratio for each quality layer.\r
+ * If the last value is 0.0, last layer is lossless compressed.\r
+ */\r
+ public float[] getRatioLayers() {\r
+ return ratioLayers;\r
+ }\r
+\r
+ /**\r
+ * sets the quality layers.\r
+ * At least one level.\r
+ * Each level is expressed as a compression ratio (float).\r
+ * If the last value is 0.0, the last layer will be losslessly compressed\r
+ */\r
+ public void setRatioLayers(float[] layers) {\r
+ this.ratioLayers = layers;\r
+ }\r
+\r
+ /** Return the PSNR Layers, i.e. the target PSNR for each quality layer.\r
+ * If the last value is -1, last layer is lossless compressed.\r
+ */\r
+ public float[] getPsnrLayers() {\r
+ return psnrLayers;\r
+ }\r
+\r
+ /**\r
+ * sets the quality layers.\r
+ * At least one level.\r
+ * Each level is expressed as a target PSNR (float).\r
+ * If the last value is -1, the last layer will be losslessly compressed\r
+ */\r
+ public void setPsnrLayers(float[] layers) {\r
+ this.psnrLayers = layers;\r
+ }\r
+\r
+ /** Set the number of resolutions that must be created */\r
+ public void setNbResolutions(int nbResolutions) {\r
+ this.nbResolutions = nbResolutions;\r
+ }\r
+\r
+ public int getWidth() {\r
+ return width;\r
+ }\r
+\r
+ /** Width of the image, in pixels */\r
+ public void setWidth(int width) {\r
+ this.width = width;\r
+ }\r
+\r
+ /** Return the compressed index file.\r
+ * Syntax: TODO PP:\r
+ */\r
+ public byte[] getCompressedIndex() {\r
+ return compressedIndex;\r
+ }\r
+ \r
+ public void setCompressedIndex(byte[] index) {\r
+ compressedIndex = index;\r
+ }\r
+\r
+ public byte[] getCompressedStream() {\r
+ return compressedStream;\r
+ }\r
+\r
+ public void reset() {\r
+ nbResolutions = -1;\r
+ ratioLayers = null;\r
+ psnrLayers = null;\r
+ image8 = null;\r
+ image16 = null;\r
+ image24 = null;\r
+ compressedStream = null;\r
+ compressedIndex = null;\r
+ width = -1;\r
+ height = -1;\r
+ depth = -1;\r
+ }\r
+\r
+ public short[] getImage16() {\r
+ return image16;\r
+ }\r
+\r
+ public int[] getImage24() {\r
+ return image24;\r
+ }\r
+\r
+ public byte[] getImage8() {\r
+ return image8;\r
+ }\r
+ \r
+ /** Sets the size of the tiles. We assume square tiles */\r
+ public void setTileSize(int tileSize) {\r
+ this.tileSize = tileSize;\r
+ }\r
+ \r
+ /** Contains all the encoding arguments other than the input/output file, compression ratio, tile size */\r
+ public void setEncoderArguments(String[] argumentsForTheEncoder) {\r
+ encoder_arguments = argumentsForTheEncoder;\r
+ }\r
+\r
+ public void logMessage(String message) {\r
+ for (IJavaJ2KEncoderLogger logger:loggers)\r
+ logger.logEncoderMessage(message);\r
+ }\r
+ \r
+ public void logError(String error) {\r
+ for (IJavaJ2KEncoderLogger logger:loggers)\r
+ logger.logEncoderError(error);\r
+ }\r
+\r
+ public long getCompressedStreamLength() {\r
+ return compressedStreamLength;\r
+ }\r
+ \r
+ private String arrayToString(String[] array) {\r
+ if (array == null)\r
+ return "NULL";\r
+ StringBuffer sb = new StringBuffer();\r
+ for (int i=0; i<array.length; i++)\r
+ sb.append(array[i]).append(" ");\r
+ sb.delete(sb.length()-1, sb.length());\r
+ return sb.toString();\r
+ }\r
+}\r