Beispiel #1
0
        /// <summary>
        /// Tries the compress the array with pixels into the provided buffer.
        /// </summary>
        /// <param name="info">The meta info that describes the format and type of the pixels.</param>
        /// <param name="pixels">An array of bytes that represents the content of a bitmap image.</param>
        /// <param name="pixelCount">The number of pixel in the pixel array.</param>
        /// <param name="jfifHeader">if set to <c>true</c> a JFIF header will be added to the encoded byte stream.</param>
        /// <param name="destination">The destination buffer that will hold the JPEG-LS compressed (encoded) bit stream.</param>
        /// <param name="destinationLength">Length of the destination buffer that can be used (can be less then the length of the destination array).</param>
        /// <param name="compressedCount">The number of bytes that have been compressed (encoded) into the destination array.</param>
        /// <returns><c>true</c> when the compressed bit stream fits into the destination array, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">info -or- pixels is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException">info.Width -or- info.Height -or- pixelCount -or- destinationLength contains an invalid value.</exception>
        public static bool TryCompress(JpegLSMetadataInfo info, byte[] pixels, int pixelCount, bool jfifHeader, byte[] destination, int destinationLength, out int compressedCount)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }
            if (info.Width <= 0 || info.Width > 65535)
            {
                throw new ArgumentOutOfRangeException(nameof(info), "info.Width property needs to be in the range <0, 65535>");
            }
            if (info.Height <= 0 || info.Height > 65535)
            {
                throw new ArgumentOutOfRangeException(nameof(info), "info.Height property needs to be in the range <0, 65535>");
            }
            if (pixels == null)
            {
                throw new ArgumentNullException(nameof(pixels));
            }
            if (pixelCount <= 0 || pixelCount > pixels.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(pixelCount), "pixelCount <= 0 || pixelCount > pixels.Length");
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }
            if (destinationLength <= 0 || destinationLength > destination.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(destinationLength), "destination <= 0 || destinationCount > destination.Length");
            }
            Contract.Ensures(Contract.ValueAtReturn(out compressedCount) >= 0);

            var parameters = default(JlsParameters);

            info.CopyTo(ref parameters);
            if (jfifHeader)
            {
                parameters.Jfif.Version  = (1 << 8) + 2; // JFIF version 1.02
                parameters.Jfif.Units    = 0;            // No units, aspect ratio only specified
                parameters.Jfif.DensityX = 1;            // use standard 1:1 aspect ratio. (density should always be set to non-zero values).
                parameters.Jfif.DensityY = 1;
            }

            var         errorMessage = new StringBuilder(256);
            JpegLSError result;

            if (Environment.Is64BitProcess)
            {
                result          = SafeNativeMethods.JpegLsEncode64(destination, destinationLength, out var count, pixels, pixelCount, ref parameters, errorMessage);
                compressedCount = (int)count;
            }
            else
            {
                result = SafeNativeMethods.JpegLsEncode(destination, destinationLength, out compressedCount, pixels, pixelCount, ref parameters, errorMessage);
            }

            Contract.Assume(compressedCount >= 0);

            if (result == JpegLSError.CompressedBufferTooSmall)
            {
                return(false);
            }

            HandleResult(result, errorMessage);
            return(true);
        }