Алгоритм декодера ascii85 для Adobe в некоторых случаях дает сбой

Я пытаюсь разработать декодер Ascii85 для C++, чтобы проанализировать файл растрового изображения из файла Adobe Illustrator (*ai).

Я нашел алгоритм в Java здесь, и я попытался переписать его в C++.

Проблема в том, что у меня есть некоторые случаи, когда мой закодированный текст не декодируется правильно. Например, если символ "a" является 7-м и последним символом в моей строке (до кодирования), он декодируется как "`", что является предыдущим символом в таблице ascii. Это странно, потому что я попытался выполнить вычисления алгоритма вручную, и в результате я получил "` ". Мне интересно, есть ли ошибка в алгоритме или это не правильный алгоритм для Adobe ASCII85 декодирования.

Вот мой код:

#include <QCoreApplication>
#include <stdio.h>
#include <string.h>
#include <QDebug>

// returns 1 when there are no more bytes to decode
// 0 otherwise
int decodeBlock(char *input, unsigned char *output, unsigned int inputSize) {
    qDebug() << input << output << inputSize;
    if (inputSize > 0) {
        unsigned int bytesToDecode = (inputSize < 5)? inputSize : 5;

        unsigned int x[5] = { 0 };
        unsigned int i;
        for (i = 0; i < bytesToDecode; i++) {
            x[i] = input[i] - 33;
            qDebug() << x[i] << ", i: " << i;
        }

        if (i > 0)
            i--;

        unsigned int value =
                x[0] * 85 * 85 * 85 * 85 +
                x[1] * 85 * 85 * 85 +
                x[2] * 85 * 85 +
                x[3] * 85 +
                x[4];

        for (unsigned int j = 0; j < i; j++) {
            int shift = 8 * (3 - j); // 8 * 3, 8 * 2, 8 * 1, 8 * 0
            unsigned char byte = (unsigned char)((value >> shift) & 0xff);
            printf("byte: %c, %d\n", byte, byte);
            *output = byte;
            output++;
        }
    }

    return inputSize <= 5;
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    char x__input[] = "<~FE1f+@;K?~>";

    unsigned char x__output[128] = { 0 };

    char *input = x__input + 2;
    unsigned int inputSize = (unsigned int)strlen(input);
    inputSize -= 2;

    unsigned char *output = x__output;

    printf("decoding %s\n", input);
    for (unsigned int i = 0; i < inputSize; i += 5, input += 5, output += 4)
        if(decodeBlock(input, output, inputSize - i))
            break;

    printf("Output is: %s\n", x__output);

    return a.exec();
}

1 ответ

Решение

Что происходит, когда inputSize не кратен 5??

    unsigned int bytesToDecode = (inputSize < 5)? inputSize : 5;

ВЫ ПРИНИМАЕТЕ, что bytesToDecode равен 5, тогда как будет несколько байтов с неизвестными значениями

Итак, когда ваш персонаж последний в позиции 7, вышеприведенное условие выполняется.

Если входное значение не кратно 5, то оно ДОЛЖНО быть дополнено значением "u". Для получения более подробной информации о процессе кодирования / декодирования, пожалуйста, посетите страницу Википедии, где она довольно хорошо объяснена:

http://en.wikipedia.org/wiki/Ascii85

Другие вопросы по тегам