public static byte[] CompressBlockMasked(byte[] rgba, int mask, SquishOptions flags) { flags = flags.FixFlags(); ColourSet colours = new ColourSet(rgba, mask, flags); if (colours.Count == 1) { // Always do a single colour fit //SingleColourFit fit = new SingleColourFit(ref colours, flags); } else if (flags.HasFlag(SquishOptions.ColourRangeFit) || colours.Count == 0) { // Do a range fit //RangeFit fit = new RangeFit(ref colours, flags, metric); } else { // Default to a cluster fit (could be iterative or not) //ClusterFit fit = new ClusterFit(ref colours, flags, metric); } // Compress alpha separately if needed if (flags.HasFlag(SquishOptions.DXT3)) { //Alpha.CompressAlphaDxt3(rgba, mask, alphaBlock); } else if (flags.HasFlag(SquishOptions.DXT5)) { //Alpha.CompressAlphaDxt5(rgba, mask, alphaBlock); } throw new NotImplementedException(); }
public ClusterFit(ColourSet colours, SquishFlags flags, float?metric) : base(colours, flags) { // set the iteration count m_iterationCount = ((m_flags & SquishFlags.kColourIterativeClusterFit) != 0 ? 8 : 1); // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) if (metric != null) { //m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f ); } else { m_metric = new Vector4(1.0f); } // initialise the best error m_besterror = new Vector4(float.MaxValue); // cache some values int count = m_colours.Count; Vector3[] values = m_colours.Points; // get the covariance matrix Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, m_colours.Weights); // compute the principle component m_principle = Sym3x3.ComputePrincipleComponent(covariance); }
protected ClusterFit(ColourSet colours, SquishOptions flags) : base(colours, flags) { // Set the iteration count. this._IterationCount = flags.HasFlag(SquishOptions.ColourIterativeClusterFit) ? MaxIterations : 1; // Initialise the best error. this._BestError = new Vector4(float.MaxValue); // Initialize the metric var perceptual = flags.HasFlag(SquishOptions.ColourMetricPerceptual); if (perceptual) { this._Metric = new Vector4(0.2126f, 0.7152f, 0.0722f, 0.0f); } else { this._Metric = new Vector4(1.0f); } // Get the covariance matrix. var covariance = Sym3x3.ComputeWeightedCovariance(colours.Count, colours.Points, colours.Weights); // Compute the principle component this._Principle = Sym3x3.ComputePrincipledComponent(covariance); }
public ClusterFit(ColourSet colours, SquishFlags flags, float? metric) : base(colours, flags) { // set the iteration count m_iterationCount = ((m_flags & SquishFlags.kColourIterativeClusterFit) != 0 ? 8 : 1); // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) if (metric != null) { //m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f ); } else { m_metric = new Vector4(1.0f); } // initialise the best error m_besterror = new Vector4(float.MaxValue); // cache some values int count = m_colours.Count; Vector3[] values = m_colours.Points; // get the covariance matrix Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, m_colours.Weights); // compute the principle component m_principle = Sym3x3.ComputePrincipleComponent(covariance); }
private SingleColourFit(ColourSet colours, SquishOptions flags) : base(colours, flags) { Vector3 values = this._Colours.Points[0]; this.colour[0] = (byte)FloatToInt(255.0f * values.X, 255); this.colour[1] = (byte)FloatToInt(255.0f * values.Y, 255); this.colour[2] = (byte)FloatToInt(255.0f * values.Z, 255); this.bestError = int.MaxValue; }
public SingleColourFit(ColourSet colours, SquishFlags flags) : base(colours, flags) { // grab the single colour Vector3[] values = m_colours.Points; m_colour[0] = (byte)ColourBlock.FloatToInt(255.0f * values[0].X, 255); m_colour[1] = (byte)ColourBlock.FloatToInt(255.0f * values[0].Y, 255); m_colour[2] = (byte)ColourBlock.FloatToInt(255.0f * values[0].Z, 255); // initialise the best error m_besterror = int.MaxValue; }
static void CompressMasked(byte[] rgba, int mask, ref byte[] block, int offset, SquishFlags flags, float?metric) { // fix any bad flags flags = FixFlags(flags); // get the block locations int colourBlock = offset; int alphaBlock = offset; if ((flags & (SquishFlags.kDxt3 | SquishFlags.kDxt5)) != 0) { colourBlock += 8; } // create the minimal point set ColourSet colours = new ColourSet(rgba, mask, flags); // check the compression type and compress colour if (colours.Count == 1) { // always do a single colour fit SingleColourFit fit = new SingleColourFit(colours, flags); fit.Compress(ref block, colourBlock); } else if ((flags & SquishFlags.kColourRangeFit) != 0 || colours.Count == 0) { // do a range fit RangeFit fit = new RangeFit(colours, flags, metric); fit.Compress(ref block, colourBlock); } else { // default to a cluster fit (could be iterative or not) ClusterFit fit = new ClusterFit(colours, flags, metric); fit.Compress(ref block, colourBlock); } // compress alpha separately if necessary if ((flags & SquishFlags.kDxt3) != 0) { CompressAlphaDxt3(rgba, mask, ref block, alphaBlock); } else if ((flags & SquishFlags.kDxt5) != 0) { CompressAlphaDxt5(rgba, mask, ref block, alphaBlock); } }
public ColourFit(ColourSet colours, SquishFlags flags) { m_colours = colours; m_flags = flags; }
public RangeFit(ColourSet colours, SquishFlags flags, float? metric) : base(colours, flags) { // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) if (metric != null) { //m_metric = new Vector3( metric[0], metric[1], metric[2] ); } else { m_metric = new Vector3(1.0f); } // initialise the best error m_besterror = float.MaxValue; // cache some values int count = m_colours.Count; Vector3[] values = m_colours.Points; float[] weights = m_colours.Weights; // get the covariance matrix Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, weights); // compute the principle component Vector3 principle = Sym3x3.ComputePrincipleComponent(covariance); // get the min and max range as the codebook endpoints Vector3 start = new Vector3(0.0f); Vector3 end = new Vector3(0.0f); if (count > 0) { float min, max; // compute the range start = end = values[0]; min = max = Vector3.Dot(values[0], principle); for (int i = 1; i < count; ++i) { float val = Vector3.Dot(values[i], principle); if (val < min) { start = values[i]; min = val; } else if (val > max) { end = values[i]; max = val; } } } // clamp the output to [0, 1] Vector3 one = new Vector3(1.0f); Vector3 zero = new Vector3(0.0f); start = Vector3.Min(one, Vector3.Max(zero, start)); end = Vector3.Min(one, Vector3.Max(zero, end)); // clamp to the grid and save Vector3 grid = new Vector3(31.0f, 63.0f, 31.0f); Vector3 gridrcp = new Vector3(1.0f / 31.0f, 1.0f / 63.0f, 1.0f / 31.0f); Vector3 half = new Vector3(0.5f); m_start = Helpers.Truncate(grid * start + half) * gridrcp; m_end = Helpers.Truncate(grid * end + half) * gridrcp; }
public RangeFit(ColourSet colours, SquishFlags flags, float?metric) : base(colours, flags) { // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) if (metric != null) { //m_metric = new Vector3( metric[0], metric[1], metric[2] ); } else { m_metric = new Vector3(1.0f); } // initialise the best error m_besterror = float.MaxValue; // cache some values int count = m_colours.Count; Vector3[] values = m_colours.Points; float[] weights = m_colours.Weights; // get the covariance matrix Sym3x3 covariance = Sym3x3.ComputeWeightedCovariance(count, values, weights); // compute the principle component Vector3 principle = Sym3x3.ComputePrincipleComponent(covariance); // get the min and max range as the codebook endpoints Vector3 start = new Vector3(0.0f); Vector3 end = new Vector3(0.0f); if (count > 0) { float min, max; // compute the range start = end = values[0]; min = max = Vector3.Dot(values[0], principle); for (int i = 1; i < count; ++i) { float val = Vector3.Dot(values[i], principle); if (val < min) { start = values[i]; min = val; } else if (val > max) { end = values[i]; max = val; } } } // clamp the output to [0, 1] Vector3 one = new Vector3(1.0f); Vector3 zero = new Vector3(0.0f); start = Vector3.Min(one, Vector3.Max(zero, start)); end = Vector3.Min(one, Vector3.Max(zero, end)); // clamp to the grid and save Vector3 grid = new Vector3(31.0f, 63.0f, 31.0f); Vector3 gridrcp = new Vector3(1.0f / 31.0f, 1.0f / 63.0f, 1.0f / 31.0f); Vector3 half = new Vector3(0.5f); m_start = Helpers.Truncate(grid * start + half) * gridrcp; m_end = Helpers.Truncate(grid * end + half) * gridrcp; }
static void CompressMasked(byte[] rgba, int mask, ref byte[] block, int offset, SquishFlags flags, float? metric) { // fix any bad flags flags = FixFlags(flags); // get the block locations int colourBlock = offset; int alphaBlock = offset; if ((flags & (SquishFlags.kDxt3 | SquishFlags.kDxt5)) != 0) { colourBlock += 8; } // create the minimal point set ColourSet colours = new ColourSet(rgba, mask, flags); // check the compression type and compress colour if (colours.Count == 1) { // always do a single colour fit SingleColourFit fit = new SingleColourFit(colours, flags); fit.Compress(ref block, colourBlock); } else if ((flags & SquishFlags.kColourRangeFit) != 0 || colours.Count == 0) { // do a range fit RangeFit fit = new RangeFit(colours, flags, metric); fit.Compress(ref block, colourBlock); } else { // default to a cluster fit (could be iterative or not) ClusterFit fit = new ClusterFit(colours, flags, metric); fit.Compress(ref block, colourBlock); } // compress alpha separately if necessary if ((flags & SquishFlags.kDxt3) != 0) { CompressAlphaDxt3(rgba, mask, ref block, alphaBlock); } else if ((flags & SquishFlags.kDxt5) != 0) { CompressAlphaDxt5(rgba, mask, ref block, alphaBlock); } }