Example #1
0
 /// <summary>
 /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
 /// </summary>
 /// <param name="jpegBuf">Pointer to a buffer containing the JPEG image to decompress. This buffer is not modified.</param>
 /// <param name="outBuf">The buffer into which to store the decompressed JPEG image.</param>
 /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="PixelFormat"/> "Pixel formats".)</param>
 /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
 /// <param name="width">Width of image in pixels.</param>
 /// <param name="height">Height of image in pixels.</param>
 /// <param name="stride">Bytes per line in the destination image.</param>
 public unsafe void Decompress(Span <byte> jpegBuf, Span <byte> outBuf, TJPixelFormat destPixelFormat, TJFlags flags, out int width, out int height, out int stride)
 {
     fixed(byte *jpegBufPtr = jpegBuf)
     fixed(byte *outBufPtr = outBuf)
     {
         this.Decompress((IntPtr)jpegBufPtr, (ulong)jpegBuf.Length, (IntPtr)outBufPtr, outBuf.Length, destPixelFormat, flags, out width, out height, out stride);
     }
 }
 /// <summary>
 /// Retrieve information about a JPEG image without decompressing it.
 /// </summary>
 /// <param name="jpegBuf">
 /// Pointer to a buffer containing a JPEG image.  This buffer is not modified.
 /// </param>
 /// <param name="jpegBufSize">
 /// Size of the JPEG image (in bytes).
 /// </param>
 /// <param name="destPixelFormat">
 /// The pixel format of the uncompressed image.
 /// </param>
 /// <param name="width">
 /// Pointer to an integer variable that will receive the width (in pixels) of the JPEG image.
 /// </param>
 /// <param name="height">
 /// Pointer to an integer variable that will receive the height (in pixels) of the JPEG image.
 /// </param>
 /// <param name="stride">
 /// Pointer to an integer variable that will receive the stride (in bytes) of the JPEG image.
 /// </param>
 /// <param name="bufSize">
 /// The size of a buffer that can receive the uncompressed JPEG image.
 /// </param>
 public unsafe void GetImageInfo(ReadOnlySpan <byte> jpegBuf, TJPixelFormat destPixelFormat, out int width, out int height, out int stride, out int bufSize)
 {
     fixed(byte *jpegBufPtr = jpegBuf)
     {
         this.GetImageInfo((IntPtr)jpegBufPtr, (ulong)jpegBuf.Length, destPixelFormat, out width, out height,
                           out stride, out bufSize);
     }
 }
Example #3
0
        /// <summary>
        /// Given the size of an image, determines the size of a decompressed image.
        /// </summary>
        /// <param name="height">
        /// The height of the image.
        /// </param>
        /// <param name="width">
        /// The width of the image.
        /// </param>
        /// <param name="destPixelFormat">
        /// The pixel format of the uncompressed image.
        /// </param>
        /// <returns>
        /// The size of a buffer that can hold the uncompressed image.
        /// </returns>
        public int GetBufferSize(int height, int width, TJPixelFormat destPixelFormat)
        {
            Verify.NotDisposed(this);

            int stride = TurboJpegImport.TJPAD(width * TurboJpegImport.PixelSizes[destPixelFormat]);

            return(stride * height);
        }
Example #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DecompressedImage"/> class.
 /// </summary>
 /// <param name="width">Width of image in pixels.</param>
 /// <param name="height">Height of image in pixels.</param>
 /// <param name="stride">
 /// Bytes per line in the source image.
 /// Normally, this should be <c>width * BytesPerPixel</c> if the image is unpadded,
 /// or <c>TJPAD(width * BytesPerPixel</c> if each line of the image
 /// is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps.
 /// You can also be clever and use this parameter to skip lines, etc.
 /// Setting this parameter to 0 is the equivalent of setting it to
 /// <c>width * BytesPerPixel</c>.</param>
 /// <param name="data">Decompressed Image array containing RGB, grayscale, or CMYK pixels.</param>
 /// <param name="pixelFormat">Pixel format of the source image (see <see cref="PixelFormat"/> "Pixel formats").</param>
 public DecompressedImage(int width, int height, int stride, byte[] data, TJPixelFormat pixelFormat)
 {
     this.Width       = width;
     this.Height      = height;
     this.Stride      = stride;
     this.Data        = data;
     this.PixelFormat = pixelFormat;
 }
Example #5
0
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">A buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="jpegBufSize">Size of jpegBuf.</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="PixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <returns>Decompressed Image.</returns>
        /// <exception cref="TJException">Throws if underlying decompress function failed.</exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        public DecompressedImage Decompress(IntPtr jpegBuf, ulong jpegBufSize, TJPixelFormat destPixelFormat, TJFlags flags)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("this");
            }

            int width;
            int height;
            int stride;

            byte[] data = this.Decompress(jpegBuf, jpegBufSize, destPixelFormat, flags, out width, out height, out stride);
            return(new DecompressedImage(width, height, stride, data, destPixelFormat));
        }
Example #6
0
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">A buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="PixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <returns>Decompressed Image.</returns>
        /// <exception cref="TJException">Throws if underlying decompress function failed.</exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        public unsafe DecompressedImage Decompress(byte[] jpegBuf, TJPixelFormat destPixelFormat, TJFlags flags)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("this");
            }

            ulong length = (ulong)jpegBuf.Length;

            fixed(byte *numPtr = jpegBuf)
            {
                return(this.Decompress((IntPtr)((void *)numPtr), length, destPixelFormat, flags));
            }
        }
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">A buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="TJPixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <param name="width">Width of image in pixels.</param>
        /// <param name="height">Height of image in pixels.</param>
        /// <param name="stride">Bytes per line in the destination image.</param>
        /// <returns>Raw pixel data of specified format.</returns>
        /// <exception cref="TJException">Throws if underlying decompress function failed.</exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        public unsafe byte[] Decompress(byte[] jpegBuf, TJPixelFormat destPixelFormat, TJFlags flags, out int width, out int height, out int stride)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("this");
            }

            var jpegBufSize = (ulong)jpegBuf.Length;

            fixed(byte *jpegPtr = jpegBuf)
            {
                return(this.Decompress((IntPtr)jpegPtr, jpegBufSize, destPixelFormat, flags, out width, out height, out stride));
            }
        }
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">Buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="TJPixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <param name="width">Width of image in pixels.</param>
        /// <param name="height">Height of image in pixels.</param>
        /// <param name="stride">Bytes per line in the destination image.</param>
        public unsafe byte[] Decompress(ReadOnlySpan <byte> jpegBuf, TJPixelFormat destPixelFormat, TJFlags flags, out int width, out int height, out int stride)
        {
            this.GetImageInfo(jpegBuf, destPixelFormat, out width, out height, out stride, out var outBufSize);

            var outBuf = new byte[outBufSize];

            fixed(byte *jpegBufPtr = jpegBuf)
            fixed(byte *outBufPtr = outBuf)
            {
                this.Decompress((IntPtr)jpegBufPtr, (ulong)jpegBuf.Length, (IntPtr)outBufPtr, outBuf.Length, destPixelFormat, flags, out width, out height, out stride);
            }

            return(outBuf);
        }
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">Pointer to a buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="jpegBufSize">Size of the JPEG image (in bytes).</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="TJPixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <param name="width">Width of image in pixels.</param>
        /// <param name="height">Height of image in pixels.</param>
        /// <param name="stride">Bytes per line in the destination image.</param>
        /// <returns>Raw pixel data of specified format.</returns>
        /// <exception cref="TJException">Throws if underlying decompress function failed.</exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        public unsafe byte[] Decompress(IntPtr jpegBuf, ulong jpegBufSize, TJPixelFormat destPixelFormat, TJFlags flags, out int width, out int height, out int stride)
        {
            int outBufSize;

            this.GetImageInfo(jpegBuf, jpegBufSize, destPixelFormat, out width, out height, out stride, out outBufSize);

            var buf = new byte[outBufSize];

            fixed(byte *bufPtr = buf)
            {
                this.Decompress(jpegBuf, jpegBufSize, (IntPtr)bufPtr, outBufSize, destPixelFormat, flags, out width, out height, out stride);
            }

            return(buf);
        }
Example #10
0
        public void DecompressArray(
            [CombinatorialValues(
                 TJPixelFormat.ABGR,
                 TJPixelFormat.RGB,
                 TJPixelFormat.Gray)]
            TJPixelFormat format)
        {
            byte[] outBuf = ArrayPool <byte> .Shared.Rent(250 * 250 * 4);

            foreach (var data in TestUtils.GetTestImagesData("*.jpg"))
            {
                this.decompressor.Decompress(data.Item2, outBuf, format, TJFlags.None, out int width, out int height, out int stride);
            }

            ArrayPool <byte> .Shared.Return(outBuf);
        }
Example #11
0
        /// <summary>
        /// Retrieve information about a JPEG image without decompressing it.
        /// </summary>
        /// <param name="jpegBuf">
        /// Pointer to a buffer containing a JPEG image.  This buffer is not modified.
        /// </param>
        /// <param name="jpegBufSize">
        /// Size of the JPEG image (in bytes).
        /// </param>
        /// <param name="destPixelFormat">
        /// The pixel format of the uncompressed image.
        /// </param>
        /// <param name="width">
        /// Pointer to an integer variable that will receive the width (in pixels) of the JPEG image.
        /// </param>
        /// <param name="height">
        /// Pointer to an integer variable that will receive the height (in pixels) of the JPEG image.
        /// </param>
        /// <param name="stride">
        /// Pointer to an integer variable that will receive the stride (in bytes) of the JPEG image.
        /// </param>
        /// <param name="bufSize">
        /// The size of a buffer that can receive the uncompressed JPEG image.
        /// </param>
        public void GetImageInfo(IntPtr jpegBuf, ulong jpegBufSize, TJPixelFormat destPixelFormat, out int width, out int height, out int stride, out int bufSize)
        {
            int subsampl;
            int colorspace;

            var funcResult = TurboJpegImport.TjDecompressHeader(
                this.decompressorHandle,
                jpegBuf,
                jpegBufSize,
                out width,
                out height,
                out subsampl,
                out colorspace);

            stride  = TurboJpegImport.TJPAD(width * TurboJpegImport.PixelSizes[destPixelFormat]);
            bufSize = stride * height;
        }
Example #12
0
        /// <summary>
        /// Decode a set of Y, U (Cb), and V (Cr) image planes into an RGB or grayscale image.
        /// </summary>
        /// <param name="yPlane">
        /// A pointer to the Y image planes of the YUV image to be decoded.
        /// The size of the plane should match the value returned by tjPlaneSizeYUV() for the given image width, height, strides, and level of chrominance subsampling.
        /// </param>
        /// <param name="uPlane">
        /// A pointer to the U (Cb) image plane (or just <see langword="null"/>, if decoding a grayscale image) of the YUV image to be decoded.
        /// The size of the plane should match the value returned by tjPlaneSizeYUV() for the given image width, height, strides, and level of chrominance subsampling.
        /// </param>
        /// <param name="vPlane">
        /// A pointer to the V (Cr)image plane (or just <see langword="null"/>, if decoding a grayscale image) of the YUV image to be decoded.
        /// The size of the plane should match the value returned by tjPlaneSizeYUV() for the given image width, height, strides, and level of chrominance subsampling.
        /// </param>
        /// <param name="strides">
        /// An array of integers, each specifying the number of bytes per line in the corresponding plane of the YUV source image.
        /// Setting the stride for any plane to 0 is the same as setting it to the plane width (see YUV Image Format Notes.)
        /// If strides is <see langword="null"/>, then the strides for all planes will be set to their respective plane widths.
        /// You can adjust the strides in order to specify an arbitrary amount of line padding in each plane or to decode a subregion of a larger YUV planar image.
        /// </param>
        /// <param name="subsamp">
        /// The level of chrominance subsampling used in the YUV source image (see Chrominance subsampling options.)
        /// </param>
        /// <param name="dstBuf">
        /// A pointer to an image buffer that will receive the decoded image. This buffer should normally be <paramref name="pitch"/> * <paramref name="height"/> bytes in size,
        /// but the <paramref name="dstBuf"/> pointer can also be used to decode into a specific region of a larger buffer.
        /// </param>
        /// <param name="width">
        /// Width (in pixels) of the source and destination images.
        /// </param>
        /// <param name="pitch">
        /// Bytes per line in the destination image. Normally, this should be <paramref name="width"/> * <c>tjPixelSize[pixelFormat]</c>
        /// if the destination image is unpadded, or <c>TJPAD(width * tjPixelSize[pixelFormat])</c> if each line of the destination image
        /// should be padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use the
        /// pitch parameter to skip lines, etc.
        /// Setting this parameter to <c>0</c> is the equivalent of setting it to <paramref name="width"/> * <c>tjPixelSize[pixelFormat]</c>.
        /// </param>
        /// <param name="height">
        /// Height (in pixels) of the source and destination images.
        /// </param>
        /// <param name="pixelFormat">
        /// Pixel format of the destination image.
        /// </param>
        /// <param name="flags">
        /// The bitwise OR of one or more of the flags.
        /// </param>
        /// <remarks>
        /// <para>
        /// This function uses the accelerated color conversion routines in the underlying codec but does not execute any of the other steps in the JPEG decompression process.
        /// </para>
        /// <para>
        /// The <paramref name="yPlane"/>, <paramref name="uPlane"/> and <paramref name="vPlane"/> planes can be contiguous or non-contiguous in memory.
        /// Refer to YUV Image Format Notes for more details.
        /// </para>
        /// </remarks>
        public unsafe void DecodeYUVPlanes(
            Span <byte> yPlane,
            Span <byte> uPlane,
            Span <byte> vPlane,
            int[] strides,
            TJSubsamplingOption subsamp,
            Span <byte> dstBuf,
            int width,
            int pitch,
            int height,
            TJPixelFormat pixelFormat,
            TJFlags flags)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException(nameof(TJDecompressor));
            }

            fixed(byte *yPlanePtr = yPlane)
            fixed(byte *uPlanePtr = uPlane)
            fixed(byte *vPlanePtr = vPlane)
            {
                byte *[] planes = new byte *[] { yPlanePtr, uPlanePtr, vPlanePtr };

                fixed(int *stridesPtr = strides)
                fixed(byte **planesPtr = planes)
                fixed(byte *dstBufPtr  = dstBuf)
                {
                    if (TurboJpegImport.TjDecodeYUVPlanes(
                            this.decompressorHandle,
                            planesPtr,
                            stridesPtr,
                            (int)subsamp,
                            (IntPtr)dstBufPtr,
                            width,
                            pitch,
                            height,
                            (int)pixelFormat,
                            (int)flags) == -1)
                    {
                        TJUtils.GetErrorAndThrow();
                    }
                }
            }
        }
Example #13
0
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">Pointer to a buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="outBuf">The buffer into which to store the decompressed JPEG image.</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="TJPixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <param name="width">Width of image in pixels.</param>
        /// <param name="height">Height of image in pixels.</param>
        /// <param name="stride">Bytes per line in the destination image.</param>
        public unsafe void Decompress(Span <byte> jpegBuf, Span <byte> outBuf, TJPixelFormat destPixelFormat, TJFlags flags, out int width, out int height, out int stride)
        {
            Verify.NotDisposed(this);

            fixed(byte *jpegBufPtr = jpegBuf)
            fixed(byte *outBufPtr = outBuf)
            {
                int subsampl;
                int colorspace;
                var funcResult = TurboJpegImport.TjDecompressHeader(
                    this.decompressorHandle,
                    jpegBufPtr,
                    (nuint)jpegBuf.Length,
                    out width,
                    out height,
                    out subsampl,
                    out colorspace);

                TJUtils.ThrowOnError(funcResult);

                var targetFormat = destPixelFormat;

                stride = TurboJpegImport.TJPAD(width * TurboJpegImport.PixelSizes[targetFormat]);
                var bufSize = stride * height;

                if (outBuf.Length < bufSize)
                {
                    throw new ArgumentOutOfRangeException(nameof(outBuf));
                }

                funcResult = TurboJpegImport.TjDecompress(
                    this.decompressorHandle,
                    jpegBufPtr,
                    (nuint)jpegBuf.Length,
                    outBufPtr,
                    width,
                    stride,
                    height,
                    (int)targetFormat,
                    (int)flags);

                TJUtils.ThrowOnError(funcResult);
            }
        }
Example #14
0
        /// <summary>
        /// Compresses input image to the jpeg format with specified quality.
        /// </summary>
        /// <param name="srcPtr">
        /// Pointer to an image buffer containing RGB, grayscale, or CMYK pixels to be compressed.
        /// This buffer is not modified.
        /// </param>
        /// <param name="stride">
        /// Bytes per line in the source image.
        /// Normally, this should be <c>width * BytesPerPixel</c> if the image is unpadded,
        /// or <c>TJPAD(width * BytesPerPixel</c> if each line of the image
        /// is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps.
        /// You can also be clever and use this parameter to skip lines, etc.
        /// Setting this parameter to 0 is the equivalent of setting it to
        /// <c>width * BytesPerPixel</c>.
        /// </param>
        /// <param name="width">Width (in pixels) of the source image.</param>
        /// <param name="height">Height (in pixels) of the source image.</param>
        /// <param name="tjPixelFormat">Pixel format of the source image (see <see cref="TJPixelFormat"/> "Pixel formats").</param>
        /// <param name="subSamp">
        /// The level of chrominance subsampling to be used when
        /// generating the JPEG image (see <see cref="TJSubsamplingOption"/> "Chrominance subsampling options".)
        /// </param>
        /// <param name="quality">The image quality of the generated JPEG image (1 = worst, 100 = best).</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <returns>
        /// A <see cref="byte"/> array containing the compressed image.
        /// </returns>
        /// <exception cref="TJException"> Throws if compress function failed. </exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        /// <exception cref="NotSupportedException">
        /// Some parameters' values are incompatible:
        /// <list type="bullet">
        /// <item><description>Subsampling not equals to <see cref="TJSubsamplingOption.Gray"/> and pixel format <see cref="TJPixelFormat.Gray"/></description></item>
        /// </list>
        /// </exception>
        public byte[] Compress(IntPtr srcPtr, int stride, int width, int height, TJPixelFormat tjPixelFormat, TJSubsamplingOption subSamp, int quality, TJFlags flags)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("this");
            }

            CheckOptionsCompatibilityAndThrow(subSamp, tjPixelFormat);

            var   buf     = IntPtr.Zero;
            ulong bufSize = 0;

            try
            {
                var result = TurboJpegImport.TjCompress2(
                    this.compressorHandle,
                    srcPtr,
                    width,
                    stride,
                    height,
                    (int)tjPixelFormat,
                    ref buf,
                    ref bufSize,
                    (int)subSamp,
                    quality,
                    (int)flags);

                if (result == -1)
                {
                    TJUtils.GetErrorAndThrow();
                }

                var jpegBuf = new byte[bufSize];
                Marshal.Copy(buf, jpegBuf, 0, (int)bufSize);
                return(jpegBuf);
            }
            finally
            {
                TurboJpegImport.TjFree(buf);
            }
        }
Example #15
0
        /// <summary>
        /// Decode a set of Y, U (Cb), and V (Cr) image planes into an RGB or grayscale image.
        /// </summary>
        /// <param name="yPlane">
        /// A pointer to the Y image planes of the YUV image to be decoded.
        /// The size of the plane should match the value returned by tjPlaneSizeYUV() for the given image width, height, strides, and level of chrominance subsampling.
        /// </param>
        /// <param name="uPlane">
        /// A pointer to the U (Cb) image plane (or just <see langword="null"/>, if decoding a grayscale image) of the YUV image to be decoded.
        /// The size of the plane should match the value returned by tjPlaneSizeYUV() for the given image width, height, strides, and level of chrominance subsampling.
        /// </param>
        /// <param name="vPlane">
        /// A pointer to the V (Cr)image plane (or just <see langword="null"/>, if decoding a grayscale image) of the YUV image to be decoded.
        /// The size of the plane should match the value returned by tjPlaneSizeYUV() for the given image width, height, strides, and level of chrominance subsampling.
        /// </param>
        /// <param name="strides">
        /// An array of integers, each specifying the number of bytes per line in the corresponding plane of the YUV source image.
        /// Setting the stride for any plane to 0 is the same as setting it to the plane width (see YUV Image Format Notes.)
        /// If strides is <see langword="null"/>, then the strides for all planes will be set to their respective plane widths.
        /// You can adjust the strides in order to specify an arbitrary amount of line padding in each plane or to decode a subregion of a larger YUV planar image.
        /// </param>
        /// <param name="subsamp">
        /// The level of chrominance subsampling used in the YUV source image (see Chrominance subsampling options.)
        /// </param>
        /// <param name="dstBuf">
        /// A pointer to an image buffer that will receive the decoded image. This buffer should normally be <paramref name="pitch"/> * <paramref name="height"/> bytes in size,
        /// but the <paramref name="dstBuf"/> pointer can also be used to decode into a specific region of a larger buffer.
        /// </param>
        /// <param name="width">
        /// Width (in pixels) of the source and destination images.
        /// </param>
        /// <param name="pitch">
        /// Bytes per line in the destination image. Normally, this should be <paramref name="width"/> * <c>tjPixelSize[pixelFormat]</c>
        /// if the destination image is unpadded, or <c>TJPAD(width * tjPixelSize[pixelFormat])</c> if each line of the destination image
        /// should be padded to the nearest 32-bit boundary, as is the case for Windows bitmaps. You can also be clever and use the
        /// pitch parameter to skip lines, etc.
        /// Setting this parameter to <c>0</c> is the equivalent of setting it to <paramref name="width"/> * <c>tjPixelSize[pixelFormat]</c>.
        /// </param>
        /// <param name="height">
        /// Height (in pixels) of the source and destination images.
        /// </param>
        /// <param name="pixelFormat">
        /// Pixel format of the destination image.
        /// </param>
        /// <param name="flags">
        /// The bitwise OR of one or more of the flags.
        /// </param>
        /// <remarks>
        /// <para>
        /// This function uses the accelerated color conversion routines in the underlying codec but does not execute any of the other steps in the JPEG decompression process.
        /// </para>
        /// <para>
        /// The <paramref name="yPlane"/>, <paramref name="uPlane"/> and <paramref name="vPlane"/> planes can be contiguous or non-contiguous in memory.
        /// Refer to YUV Image Format Notes for more details.
        /// </para>
        /// </remarks>
        public unsafe void DecodeYUVPlanes(
            Span <byte> yPlane,
            Span <byte> uPlane,
            Span <byte> vPlane,
            int[] strides,
            TJSubsamplingOption subsamp,
            Span <byte> dstBuf,
            int width,
            int pitch,
            int height,
            TJPixelFormat pixelFormat,
            TJFlags flags)
        {
            Verify.NotDisposed(this);

            fixed(byte *yPlanePtr = yPlane)
            fixed(byte *uPlanePtr = uPlane)
            fixed(byte *vPlanePtr = vPlane)
            {
                byte *[] planes = new byte *[] { yPlanePtr, uPlanePtr, vPlanePtr };

                fixed(int *stridesPtr = strides)
                fixed(byte **planesPtr = planes)
                fixed(byte *dstBufPtr  = dstBuf)
                {
                    TJUtils.ThrowOnError(
                        TurboJpegImport.TjDecodeYUVPlanes(
                            this.decompressorHandle,
                            planesPtr,
                            stridesPtr,
                            (int)subsamp,
                            (IntPtr)dstBufPtr,
                            width,
                            pitch,
                            height,
                            (int)pixelFormat,
                            (int)flags));
                }
            }
        }
Example #16
0
        /// <summary>
        /// Retrieve information about a JPEG image without decompressing it.
        /// </summary>
        /// <param name="jpegBuf">
        /// Pointer to a buffer containing a JPEG image.  This buffer is not modified.
        /// </param>
        /// <param name="destPixelFormat">
        /// The pixel format of the uncompressed image.
        /// </param>
        /// <param name="width">
        /// Pointer to an integer variable that will receive the width (in pixels) of the JPEG image.
        /// </param>
        /// <param name="height">
        /// Pointer to an integer variable that will receive the height (in pixels) of the JPEG image.
        /// </param>
        /// <param name="stride">
        /// Pointer to an integer variable that will receive the stride (in bytes) of the JPEG image.
        /// </param>
        /// <param name="bufSize">
        /// The size of a buffer that can receive the uncompressed JPEG image.
        /// </param>
        public void GetImageInfo(Span <byte> jpegBuf, TJPixelFormat destPixelFormat, out int width, out int height, out int stride, out int bufSize)
        {
            Verify.NotDisposed(this);

            int subsampl;
            int colorspace;

            fixed(byte *jpegBufPtr = jpegBuf)
            {
                var funcResult = TurboJpegImport.TjDecompressHeader(
                    this.decompressorHandle,
                    jpegBufPtr,
                    (nuint)jpegBuf.Length,
                    out width,
                    out height,
                    out subsampl,
                    out colorspace);

                stride  = TurboJpegImport.TJPAD(width * TurboJpegImport.PixelSizes[destPixelFormat]);
                bufSize = stride * height;
            }
        }
Example #17
0
        /// <summary>
        /// Compresses input image to the jpeg format with specified quality.
        /// </summary>
        /// <param name="srcBuf">
        /// Image buffer containing RGB, grayscale, or CMYK pixels to be compressed.
        /// This buffer is not modified.
        /// </param>
        /// <param name="destBuf">
        /// A <see cref="byte"/> array containing the compressed image.
        /// </param>
        /// <param name="stride">
        /// Bytes per line in the source image.
        /// Normally, this should be <c>width * BytesPerPixel</c> if the image is unpadded,
        /// or <c>TJPAD(width * BytesPerPixel</c> if each line of the image
        /// is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps.
        /// You can also be clever and use this parameter to skip lines, etc.
        /// Setting this parameter to 0 is the equivalent of setting it to
        /// <c>width * BytesPerPixel</c>.
        /// </param>
        /// <param name="width">Width (in pixels) of the source image.</param>
        /// <param name="height">Height (in pixels) of the source image.</param>
        /// <param name="pixelFormat">Pixel format of the source image (see <see cref="TJPixelFormat"/> "Pixel formats").</param>
        /// <param name="subSamp">
        /// The level of chrominance subsampling to be used when
        /// generating the JPEG image (see <see cref="TJSubsamplingOption"/> "Chrominance subsampling options".)
        /// </param>
        /// <param name="quality">The image quality of the generated JPEG image (1 = worst, 100 = best).</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <returns>
        /// A <see cref="Span{T}"/> which is a slice of <paramref name="destBuf"/> which holds the compressed image.
        /// </returns>
        /// <exception cref="TJException">
        /// Throws if compress function failed.
        /// </exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        /// <exception cref="NotSupportedException">
        /// Some parameters' values are incompatible:
        /// <list type="bullet">
        /// <item><description>Subsampling not equals to <see cref="TJSubsamplingOption.Gray"/> and pixel format <see cref="TJPixelFormat.Gray"/></description></item>
        /// </list>
        /// </exception>
        public unsafe Span <byte> Compress(Span <byte> srcBuf, Span <byte> destBuf, int stride, int width, int height, TJPixelFormat pixelFormat, TJSubsamplingOption subSamp, int quality, TJFlags flags)
        {
            Verify.NotDisposed(this);

            CheckOptionsCompatibilityAndThrow(subSamp, pixelFormat);

            ulong destBufSize = (ulong)destBuf.Length;

            fixed(byte *srcBufPtr = srcBuf)
            fixed(byte *destBufPtr = destBuf)
            {
                IntPtr destBufPtr2 = (IntPtr)destBufPtr;

                var result = TurboJpegImport.TjCompress2(
                    this.compressorHandle,
                    (IntPtr)srcBufPtr,
                    width,
                    stride,
                    height,
                    (int)pixelFormat,
                    ref destBufPtr2,
                    ref destBufSize,
                    (int)subSamp,
                    quality,
                    (int)flags);

                TJUtils.ThrowOnError(result);
            }

            return(destBuf.Slice(0, (int)destBufSize));
        }
Example #18
0
 /// <exception cref="NotSupportedException">
 /// Some parameters' values are incompatible:
 /// <list type="bullet">
 /// <item><description>Subsampling not equals to <see cref="TJSubsamplingOption.Gray"/> and pixel format <see cref="TJPixelFormat.Gray"/></description></item>
 /// </list>
 /// </exception>
 private static void CheckOptionsCompatibilityAndThrow(TJSubsamplingOption subSamp, TJPixelFormat srcFormat)
 {
     if (srcFormat == TJPixelFormat.Gray && subSamp != TJSubsamplingOption.Gray)
     {
         throw new NotSupportedException(
                   $"Subsampling differ from {TJSubsamplingOption.Gray} for pixel format {TJPixelFormat.Gray} is not supported");
     }
 }
Example #19
0
        /// <summary>
        /// Decompress a JPEG image to an RGB, grayscale, or CMYK image.
        /// </summary>
        /// <param name="jpegBuf">Pointer to a buffer containing the JPEG image to decompress. This buffer is not modified.</param>
        /// <param name="jpegBufSize">Size of the JPEG image (in bytes).</param>
        /// <param name="outBuf">The buffer into which to store the decompressed JPEG image.</param>
        /// <param name="outBufSize">Size of <paramref name="outBuf"/> (in bytes).</param>
        /// <param name="destPixelFormat">Pixel format of the destination image (see <see cref="TJPixelFormat"/> "Pixel formats".)</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <param name="width">Width of image in pixels.</param>
        /// <param name="height">Height of image in pixels.</param>
        /// <param name="stride">Bytes per line in the destination image.</param>
        public unsafe void Decompress(IntPtr jpegBuf, ulong jpegBufSize, IntPtr outBuf, int outBufSize, TJPixelFormat destPixelFormat, TJFlags flags, out int width, out int height, out int stride)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException("this");
            }

            int subsampl;
            int colorspace;
            var funcResult = TurboJpegImport.TjDecompressHeader(
                this.decompressorHandle,
                jpegBuf,
                jpegBufSize,
                out width,
                out height,
                out subsampl,
                out colorspace);

            if (funcResult == -1)
            {
                TJUtils.GetErrorAndThrow();
            }

            var targetFormat = destPixelFormat;

            stride = TurboJpegImport.TJPAD(width * TurboJpegImport.PixelSizes[targetFormat]);
            var bufSize = stride * height;

            if (outBufSize < bufSize)
            {
                throw new ArgumentOutOfRangeException(nameof(outBufSize));
            }

            funcResult = TurboJpegImport.TjDecompress(
                this.decompressorHandle,
                jpegBuf,
                jpegBufSize,
                outBuf,
                width,
                stride,
                height,
                (int)targetFormat,
                (int)flags);

            if (funcResult == -1)
            {
                TJUtils.GetErrorAndThrow();
            }
        }
Example #20
0
        /// <summary>
        /// Compresses input image to the jpeg format with specified quality.
        /// </summary>
        /// <param name="srcBuf">
        /// Image buffer containing RGB, grayscale, or CMYK pixels to be compressed.
        /// This buffer is not modified.
        /// </param>
        /// <param name="destBuf">
        /// A <see cref="byte"/> array containing the compressed image.
        /// </param>
        /// <param name="stride">
        /// Bytes per line in the source image.
        /// Normally, this should be <c>width * BytesPerPixel</c> if the image is unpadded,
        /// or <c>TJPAD(width * BytesPerPixel</c> if each line of the image
        /// is padded to the nearest 32-bit boundary, as is the case for Windows bitmaps.
        /// You can also be clever and use this parameter to skip lines, etc.
        /// Setting this parameter to 0 is the equivalent of setting it to
        /// <c>width * BytesPerPixel</c>.
        /// </param>
        /// <param name="width">Width (in pixels) of the source image.</param>
        /// <param name="height">Height (in pixels) of the source image.</param>
        /// <param name="pixelFormat">Pixel format of the source image (see <see cref="PixelFormat"/> "Pixel formats").</param>
        /// <param name="subSamp">
        /// The level of chrominance subsampling to be used when
        /// generating the JPEG image (see <see cref="TJSubsamplingOption"/> "Chrominance subsampling options".)
        /// </param>
        /// <param name="quality">The image quality of the generated JPEG image (1 = worst, 100 = best).</param>
        /// <param name="flags">The bitwise OR of one or more of the <see cref="TJFlags"/> "flags".</param>
        /// <returns>
        /// A <see cref="Span{T}"/> which is a slice of <paramref name="destBuf"/> which holds the compressed image.
        /// </returns>
        /// <exception cref="TJException">
        /// Throws if compress function failed.
        /// </exception>
        /// <exception cref="ObjectDisposedException">Object is disposed and can not be used anymore.</exception>
        /// <exception cref="NotSupportedException">
        /// Some parameters' values are incompatible:
        /// <list type="bullet">
        /// <item><description>Subsampling not equals to <see cref="TJSubsamplingOption.Gray"/> and pixel format <see cref="TJPixelFormat.Gray"/></description></item>
        /// </list>
        /// </exception>
        public unsafe Span <byte> Compress(Span <byte> srcBuf, Span <byte> destBuf, int stride, int width, int height, TJPixelFormat pixelFormat, TJSubsamplingOption subSamp, int quality, TJFlags flags)
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException(nameof(TJCompressor));
            }

            CheckOptionsCompatibilityAndThrow(subSamp, pixelFormat);

            ulong destBufSize = (ulong)destBuf.Length;

            fixed(byte *srcBufPtr = srcBuf)
            fixed(byte *destBufPtr = destBuf)
            {
                IntPtr destBufPtr2 = (IntPtr)destBufPtr;

                var result = TurboJpegImport.TjCompress2(
                    this.compressorHandle,
                    (IntPtr)srcBufPtr,
                    width,
                    stride,
                    height,
                    (int)pixelFormat,
                    ref destBufPtr2,
                    ref destBufSize,
                    (int)subSamp,
                    quality,
                    (int)flags);

                if (result == -1)
                {
                    TJUtils.GetErrorAndThrow();
                }
            }

            return(destBuf.Slice(0, (int)destBufSize));
        }