Merge to XFA: Kill FXSYS_mem{cpy,cmp,set.move}{32,8}.
[pdfium.git] / xfa / src / fxbarcode / BC_UtilRSS.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 // Original code is licensed as follows:\r
7 /*\r
8  * Copyright 2009 ZXing authors\r
9  *\r
10  * Licensed under the Apache License, Version 2.0 (the "License");\r
11  * you may not use this file except in compliance with the License.\r
12  * You may obtain a copy of the License at\r
13  *\r
14  *      http://www.apache.org/licenses/LICENSE-2.0\r
15  *\r
16  * Unless required by applicable law or agreed to in writing, software\r
17  * distributed under the License is distributed on an "AS IS" BASIS,\r
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
19  * See the License for the specific language governing permissions and\r
20  * limitations under the License.\r
21  */\r
22 \r
23 #include "barcode.h"\r
24 #include "BC_UtilRSS.h"\r
25 CBC_UtilRSS::CBC_UtilRSS()\r
26 {\r
27 }\r
28 CBC_UtilRSS::~CBC_UtilRSS()\r
29 {\r
30 }\r
31 CFX_Int32Array *CBC_UtilRSS::GetRssWidths(int32_t val, int32_t n, int32_t elements, int32_t maxWidth, FX_BOOL noNarrow)\r
32 {\r
33     CFX_Int32Array *iTemp =  FX_NEW CFX_Int32Array;\r
34     iTemp->SetSize(elements);\r
35     CBC_AutoPtr<CFX_Int32Array > widths(iTemp);\r
36     int32_t bar;\r
37     int32_t narrowMask = 0;\r
38     for (bar = 0; bar < elements - 1; bar++) {\r
39         narrowMask |= (1 << bar);\r
40         int32_t elmWidth = 1;\r
41         int32_t subVal;\r
42         while (TRUE) {\r
43             subVal = Combins(n - elmWidth - 1, elements - bar - 2);\r
44             if (noNarrow && (narrowMask == 0) &&\r
45                     (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {\r
46                 subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2);\r
47             }\r
48             if (elements - bar - 1 > 1) {\r
49                 int32_t lessVal = 0;\r
50                 for (int32_t mxwElement = n - elmWidth - (elements - bar - 2);\r
51                         mxwElement > maxWidth;\r
52                         mxwElement--) {\r
53                     lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3);\r
54                 }\r
55                 subVal -= lessVal * (elements - 1 - bar);\r
56             } else if (n - elmWidth > maxWidth) {\r
57                 subVal--;\r
58             }\r
59             val -= subVal;\r
60             if (val < 0) {\r
61                 break;\r
62             }\r
63             elmWidth++;\r
64             narrowMask &= ~(1 << bar);\r
65         }\r
66         val += subVal;\r
67         n -= elmWidth;\r
68         (*widths)[bar] = elmWidth;\r
69     }\r
70     (*widths)[bar] = n;\r
71     return widths.release();\r
72 }\r
73 int32_t CBC_UtilRSS::GetRSSvalue(CFX_Int32Array &widths, int32_t maxWidth, FX_BOOL noNarrow)\r
74 {\r
75     int32_t elements = widths.GetSize();\r
76     int32_t n = 0;\r
77     for (int32_t i = 0; i < elements; i++) {\r
78         n += widths[i];\r
79     }\r
80     int32_t val = 0;\r
81     int32_t narrowMask = 0;\r
82     for (int32_t bar = 0; bar < elements - 1; bar++) {\r
83         int32_t elmWidth;\r
84         for (elmWidth = 1, narrowMask |= (1 << bar);\r
85                 elmWidth < widths[bar];\r
86                 elmWidth++, narrowMask &= ~(1 << bar)) {\r
87             int32_t subVal = Combins(n - elmWidth - 1, elements - bar - 2);\r
88             if (noNarrow && (narrowMask == 0) &&\r
89                     (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {\r
90                 subVal -= Combins(n - elmWidth - (elements - bar),\r
91                                   elements - bar - 2);\r
92             }\r
93             if (elements - bar - 1 > 1) {\r
94                 int32_t lessVal = 0;\r
95                 for (int32_t mxwElement = n - elmWidth - (elements - bar - 2);\r
96                         mxwElement > maxWidth; mxwElement--) {\r
97                     lessVal += Combins(n - elmWidth - mxwElement - 1,\r
98                                        elements - bar - 3);\r
99                 }\r
100                 subVal -= lessVal * (elements - 1 - bar);\r
101             } else if (n - elmWidth > maxWidth) {\r
102                 subVal--;\r
103             }\r
104             val += subVal;\r
105         }\r
106         n -= elmWidth;\r
107     }\r
108     return val;\r
109 }\r
110 int32_t CBC_UtilRSS::Combins(int32_t n, int32_t r)\r
111 {\r
112     int32_t maxDenom;\r
113     int32_t minDenom;\r
114     if (n - r > r) {\r
115         minDenom = r;\r
116         maxDenom = n - r;\r
117     } else {\r
118         minDenom = n - r;\r
119         maxDenom = r;\r
120     }\r
121     int32_t val = 1;\r
122     int32_t j = 1;\r
123     for (int32_t i = n; i > maxDenom; i--) {\r
124         val *= i;\r
125         if (j <= minDenom) {\r
126             val /= j;\r
127             j++;\r
128         }\r
129     }\r
130     while (j <= minDenom) {\r
131         val /= j;\r
132         j++;\r
133     }\r
134     return val;\r
135 }\r
136 CFX_Int32Array *CBC_UtilRSS::Elements(CFX_Int32Array &eDist, int32_t N, int32_t K)\r
137 {\r
138     CFX_Int32Array *widths = FX_NEW CFX_Int32Array;\r
139     widths->SetSize(eDist.GetSize() + 2);\r
140     int32_t twoK = K << 1;\r
141     (*widths)[0] = 1;\r
142     int32_t i;\r
143     int32_t minEven = 10;\r
144     int32_t barSum = 1;\r
145     for (i = 1; i < twoK - 2; i += 2) {\r
146         (*widths)[i] = eDist[i - 1] - (*widths)[i - 1];\r
147         (*widths)[i + 1] = eDist[i] - (*widths)[i];\r
148         barSum += (*widths)[i] + (*widths)[i + 1];\r
149         if ((*widths)[i] < minEven) {\r
150             minEven = (*widths)[i];\r
151         }\r
152     }\r
153     (*widths)[twoK - 1] = N - barSum;\r
154     if ((*widths)[twoK - 1] < minEven) {\r
155         minEven = (*widths)[twoK - 1];\r
156     }\r
157     if (minEven > 1) {\r
158         for (i = 0; i < twoK; i += 2) {\r
159             (*widths)[i] += minEven - 1;\r
160             (*widths)[i + 1] -= minEven - 1;\r
161         }\r
162     }\r
163     return widths;\r
164 }\r