/// <summary> /// Losslessly transform the JPEG image associated with this transformer instance and return an array of /// <seealso cref="TurboJpegDecompressor" /> instances, each of which has a transformed JPEG image associated /// with it. /// </summary> /// <param name="transforms">An array of <see cref="TurboJpegTransform" /> instances, each of which specifies /// the transform parameters and/or cropping region for the corresponding transformed output image.</param> /// <param name="flags">The flags to use when transforming.</param> /// <param name="preallocateBuffers">If set to <c>true</c>, preallocate buffers.</param> /// <returns> /// An array of <seealso cref="TurboJpegDecompressor" /> instances, each of which has a transformed /// JPEG image associated with it. /// </returns> public TurboJpegDecompressor[] Transform(TurboJpegTransform[] transforms, TurboJpegFlags flags, bool preallocateBuffers) { Contract.Requires(transforms != null); Contract.Requires(Enum.IsDefined(typeof(TransformOptions), flags)); Contract.Ensures(Contract.Result <TurboJpegDecompressor[]>() != null); Contract.Ensures(Contract.Result <TurboJpegDecompressor[]>().Length == transforms.Length); Contract.Ensures(Contract.ForAll(Contract.Result <TurboJpegDecompressor[]>(), _ => _ != null)); var count = transforms.Length; var destinationBuffers = new byte[count][]; Contract.Assume(this.Width > 0, "JPEG buffer not initialized"); Contract.Assume(this.Height > 0, "JPEG buffer not initialized"); var decompressors = new TurboJpegDecompressor[count]; if (preallocateBuffers) { for (var i = 0; i < count; i++) { var width = this.Width; var height = this.Height; if ((transforms[i].Options & TransformOptions.Crop) != 0) { if (transforms[i].Width != 0) { width = transforms[i].Width; } if (transforms[i].Height != 0) { height = transforms[i].Height; } } destinationBuffers[i] = new byte[NativeMethods.bufSize(width, height, this.Subsampling)]; } this.Transform(destinationBuffers, transforms, flags); for (var i = 0; i < count; i++) { decompressors[i] = new TurboJpegDecompressor(destinationBuffers[i]); } } else { var destBufferPtrs = new IntPtr[count]; this.transformedSizes = new int[count]; if (NativeMethods.transform(this.Handle, this.JpegBuffer, this.JpegSize, count, ref destBufferPtrs, ref this.transformedSizes, transforms, flags) != 0) { throw new Exception(TurboJpegInterop.GetLastError()); } // we now have the result in buffers on the unmanaged heap for (var i = 0; i < count; ++i) { decompressors[i] = new TurboJpegDecompressor(); decompressors[i].SetJpegImage(destBufferPtrs[i]); } } return(decompressors); }
/// <summary> /// Losslessly transform the JPEG image associated with this transformer instance and return an array of /// <seealso cref="TurboJpegDecompressor" /> instances, each of which has a transformed JPEG image associated /// with it. /// </summary> /// <param name="transforms">An array of <see cref="TurboJpegTransform" /> instances, each of which specifies /// the transform parameters and/or cropping region for the corresponding transformed output image.</param> /// <param name="flags">The flags to use when transforming.</param> /// <param name="preallocateBuffers">If set to <c>true</c>, preallocate buffers.</param> /// <returns> /// An array of <seealso cref="TurboJpegDecompressor" /> instances, each of which has a transformed /// JPEG image associated with it. /// </returns> public TurboJpegDecompressor[] Transform(TurboJpegTransform[] transforms, TurboJpegFlags flags, bool preallocateBuffers) { Contract.Requires(transforms != null); Contract.Requires(Enum.IsDefined(typeof(TransformOptions), flags)); Contract.Ensures(Contract.Result<TurboJpegDecompressor[]>() != null); Contract.Ensures(Contract.Result<TurboJpegDecompressor[]>().Length == transforms.Length); Contract.Ensures(Contract.ForAll(Contract.Result<TurboJpegDecompressor[]>(), _ => _ != null)); var count = transforms.Length; var destinationBuffers = new byte[count][]; Contract.Assume(this.Width > 0, "JPEG buffer not initialized"); Contract.Assume(this.Height > 0, "JPEG buffer not initialized"); var decompressors = new TurboJpegDecompressor[count]; if (preallocateBuffers) { for (var i = 0; i < count; i++) { var width = this.Width; var height = this.Height; if ((transforms[i].Options & TransformOptions.Crop) != 0) { if (transforms[i].Width != 0) { width = transforms[i].Width; } if (transforms[i].Height != 0) { height = transforms[i].Height; } } destinationBuffers[i] = new byte[NativeMethods.bufSize(width, height, this.Subsampling)]; } this.Transform(destinationBuffers, transforms, flags); for (var i = 0; i < count; i++) { decompressors[i] = new TurboJpegDecompressor(destinationBuffers[i]); } } else { var destBufferPtrs = new IntPtr[count]; this.transformedSizes = new int[count]; if (NativeMethods.transform(this.Handle, this.JpegBuffer, this.JpegSize, count, ref destBufferPtrs, ref this.transformedSizes, transforms, flags) != 0) { throw new Exception(TurboJpegInterop.GetLastError()); } // we now have the result in buffers on the unmanaged heap for (var i = 0; i < count; ++i) { decompressors[i] = new TurboJpegDecompressor(); decompressors[i].SetJpegImage(destBufferPtrs[i]); } } return decompressors; }