Files
aistudio-wpf-diagram/zxing.core/xx/oned/rss/RSSUtils.cs
2021-07-23 09:42:22 +08:00

205 lines
6.2 KiB
C#

/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace ZXing.OneD.RSS
{
/// <summary>
/// Adapted from listings in ISO/IEC 24724 Appendix B and Appendix G.
/// </summary>
public static class RSSUtils
{
/*
/// <summary>
/// Gets the RS swidths.
/// </summary>
/// <param name="val">The val.</param>
/// <param name="n">The n.</param>
/// <param name="elements">The elements.</param>
/// <param name="maxWidth">Width of the max.</param>
/// <param name="noNarrow">if set to <c>true</c> [no narrow].</param>
/// <returns></returns>
public static int[] getRSSwidths(int val, int n, int elements, int maxWidth, bool noNarrow)
{
int[] widths = new int[elements];
int bar;
int narrowMask = 0;
for (bar = 0; bar < elements - 1; bar++)
{
narrowMask |= 1 << bar;
int elmWidth = 1;
int subVal;
while (true)
{
subVal = combins(n - elmWidth - 1, elements - bar - 2);
if (noNarrow && (narrowMask == 0) &&
(n - elmWidth - (elements - bar - 1) >= elements - bar - 1))
{
subVal -= combins(n - elmWidth - (elements - bar), elements - bar - 2);
}
if (elements - bar - 1 > 1)
{
int lessVal = 0;
for (int mxwElement = n - elmWidth - (elements - bar - 2);
mxwElement > maxWidth;
mxwElement--)
{
lessVal += combins(n - elmWidth - mxwElement - 1, elements - bar - 3);
}
subVal -= lessVal * (elements - 1 - bar);
}
else if (n - elmWidth > maxWidth)
{
subVal--;
}
val -= subVal;
if (val < 0)
{
break;
}
elmWidth++;
narrowMask &= ~(1 << bar);
}
val += subVal;
n -= elmWidth;
widths[bar] = elmWidth;
}
widths[bar] = n;
return widths;
}
*/
/// <summary>
/// Gets the RS svalue.
/// </summary>
/// <param name="widths">The widths.</param>
/// <param name="maxWidth">Width of the max.</param>
/// <param name="noNarrow">if set to <c>true</c> [no narrow].</param>
/// <returns></returns>
public static int getRSSvalue(int[] widths, int maxWidth, bool noNarrow)
{
int elements = widths.Length;
int n = 0;
foreach (var width in widths)
{
n += width;
}
int val = 0;
int narrowMask = 0;
for (int bar = 0; bar < elements - 1; bar++)
{
int elmWidth;
for (elmWidth = 1, narrowMask |= 1 << bar;
elmWidth < widths[bar];
elmWidth++, narrowMask &= ~(1 << bar))
{
int subVal = combins(n - elmWidth - 1, elements - bar - 2);
if (noNarrow && (narrowMask == 0) &&
(n - elmWidth - (elements - bar - 1) >= elements - bar - 1))
{
subVal -= combins(n - elmWidth - (elements - bar),
elements - bar - 2);
}
if (elements - bar - 1 > 1)
{
int lessVal = 0;
for (int mxwElement = n - elmWidth - (elements - bar - 2);
mxwElement > maxWidth; mxwElement--)
{
lessVal += combins(n - elmWidth - mxwElement - 1,
elements - bar - 3);
}
subVal -= lessVal * (elements - 1 - bar);
}
else if (n - elmWidth > maxWidth)
{
subVal--;
}
val += subVal;
}
n -= elmWidth;
}
return val;
}
private static int combins(int n, int r)
{
int maxDenom;
int minDenom;
if (n - r > r)
{
minDenom = r;
maxDenom = n - r;
}
else
{
minDenom = n - r;
maxDenom = r;
}
int val = 1;
int j = 1;
for (int i = n; i > maxDenom; i--)
{
val *= i;
if (j <= minDenom)
{
val /= j;
j++;
}
}
while (j <= minDenom)
{
val /= j;
j++;
}
return val;
}
/*
internal static int[] elements(int[] eDist, int N, int K)
{
int[] widths = new int[eDist.Length + 2];
int twoK = K << 1;
widths[0] = 1;
int i;
int minEven = 10;
int barSum = 1;
for (i = 1; i < twoK - 2; i += 2)
{
widths[i] = eDist[i - 1] - widths[i - 1];
widths[i + 1] = eDist[i] - widths[i];
barSum += widths[i] + widths[i + 1];
if (widths[i] < minEven)
{
minEven = widths[i];
}
}
widths[twoK - 1] = N - barSum;
if (widths[twoK - 1] < minEven)
{
minEven = widths[twoK - 1];
}
if (minEven > 1)
{
for (i = 0; i < twoK; i += 2)
{
widths[i] += minEven - 1;
widths[i + 1] -= minEven - 1;
}
}
return widths;
}
*/
}
}