You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright 2012 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ZXGenericGF.h"
  17. #import "ZXGenericGFPoly.h"
  18. #import "ZXIntArray.h"
  19. #import "ZXReedSolomonEncoder.h"
  20. @interface ZXReedSolomonEncoder ()
  21. @property (nonatomic, strong, readonly) NSMutableArray *cachedGenerators;
  22. @property (nonatomic, strong, readonly) ZXGenericGF *field;
  23. @end
  24. @implementation ZXReedSolomonEncoder
  25. - (id)initWithField:(ZXGenericGF *)field {
  26. if (self = [super init]) {
  27. _field = field;
  28. ZXIntArray *one = [[ZXIntArray alloc] initWithLength:1];
  29. one.array[0] = 1;
  30. _cachedGenerators = [NSMutableArray arrayWithObject:[[ZXGenericGFPoly alloc] initWithField:field coefficients:one]];
  31. }
  32. return self;
  33. }
  34. - (ZXGenericGFPoly *)buildGenerator:(int)degree {
  35. if (degree >= self.cachedGenerators.count) {
  36. ZXGenericGFPoly *lastGenerator = self.cachedGenerators[[self.cachedGenerators count] - 1];
  37. for (NSUInteger d = [self.cachedGenerators count]; d <= degree; d++) {
  38. ZXIntArray *next = [[ZXIntArray alloc] initWithLength:2];
  39. next.array[0] = 1;
  40. next.array[1] = [self.field exp:(int)d - 1 + self.field.generatorBase];
  41. ZXGenericGFPoly *nextGenerator = [lastGenerator multiply:[[ZXGenericGFPoly alloc] initWithField:self.field coefficients:next]];
  42. [self.cachedGenerators addObject:nextGenerator];
  43. lastGenerator = nextGenerator;
  44. }
  45. }
  46. return (ZXGenericGFPoly *)self.cachedGenerators[degree];
  47. }
  48. - (void)encode:(ZXIntArray *)toEncode ecBytes:(int)ecBytes {
  49. if (ecBytes == 0) {
  50. @throw [NSException exceptionWithName:NSInvalidArgumentException
  51. reason:@"No error correction bytes"
  52. userInfo:nil];
  53. }
  54. int dataBytes = toEncode.length - ecBytes;
  55. if (dataBytes <= 0) {
  56. @throw [NSException exceptionWithName:NSInvalidArgumentException
  57. reason:@"No data bytes provided"
  58. userInfo:nil];
  59. }
  60. ZXGenericGFPoly *generator = [self buildGenerator:ecBytes];
  61. ZXIntArray *infoCoefficients = [[ZXIntArray alloc] initWithLength:dataBytes];
  62. for (int i = 0; i < dataBytes; i++) {
  63. infoCoefficients.array[i] = toEncode.array[i];
  64. }
  65. ZXGenericGFPoly *info = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:infoCoefficients];
  66. info = [info multiplyByMonomial:ecBytes coefficient:1];
  67. ZXGenericGFPoly *remainder = [info divide:generator][1];
  68. ZXIntArray *coefficients = remainder.coefficients;
  69. int numZeroCoefficients = ecBytes - coefficients.length;
  70. for (int i = 0; i < numZeroCoefficients; i++) {
  71. toEncode.array[dataBytes + i] = 0;
  72. }
  73. for (int i = 0; i < coefficients.length; i++) {
  74. toEncode.array[dataBytes + numZeroCoefficients + i] = coefficients.array[i];
  75. }
  76. }
  77. @end