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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 "ZXBarcodeFormat.h"
  17. #import "ZXBinaryBitmap.h"
  18. #import "ZXBitMatrix.h"
  19. #import "ZXDecodeHints.h"
  20. #import "ZXDecoderResult.h"
  21. #import "ZXDetectorResult.h"
  22. #import "ZXErrors.h"
  23. #import "ZXPDF417Common.h"
  24. #import "ZXPDF417Detector.h"
  25. #import "ZXPDF417DetectorResult.h"
  26. #import "ZXPDF417Reader.h"
  27. #import "ZXPDF417ResultMetadata.h"
  28. #import "ZXPDF417ScanningDecoder.h"
  29. #import "ZXResult.h"
  30. #import "ZXResultPoint.h"
  31. @implementation ZXPDF417Reader
  32. /**
  33. * Locates and decodes a PDF417 code in an image.
  34. *
  35. * @return a String representing the content encoded by the PDF417 code
  36. * @return nil if a PDF417 code cannot be found,
  37. * @return nil if a PDF417 cannot be decoded
  38. */
  39. - (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
  40. return [self decode:image hints:nil error:error];
  41. }
  42. - (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
  43. NSArray *result = [self decode:image hints:hints multiple:NO error:error];
  44. if (!result || result.count == 0 || !result[0]) {
  45. if (error) *error = ZXNotFoundErrorInstance();
  46. return nil;
  47. }
  48. return result[0];
  49. }
  50. - (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error {
  51. return [self decodeMultiple:image hints:nil error:error];
  52. }
  53. - (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
  54. return [self decode:image hints:hints multiple:YES error:error];
  55. }
  56. - (NSArray *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints multiple:(BOOL)multiple error:(NSError **)error {
  57. NSMutableArray *results = [NSMutableArray array];
  58. ZXPDF417DetectorResult *detectorResult = [ZXPDF417Detector detect:image hints:hints multiple:multiple error:error];
  59. if (!detectorResult) {
  60. return nil;
  61. }
  62. for (NSArray *points in detectorResult.points) {
  63. ZXResultPoint *imageTopLeft = points[4] == [NSNull null] ? nil : points[4];
  64. ZXResultPoint *imageBottomLeft = points[5] == [NSNull null] ? nil : points[5];
  65. ZXResultPoint *imageTopRight = points[6] == [NSNull null] ? nil : points[6];
  66. ZXResultPoint *imageBottomRight = points[7] == [NSNull null] ? nil : points[7];
  67. ZXDecoderResult *decoderResult = [ZXPDF417ScanningDecoder decode:detectorResult.bits
  68. imageTopLeft:imageTopLeft
  69. imageBottomLeft:imageBottomLeft
  70. imageTopRight:imageTopRight
  71. imageBottomRight:imageBottomRight
  72. minCodewordWidth:[self minCodewordWidth:points]
  73. maxCodewordWidth:[self maxCodewordWidth:points]
  74. error:error];
  75. if (!decoderResult) {
  76. return nil;
  77. }
  78. ZXResult *result = [[ZXResult alloc] initWithText:decoderResult.text
  79. rawBytes:decoderResult.rawBytes
  80. resultPoints:points
  81. format:kBarcodeFormatPDF417];
  82. [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:decoderResult.ecLevel];
  83. ZXPDF417ResultMetadata *pdf417ResultMetadata = decoderResult.other;
  84. if (pdf417ResultMetadata) {
  85. [result putMetadata:kResultMetadataTypePDF417ExtraMetadata value:pdf417ResultMetadata];
  86. }
  87. [results addObject:result];
  88. }
  89. return [NSArray arrayWithArray:results];
  90. }
  91. - (int)maxWidth:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 {
  92. if (!p1 || !p2 || (id)p1 == [NSNull null] || p2 == (id)[NSNull null]) {
  93. return 0;
  94. }
  95. return fabsf(p1.x - p2.x);
  96. }
  97. - (int)minWidth:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 {
  98. if (!p1 || !p2 || (id)p1 == [NSNull null] || p2 == (id)[NSNull null]) {
  99. return INT_MAX;
  100. }
  101. return fabsf(p1.x - p2.x);
  102. }
  103. - (int)maxCodewordWidth:(NSArray *)p {
  104. return MAX(
  105. MAX([self maxWidth:p[0] p2:p[4]], [self maxWidth:p[6] p2:p[2]] * ZX_PDF417_MODULES_IN_CODEWORD /
  106. ZX_PDF417_MODULES_IN_STOP_PATTERN),
  107. MAX([self maxWidth:p[1] p2:p[5]], [self maxWidth:p[7] p2:p[3]] * ZX_PDF417_MODULES_IN_CODEWORD /
  108. ZX_PDF417_MODULES_IN_STOP_PATTERN));
  109. }
  110. - (int)minCodewordWidth:(NSArray *)p {
  111. return MIN(
  112. MIN([self minWidth:p[0] p2:p[4]], [self minWidth:p[6] p2:p[2]] * ZX_PDF417_MODULES_IN_CODEWORD /
  113. ZX_PDF417_MODULES_IN_STOP_PATTERN),
  114. MIN([self minWidth:p[1] p2:p[5]], [self minWidth:p[7] p2:p[3]] * ZX_PDF417_MODULES_IN_CODEWORD /
  115. ZX_PDF417_MODULES_IN_STOP_PATTERN));
  116. }
  117. - (void)reset {
  118. // nothing needs to be reset
  119. }
  120. @end