all repos — mgba @ c207675dfb0ae3e39f9cb0745fe0cca79a697ae2

mGBA Game Boy Advance Emulator

src/third-party/zlib/contrib/dotzlib/DotZLib/Deflater.cs (view raw)

  1//
  2// � Copyright Henrik Ravn 2004
  3//
  4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
  5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6//
  7
  8using System;
  9using System.Diagnostics;
 10using System.Runtime.InteropServices;
 11
 12namespace DotZLib
 13{
 14
 15    /// <summary>
 16    /// Implements a data compressor, using the deflate algorithm in the ZLib dll
 17    /// </summary>
 18	public sealed class Deflater : CodecBase
 19	{
 20        #region Dll imports
 21        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
 22        private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
 23
 24        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
 25        private static extern int deflate(ref ZStream sz, int flush);
 26
 27        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
 28        private static extern int deflateReset(ref ZStream sz);
 29
 30        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
 31        private static extern int deflateEnd(ref ZStream sz);
 32        #endregion
 33
 34        /// <summary>
 35        /// Constructs an new instance of the <c>Deflater</c>
 36        /// </summary>
 37        /// <param name="level">The compression level to use for this <c>Deflater</c></param>
 38		public Deflater(CompressLevel level) : base()
 39		{
 40            int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
 41            if (retval != 0)
 42                throw new ZLibException(retval, "Could not initialize deflater");
 43
 44            resetOutput();
 45		}
 46
 47        /// <summary>
 48        /// Adds more data to the codec to be processed.
 49        /// </summary>
 50        /// <param name="data">Byte array containing the data to be added to the codec</param>
 51        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
 52        /// <param name="count">The number of bytes to add</param>
 53        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
 54        public override void Add(byte[] data, int offset, int count)
 55        {
 56            if (data == null) throw new ArgumentNullException();
 57            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
 58            if ((offset+count) > data.Length) throw new ArgumentException();
 59
 60            int total = count;
 61            int inputIndex = offset;
 62            int err = 0;
 63
 64            while (err >= 0 && inputIndex < total)
 65            {
 66                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
 67                while (err >= 0 && _ztream.avail_in > 0)
 68                {
 69                    err = deflate(ref _ztream, (int)FlushTypes.None);
 70                    if (err == 0)
 71                        while (_ztream.avail_out == 0)
 72                        {
 73                            OnDataAvailable();
 74                            err = deflate(ref _ztream, (int)FlushTypes.None);
 75                        }
 76                    inputIndex += (int)_ztream.total_in;
 77                }
 78            }
 79            setChecksum( _ztream.adler );
 80        }
 81
 82
 83        /// <summary>
 84        /// Finishes up any pending data that needs to be processed and handled.
 85        /// </summary>
 86        public override void Finish()
 87        {
 88            int err;
 89            do
 90            {
 91                err = deflate(ref _ztream, (int)FlushTypes.Finish);
 92                OnDataAvailable();
 93            }
 94            while (err == 0);
 95            setChecksum( _ztream.adler );
 96            deflateReset(ref _ztream);
 97            resetOutput();
 98        }
 99
100        /// <summary>
101        /// Closes the internal zlib deflate stream
102        /// </summary>
103        protected override void CleanUp() { deflateEnd(ref _ztream); }
104
105    }
106}