/*
|
* 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 "ZXBitMatrix.h"
|
#import "ZXByteArray.h"
|
#import "ZXEncodeHints.h"
|
#import "ZXPDF417.h"
|
#import "ZXPDF417BarcodeMatrix.h"
|
#import "ZXPDF417Dimensions.h"
|
#import "ZXPDF417Writer.h"
|
|
/**
|
* default white space (margin) around the code
|
*/
|
const int ZX_PDF417_WHITE_SPACE = 30;
|
|
@implementation ZXPDF417Writer
|
|
- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height
|
hints:(ZXEncodeHints *)hints error:(NSError **)error {
|
if (format != kBarcodeFormatPDF417) {
|
[NSException raise:NSInvalidArgumentException format:@"Can only encode PDF_417, but got %d", format];
|
}
|
|
ZXPDF417 *encoder = [[ZXPDF417 alloc] init];
|
int margin = ZX_PDF417_WHITE_SPACE;
|
|
if (hints != nil) {
|
encoder.compact = hints.pdf417Compact;
|
encoder.compaction = hints.pdf417Compaction;
|
if (hints.pdf417Dimensions != nil) {
|
ZXPDF417Dimensions *dimensions = hints.pdf417Dimensions;
|
[encoder setDimensionsWithMaxCols:dimensions.maxCols
|
minCols:dimensions.minCols
|
maxRows:dimensions.maxRows
|
minRows:dimensions.minRows];
|
}
|
if (hints.margin) {
|
margin = [hints.margin intValue];
|
}
|
if (hints.encoding > 0) {
|
encoder.encoding = hints.encoding;
|
}
|
}
|
|
return [self bitMatrixFromEncoder:encoder contents:contents width:width height:height margin:margin error:error];
|
}
|
|
- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
|
return [self encode:contents format:format width:width height:height hints:nil error:error];
|
}
|
|
/**
|
* Takes encoder, accounts for width/height, and retrieves bit matrix
|
*/
|
- (ZXBitMatrix *)bitMatrixFromEncoder:(ZXPDF417 *)encoder
|
contents:(NSString *)contents
|
width:(int)width
|
height:(int)height
|
margin:(int)margin
|
error:(NSError **)error {
|
int errorCorrectionLevel = 2;
|
if (![encoder generateBarcodeLogic:contents errorCorrectionLevel:errorCorrectionLevel error:error]) {
|
return nil;
|
}
|
|
int lineThickness = 2;
|
int aspectRatio = 4;
|
NSArray *originalScale = [[encoder barcodeMatrix] scaledMatrixWithXScale:lineThickness yScale:aspectRatio * lineThickness];
|
BOOL rotated = NO;
|
if ((height > width) ^ ([(ZXByteArray *)originalScale[0] length] < [originalScale count])) {
|
originalScale = [self rotateArray:originalScale];
|
rotated = YES;
|
}
|
|
int scaleX = width / [(ZXByteArray *)originalScale[0] length];
|
int scaleY = height / [originalScale count];
|
|
int scale;
|
if (scaleX < scaleY) {
|
scale = scaleX;
|
} else {
|
scale = scaleY;
|
}
|
|
if (scale > 1) {
|
NSArray *scaledMatrix =
|
[[encoder barcodeMatrix] scaledMatrixWithXScale:scale * lineThickness yScale:scale * aspectRatio * lineThickness];
|
if (rotated) {
|
scaledMatrix = [self rotateArray:scaledMatrix];
|
}
|
return [self bitMatrixFrombitArray:scaledMatrix margin:margin];
|
}
|
return [self bitMatrixFrombitArray:originalScale margin:margin];
|
}
|
|
/**
|
* This takes an array holding the values of the PDF 417
|
*
|
* @param input a byte array of information with 0 is black, and 1 is white
|
* @param margin border around the barcode
|
* @return BitMatrix of the input
|
*/
|
- (ZXBitMatrix *)bitMatrixFrombitArray:(NSArray *)input margin:(int)margin {
|
// Creates the bitmatrix with extra space for whtespace
|
ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:[(ZXByteArray *)input[0] length] + 2 * margin height:(int)[input count] + 2 * margin];
|
[output clear];
|
for (int y = 0, yOutput = output.height - margin; y < [input count]; y++, yOutput--) {
|
for (int x = 0; x < [(ZXByteArray *)input[0] length]; x++) {
|
// Zero is white in the bytematrix
|
if ([(ZXByteArray *)input[y] array][x] == 1) {
|
[output setX:x + margin y:yOutput];
|
}
|
}
|
}
|
return output;
|
}
|
|
/**
|
* Takes and rotates the it 90 degrees
|
*/
|
- (NSArray *)rotateArray:(NSArray *)bitarray {
|
NSMutableArray *temp = [NSMutableArray array];
|
for (int i = 0; i < [(ZXByteArray *)bitarray[0] length]; i++) {
|
[temp addObject:[[ZXByteArray alloc] initWithLength:(unsigned int)[bitarray count]]];
|
}
|
|
for (int ii = 0; ii < [bitarray count]; ii++) {
|
// This makes the direction consistent on screen when rotating the
|
// screen;
|
int inverseii = (int)[bitarray count] - ii - 1;
|
for (int jj = 0; jj < [(ZXByteArray *)bitarray[0] length]; jj++) {
|
ZXByteArray *b = temp[jj];
|
b.array[inverseii] = [(ZXByteArray *)bitarray[ii] array][jj];
|
}
|
}
|
return temp;
|
}
|
|
@end
|