12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /*
- * Copyright 2012 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.
- */
-
- #import "ZXGenericGF.h"
- #import "ZXGenericGFPoly.h"
- #import "ZXIntArray.h"
- #import "ZXReedSolomonEncoder.h"
-
- @interface ZXReedSolomonEncoder ()
-
- @property (nonatomic, strong, readonly) NSMutableArray *cachedGenerators;
- @property (nonatomic, strong, readonly) ZXGenericGF *field;
-
- @end
-
- @implementation ZXReedSolomonEncoder
-
- - (id)initWithField:(ZXGenericGF *)field {
- if (self = [super init]) {
- _field = field;
- ZXIntArray *one = [[ZXIntArray alloc] initWithLength:1];
- one.array[0] = 1;
- _cachedGenerators = [NSMutableArray arrayWithObject:[[ZXGenericGFPoly alloc] initWithField:field coefficients:one]];
- }
-
- return self;
- }
-
- - (ZXGenericGFPoly *)buildGenerator:(int)degree {
- if (degree >= self.cachedGenerators.count) {
- ZXGenericGFPoly *lastGenerator = self.cachedGenerators[[self.cachedGenerators count] - 1];
- for (NSUInteger d = [self.cachedGenerators count]; d <= degree; d++) {
- ZXIntArray *next = [[ZXIntArray alloc] initWithLength:2];
- next.array[0] = 1;
- next.array[1] = [self.field exp:(int)d - 1 + self.field.generatorBase];
- ZXGenericGFPoly *nextGenerator = [lastGenerator multiply:[[ZXGenericGFPoly alloc] initWithField:self.field coefficients:next]];
- [self.cachedGenerators addObject:nextGenerator];
- lastGenerator = nextGenerator;
- }
- }
-
- return (ZXGenericGFPoly *)self.cachedGenerators[degree];
- }
-
- - (void)encode:(ZXIntArray *)toEncode ecBytes:(int)ecBytes {
- if (ecBytes == 0) {
- @throw [NSException exceptionWithName:NSInvalidArgumentException
- reason:@"No error correction bytes"
- userInfo:nil];
- }
- int dataBytes = toEncode.length - ecBytes;
- if (dataBytes <= 0) {
- @throw [NSException exceptionWithName:NSInvalidArgumentException
- reason:@"No data bytes provided"
- userInfo:nil];
- }
- ZXGenericGFPoly *generator = [self buildGenerator:ecBytes];
- ZXIntArray *infoCoefficients = [[ZXIntArray alloc] initWithLength:dataBytes];
- for (int i = 0; i < dataBytes; i++) {
- infoCoefficients.array[i] = toEncode.array[i];
- }
- ZXGenericGFPoly *info = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:infoCoefficients];
- info = [info multiplyByMonomial:ecBytes coefficient:1];
- ZXGenericGFPoly *remainder = [info divide:generator][1];
- ZXIntArray *coefficients = remainder.coefficients;
- int numZeroCoefficients = ecBytes - coefficients.length;
- for (int i = 0; i < numZeroCoefficients; i++) {
- toEncode.array[dataBytes + i] = 0;
- }
- for (int i = 0; i < coefficients.length; i++) {
- toEncode.array[dataBytes + numZeroCoefficients + i] = coefficients.array[i];
- }
- }
-
- @end
|