| // Copyright 2014 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| // Original code is licensed as follows: | |
| /* | |
| * 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. | |
| */ | |
| #include "barcode.h" | |
| #include "BC_UtilRSS.h" | |
| CBC_UtilRSS::CBC_UtilRSS() {} | |
| CBC_UtilRSS::~CBC_UtilRSS() {} | |
| CFX_Int32Array* CBC_UtilRSS::GetRssWidths(int32_t val, | |
| int32_t n, | |
| int32_t elements, | |
| int32_t maxWidth, | |
| FX_BOOL noNarrow) { | |
| CFX_Int32Array* iTemp = new CFX_Int32Array; | |
| iTemp->SetSize(elements); | |
| CBC_AutoPtr<CFX_Int32Array> widths(iTemp); | |
| int32_t bar; | |
| int32_t narrowMask = 0; | |
| for (bar = 0; bar < elements - 1; bar++) { | |
| narrowMask |= (1 << bar); | |
| int32_t elmWidth = 1; | |
| int32_t 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) { | |
| int32_t lessVal = 0; | |
| for (int32_t 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.release(); | |
| } | |
| int32_t CBC_UtilRSS::GetRSSvalue(CFX_Int32Array& widths, | |
| int32_t maxWidth, | |
| FX_BOOL noNarrow) { | |
| int32_t elements = widths.GetSize(); | |
| int32_t n = 0; | |
| for (int32_t i = 0; i < elements; i++) { | |
| n += widths[i]; | |
| } | |
| int32_t val = 0; | |
| int32_t narrowMask = 0; | |
| for (int32_t bar = 0; bar < elements - 1; bar++) { | |
| int32_t elmWidth; | |
| for (elmWidth = 1, narrowMask |= (1 << bar); elmWidth < widths[bar]; | |
| elmWidth++, narrowMask &= ~(1 << bar)) { | |
| int32_t 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) { | |
| int32_t lessVal = 0; | |
| for (int32_t 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; | |
| } | |
| int32_t CBC_UtilRSS::Combins(int32_t n, int32_t r) { | |
| int32_t maxDenom; | |
| int32_t minDenom; | |
| if (n - r > r) { | |
| minDenom = r; | |
| maxDenom = n - r; | |
| } else { | |
| minDenom = n - r; | |
| maxDenom = r; | |
| } | |
| int32_t val = 1; | |
| int32_t j = 1; | |
| for (int32_t i = n; i > maxDenom; i--) { | |
| val *= i; | |
| if (j <= minDenom) { | |
| val /= j; | |
| j++; | |
| } | |
| } | |
| while (j <= minDenom) { | |
| val /= j; | |
| j++; | |
| } | |
| return val; | |
| } | |
| CFX_Int32Array* CBC_UtilRSS::Elements(CFX_Int32Array& eDist, | |
| int32_t N, | |
| int32_t K) { | |
| CFX_Int32Array* widths = new CFX_Int32Array; | |
| widths->SetSize(eDist.GetSize() + 2); | |
| int32_t twoK = K << 1; | |
| (*widths)[0] = 1; | |
| int32_t i; | |
| int32_t minEven = 10; | |
| int32_t 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; | |
| } |