/*
|
* 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 "ZXDefaultGridSampler.h"
|
#import "ZXErrors.h"
|
#import "ZXPerspectiveTransform.h"
|
|
@implementation ZXDefaultGridSampler
|
|
- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
|
dimensionX:(int)dimensionX
|
dimensionY:(int)dimensionY
|
p1ToX:(float)p1ToX p1ToY:(float)p1ToY
|
p2ToX:(float)p2ToX p2ToY:(float)p2ToY
|
p3ToX:(float)p3ToX p3ToY:(float)p3ToY
|
p4ToX:(float)p4ToX p4ToY:(float)p4ToY
|
p1FromX:(float)p1FromX p1FromY:(float)p1FromY
|
p2FromX:(float)p2FromX p2FromY:(float)p2FromY
|
p3FromX:(float)p3FromX p3FromY:(float)p3FromY
|
p4FromX:(float)p4FromX p4FromY:(float)p4FromY
|
error:(NSError **)error {
|
ZXPerspectiveTransform *transform =
|
[ZXPerspectiveTransform quadrilateralToQuadrilateral:p1ToX y0:p1ToY
|
x1:p2ToX y1:p2ToY
|
x2:p3ToX y2:p3ToY
|
x3:p4ToX y3:p4ToY
|
x0p:p1FromX y0p:p1FromY
|
x1p:p2FromX y1p:p2FromY
|
x2p:p3FromX y2p:p3FromY
|
x3p:p4FromX y3p:p4FromY];
|
return [self sampleGrid:image dimensionX:dimensionX dimensionY:dimensionY transform:transform error:error];
|
}
|
|
- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
|
dimensionX:(int)dimensionX
|
dimensionY:(int)dimensionY
|
transform:(ZXPerspectiveTransform *)transform
|
error:(NSError **)error {
|
if (dimensionX <= 0 || dimensionY <= 0) {
|
if (error) *error = ZXNotFoundErrorInstance();
|
return nil;
|
}
|
ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:dimensionX height:dimensionY];
|
int pointsLen = 2 * dimensionX;
|
float pointsf[pointsLen];
|
memset(pointsf, 0, pointsLen * sizeof(float));
|
|
for (int y = 0; y < dimensionY; y++) {
|
int max = dimensionX << 1;
|
float iValue = (float)y + 0.5f;
|
for (int x = 0; x < max; x += 2) {
|
pointsf[x] = (float) (x / 2) + 0.5f;
|
pointsf[x + 1] = iValue;
|
}
|
[transform transformPoints:pointsf pointsLen:pointsLen];
|
|
if (![ZXGridSampler checkAndNudgePoints:image points:pointsf pointsLen:pointsLen error:error]) {
|
return nil;
|
}
|
for (int x = 0; x < max; x += 2) {
|
int xx = (int)pointsf[x];
|
int yy = (int)pointsf[x + 1];
|
if (xx < 0 || yy < 0 || xx >= image.width || yy >= image.height) {
|
if (error) *error = ZXNotFoundErrorInstance();
|
return nil;
|
}
|
|
if ([image getX:xx y:yy]) {
|
[bits setX:x / 2 y:y];
|
}
|
}
|
}
|
|
return bits;
|
}
|
|
@end
|