/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.jpeg.cpp; import java.nio.ByteBuffer; import org.bytedeco.javacpp.BytePointer; import org.bytedeco.javacpp.Loader; import org.bytedeco.javacpp.Pointer; import org.bytedeco.javacpp.SizeTPointer; import org.bytedeco.javacpp.annotation.ByVal; import org.bytedeco.javacpp.annotation.Cast; import org.bytedeco.javacpp.annotation.Platform; import org.weasis.jpeg.internal.DecoderIJG; /** * Wrap native API of IJG and CHARLS * * */ @Platform(include = { "libcparam.h", "libeijg8.h", "jpeglib8.h", "libijg8.h", "libijg12.h", "libijg16.h", "interface.h" }) // "charls.h" }) // new lib 2.0, charls.h instead of interface.h // , @Platform(value = "windows", define = "CHARLS_STATIC 0x01"), public class libijg { static { Loader.load(); } /** enum ERROR_TYPE */ public static final int NONE = 0, EC_MemoryExhausted = 1, EC_IllegalCall = 2, EJCode_IJG8_Decompression = 3, EJ_Suspension = 4, EJ_UnsupportedColorConversion = 5, EJ_IJG8_FrameBufferTooSmall = 6; /** enum J_COLOR_SPACE */ public static final int JCS_UNKNOWN = 0, /* error/unspecified */ JCS_GRAYSCALE = 1, /* monochrome */ JCS_RGB = 2, /* red/green/blue */ JCS_YCbCr = 3, /* Y/Cb/Cr (also known as YUV) */ JCS_CMYK = 4, /* C/M/Y/K */ JCS_YCCK = 5; /* Y/Cb/Cr/K */ /** enum EP_Interpretation: constants for photometric interpretation */ public static final int EPI_Unknown = 0, // unknown, undefined, invalid // no element value available EPI_Missing = 1, // / monochrome 1 EPI_Monochrome1 = 2, // / monochrome 2 EPI_Monochrome2 = 3, // / palette color EPI_PaletteColor = 4, // / RGB color EPI_RGB = 5, // / HSV color (retired) EPI_HSV = 6, // / ARGB color (retired) EPI_ARGB = 7, // / CMYK color (retired) EPI_CMYK = 8, // / YCbCr full EPI_YBR_Full = 9, // / YCbCr full 4:2:2 EPI_YBR_Full_422 = 10, // / YCbCr partial 4:2:2 EPI_YBR_Partial_422 = 11; /** * enum EJ_Mode: describes the different modes of operation of a JPEG codec */ public static final int EJM_baseline = 0, // JPEG baseline // JPEG extended sequential EJM_sequential = 1, // JPEG spectral selection EJM_spectralSelection = 2, // JPEG full progression EJM_progressive = 3, // JPEG lossless EJM_lossless = 4; /** * enum E_CompressionColorSpaceConversion: describes how color space conversion should be handled during the * conversion of an uncompressed DICOM image to a JPEG-compressed image */ public static final int ECC_lossyYCbCr = 0, /** * encode color images in YCbCr if lossy JPEG. If lossless JPEG, images are encoded as RGB unless * the source image is YCbCr in which case no color conversion is performed. */ /** * encode color images in RGB unless the source image is YCbCr in which case no color conversion is * performed. */ ECC_lossyRGB = 1, /** * convert color images to monochrome before compressing */ ECC_monochrome = 2; /** * enum E_SubSampling: describes the different types of component sub-sampling to be used with lossy image * compression. */ public static final int ESS_444 = 0, // 4:4:4 sampling (no subsampling) // 4:2:2 sampling (horizontal subsampling of chroma components) ESS_422 = 1, // 4:1:1 sampling (horizontal and vertical subsampling of chroma components) ESS_411 = 2; public static class RETURN_MSG extends Pointer { static { Loader.load(); } public RETURN_MSG() { allocate(); } private native void allocate(); @Cast("ERROR_TYPE") public native int code(); public native RETURN_MSG code(@Cast("ERROR_TYPE") int code); @Cast("const char*") public native BytePointer msg(); public native RETURN_MSG msg(@Cast("const char*") BytePointer msg); } public static class jpeg_decompress_struct extends Pointer { static { Loader.load(); } public jpeg_decompress_struct() { allocate(); } private native void allocate(); public native int data_precision(); public native jpeg_decompress_struct data_precision(int data_precision); @Cast("J_COLOR_SPACE") public native int jpeg_color_space(); public native jpeg_decompress_struct jpeg_color_space(@Cast("J_COLOR_SPACE") int jpeg_color_space); @Cast("unsigned int") public native int image_width(); public native jpeg_decompress_struct image_width(@Cast("unsigned int") int image_width); @Cast("unsigned int") public native int image_height(); public native jpeg_decompress_struct image_height(@Cast("unsigned int") int image_width); public native int num_components(); public native jpeg_decompress_struct num_components(int num_components); @Cast("unsigned int") public native int output_width(); public native jpeg_decompress_struct output_width(@Cast("unsigned int") int output_width); @Cast("unsigned int") public native int output_height(); public native jpeg_decompress_struct output_height(@Cast("unsigned int") int output_height); public native int output_components(); public native jpeg_decompress_struct output_components(int output_components); } public static class DJDecompressIJG8Bit extends Pointer implements DecoderIJG { static { Loader.load(); } public DJDecompressIJG8Bit() { allocate(); } private native void allocate(); @Override public native jpeg_decompress_struct getJpeg_DecompressStruct(); @Override public native int getDecompressedColorModel(); @Override @Cast("unsigned short") public native int bytesPerSample(); @Override @ByVal public native RETURN_MSG init(boolean isYBR); @Override @ByVal public native RETURN_MSG readHeader(@Cast("unsigned char*") ByteBuffer compressedFrameBuffer, @Cast("unsigned long") long compressedFrameBufferSize, boolean isSigned); @Override @ByVal public native RETURN_MSG decode(@Cast("unsigned char*") ByteBuffer compressedFrameBuffer, @Cast("unsigned long") long compressedFrameBufferSize, @Cast("unsigned char*") ByteBuffer uncompressedFrameBuffer, @Cast("unsigned long") long uncompressedFrameBufferSize); } public static class DJDecompressIJG12Bit extends Pointer implements DecoderIJG { static { Loader.load(); } public DJDecompressIJG12Bit() { allocate(); } @Override public void close() { this.deallocate(); } private native void allocate(); @Override public native jpeg_decompress_struct getJpeg_DecompressStruct(); @Override public native int getDecompressedColorModel(); @Override @Cast("unsigned short") public native int bytesPerSample(); @Override @ByVal public native RETURN_MSG init(boolean isYBR); @Override @ByVal public native RETURN_MSG readHeader(@Cast("unsigned char*") ByteBuffer compressedFrameBuffer, @Cast("unsigned long") long compressedFrameBufferSize, boolean isSigned); @Override @ByVal public native RETURN_MSG decode(@Cast("unsigned char*") ByteBuffer compressedFrameBuffer, @Cast("unsigned long") long compressedFrameBufferSize, @Cast("unsigned char*") ByteBuffer uncompressedFrameBuffer, @Cast("unsigned long") long uncompressedFrameBufferSize); } public static class DJDecompressIJG16Bit extends Pointer implements DecoderIJG { static { Loader.load(); } public DJDecompressIJG16Bit() { allocate(); } private native void allocate(); @Override public native jpeg_decompress_struct getJpeg_DecompressStruct(); @Override public native int getDecompressedColorModel(); @Override @Cast("unsigned short") public native int bytesPerSample(); @Override @ByVal public native RETURN_MSG init(boolean isYBR); @Override @ByVal public native RETURN_MSG readHeader(@Cast("unsigned char*") ByteBuffer compressedFrameBuffer, @Cast("unsigned long") long compressedFrameBufferSize, boolean isSigned); @Override @ByVal public native RETURN_MSG decode(@Cast("unsigned char*") ByteBuffer compressedFrameBuffer, @Cast("unsigned long") long compressedFrameBufferSize, @Cast("unsigned char*") ByteBuffer uncompressedFrameBuffer, @Cast("unsigned long") long uncompressedFrameBufferSize); } /****************** * IJG Compression *****************/ /** * codec parameter for IJG codecs */ // public static class DJCodecParameter extends Pointer { // static { // Loader.load(); // } // // /** // * constructor. // * // * @param pCompressionCSConversion // * color conversion mode for compression // * @param pOptimizeHuffman // * perform huffman table optimization for 8 bits/pixel compression? // * @param pSmoothingFactor // * smoothing factor for image compression, 0..100 // * @param pForcedBitDepth // * forced bit depth for image compression, 0 (auto) or 8/12/16 // * @param pFragmentSize // * maximum fragment size (in kbytes) for compression, 0 for unlimited. // * @param pSampleFactors // * subsampling mode for color image compression // */ // public DJCodecParameter(@Cast("E_CompressionColorSpaceConversion") int pCompressionCSConversion, // boolean pOptimizeHuffman, int pSmoothingFactor, int pForcedBitDepth, // @Cast("unsigned int") int pFragmentSize, @Cast("E_SubSampling") int pSampleFactors) { // allocate(pCompressionCSConversion, pOptimizeHuffman, pSmoothingFactor, pForcedBitDepth, pFragmentSize, // pSampleFactors); // } // // public DJCodecParameter(@Cast("E_CompressionColorSpaceConversion") int pCompressionCSConversion) { // allocate(pCompressionCSConversion); // } // // public DJCodecParameter(@ByRef DJCodecParameter arg) { // allocate(arg); // } // // private native void allocate(@Cast("E_CompressionColorSpaceConversion") int pCompressionCSConversion, // boolean pOptimizeHuffman, int pSmoothingFactor, int pForcedBitDepth, // @Cast("unsigned int") int pFragmentSize, @Cast("E_SubSampling") int pSampleFactors); // // private native void allocate(@Cast("E_CompressionColorSpaceConversion") int pCompressionCSConversion); // // private native void allocate(@ByRef DJCodecParameter arg); // // public native int getSmoothingFactor(); // // } // // public static class DJCompressIJG8Bit extends Pointer implements EncoderIJG { // static { // Loader.load(); // } // // public DJCompressIJG8Bit(@ByRef DJCodecParameter cp, @Cast("EJ_Mode") int mode, // @Cast("unsigned char") byte quality) { // allocate(cp, mode, quality); // } // // public DJCompressIJG8Bit(@ByRef DJCodecParameter cp, @Cast("EJ_Mode") int mode, int prediction, int ptrans) { // allocate(cp, mode, prediction, ptrans); // } // // private native void allocate(@ByRef DJCodecParameter cp, @Cast("EJ_Mode") int mode, // @Cast("unsigned char") byte quality); // // private native void allocate(@ByRef DJCodecParameter cp, @Cast("EJ_Mode") int mode, int prediction, int ptrans); // // /** // * single frame compression routine for 8-bit raw pixel data. May only be called if bytesPerSample() == 1. // * // * @param columns // * columns of frame // * @param rows // * rows of frame // * @param interpr // * photometric interpretation of input frame // * @param samplesPerPixel // * samples per pixel of input frame // * @param image_buffer // * pointer to frame buffer // * @param to // * compressed frame returned in this parameter upon success // * @param length // * length of compressed frame (in bytes) returned in this parameter upon success; length guaranteed // * to be always even. // * @return EC_Normal if successful, an error code otherwise. // */ // @Override // public native @ByVal RETURN_MSG encode(@Cast("unsigned short") int columns, @Cast("unsigned short") int rows, // @Cast("EP_Interpretation") int interpr, @Cast("unsigned short") int samplesPerPixel, // @Cast("unsigned char*") ByteBuffer image_buffer, @Cast("unsigned char*") ByteBuffer to, // @Cast("unsigned int&") IntPointer length); // // /** // * returns the number of bytes per sample that will be expected when encoding. // */ // @Override // @Cast("unsigned short") // public native int bytesPerSample(); // // /** // * returns the number of bits per sample that will be expected when encoding. // */ // @Override // @Cast("unsigned short") // public native int bitsPerSample(); // } /******************************************************************************************************************************************* * * CHARLS LIB * *******************************************************************************************************************************************/ /** enum interleavemode */ public static final int ILV_NONE = 0, ILV_LINE = 1, ILV_SAMPLE = 2; /** enum JLS_ERROR */ public static final int OK = 0; public static final String getErrorMessage(int error) { switch (error) { case 0: return "No error"; case 1: return "Invalid JlsParameters"; case 2: return "Parameter Value Not Supported"; case 3: return "Uncompressed Buffer Too Small"; case 4: return "Compressed Buffer Too Small"; case 5: // This error is returned when the encoded bit stream contains a general structural problem. return "Invalid Compressed Data"; case 6: return "Too Much Compressed Data"; case 7: // This error is returned when the bit stream is encoded with an option that is not supported by this // implementation. return "Image Type Not Supported"; case 8: return "Unsupported Bit Depth For Transform"; case 9: return "Unsupported Color Transform"; case 10: // This error is returned when an encoded frame is found that is not encoded with the JPEG-LS algorithm. return "Unsupported Encoding"; case 11: // This error is returned when an unknown JPEG marker code is detected in the encoded bit stream. return "Unknown Jpeg Marker"; case 12: // This error is returned when the algorithm expect a 0xFF code (indicates start of a JPEG marker) but // none was found. return "Missing Jpeg Marker Start"; default: return "Unexpected error"; } } public static class ByteStreamInfo extends Pointer { static { Loader.load(); } public ByteStreamInfo() { allocate(); } private native void allocate(); @Cast("unsigned char*") private native ByteBuffer rawData(); public native void rawData(@Cast("unsigned char*") ByteBuffer buf); @ByVal public native SizeTPointer count(); public native void count(@ByVal SizeTPointer count); } @ByVal public static native ByteStreamInfo FromByteArray(ByteBuffer buf, @ByVal SizeTPointer count); @ByVal public static native ByteStreamInfo FromByteArray(byte[] buf, @ByVal SizeTPointer count); @ByVal public static native ByteStreamInfo FromByteArray(BytePointer buf, @ByVal SizeTPointer count); public static class JlsParameters extends Pointer { static { Loader.load(); } public JlsParameters() { allocate(); } private native void allocate(); public native int width(); public native JlsParameters width(int width); public native int height(); public native JlsParameters height(int height); public native int bitspersample(); public native JlsParameters bitspersample(int bitspersample); public native int bytesperline(); public native JlsParameters bytesperline(int bytesperline); public native int components(); public native JlsParameters components(int components); public native int allowedlossyerror(); public native JlsParameters allowedlossyerror(int allowedlossyerror); @Cast("interleavemode") public native int ilv(); public native JlsParameters ilv(@Cast("interleavemode") int ilv); public native int colorTransform(); public native JlsParameters colorTransform(int colorTransform); public native char outputBgr(); public native JlsParameters outputBgr(char outputBgr); // struct JlsCustomParameters custom; // struct JfifParameters jfif; } @Cast("JLS_ERROR") public static native int JpegLsEncodeStream(@ByVal ByteStreamInfo rawStream, SizeTPointer bytesWritten, @ByVal ByteStreamInfo inputStream, JlsParameters info); @Cast("JLS_ERROR") public static native int JpegLsDecodeStream(@ByVal ByteStreamInfo output, @ByVal ByteStreamInfo input, JlsParameters info); @Cast("JLS_ERROR") public static native int JpegLsReadHeaderStream(@ByVal ByteStreamInfo input, JlsParameters info); }