private static extern int tjTransform_64(IntPtr handle, byte [] jpegBuf, ulong jpegSize, int n, IntPtr[] dstBufs, ulong [] dstSizes, Transform [] transforms, FunctionFlags flags);
/// <summary> /// Losslessly transform a JPEG image into another JPEG image. Lossless /// transforms work by moving the raw coefficients from one JPEG image structure /// to another without altering the values of the coefficients. While this is /// typically faster than decompressing the image, transforming it, and /// re-compressing it, lossless transforms are not free. Each lossless /// transform requires reading and performing Huffman decoding on all of the /// coefficients in the source image, regardless of the size of the destination /// image. Thus, this function provides a means of generating multiple /// transformed images from the same source or applying multiple /// transformations simultaneously, in order to eliminate the need to read the /// source coefficients multiple times. /// </summary> /// <returns>An array of byte arrays containing the losslessly transformed JPEG images.</returns> /// <param name="jpegBuf">Buffer containing the JPEG image to transform.</param> /// <param name="transforms">An array of <see cref="Transform"/> structures, each of /// which specifies the transform parameters and/or cropping region for /// the corresponding transformed output image.</param> public byte[][] Transform(byte[] jpegBuf, Transform[] transforms) { if (jpegBuf == null) throw new ArgumentNullException(nameof (jpegBuf)); if (transforms == null) throw new ArgumentNullException(nameof (transforms)); IntPtr[] dstBufs = new IntPtr[transforms.Length]; // Initialize all destination buffer pointers to NULL, to tell TurboJPEG to allocate the buffers for us for (int i = 0; i < dstBufs.Length; ++i) { dstBufs[i] = IntPtr.Zero; } uint[] dstSizes = new uint[transforms.Length]; Library.tjTransform(_handle, jpegBuf, dstBufs, dstSizes, transforms, (FunctionFlags)0); byte[][] output = new byte[transforms.Length][]; for (int i = 0; i < transforms.Length; ++i) { output[i] = new byte[dstSizes[i]]; Marshal.Copy(dstBufs[i], output[i], 0, output[i].Length); Library.tjFree(dstBufs[i]); dstBufs[i] = IntPtr.Zero; } return output; }
/// <summary> /// Losslessly transform a JPEG image into another JPEG image. Lossless /// transforms work by moving the raw coefficients from one JPEG image structure /// to another without altering the values of the coefficients. While this is /// typically faster than decompressing the image, transforming it, and /// re-compressing it, lossless transforms are not free. Each lossless /// transform requires reading and performing Huffman decoding on all of the /// coefficients in the source image, regardless of the size of the destination /// image. Thus, this function provides a means of generating multiple /// transformed images from the same source or applying multiple /// transformations simultaneously, in order to eliminate the need to read the /// source coefficients multiple times. /// </summary> /// <param name="handle">a handle to a TurboJPEG transformer instance.</param> /// <param name="jpegBuf">pointer to a buffer containing the JPEG image to transform</param> /// <param name="dstBufs"> /// pointer to an array of <paramref name="n"/> image buffers. <paramref name="dstBufs"/>[i] /// will receive a JPEG image that has been transformed using the /// parameters in <paramref name="transforms"/>[i]. TurboJPEG has the ability to /// reallocate the JPEG buffer to accommodate the size of the JPEG image. /// Thus, you can choose to: /// <list type="bullet"> /// <item> /// <description> /// pre-allocate the JPEG buffer with an arbitrary size using /// <see cref="tjAlloc"/> and let TurboJPEG grow the buffer as needed, /// </description> /// </item> /// <item> /// <description> /// set <paramref name="dstBufs"/>[i] to NULL to tell TurboJPEG to allocate the /// buffer for you, or /// </description> /// </item> /// <item> /// <description> /// pre-allocate the buffer to a "worst case" size determined by /// calling <see cref="tjBufSize"/> with the transformed or cropped width and /// height. This should ensure that the buffer never has to be /// re-allocated (setting <see cref="FunctionFlags.NoRealloc"/> guarantees this.) /// </description> /// </item> /// </list> /// If you choose option 1, <paramref name="dstSizes"/>[i] should be set to /// the size of your pre-allocated buffer. In any case, unless you have set /// <see cref="FunctionFlags.NoRealloc"/>, you should always check <paramref name="dstBufs"/>[i] /// upon return from this function, as it may have changed. /// </param> /// <param name="dstSizes"> /// pointer to an array of <paramref name="n"/> unsigned long variables that will /// receive the actual sizes (in bytes) of each transformed JPEG image. If /// <paramref name="dstBufs"/>[i] points to a pre-allocated buffer, then /// <paramref name="dstSizes"/>[i] should be set to the size of the buffer. Upon return, /// <paramref name="dstSizes"/>[i] will contain the size of the JPEG image (in bytes.) /// </param> /// <param name="transforms"> /// pointer to an array of <paramref name="n"/> <see cref="Transform"/> structures, each of /// which specifies the transform parameters and/or cropping region for /// the corresponding transformed output image. /// </param> /// <param name="flags">the bitwise OR of one or more of the <see cref="FunctionFlags"/>.</param> /// <returns>0 if successful, or -1 if an error occurred (see <see cref="tjGetErrorStr"/>.)</returns> /// <remarks> /// Defined in turbojpeg.h as: /// /// DLLEXPORT int DLLCALL tjTransform(tjhandle handle, /// const unsigned char* jpegBuf, unsigned long jpegSize, int n, /// unsigned char** dstBufs, unsigned long* dstSizes, tjtransform *transforms, /// int flags); /// </remarks> internal static void tjTransform(IntPtr handle, byte [] jpegBuf, IntPtr[] dstBufs, uint [] dstSizes, Transform [] transforms, FunctionFlags flags) { int retval; if (IsLP64) { ulong [] dstSizes64 = new ulong [dstSizes.Length]; dstSizes.CopyTo (dstSizes64, 0); retval = tjTransform_64 (handle, jpegBuf, (ulong)jpegBuf.Length, transforms.Length, dstBufs, dstSizes64, transforms, flags); for (int i = 0; i < dstSizes.Length; ++i) dstSizes [i] = (uint)dstSizes64 [i]; } else retval = tjTransform_32 (handle, jpegBuf, (uint)jpegBuf.Length, transforms.Length, dstBufs, dstSizes, transforms, flags); if (retval != 0) throw new TurboJPEGException (); }