Я пытаюсь создать код для распаковки байтово-ориентированного изображения RLE из файла PostScript. Я уже пробовал решения, найденные в Интернете, а также пытался создать свой собственный;но ни один из них не дал нужного мне результата.
После распаковки изображения rle у меня должно быть изображение RAW, которое я могу открыть в фотошопе (с указанием ширины, высоты и количества каналов).Однако, когда я пытаюсь открыть извлеченное изображение, это не работает;показывается только черный вывод.
Мои входные данные - это двоичный файл в кодировке ASCII (закодированный в виде шестнадцатеричной строки) и двоичный файл;оба сжатых RLE Byte-Oriented (в случае шестнадцатеричного файла, это просто вопрос преобразования его в байты перед попыткой декомпрессии rle).
https://drive.google.com/drive/u/0/folders/1Q476HB9SvOG_RDwK6J7PPycbw94zjPYU Я разместил здесь образцы.
WorkingSample.raw -> Образец изображения, полученный с помощью другого программного обеспечения, а также его размеры.
MySample.raw -> Образец изображения, который я построилиспользуя мой код, а также его размеры.
OriginalFile.ppf -> Файл, содержащий исходные данные изображения и все остальное.
ExtractedBinary.bin -> Только двоичная часть из OriginalFile.ppf - облегчает чтение и работу с данными.
Этот код был предоставлен пользователем nyerguds , он является частью SOсообщество.Первоначальный источник: http://www.shikadi.net/moddingwiki/RLE_Compression#Types_of_RLE Это тот, который я пытался использовать, но результаты не были правильными.И, честно говоря, у меня были трудности с пониманием его кода (он сказал мне изменить несколько вещей, чтобы он работал в моем случае, но я не смог).
И вот что я пытался сделать, следуяКрасная книга PostScript: Книга: https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf Часть: «Фильтр RunLengthEncode кодирует данные в однобайтовом формате, основанном на длине прогона. Формат сжатых данных представляет собой последовательность прогонов, где каждый прогон состоит из длиныбайт, за которым следуют от 1 до 128 байтов данных.Если длина байта находится в диапазоне от 0 до 127, следующая длина + 1 байт (от 1 до 128 байтов) должна быть скопирована буквально при распаковке., если длина находится в диапазоне 129до 255, следующий отдельный байт должен быть реплицирован 257 - длина раз (от 2 до 128 раз) после распаковки ".Страница 142, RunLengthEncode Filter.
List<byte> final = new List<byte>();
var split01 = ArraySplit(bytefile, 2);
foreach (var binPart in split01)
{
try
{
if (binPart.ElementAt(0) <= 127)
{
int currLen = binPart[0] + 1;
for (int i = 0; i <= binPart[0]; i++)
{
final.Add(binPart[1]);
//Console.WriteLine(binPart[1]);
}
}
else if (binPart[0] >= 128)
{
int currLen = 257 - binPart[0];
for (int i = 0; i < currLen; i++)
{
final.Add(binPart[1]);
// Console.WriteLine(binPart[1]);
}
}
}
catch(Exception)
{
break;
}
}
File.WriteAllBytes(@"C:\test\again.raw", final.ToArray());
private static IEnumerable<byte[]> ArraySplit(byte[] bArray, int intBufforLengt)
{
int bArrayLenght = bArray.Length;
byte[] bReturn = null;
int i = 0;
for (; bArrayLenght > (i + 1) * intBufforLengt; i++)
{
bReturn = new byte[intBufforLengt];
Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt);
yield return bReturn;
}
int intBufforLeft = bArrayLenght - i * intBufforLengt;
if (intBufforLeft > 0)
{
bReturn = new byte[intBufforLeft];
Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft);
yield return bReturn;
}
}
private static byte[] StringToByteArray(String hex)
{
int iValue = 0;
int NumberChars = hex.Length;
if (NumberChars % 2 != 0)
{
string m = string.Empty;
}
byte[] bytes = new byte[NumberChars / 2];
try
{
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
iValue = i;
}
}
catch (Exception e)
{
var value = iValue;
Console.WriteLine(e.Message);
}
return bytes;
}
Желаемый результат будет в градациях серого TIFF.Тем не менее, я могу иметь дело и с PNG.Мне уже удалось извлечь несжатых данных из этого типа файла;с помощью Emgu (OpenCV Wrapper) я смог создать видимое изображение и сделать с ним свою логику.
Мои реальные результаты в RLE Compressed - это только недействительные файлы RAW, которые невозможно просмотреть даже в фотошопе или IrfanViewer.
Любой вклад приветствуется.Спасибо.
EDIT1 : застрял на этой части
for(int i=0; i < bytefile.Length; i+=2)
{
try
{
var lengthByte = bytefile[i];
if (lengthByte <= 127)
{
int currLen = lengthByte + 1;
for (int j = 0; j < currLen; j++)
{
final.Add(bytefile[i]);
i++;
}
}
if (bytefile[i] >= 128)
{
int currLen = 257 - bytefile[i];
for (int k = 0; k < currLen; k++)
{
final.Add(bytefile[i + 1]);
}
}
}
catch(Exception)
{
break;
}
}
Это логика, которой я следую.До того, как оно вызывало Исключение, но я понял это (это потому, что я забыл добавить завершающий байт; без разницы в конечном результате).