Beispiel #1
0
        // returns all possible combinations of tile values.
        // this sets the ID for the resulting ValueSets which is an ordered number,
        // required for the un-mapping algo to know where things are.
        public unsafe static ValueSet[] Permutate(int numDimensions, float[] discreteNormalizedValuesPerTile)
        {
            // we will just do this as if each value is a digit in a number. that's the analogy that drives this.
            // actually this symbolizes the # of digits in the result, PLUS the number of possible values per digit.
            ulong numDigits         = (ulong)discreteNormalizedValuesPerTile.Length;
            ulong theoreticalBase   = numDigits;
            ulong totalPermutations = (ulong)Pow((long)numDigits, (uint)numDimensions);

            if (totalPermutations > int.MaxValue)
            {
                Log.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!");
                Log.WriteLine("!!!!!  Total map keys is just too big. Must be less than 2 billion.");
                Log.WriteLine("You requested a map with {0:N0} mappings", totalPermutations);
                Log.WriteLine("Which would result in a map ref image {0:N0} x {0:N0}", (int)Math.Sqrt(totalPermutations));
                Log.WriteLine("And take {0:N0} MB on disk", totalPermutations / 1024 / 1024 * 3);
                throw new Exception("Map is too big to process");
            }
            float[] normalizedValues = new float[numDimensions];

            Log.WriteLine("Allocating {0:N0} valuesets. Valueset size = {1}, so {2:N0} bytes of memory", totalPermutations, sizeof(ValueSet),
                          (ulong)totalPermutations * (ulong)sizeof(ValueSet));


            ValueSet[] ret = new ValueSet[totalPermutations];
            for (ulong i = 0; i < totalPermutations; ++i)
            {
                // just like digits in a number, use % and divide to shave off "digits" one by one.
                ulong a = i;// the value that originates from i and we shift/mod to enumerate digits
                //ValueSet n = NewValueSet(numTiles, i);
                for (int d = 0; d < numDimensions; ++d)
                {
                    ulong thisIndex = a % theoreticalBase;
                    a /= theoreticalBase;
                    normalizedValues[d] = discreteNormalizedValuesPerTile[(int)thisIndex];
                    //ret[i].Values[d] = discreteValuesPerTile[(int)thisIndex];
                }
                ValueSet.Init(ref ret[i], numDimensions, (long)i, normalizedValues);
                //ret.Add(n);
                //for (int xxx = 0; xxx < ret[i].ValuesLength; ++xxx)
                //{
                //  Debug.Assert(ret[14].ColorData[xxx] == 0 || ret[14].ColorData[xxx] == 0.5 || ret[14].ColorData[xxx] == 1.0);
                //}
            }

            //foreach (var r in ret)
            //{
            //  for (int i = 0; i < r.ValuesLength; ++ i)
            //  {
            //    Debug.Assert(r.ColorData[i] == 0 || r.ColorData[i] == 0.5 || r.ColorData[i] == 1.0);
            //  }
            //}

            return(ret);
        }
Beispiel #2
0
        public static ValueSet GetValueSetForSinglePixel(this ILCCColorSpace cs, ColorF color, bool useChroma)
        {
            // a value set normally consists of multiple luma & chroma components for a char (for example 5 luma + 2 chroma)
            // for this we just have the normal default 3-component. all our colorspaces are LCC (luma chroma chroma).
            LCCColorDenorm denorm = cs.RGBToLCC(color);
            ValueSet       src    = new ValueSet();

            float[] normArray = new float[]
            {
                (float)cs.NormalizeL(denorm.L),
                (float)cs.NormalizeC1(denorm.C1),
                (float)cs.NormalizeC2(denorm.C2),
            };
            ValueSet.Init(ref src, useChroma ? 3 : 1, 0, normArray);
            src.DenormalizedValues[0] = (float)denorm.L;
            src.DenormalizedValues[1] = (float)denorm.C1;
            src.DenormalizedValues[2] = (float)denorm.C2;
            return(src);
        }