Я пытаюсь реализовать простой Gif-Reader в C++.
В настоящее время я зациклился на распаковке данных изображения. Если изображение содержит Clear Code, мой алгоритм декомпрессии дает сбой.
После Clear Code я перестраиваю CodeTable и сбрасываю < strong>CodeSize в MinimumLzwCodeSize + 1.
Затем я читаю следующий код и добавляю его в индексный поток. Проблема в том, что после очистки следующие коды включают значения, превышающие размер текущей кодовой таблицы.
Например, пример файла из Википедии: rotating- earth.gif имеет кодовое значение 262, но GlobalColorTable — только 256.
Как с этим справиться?
Я применил распаковку lzw в соответствии с спецификацией gif.
вот основная часть кода распаковки:
int prevCode = GetCode(ptr, offset, codeSize);
codeStream.push_back(prevCode);
while (true)
{
auto code = GetCode(ptr, offset, codeSize);
//
//Clear code
//
if (code == IndexClearCode)
{
//reset codesize
codeSize = blockA.LZWMinimumCodeSize + 1;
currentNodeValue = pow(2, codeSize) - 1;
//reset codeTable
codeTable.resize(colorTable.size() + 2);
//read next code
prevCode = GetCode(ptr, offset, codeSize);
codeStream.push_back(prevCode);
continue;
}
else if (code == IndexEndOfInformationCode)
break;
//exists in dictionary
if (codeTable.size() > code)
{
if (prevCode >= codeTable.size())
{
prevCode = code;
continue;
}
for (auto c : codeTable[code])
codeStream.push_back(c);
newEntry = codeTable[prevCode];
newEntry.push_back(codeTable[code][0]);
codeTable.push_back(newEntry);
prevCode = code;
if (codeTable.size() - 1 == currentNodeValue)
{
codeSize++;
currentNodeValue = pow(2, codeSize) - 1;
}
}
else
{
if (prevCode >= codeTable.size())
{
prevCode = code;
continue;
}
newEntry = codeTable[prevCode];
newEntry.push_back(codeTable[prevCode][0]);
for (auto c : newEntry)
codeStream.push_back(c);
codeTable.push_back(newEntry);
prevCode = codeTable.size() - 1;
if (codeTable.size() - 1 == currentNodeValue)
{
codeSize++;
currentNodeValue = pow(2, codeSize) - 1;
}
}
}