예제 #1
0
 public void FromPixel(Pixel pixel)
 {
     pixel  = Numeric.Clamp(pixel, Pixel.Zero, Pixel.One) * Max;
     this.R = (ushort)MathF.Round(pixel.R);
     this.G = (ushort)MathF.Round(pixel.G);
     this.B = (ushort)MathF.Round(pixel.B);
 }
예제 #2
0
 public void FromPixel(Pixel pixel)
 {
     pixel  = Numeric.Clamp(pixel, Pixel.Zero, Pixel.One);
     this.R = pixel.R;
     this.G = pixel.G;
     this.B = pixel.B;
     this.A = pixel.A;
 }
예제 #3
0
 private static ushort Pack(ref Pixel pixel)
 {
     pixel = Numeric.Clamp(pixel, Pixel.Zero, Pixel.One);
     return((ushort)((((int)Math.Round(pixel.A * 15F) & 0x0F) << 12)
                     | (((int)Math.Round(pixel.R * 15F) & 0x0F) << 8)
                     | (((int)Math.Round(pixel.G * 15F) & 0x0F) << 4)
                     | ((int)Math.Round(pixel.B * 15F) & 0x0F)));
 }
예제 #4
0
 public Rgba64(Vector4 vector)
 {
     vector = Numeric.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);
     this.A = (ushort)MathF.Round(vector.W);
 }
예제 #5
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)Numeric.Clamp((item * byte.MaxValue) + 0.5F, 0, byte.MaxValue));
            }

            return(value.Values.Length);
        }
예제 #6
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)Numeric.Clamp((item * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
            }

            return(value.Values.Length * 2);
        }
예제 #7
0
 private static ushort Pack(ref Pixel pixel)
 {
     pixel = Numeric.Clamp(pixel, Pixel.Zero, Pixel.One);
     return((ushort)(
                (((int)Math.Round(pixel.R * 31F) & 0x1F) << 10)
                | (((int)Math.Round(pixel.G * 31F) & 0x1F) << 5)
                | (((int)Math.Round(pixel.B * 31F) & 0x1F) << 0)
                | (((int)Math.Round(pixel.A) & 0x1) << 15)));
 }
예제 #8
0
        private static uint Pack(ref Pixel pixel)
        {
            pixel = Numeric.Clamp(pixel, Pixel.Zero, Pixel.One) * Multiplier;

            return((uint)(
                       (((int)Math.Round(pixel.R) & 0x03FF) << 0)
                       | (((int)Math.Round(pixel.G) & 0x03FF) << 10)
                       | (((int)Math.Round(pixel.B) & 0x03FF) << 20)
                       | (((int)Math.Round(pixel.A) & 0x03) << 30)));
        }
예제 #9
0
        private void Pack(ref Pixel pixel)
        {
            pixel *= MaxBytes;
            pixel += Half;
            pixel  = Numeric.Clamp(pixel, Pixel.Zero, MaxBytes);

            this.R = (byte)pixel.R;
            this.G = (byte)pixel.G;
            this.B = (byte)pixel.B;
        }
        /// <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  = Numeric.Clamp(value, Min, Max);
            value *= 65536d;

            return(this.WriteUInt32((uint)Math.Round(value, MidpointRounding.AwayFromZero)));
        }
        /// <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  = Numeric.Clamp(value, Min, Max);
            value *= 32768d;

            return(this.WriteUInt16((ushort)Math.Round(value, MidpointRounding.AwayFromZero)));
        }
        /// <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  = Numeric.Clamp(value, Min, Max);
            value *= 256d;

            return(this.WriteUInt16((ushort)Math.Round(value, MidpointRounding.AwayFromZero)));
        }
예제 #13
0
        private static uint Pack(ref Pixel pixel)
        {
            var vec = Numeric.Clamp(pixel, MinusOne, Pixel.One) * Half;

            uint byte4 = ((uint)MathF.Round(vec.R) & 0xFF) << 0;
            uint byte3 = ((uint)MathF.Round(vec.G) & 0xFF) << 8;
            uint byte2 = ((uint)MathF.Round(vec.B) & 0xFF) << 16;
            uint byte1 = ((uint)MathF.Round(vec.A) & 0xFF) << 24;

            return(byte4 | byte3 | byte2 | byte1);
        }
예제 #14
0
        private static ulong Pack(ref Pixel pixel)
        {
            pixel = Numeric.Clamp(pixel, Min, Max);

            // Clamp the value between min and max values
            ulong word4 = ((ulong)Math.Round(pixel.R) & 0xFFFF) << 0x00;
            ulong word3 = ((ulong)Math.Round(pixel.G) & 0xFFFF) << 0x10;
            ulong word2 = ((ulong)Math.Round(pixel.B) & 0xFFFF) << 0x20;
            ulong word1 = ((ulong)Math.Round(pixel.A) & 0xFFFF) << 0x30;

            return(word4 | word3 | word2 | word1);
        }
예제 #15
0
        private static ulong Pack(ref Pixel pixel)
        {
            pixel *= Max;
            pixel  = Numeric.Clamp(pixel, Min, Max);

            // Round rather than truncate.
            ulong word4 = ((ulong)MathF.Round(pixel.R) & 0xFFFF) << 0x00;
            ulong word3 = ((ulong)MathF.Round(pixel.G) & 0xFFFF) << 0x10;
            ulong word2 = ((ulong)MathF.Round(pixel.B) & 0xFFFF) << 0x20;
            ulong word1 = ((ulong)MathF.Round(pixel.A) & 0xFFFF) << 0x30;

            return(word4 | word3 | word2 | word1);
        }
예제 #16
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)Numeric.Clamp((item * ushort.MaxValue) + 0.5F, 0, ushort.MaxValue));
                }
            }

            return(count);
        }
예제 #17
0
        /// <summary>
        /// Writes a 8bit color lookup table
        /// </summary>
        /// <param name="value">The CLUT to write</param>
        /// <returns>The number of bytes written</returns>
        public int WriteClut8(IccClut value)
        {
            int count = 0;

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

            return(count);
        }
예제 #18
0
        private static uint Pack(ref Pixel pixel)
        {
            const float Max = 255F;

            // Clamp the value between min and max values
            pixel = Numeric.Clamp(pixel, Pixel.Zero, new Pixel(Max));

            uint byte4 = (uint)Math.Round(pixel.R) & 0xFF;
            uint byte3 = ((uint)Math.Round(pixel.G) & 0xFF) << 0x8;
            uint byte2 = ((uint)Math.Round(pixel.B) & 0xFF) << 0x10;
            uint byte1 = ((uint)Math.Round(pixel.A) & 0xFF) << 0x18;

            return(byte4 | byte3 | byte2 | byte1);
        }
예제 #19
0
        /// <summary>
        /// Level shift by +maximum/2, clip to [0, maximum]
        /// </summary>
        public void NormalizeColorsInPlace(float maximum)
        {
            var CMin4 = new Vector4(0F);
            var CMax4 = new Vector4(maximum);
            var COff4 = new Vector4(MathF.Ceiling(maximum / 2));

            this.V0L = Numeric.Clamp(this.V0L + COff4, CMin4, CMax4);
            this.V0R = Numeric.Clamp(this.V0R + COff4, CMin4, CMax4);
            this.V1L = Numeric.Clamp(this.V1L + COff4, CMin4, CMax4);
            this.V1R = Numeric.Clamp(this.V1R + COff4, CMin4, CMax4);
            this.V2L = Numeric.Clamp(this.V2L + COff4, CMin4, CMax4);
            this.V2R = Numeric.Clamp(this.V2R + COff4, CMin4, CMax4);
            this.V3L = Numeric.Clamp(this.V3L + COff4, CMin4, CMax4);
            this.V3R = Numeric.Clamp(this.V3R + COff4, CMin4, CMax4);
            this.V4L = Numeric.Clamp(this.V4L + COff4, CMin4, CMax4);
            this.V4R = Numeric.Clamp(this.V4R + COff4, CMin4, CMax4);
            this.V5L = Numeric.Clamp(this.V5L + COff4, CMin4, CMax4);
            this.V5R = Numeric.Clamp(this.V5R + COff4, CMin4, CMax4);
            this.V6L = Numeric.Clamp(this.V6L + COff4, CMin4, CMax4);
            this.V6R = Numeric.Clamp(this.V6R + COff4, CMin4, CMax4);
            this.V7L = Numeric.Clamp(this.V7L + COff4, CMin4, CMax4);
            this.V7R = Numeric.Clamp(this.V7R + COff4, CMin4, CMax4);
        }
예제 #20
0
        internal static Vector4 PseudoRound(this Vector4 v)
        {
            Vector4 sign = Numeric.Clamp(v, new Vector4(-1), new Vector4(1));

            return(v + (sign * 0.5f));
        }
예제 #21
0
        /// <summary>
        /// Encode writes the image to the jpeg baseline format with the given options.
        /// </summary>
        /// <param name="image">The image to write from.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="cancellationToken">The token to request cancellation.</param>
        public void Encode(Buffer2D <Pixel> image, ImageMetadata metadata, Stream stream, CancellationToken cancellationToken)
        {
            //Guard.NotNull(image, nameof(image));
            //Guard.NotNull(stream, nameof(stream));
            cancellationToken.ThrowIfCancellationRequested();

            const ushort max = JpegConstants.MaxLength;

            if (image.Width >= max || image.Height >= max)
            {
                throw new ImageFormatException($"Image is too large to encode at {image.Width}x{image.Height}.");
            }

            this.outputStream = stream;

            // System.Drawing produces identical output for jpegs with a quality parameter of 0 and 1.
            int qlty = Numeric.Clamp(this.quality ?? metadata.GetFormatMetadata(new JpegFormat()).Quality, 1, 100);

            this.subsample ??= qlty >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420;

            // Convert from a quality rating to a scaling factor.
            int scale;

            if (qlty < 50)
            {
                scale = 5000 / qlty;
            }
            else
            {
                scale = 200 - (qlty * 2);
            }

            // Initialize the quantization tables.
            InitQuantizationTable(0, scale, ref this.luminanceQuantTable);
            InitQuantizationTable(1, scale, ref this.chrominanceQuantTable);

            // Compute number of components based on input image type.
            const int componentCount = 3;

            // Write the Start Of Image marker.
            this.WriteApplicationHeader(metadata);

            // Write Exif, ICC and IPTC profiles
            this.WriteProfiles(metadata);

            // Write the quantization tables.
            this.WriteDefineQuantizationTables();

            // Write the image dimensions.
            this.WriteStartOfFrame(image.Width, image.Height, componentCount);

            // Write the Huffman tables.
            this.WriteDefineHuffmanTables(componentCount);

            // Write the image data.
            this.WriteStartOfScan(image, cancellationToken);

            // Write the End Of Image marker.
            this.buffer[0] = JpegConstants.Markers.XFF;
            this.buffer[1] = JpegConstants.Markers.EOI;
            stream.Write(this.buffer, 0, 2);
            stream.Flush();
        }
예제 #22
0
 /// <summary>
 /// Sets the reading position to the given value
 /// </summary>
 /// <param name="index">The new index position</param>
 public void SetIndex(int index)
 {
     this.currentIndex = Numeric.Clamp(index, 0, this.data.Length);
 }