al_zatv ([info]al_zatv) wrote,
@ 2009-06-05 12:16:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
забавная задачка для программистов.

1. Все знают что такое RLE-сжатие.
Если кто не, это сжатие путём замены повторяющихся символов на их количество. Например, самый редко используемый символ будет маркером. Где видим кучу одинаковых байт - заменяем на три байта: маркер, символ, кол-во повторов.

2. Все знают что такое мало памяти.

Ну вот у меня RLE-сжатие и мало памяти. Мне хочется, чтобы и сжатие, и распаковка происходили в одном и том же буфере. Размер буфера - тютелька в тютельку чтобы вместить распакованные данные (это картинка, кстати: buf=malloc(width*height*bytes_per_pixel); - и ни байтом больше:)))

Надо: сделать такое RLE, чтобы и сжимало, и разжимало - в один и тот же буфер, и не более того.

Я придумал алгоритм, требующий отдельного хранения двух чисел: count после сжатия, и seed. Фактически, они в буфер не влезают:)

void myRLE_Encode(IN void *buffer, IN int size, OUT int *packed_size, OUT int *seed);
void myRLE_Decode(IN void *buffer, IN int packed_size, IN int seed);

Можно ли обойтись одним числом? Можно ли вообще без чисел?
Эффективность сжатия можно чуточку ухудшить,если надо.



(Read 6 comments) - (Post a new comment)


[info]ddima
2009-06-06 12:11 pm UTC (link)
Чтобы было понятнее, свои комментарии, которые взяты из другого поста, тоже присовокупил к ответам

>> 1. Размеры загружаемых файлов несопоставимы с экономией
>> 3-5 слов - такой экономией можно пренебречь.
> 1. У меня файлы не загружаются, а передаются по сети на мобильное устройство.
Не вижу принципиальной разницы - в качестве data source может выступать все что угодно - DVD, TCP и так далее

>> 2. Упакованные файлы белого шума для распаковки "на месте"
>> занимают больше, чем оригинал.
> 2. А вот и фигушки: у меня ЛЮБОЙ набор данных будет
> занимать столько же, сколько и непакованный.
Не очень понимаю тогда, зачем паковать, если не видно разницы :)))))
Это если в шутку. Если всерьез, то непонятно, откуда взялось такое условие на контент. Если оно налагается пайплайном - окей. Если же существует теоретическая возможность того, что в процессе распаковки контента произойдет перехлест пакованных и непакованных данных - то такое произойдет. Дай бог, чтобы не случилось за 2 часа до релиза :).

>> 3. В упакованном файле обязательно есть хидер
>> (как минимум, там надо знать "маркер")
> 3. Хе:) Удалось таки обойтись и без хидера,
> маркер можно и не знать:)
Верю, можно. Тогда формат компрессии явно избыточный будет. И больше вероятность того, что я написал в пункте 2.

Мотивация понятна и очевидна, не спорю. Только у нас разные выводы из мотивации. Тебе хочется для самоудовлетворения получить олимпиадное решение (буфер + 2 DWORD или буфер + DWORD). Мне хочется получить быстрое и 100%-надежное решение, ценой трех, пяти или десяти лишних DWORD. Возможно, завязавшись на формат фыйла или видеобуфера. Например, если известно, что каждый 4-й байт (альфа канал) в видеобуфере не используется, можно интересные фокусы начать выделывать :)

(Reply to this) (Parent)(Thread)


[info]al_zatv
2009-06-06 06:05 pm UTC (link)
Покумекал малость ещё на досуге - да, перехлёст будет. То есть, пока-что путёвый алгортитм придумать не удалось.

И ещё: пока нету "быстрого и 100%надёжного решения ценой 3-5-10 двордов". Есть решение ценой нескольких двордов + ещё один буфер неслабого размера:)

И да, согласен, мотивация чисто спортивная:) Присоединяйся:)

(Reply to this) (Parent)(Thread)


[info]ddima
2009-06-07 10:45 am UTC (link)
Ну сначала объясни, как в буфер width*height*bytes_per_pixel будет засовываться компрессированный файл который в оригинальном виде выглядел как:
AABBCCDDEEFFGGHH...

(Reply to this) (Parent)(Thread)


[info]al_zatv
2009-06-08 06:32 pm UTC (link)
Это худший случай. Классически, мы должны были бы:
1. Найти наименее используемый символ
(положим, они все одинаково используются и это будет символ A)
2. Закодировать.
Вышло бы:

AA2BBCCDDEE...

Что в буфер бы не полезло, не говоря уж о перехлёсте.



С этим надо бороться, думаю, так.
RLE_Encoder всё равно работает в два прохода (хотя мне это и не нравится). Раз так, на первом проходе считаем ещё и размер, который будет у буфера после сжатия - PrognosedSize.
Ну а потом:
ежели (PrognosedSize>=BufferSize)
Ничего_Сжимать_Не_надо;

(Reply to this) (Parent)


(Read 6 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…