0

I'm working on an iOS app that's supposed to decode a certain type of Aztec barcode (example, PDF). I need the scanner to return the data on a low level, since it's zlib compressed and I need to decompress it afterwards. The built-in barcode scanner using AVCapture works fine for regular string data but fails in my case.

I have turned to Zxing, or rather its Objective C port ZXingObjC, in the hope of being able to access the decoded barcode data before it gets turned into a string. I was half successful. The ZXResult returned does contain a ZXByteArray called rawBytes, but only for QR codes (for Aztec codes it's nil)! I looked inside ZXAztecDecoder.m and sure enough, the byte array is never populated, not even in the original Zxing code in Java. Someone tried to fix it for the original library (Pull Request, Line 80) by doing

byte[] rawBytes = convertBoolArrayToByteArray(correctedBits);

I'd like to add the same functionality for ZXingObjC, but I'm stuck trying to convert theZXBoolArray to a ZXByteArray. Here is the decode function as I envision it:

- (ZXDecoderResult *)decode:(ZXAztecDetectorResult *)detectorResult error:(NSError **)error {
    self.ddata = detectorResult;
    ZXBitMatrix *matrix = [detectorResult bits];
    ZXBoolArray *rawbits = [self extractBits:matrix];
    if (!rawbits) {
        if (error) *error = ZXFormatErrorInstance();
        return nil;
    }

    ZXBoolArray *correctedBits = [self correctBits:rawbits error:error];
    if (!correctedBits) {
        return nil;
    }

    ZXByteArray *rawBytes = /* somehow turn correctedBits into ZXByteArray */;

    NSString *result = [[self class] encodedData:correctedBits];
    return [[ZXDecoderResult alloc] initWithRawBytes:rawBytes text:result byteSegments:nil ecLevel:nil];
}

If somebody knows how to do this or has an idea how to go about it, I'd appreciate it. If it works out, I'd like to contribute the code to ZXingObjC, so this won't bug people in the future. Thanks in advance!

Community
  • 1
  • 1
oelna
  • 2,210
  • 3
  • 22
  • 40

1 Answers1

0

It's not actually a solution to the problem, but my persistent nagging helped fix this overdue issue in the original ZXing Github repo. If that change makes it upstream into ZXingObjC at some point, I can close this question for good.

If anybody wants to help translate these Java lines (source) to Objective-C, I'd surely appreciate it.

/**
  * Reads a code of length 8 in an array of bits, padding with zeros
  */
private static byte readByte(boolean[] rawbits, int startIndex) {
    int n = rawbits.length - startIndex;
    if (n >= 8) {
        return (byte) readCode(rawbits, startIndex, 8);
    }
    return (byte) (readCode(rawbits, startIndex, n) << (8 - n));
}

/**
  * Packs a bit array into bytes, most significant bit first
  */
static byte[] convertBoolArrayToByteArray(boolean[] boolArr) {
    byte[] byteArr = new byte[(boolArr.length + 7) / 8];
    for (int i = 0; i < byteArr.length; i++) {
        byteArr[i] = readByte(boolArr, 8 * i);
    }
    return byteArr;
}
oelna
  • 2,210
  • 3
  • 22
  • 40