/// <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 (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"); } 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; } JpegLSError result; if (Environment.Is64BitProcess) { result = SafeNativeMethods.JpegLsEncode64(destination, destinationLength, out var count, pixels, pixelCount, ref parameters, IntPtr.Zero); compressedCount = (int)count; } else { result = SafeNativeMethods.JpegLsEncode(destination, destinationLength, out compressedCount, pixels, pixelCount, ref parameters, IntPtr.Zero); } if (result == JpegLSError.SourceBufferTooSmall) { return(false); } HandleResult(result); return(true); }
/// <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 (Is64BitProcess) { long count; result = SafeNativeMethods.JpegLsEncode64(destination, destinationLength, out 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); }