PDF417Encoder.java 12.8 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.xfa.pmp.adobepdf417pmp;

import com.adobe.xfa.pmp.adobepdf417pmp.PDF417CompactorManager;
import com.adobe.xfa.pmp.adobepdf417pmp.PDF417EncoderErrorCode;
import com.adobe.xfa.pmp.adobepdf417pmp.PDF417EncoderException;
import com.adobe.xfa.pmp.adobepdf417pmp.PDF417ImageBuilder;
import com.adobe.xfa.pmp.adobepdf417pmp.PDF417ReedSolomon;
import com.adobe.xfa.pmp.adobepdf417pmp.PDF417SpecialCode;
import com.adobe.xfa.pmp.adobepdf417pmp.PDF417XSequenceBuilder;
import com.adobe.xfa.pmp.common.BarcodeEncoder;
import com.adobe.xfa.pmp.common.BarcodeGenerationParams;
import com.adobe.xfa.pmp.common.IntegerHolder;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class PDF417Encoder
implements BarcodeEncoder {
    @Override
    public BufferedImage encode(char[] message, BarcodeGenerationParams pmpParams) throws PDF417EncoderException {
        double resolution = pmpParams.getResolution();
        if (resolution < 1.0) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.RESOLUTION);
        }
        int ecc = pmpParams.getEccLevel();
        if (ecc < 0 || ecc > 8) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.ECC);
        }
        IntegerHolder width = new IntegerHolder((int)(pmpParams.getWidth() * resolution + 0.5));
        IntegerHolder height = new IntegerHolder((int)(pmpParams.getHeight() * resolution + 0.5));
        int xSymWidth = pmpParams.getXSymbolWidth();
        if (xSymWidth < 1) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.XSYMWIDTH);
        }
        int xSymHeight = pmpParams.getXSymbolHeight();
        if (xSymHeight < 1) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.XSYMHEIGHT);
        }
        if (xSymWidth == 3 && (xSymHeight == 59 || xSymHeight == 60)) {
            xSymHeight = 9;
        }
        IntegerHolder dataCols = new IntegerHolder(0);
        IntegerHolder dataRows = new IntegerHolder(0);
        IntegerHolder actualXDimension = new IntegerHolder(0);
        IntegerHolder actualYDimension = new IntegerHolder(0);
        String xSequence = PDF417Encoder.getXSequence2(message, width, height, xSymWidth, xSymHeight, ecc, false, dataCols, dataRows, actualXDimension, actualYDimension);
        BufferedImage image = PDF417ImageBuilder.buildCentered(xSequence, actualXDimension.getValue(), actualYDimension.getValue(), 0, 0, dataCols.getValue(), dataRows.getValue(), width.getValue(), height.getValue());
        return image;
    }

    static String getXSequence2(char[] message, IntegerHolder imageCols, IntegerHolder imageRows, int xDimension, int yDimension, int eccLevel, boolean readerInitialization, IntegerHolder dataCols, IntegerHolder dataRows, IntegerHolder actualXDimension, IntegerHolder actualYDimension) throws PDF417EncoderException {
        ArrayList<Integer> data = new ArrayList<Integer>();
        PDF417CompactorManager.compact(message, data);
        if (readerInitialization) {
            data.add(0);
            for (int idx = data.size() - 1; idx > 1; --idx) {
                data.set(idx, data.get(idx - 1));
            }
            data.set(1, PDF417SpecialCode.INITIALIZER.getValue());
        }
        dataCols.setValue(1);
        dataRows.setValue(3);
        actualXDimension.setValue(4);
        actualYDimension.setValue(8);
        if (imageCols.getValue() <= 0 && imageRows.getValue() <= 0) {
            PDF417Encoder.calculateRowsAndColsWidthAndHeightVariable(data.size() + PDF417ReedSolomon.getNumberOfECC(eccLevel), imageCols, imageRows, xDimension, yDimension, dataCols, dataRows, actualXDimension, actualYDimension);
        } else if (imageCols.getValue() <= 0) {
            PDF417Encoder.calculateRowsAndColsWidthVariable(data.size() + PDF417ReedSolomon.getNumberOfECC(eccLevel), imageCols, imageRows.getValue(), xDimension, yDimension, dataCols, dataRows, actualXDimension, actualYDimension);
        } else if (imageRows.getValue() <= 0) {
            PDF417Encoder.calculateRowsAndColsHeightVariable(data.size() + PDF417ReedSolomon.getNumberOfECC(eccLevel), imageCols.getValue(), imageRows, xDimension, yDimension, dataCols, dataRows, actualXDimension, actualYDimension);
        } else {
            PDF417Encoder.calculateRowsAndCols2(data.size() + PDF417ReedSolomon.getNumberOfECC(eccLevel), imageCols.getValue(), imageRows.getValue(), xDimension, yDimension, dataCols, dataRows, actualXDimension, actualYDimension);
        }
        PDF417Encoder.padData(data, dataCols.getValue(), dataRows.getValue(), eccLevel);
        ArrayList<Integer> ecc = new ArrayList<Integer>();
        PDF417ReedSolomon.getECC(data, eccLevel, ecc);
        int size = ecc.size();
        for (int idx = size - 1; idx >= 0; --idx) {
            data.add(ecc.get(idx));
        }
        return PDF417XSequenceBuilder.build(data, dataCols.getValue(), dataRows.getValue(), eccLevel);
    }

    static void calculateRowsAndCols2(int messageCodeWords, int imageCols, int imageRows, int xDimension, int yDimension, IntegerHolder codeWordCols, IntegerHolder codeWordRows, IntegerHolder actualXDimension, IntegerHolder actualYDimension) throws PDF417EncoderException {
        int xDimensionMax = xDimension;
        int xDimensionMin = xDimension - 1;
        int idxX = 4;
        int idxY = 8;
        int cwCols = 0;
        int cwRows = 0;
        boolean found = false;
        for (idxX = xDimensionMax; idxX > xDimensionMin; --idxX) {
            int neededCodeWordRows;
            cwCols = (int)Math.floor((double)(imageCols - idxX * 73) / (double)(17 * idxX));
            if (cwCols < 1) continue;
            if (cwCols > 30) {
                cwCols = 30;
            }
            if ((neededCodeWordRows = (int)Math.ceil((double)messageCodeWords / (double)cwCols)) < 3) {
                neededCodeWordRows = 3;
            }
            if (neededCodeWordRows > 90) continue;
            int yDimensionMax = (int)Math.floor((double)(imageRows - 4 * idxX) / (double)neededCodeWordRows);
            int yDimensionMin = (int)Math.floor((double)(imageRows - 4 * idxX) / 90.0);
            if (yDimensionMin < yDimension) {
                yDimensionMin = yDimension;
            }
            if (yDimensionMin < 2 * idxX) {
                yDimensionMin = 2 * idxX;
            }
            if (yDimensionMax > 20 * idxX) {
                yDimensionMax = 20 * idxX;
            }
            for (idxY = yDimensionMax; idxY >= yDimensionMin; --idxY) {
                cwRows = (int)Math.floor((double)(imageRows - idxX * 4) / (double)idxY);
                if (cwRows > 90) continue;
                boolean bl = found = cwCols * cwRows >= messageCodeWords;
                if (found) break;
            }
            if (found) break;
        }
        if (!found) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        actualXDimension.setValue(idxX);
        actualYDimension.setValue(idxY);
        codeWordCols.setValue(cwCols);
        codeWordRows.setValue(cwRows);
        if (codeWordRows.getValue() < 3) {
            codeWordRows.setValue(3);
        }
        if (codeWordCols.getValue() < 1) {
            codeWordCols.setValue(1);
        }
        if (codeWordRows.getValue() > 90) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        if (codeWordCols.getValue() > 30) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.TOO_MANY_COLS);
        }
        if (codeWordCols.getValue() * codeWordRows.getValue() > 928) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.SYMBOL_TOO_BIG);
        }
        if (codeWordCols.getValue() * codeWordRows.getValue() < messageCodeWords) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
    }

    static void calculateRowsAndColsWidthVariable(int messageCodeWords, IntegerHolder imageCols, int imageRows, int xDimension, int yDimension, IntegerHolder codeWordCols, IntegerHolder codeWordRows, IntegerHolder actualXDimension, IntegerHolder actualYDimension) throws PDF417EncoderException {
        int cwCols;
        if (messageCodeWords > 928) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        int cwRows = (imageRows - 4 * xDimension) / yDimension;
        if (cwRows > messageCodeWords) {
            cwRows = messageCodeWords;
        }
        if (cwRows < 3) {
            cwRows = 3;
        }
        if (cwRows > 90) {
            cwRows = 90;
        }
        if ((cwCols = (int)Math.ceil((double)messageCodeWords / (double)cwRows)) < 1) {
            cwCols = 1;
        }
        if (cwCols > 30) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        imageCols.setValue((17 * cwCols + 17 + 17 + 17 + 18 + 4) * xDimension);
        actualXDimension.setValue(xDimension);
        actualYDimension.setValue(yDimension);
        codeWordCols.setValue(cwCols);
        codeWordRows.setValue(cwRows);
        if (codeWordCols.getValue() * codeWordRows.getValue() > 928) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.SYMBOL_TOO_BIG);
        }
    }

    static void calculateRowsAndColsHeightVariable(int messageCodeWords, int imageCols, IntegerHolder imageRows, int xDimension, int yDimension, IntegerHolder codeWordCols, IntegerHolder codeWordRows, IntegerHolder actualXDimension, IntegerHolder actualYDimension) throws PDF417EncoderException {
        if (messageCodeWords > 928) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        int cwCols = (imageCols / xDimension - 17 - 17 - 17 - 18 - 4) / 17;
        if (cwCols > messageCodeWords) {
            cwCols = messageCodeWords;
        }
        if (cwCols < 1) {
            cwCols = 1;
        }
        if (cwCols > 30) {
            cwCols = 30;
        }
        int cwRows = (int)Math.ceil((double)messageCodeWords / (double)cwCols);
        imageRows.setValue(cwRows * yDimension + 4 * xDimension);
        if (cwRows < 3) {
            cwRows = 3;
        }
        if (cwRows > 90) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        actualXDimension.setValue(xDimension);
        actualYDimension.setValue(yDimension);
        codeWordCols.setValue(cwCols);
        codeWordRows.setValue(cwRows);
        if (codeWordCols.getValue() * codeWordRows.getValue() > 928) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.SYMBOL_TOO_BIG);
        }
    }

    static void calculateRowsAndColsWidthAndHeightVariable(int messageCodeWords, IntegerHolder imageCols, IntegerHolder imageRows, int xDimension, int yDimension, IntegerHolder codeWordCols, IntegerHolder codeWordRows, IntegerHolder actualXDimension, IntegerHolder actualYDimension) throws PDF417EncoderException {
        if (messageCodeWords > 928) {
            throw new PDF417EncoderException(PDF417EncoderErrorCode.MESSAGE_TOO_BIG);
        }
        int cwRows = 0;
        int cwCols = (int)Math.ceil(Math.sqrt(4.0 + (double)messageCodeWords * (double)yDimension / ((double)xDimension * 17.0))) - 2;
        if (cwCols > 30) {
            cwCols = 30;
        }
        if (cwCols < 1) {
            cwCols = 1;
        }
        boolean found = false;
        while (cwCols <= 30) {
            int cwRowsMax;
            cwRows = messageCodeWords / cwCols;
            if (cwRows < 3) {
                cwRows = 3;
            }
            if (cwRows > 90) {
                cwRows = 90;
            }
            if ((cwRowsMax = cwRows + 17 * xDimension / yDimension + 2) > 90) {
                cwRowsMax = 90;
            }
            while (cwRows <= cwRowsMax) {
                boolean bl = found = cwCols * cwRows >= messageCodeWords;
                if (found) break;
                ++cwRows;
            }
            if (found) break;
            ++cwCols;
        }
        if (!found) {
            cwCols = 16;
            cwRows = 58;
        }
        if (codeWordCols.getValue() * codeWordRows.getValue() > 928) {
            cwCols = 16;
            cwRows = 58;
        }
        actualXDimension.setValue(xDimension);
        actualYDimension.setValue(yDimension);
        codeWordCols.setValue(cwCols);
        codeWordRows.setValue(cwRows);
        imageCols.setValue((17 * cwCols + 17 + 17 + 17 + 18 + 4) * xDimension);
        imageRows.setValue(cwRows * yDimension + 4 * xDimension);
    }

    static void padData(List<Integer> data, int dataCols, int dataRows, int eccLevel) {
        int eccSize = PDF417ReedSolomon.getNumberOfECC(eccLevel);
        int symbolSize = dataCols * dataRows;
        int dataSize = data.size();
        int pad = symbolSize - eccSize - dataSize;
        for (int idx = 0; idx < pad; ++idx) {
            data.add(PDF417SpecialCode.TextCompactionLatch.getValue());
        }
        data.set(0, data.size());
    }
}