示例#1
0
        /// <summary>
        /// Sets the MCT matrix to use.
        /// </summary>
        /// <param name="parameters">The <see cref="CompressionParameters"/> to change.</param>
        /// <param name="encodingMatrix">The encoding matrix.</param>
        /// <param name="dcShift">The dc shift coefficients to use.</param>
        /// <param name="components">The number of components of the image.</param>
        /// <returns><code>true</code> if the parameters could be set; otherwise, <code>false</code>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="parameters"/>, <paramref name="encodingMatrix"/> or <paramref name="dcShift"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="parameters"/> is disposed.</exception>
        /// <exception cref="ArgumentOutOfRangeException">The length of <paramref name="encodingMatrix"/> must be <paramref name="components"/> x <paramref name="components"/> or less. Or The length of <paramref name="dcShift"/> must be <paramref name="components"/> or less</exception>
        public static bool SetMCT(CompressionParameters parameters,
                                  float[] encodingMatrix,
                                  int[] dcShift,
                                  uint components)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            if (encodingMatrix == null)
            {
                throw new ArgumentNullException(nameof(encodingMatrix));
            }
            if (dcShift == null)
            {
                throw new ArgumentNullException(nameof(dcShift));
            }

            parameters.ThrowIfDisposed();

            var matrixSize  = components * components;
            var dcShiftSize = components;

            if (!(encodingMatrix.Length <= matrixSize))
            {
                throw new ArgumentOutOfRangeException($"{nameof(encodingMatrix)}", $"The length of {nameof(encodingMatrix)} must be {nameof(components)} x {nameof(components)} or less.");
            }
            if (!(dcShift.Length <= dcShiftSize))
            {
                throw new ArgumentOutOfRangeException($"{nameof(dcShift)}", $"The length of {nameof(dcShift)} must be {nameof(components)} or less.");
            }

            return(NativeMethods.openjpeg_openjp2_opj_set_MCT(parameters.NativePtr, encodingMatrix, dcShift, components));
        }
        /// <summary>
        /// Set encoding parameters to default values.
        /// </summary>
        /// <param name="parameters">The <see cref="CompressionParameters"/> to compress image.</param>
        /// <exception cref="ArgumentNullException"><paramref name="parameters"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="parameters"/> is disposed.</exception>
        public static void SetDefaultEncoderParameters(CompressionParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            parameters.ThrowIfDisposed();

            NativeMethods.openjpeg_openjp2_opj_set_default_encoder_parameters(parameters.NativePtr);
        }
        /// <summary>
        /// Setup the decoder with decompression parameters provided by the user and with the message handler provided by the user.
        /// </summary>
        /// <param name="codec">The <see cref="Codec"/> to compress image.</param>
        /// <param name="parameters">The <see cref="CompressionParameters"/> to ccompress image.</param>
        /// <param name="image">Input filled image.</param>
        /// <returns><code>true</code> if the decoder is correctly set; otherwise, <code>false</code>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="codec"/>, <paramref name="parameters"/> or <paramref name="image"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="codec"/>, <paramref name="parameters"/> or <paramref name="image"/> is disposed.</exception>
        public static bool SetupEncoder(Codec codec, CompressionParameters parameters, Image image)
        {
            if (codec == null)
            {
                throw new ArgumentNullException(nameof(codec));
            }
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }

            codec.ThrowIfDisposed();
            parameters.ThrowIfDisposed();
            image.ThrowIfDisposed();

            return(NativeMethods.openjpeg_openjp2_opj_setup_encoder(codec.NativePtr, parameters.NativePtr, image.NativePtr));
        }
        public static Image FromBitmap(Bitmap bitmap)
        {
            if (bitmap == null)
            {
                throw new ArgumentNullException(nameof(bitmap));
            }

            var        width  = bitmap.Width;
            var        height = bitmap.Height;
            var        format = bitmap.PixelFormat;
            int        channels;
            var        byteAllocated = 0;
            ColorSpace colorSpace;

            switch (format)
            {
            case PixelFormat.Format24bppRgb:
                channels      = 3;
                colorSpace    = ColorSpace.Srgb;
                byteAllocated = 1;
                break;

            case PixelFormat.Format32bppArgb:
                channels      = 4;
                colorSpace    = ColorSpace.Srgb;
                byteAllocated = 1;
                break;

            case PixelFormat.Format8bppIndexed:
                channels      = 1;
                colorSpace    = ColorSpace.Gray;
                byteAllocated = 1;
                break;

            default:
                throw new NotSupportedException();
            }
            var precision = 24u / (uint)channels;

            BitmapData bitmapData = null;

            try
            {
                bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, format);
                var stride = bitmapData.Stride;
                var gap    = stride - width * channels;
                var scan0  = bitmapData.Scan0;

                using (var compressionParameters = new CompressionParameters())
                {
                    OpenJpeg.SetDefaultEncoderParameters(compressionParameters);

                    var subsamplingDx = compressionParameters.SubsamplingDx;
                    var subsamplingDy = compressionParameters.SubsamplingDy;

                    var componentParametersArray = new ImageComponentParameters[channels];
                    for (var i = 0; i < channels; i++)
                    {
                        componentParametersArray[i] = new ImageComponentParameters
                        {
                            Precision = precision,
                            Bpp       = precision,
                            Signed    = false,
                            Dx        = (uint)subsamplingDx,
                            Dy        = (uint)subsamplingDy,
                            Width     = (uint)width,
                            Height    = (uint)height
                        };
                    }

                    var image = OpenJpeg.ImageCreate((uint)channels, componentParametersArray, colorSpace);
                    if (image == null)
                    {
                        return(null);
                    }

                    image.X0 = (uint)compressionParameters.ImageOffsetX0;
                    image.Y0 = (uint)compressionParameters.ImageOffsetY0;
                    image.X1 = image.X0 == 0 ? (uint)(width - 1) * (uint)subsamplingDx + 1 : image.X0 + (uint)(width - 1) * (uint)subsamplingDx + 1;
                    image.Y1 = image.Y0 == 0 ? (uint)(height - 1) * (uint)subsamplingDy + 1 : image.Y0 + (uint)(height - 1) * (uint)subsamplingDy + 1;

                    unsafe
                    {
                        // Bitmap data is interleave.
                        // Convert it to planer
                        if (byteAllocated == 1)
                        {
                            for (var i = 0; i < channels; i++)
                            {
                                // need to fix the colorspace
                                IntPtr target;
                                if (channels >= 3)
                                {
                                    if (i == 0)
                                    {
                                        target = image.Components[2].Data; // B-R
                                    }
                                    else if (i == 1)
                                    {
                                        target = image.Components[1].Data; // G-G
                                    }
                                    else if (i == 2)
                                    {
                                        target = image.Components[0].Data; // R-B
                                    }
                                    else
                                    {
                                        target = image.Components[i].Data;
                                    }
                                }
                                else
                                {
                                    target = image.Components[i].Data;
                                }

                                var pTarget = (int *)target;
                                var source  = (byte *)scan0;
                                source += i;
                                for (var y = 0; y < height; y++)
                                {
                                    for (var x = 0; x < width; x++)
                                    {
                                        *pTarget = *source;
                                        pTarget++;
                                        source += channels;
                                    }

                                    source += gap;
                                }
                            }
                        }
                    }

                    return(image);
                }
            }
            finally
            {
                if (bitmapData != null)
                {
                    bitmap.UnlockBits(bitmapData);
                }
            }
        }
        public static Image FromRaw(byte[] raw, int width, int height, int stride, int channels, bool interleaved)
        {
            if (raw == null)
            {
                throw new ArgumentNullException(nameof(raw));
            }

            var byteAllocated = 1;
            var colorSpace    = ColorSpace.Srgb;
            var precision     = 24u / (uint)channels;
            var gap           = stride - width * channels;

            using (var compressionParameters = new CompressionParameters())
            {
                OpenJpeg.SetDefaultEncoderParameters(compressionParameters);

                var subsamplingDx = compressionParameters.SubsamplingDx;
                var subsamplingDy = compressionParameters.SubsamplingDy;

                var componentParametersArray = new ImageComponentParameters[channels];
                for (var i = 0; i < channels; i++)
                {
                    componentParametersArray[i] = new ImageComponentParameters
                    {
                        Precision = precision,
                        Bpp       = precision,
                        Signed    = false,
                        Dx        = (uint)subsamplingDx,
                        Dy        = (uint)subsamplingDy,
                        Width     = (uint)width,
                        Height    = (uint)height
                    };
                }

                var image = OpenJpeg.ImageCreate((uint)channels, componentParametersArray, colorSpace);
                if (image == null)
                {
                    return(null);
                }

                image.X0 = (uint)compressionParameters.ImageOffsetX0;
                image.Y0 = (uint)compressionParameters.ImageOffsetY0;
                image.X1 = image.X0 == 0 ? (uint)(width - 1) * (uint)subsamplingDx + 1 : image.X0 + (uint)(width - 1) * (uint)subsamplingDx + 1;
                image.Y1 = image.Y0 == 0 ? (uint)(height - 1) * (uint)subsamplingDy + 1 : image.Y0 + (uint)(height - 1) * (uint)subsamplingDy + 1;

                unsafe
                {
                    fixed(byte *pRaw = &raw[0])
                    {
                        // Bitmap data is interleave.
                        // Convert it to planer
                        if (byteAllocated == 1)
                        {
                            if (interleaved)
                            {
                                for (var i = 0; i < channels; i++)
                                {
                                    var target  = image.Components[i].Data;
                                    var pTarget = (int *)target;
                                    var source  = pRaw + i;
                                    for (var y = 0; y < height; y++)
                                    {
                                        for (var x = 0; x < width; x++)
                                        {
                                            *pTarget = *source;
                                            pTarget++;
                                            source += channels;
                                        }

                                        source += gap;
                                    }
                                }
                            }
                            else
                            {
                                for (var i = 0; i < channels; i++)
                                {
                                    var target  = image.Components[i].Data;
                                    var pTarget = (int *)target;
                                    var source  = pRaw + i * (stride * height);
                                    for (var y = 0; y < height; y++)
                                    {
                                        for (var x = 0; x < width; x++)
                                        {
                                            *pTarget = *source;
                                            pTarget++;
                                            source++;
                                        }

                                        source += gap;
                                    }
                                }
                            }
                        }
                    }
                }

                return(image);
            }
        }