выход из ситуации - добавить в конец пакуемого блока кучу нулей. штук так 50-200.
Вид для печати
выход из ситуации - добавить в конец пакуемого блока кучу нулей. штук так 50-200.
именно так.
А разве распаковщик не знает, каков размер неупакованного блока? Всё еще с трудом понимаю, почему нахлест возникает. Ему для распаковки нужен какой-то буфер, который приплюсовывается к архиву, и поэтому оно не влезло?
Просто я почитал первоначальный пример - там у меня распакованный файл весил примерно 6кб. Упакованный, соответственно, тоже не больше. Распаковка велась на 49152 - то есть 16 кб до конца памяти было, должен был влезть и упакованный, и распакованный вариант.
Кстати, а megalz тоже так свободно по памяти катается?
следите за руками:
0. допустим, есть у нас исходный файл в 6к, сжатый до 3х.
1. распаковщик перемещает упакованный 3к блок так, что последний байт упакованного блока совпадает с посл. байтом будущего распакованного (т.е. он старается не занимать места больше, чем распакованный блок, не вылезать из этого окна).
2. начинает распаковывать. чем дальше к окончанию распаковки, тем указатели ОТКУДА (упак.) и КУДА (распак.) ближе друг к другу. в идеале, в самом конце они совпадают:)
3. при определенных условиях (те самые плохо сжимающиеся данные в конце) распакованные данные начинают перезатирать еще не распакованные... всё, капут.
таким образом, просто добавляем много нулей в конец пакуемого блока и бережем нервы. когда ничего не перезатирается, когда есть запас, все хорошо:)
Непонятен этот шаг с перемещением запакованного блока в конец распакованного.
Для чего?
Ведь запакованный блок УЖЕ находится в памяти. Неужели нельзя брать байты для распаковки прямо оттуда?
Зачем его таскать по памяти то лишний раз?
John North,
еще раз
hrust программа универсальная и считает что файл который она распаковывает имеет размер #a000 и находится по адресу #6000
поэтому он всегда старается переместить упакованный блок как можно дальше
что и видно на данном фрагменте исходника
но последние 6 байт упакованного файла всегда сохраняются вместе с упаковщикомЦитата:
DEHRUST PUSH DE
PUSH HL
берем размер распакованого блока
INC HL
INC HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
вычисляем конец распакованых данных
DEC BC
EX DE,HL
ADD HL,BC
EX DE,HL
берем длину пакованого блока
LD C,(HL)
INC HL
LD B,(HL)
DEC BC
проверяем на вероятность затирания
по умолчанию считается что блок будет загружен туда же куда будет распакован
POP HL
ADD HL,BC
SBC HL,DE
ADD HL,DE
JR C,LL4019
оставляем на месте
LD D,H
LD E,L
LL4019 LDDR
но если блок находится по адресу 60000
а распаковывать надо например заставку он этот блок трогать не будет
Мне, честно говоря, даже в голову не приходило, что можно попытаться распаковать блок с пересечением с упакованным файлом.
Имхо, в таком случае в распаковщик нужно добавить проверку - если в памяти достаточно места, то не делать копирование. Размер распаковщика, конечно, вырастет, но геморроя уменьшится.
С MegaLZ я не встречал такой ситуации ни разу - MegaLZ работает иначе или мне еще "повезет"? :)