예제 #1
0
 public void ClampNoIntrinsics()
 {
     for (int i = 0; i < A.Length; i++)
     {
         ref int x = ref A[i];
         x = Numerics.Clamp(x, 64, 128);
     }
예제 #2
0
        private void SetupFilterStrength()
        {
            int filterSharpness = 0; // TODO: filterSharpness is hardcoded
            int filterType      = 1; // TODO: filterType is hardcoded

            // level0 is in [0..500]. Using '-f 50' as filter_strength is mid-filtering.
            int level0 = 5 * this.filterStrength;

            for (int i = 0; i < WebpConstants.NumMbSegments; i++)
            {
                Vp8SegmentInfo m = this.SegmentInfos[i];

                // We focus on the quantization of AC coeffs.
                int qstep        = WebpLookupTables.AcTable[Numerics.Clamp(m.Quant, 0, 127)] >> 2;
                int baseStrength = this.FilterStrengthFromDelta(this.FilterHeader.Sharpness, qstep);

                // Segments with lower complexity ('beta') will be less filtered.
                int f = baseStrength * level0 / (256 + m.Beta);
                m.FStrength = f < WebpConstants.FilterStrengthCutoff ? 0 : f > 63 ? 63 : f;
            }

            // We record the initial strength (mainly for the case of 1-segment only).
            this.FilterHeader.FilterLevel = this.SegmentInfos[0].FStrength;
            this.FilterHeader.Simple      = filterType == 0;
            this.FilterHeader.Sharpness   = filterSharpness;
        }
예제 #3
0
        /// <summary>
        /// Initializes quantization tables.
        /// </summary>
        /// <remarks>
        /// We take quality values in a hierarchical order:
        /// 1. Check if encoder has set quality
        /// 2. Check if metadata has special table for encoding
        /// 3. Check if metadata has set quality
        /// 4. Take default quality value - 75
        /// </remarks>
        /// <param name="componentCount">Color components count.</param>
        /// <param name="metadata">Jpeg metadata instance.</param>
        /// <param name="luminanceQuantTable">Output luminance quantization table.</param>
        /// <param name="chrominanceQuantTable">Output chrominance quantization table.</param>
        private void InitQuantizationTables(int componentCount, JpegMetadata metadata, out Block8x8F luminanceQuantTable, out Block8x8F chrominanceQuantTable)
        {
            int lumaQuality;
            int chromaQuality;

            if (this.quality.HasValue)
            {
                lumaQuality   = this.quality.Value;
                chromaQuality = this.quality.Value;
            }
            else
            {
                lumaQuality   = metadata.LuminanceQuality;
                chromaQuality = metadata.ChrominanceQuality;
            }

            // Luminance
            lumaQuality         = Numerics.Clamp(lumaQuality, 1, 100);
            luminanceQuantTable = Quantization.ScaleLuminanceTable(lumaQuality);

            // Chrominance
            chrominanceQuantTable = default;
            if (componentCount > 1)
            {
                chromaQuality         = Numerics.Clamp(chromaQuality, 1, 100);
                chrominanceQuantTable = Quantization.ScaleChrominanceTable(chromaQuality);

                if (!this.colorType.HasValue)
                {
                    this.colorType = chromaQuality >= 91 ? JpegColorType.YCbCrRatio444 : JpegColorType.YCbCrRatio420;
                }
            }
        }
예제 #4
0
 public void FromVector4(Vector4 vector)
 {
     vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
     this.R = (ushort)MathF.Round(vector.X);
     this.G = (ushort)MathF.Round(vector.Y);
     this.B = (ushort)MathF.Round(vector.Z);
 }
예제 #5
0
        public float ComputeNextQ()
        {
            float dq;

            if (this.IsFirst)
            {
                dq           = this.Value > this.Target ? -this.Dq : this.Dq;
                this.IsFirst = false;
            }
            else if (this.Value != this.LastValue)
            {
                double slope = (this.Target - this.Value) / (this.LastValue - this.Value);
                dq = (float)(slope * (this.LastQ - this.Q));
            }
            else
            {
                dq = 0.0f;  // we're done?!
            }

            // Limit variable to avoid large swings.
            this.Dq        = Numerics.Clamp(dq, -30.0f, 30.0f);
            this.LastQ     = this.Q;
            this.LastValue = this.Value;
            this.Q         = Numerics.Clamp(this.Q + this.Dq, this.Qmin, this.Qmax);

            return(this.Q);
        }
예제 #6
0
 private void renderArea_MouseWheel(object sender, MouseEventArgs e)
 {
     if (e.Delta != 0)
     {
         renderArea.ImageScale *= Numerics.Pow(1.1f, Numerics.Clamp(e.Delta, -2, 2));
     }
 }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PaletteDitherProcessor"/> class.
 /// </summary>
 /// <param name="dither">The dithering algorithm.</param>
 /// <param name="ditherScale">The dithering scale used to adjust the amount of dither.</param>
 /// <param name="palette">The palette to select substitute colors from.</param>
 public PaletteDitherProcessor(IDither dither, float ditherScale, ReadOnlyMemory <Color> palette)
 {
     Guard.MustBeGreaterThan(palette.Length, 0, nameof(palette));
     Guard.NotNull(dither, nameof(dither));
     this.Dither      = dither;
     this.DitherScale = Numerics.Clamp(ditherScale, QuantizerConstants.MinDitherScale, QuantizerConstants.MaxDitherScale);
     this.Palette     = palette;
 }
예제 #8
0
 public void FromVector4(Vector4 vector)
 {
     vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One);
     this.R = vector.X;
     this.G = vector.Y;
     this.B = vector.Z;
     this.A = vector.W;
 }
예제 #9
0
 private static ushort Pack(ref Vector4 vector)
 {
     vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One);
     return((ushort)((((int)Math.Round(vector.W * 15F) & 0x0F) << 12)
                     | (((int)Math.Round(vector.X * 15F) & 0x0F) << 8)
                     | (((int)Math.Round(vector.Y * 15F) & 0x0F) << 4)
                     | ((int)Math.Round(vector.Z * 15F) & 0x0F)));
 }
예제 #10
0
 public Cmyk(Vector4 vector)
 {
     vector = Numerics.Clamp(vector, Min, Max);
     this.C = vector.X;
     this.M = vector.Y;
     this.Y = vector.Z;
     this.K = vector.W;
 }
예제 #11
0
        /// <summary>
        /// Writes an 8bit lookup table
        /// </summary>
        /// <param name="value">The LUT to write</param>
        /// <returns>The number of bytes written</returns>
        public int WriteLut8(IccLut value)
        {
            foreach (float item in value.Values)
            {
                this.WriteByte((byte)Numerics.Clamp((item * byte.MaxValue) + 0.5F, 0, byte.MaxValue));
            }

            return(value.Values.Length);
        }
예제 #12
0
        public override bool TrySetValue(object value)
        {
            if (base.TrySetValue(value))
            {
                return(true);
            }

            switch (value)
            {
            case int val:
                return(this.SetSingle((ulong)Numerics.Clamp(val, 0, int.MaxValue)));

            case uint val:
                return(this.SetSingle((ulong)val));

            case short val:
                return(this.SetSingle((ulong)Numerics.Clamp(val, 0, short.MaxValue)));

            case ushort val:
                return(this.SetSingle((ulong)val));

            case long val:
                return(this.SetSingle((ulong)Numerics.Clamp(val, 0, long.MaxValue)));

            case long[] array:
            {
                if (value.GetType() == typeof(ulong[]))
                {
                    return(this.SetArray((ulong[])value));
                }

                return(this.SetArray(array));
            }

            case int[] array:
            {
                if (value.GetType() == typeof(uint[]))
                {
                    return(this.SetArray((uint[])value));
                }

                return(this.SetArray(array));
            }

            case short[] array:
            {
                if (value.GetType() == typeof(ushort[]))
                {
                    return(this.SetArray((ushort[])value));
                }

                return(this.SetArray(array));
            }
            }

            return(false);
        }
예제 #13
0
        /// <summary>
        /// Writes an 16bit lookup table
        /// </summary>
        /// <param name="value">The LUT to write</param>
        /// <returns>The number of bytes written</returns>
        public int WriteLut16(IccLut value)
        {
            foreach (float item in value.Values)
            {
                this.WriteUInt16((ushort)Numerics.Clamp((item * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
            }

            return(value.Values.Length * 2);
        }
예제 #14
0
 public void ClampDouble(int length, double min, double max)
 {
     TestClampSpan(
         length,
         min,
         max,
         (s, m1, m2) => Numerics.Clamp(s, m1, m2),
         (v, m1, m2) => Numerics.Clamp(v, m1, m2));
 }
예제 #15
0
 public void ClampFloat(int length, float min, float max)
 {
     TestClampSpan(
         length,
         min,
         max,
         (s, m1, m2) => Numerics.Clamp(s, m1, m2),
         (v, m1, m2) => Numerics.Clamp(v, m1, m2));
 }
예제 #16
0
 public void ClampUInt(int length, uint min, uint max)
 {
     TestClampSpan(
         length,
         min,
         max,
         (s, m1, m2) => Numerics.Clamp(s, m1, m2),
         (v, m1, m2) => Numerics.Clamp(v, m1, m2));
 }
예제 #17
0
 public void ClampByte(int length, byte min, byte max)
 {
     TestClampSpan(
         length,
         min,
         max,
         (s, m1, m2) => Numerics.Clamp(s, m1, m2),
         (v, m1, m2) => Numerics.Clamp(v, m1, m2));
 }
예제 #18
0
 private static ushort Pack(ref Vector4 vector)
 {
     vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One);
     return((ushort)(
                (((int)Math.Round(vector.X * 31F) & 0x1F) << 10)
                | (((int)Math.Round(vector.Y * 31F) & 0x1F) << 5)
                | (((int)Math.Round(vector.Z * 31F) & 0x1F) << 0)
                | (((int)Math.Round(vector.W) & 0x1) << 15)));
 }
예제 #19
0
        private void Pack(ref Vector4 vector)
        {
            vector *= MaxBytes;
            vector += Half;
            vector  = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);

            this.R = (byte)vector.X;
            this.G = (byte)vector.Y;
            this.B = (byte)vector.Z;
        }
예제 #20
0
        /// <summary>
        /// Writes an unsigned 16bit number with 8 value bits and 8 fractional bits
        /// </summary>
        /// <param name="value">The value to write</param>
        /// <returns>the number of bytes written</returns>
        public int WriteUFix8(double value)
        {
            const double Max = byte.MaxValue + (255d / 256d);
            const double Min = byte.MinValue;

            value  = Numerics.Clamp(value, Min, Max);
            value *= 256d;

            return(this.WriteUInt16((ushort)Math.Round(value, MidpointRounding.AwayFromZero)));
        }
예제 #21
0
        private static uint Pack(ref Vector4 vector)
        {
            vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Multiplier;

            return((uint)(
                       (((int)Math.Round(vector.X) & 0x03FF) << 0)
                       | (((int)Math.Round(vector.Y) & 0x03FF) << 10)
                       | (((int)Math.Round(vector.Z) & 0x03FF) << 20)
                       | (((int)Math.Round(vector.W) & 0x03) << 30)));
        }
예제 #22
0
        /// <summary>
        /// Writes an unsigned 32bit number with 16 value bits and 16 fractional bits
        /// </summary>
        /// <param name="value">The value to write</param>
        /// <returns>the number of bytes written</returns>
        public int WriteUFix16(double value)
        {
            const double Max = ushort.MaxValue + (65535d / 65536d);
            const double Min = ushort.MinValue;

            value  = Numerics.Clamp(value, Min, Max);
            value *= 65536d;

            return(this.WriteUInt32((uint)Math.Round(value, MidpointRounding.AwayFromZero)));
        }
예제 #23
0
        /// <summary>
        /// Writes an unsigned 16bit number with 1 value bit and 15 fractional bits
        /// </summary>
        /// <param name="value">The value to write</param>
        /// <returns>the number of bytes written</returns>
        public int WriteU1Fix15(double value)
        {
            const double Max = 1 + (32767d / 32768d);
            const double Min = 0;

            value  = Numerics.Clamp(value, Min, Max);
            value *= 32768d;

            return(this.WriteUInt16((ushort)Math.Round(value, MidpointRounding.AwayFromZero)));
        }
예제 #24
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TiffBitsPerSample"/> struct.
        /// </summary>
        /// <param name="channel0">The bits for the channel 0.</param>
        /// <param name="channel1">The bits for the channel 1.</param>
        /// <param name="channel2">The bits for the channel 2.</param>
        public TiffBitsPerSample(ushort channel0, ushort channel1, ushort channel2)
        {
            this.Channel0 = (ushort)Numerics.Clamp(channel0, 0, 32);
            this.Channel1 = (ushort)Numerics.Clamp(channel1, 0, 32);
            this.Channel2 = (ushort)Numerics.Clamp(channel2, 0, 32);

            this.Channels  = 0;
            this.Channels += (byte)(this.Channel0 != 0 ? 1 : 0);
            this.Channels += (byte)(this.Channel1 != 0 ? 1 : 0);
            this.Channels += (byte)(this.Channel2 != 0 ? 1 : 0);
        }
예제 #25
0
        private static uint Pack(ref Vector4 vector)
        {
            vector = Numerics.Clamp(vector, MinusOne, Vector4.One) * Half;

            uint byte4 = ((uint)MathF.Round(vector.X) & 0xFF) << 0;
            uint byte3 = ((uint)MathF.Round(vector.Y) & 0xFF) << 8;
            uint byte2 = ((uint)MathF.Round(vector.Z) & 0xFF) << 16;
            uint byte1 = ((uint)MathF.Round(vector.W) & 0xFF) << 24;

            return(byte4 | byte3 | byte2 | byte1);
        }
예제 #26
0
        private static ulong Pack(ref Vector4 vector)
        {
            vector = Numerics.Clamp(vector, Min, Max);

            // Clamp the value between min and max values
            ulong word4 = ((ulong)Convert.ToInt32(Math.Round(vector.X)) & 0xFFFF) << 0x00;
            ulong word3 = ((ulong)Convert.ToInt32(Math.Round(vector.Y)) & 0xFFFF) << 0x10;
            ulong word2 = ((ulong)Convert.ToInt32(Math.Round(vector.Z)) & 0xFFFF) << 0x20;
            ulong word1 = ((ulong)Convert.ToInt32(Math.Round(vector.W)) & 0xFFFF) << 0x30;

            return(word4 | word3 | word2 | word1);
        }
예제 #27
0
        private bool SetArray(short[] values)
        {
            var numbers = new ulong[values.Length];

            for (int i = 0; i < values.Length; i++)
            {
                numbers[i] = (ulong)Numerics.Clamp(values[i], 0, short.MaxValue);
            }

            this.Value = numbers;
            return(true);
        }
예제 #28
0
        private static Block8x8F ScaleQuantizationTable(int scale, ReadOnlySpan <byte> unscaledTable)
        {
            Block8x8F table = default;

            for (int j = 0; j < Block8x8F.Size; j++)
            {
                int x = ((unscaledTable[j] * scale) + 50) / 100;
                table[j] = Numerics.Clamp(x, 1, 255);
            }

            return(table);
        }
예제 #29
0
        private static ulong Pack(ref Vector4 vector)
        {
            vector *= Max;
            vector  = Numerics.Clamp(vector, Min, Max);

            // Round rather than truncate.
            ulong word4 = ((ulong)MathF.Round(vector.X) & 0xFFFF) << 0x00;
            ulong word3 = ((ulong)MathF.Round(vector.Y) & 0xFFFF) << 0x10;
            ulong word2 = ((ulong)MathF.Round(vector.Z) & 0xFFFF) << 0x20;
            ulong word1 = ((ulong)MathF.Round(vector.W) & 0xFFFF) << 0x30;

            return(word4 | word3 | word2 | word1);
        }
예제 #30
0
        /// <summary>
        /// Writes a 16bit color lookup table
        /// </summary>
        /// <param name="value">The CLUT to write</param>
        /// <returns>The number of bytes written</returns>
        public int WriteClut16(IccClut value)
        {
            int count = 0;

            foreach (float[] inArray in value.Values)
            {
                foreach (float item in inArray)
                {
                    count += this.WriteUInt16((ushort)Numerics.Clamp((item * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
                }
            }

            return(count);
        }