Comments 39
вопрос - а почему нельзя просто было переписать libpng?
Это отчасти раскрывается в абзаце "Почему нет смысла патчить libpng?". Насколько я понял, главная причина заключается в том, что в libpng очень много движущихся частей, которые сильно связаны друг с другом, то есть изолированно оптимизировать какой-то кусок не выйдет, и в итоге придется переписывать большую часть огромной библиотеки. Короче, легаси, как всегда.
Что там огромного-то в библиотеке ?
https://github.com/glennrp/libpng
200к строк кода
я не о том чтобы пропатчить libpng для достижения результата, а о том чтобы сделать libpng2 - но быстрее-выше-сильнее, безо всяких Wuffs, тем более что это по сути тот же Си. Просто наверное есть что-то что определило такой подход?
Проблема в том, что на libpng очень много всего завязано. И чтобы оно не поломалось, в этой самой гипотетической libpng2 нужно детально воспроизвести весь функционал текущей libpng, включая константы, макросы, типы и т.д. А это over do figa всего. Если же делать что-то принципиально новое, со своим API, то кому оно будет нужно? область применения будет крохотной...
Проблема в том, что на libpng очень много всего завязано. И чтобы оно не поломалось
А теперь вместо переписывания одной библиотеки потребуется переписать всё остальное, но кого это вообще волнует?!
Ну а при подходе из статьи получаем сразу и соль, и матумбу - и библиотеку пришлось переписать (написав новую), и все остальное теперь нужно переписать, чтобы ей пользоваться, это ещё больше over do figa всего.
Ну а при подходе из статьи
Я что-то не уловил, в какой момент авторы wuffы заявили, что они хотят внедриться в libpng или сделать её замену. В данном топике такая мысль возникла не у них, пару часов назад, и странно что-то говорить про "их подход", который вообще ничего такого не предполагает.
Я что-то не уловил, в какой момент авторы wuffы заявили, что они хотят внедриться в libpng или сделать её замену.
Ну так в этом и проблема. В результате ей будут пользоваться 2.5 человека, потому что про libpng знают все, и работают с ней все, а про этот wuff, возможно, через определенное время и сами авторы забудут. А вот сделали бы libpng-совместимый API (хотя бы в качестве дополнительного/переходного), чтобы можно было просто линковать с этой либой уже существующий код, пусть и с какими-то минимальными изменениями - тогда было бы о чем разговаривать...
Можно запросто обернуть реализацию на Wuffs в libpng-подобный API, никаких принципиальных ограничений для этого нет.
А насчет того, зачем и почему автор решил изобрести велосипед вместо того, чтобы оптимизировать имеющиеся реализации, так он это пытался пояснить в абзаце про попытки и перспективы пропатчить разные реализации:
libpng слишком сложен, чтобы его патчить.
zlib можно и нужно патчить, но это не очень сильно влияет на скорость декодирования PNG в целом из slow/fast декодирования строк.
Go и Rust можно пропатчить, но это не поможет проектам на C/C++, и memory safety в Go и Rust обеспечивается в том числе runtime механизмами, которые бьют по производительности и которые можно было бы в этой конкретной задаче не использовать совсем.
Кроме того, Wuffs - это не yet another PNG decoder, а инструмент для разработки быстрых и безопасных декодеров для любых форматов даных. Подробнее про это можно почитать в соответствующей части его документации.
Можно запросто обернуть реализацию на Wuffs в libpng-подобный API, никаких принципиальных ограничений для этого нет.
Вот и удивительно, что это не сделано. Тем более, что они сами заявляют, что "Wuffs is not a general purpose programming language. It is for writing libraries, not programs."
libpng слишком сложен, чтобы его патчить
Никто не предлагает его патчить. Предлагают его переписать - сделать условную libpng2 с таким же API, как у libpng, чтобы ее бесшовно можно было вызывать из существующего C/C++/whatever кода (тем более что wuffs транспилируется в C). И доброе дело бы сделали, и этот свой wuffs прорекламировали. Приведенные пояснения, как по мне, не поясняют, почему автор(ы) этого не сделал(и). А очередной велосипед - он очередной велосипед и есть.
почему автор(ы) этого не сделал(и)
Наверное, потому, что это даже не в разы - на порядок, а может и не один, сложней и ресурсоёмче, чем написать декодер?
Быть, а не казаться, вообще сложно.
Как-то довелось портировать банальную getline(). Из glibc, казалось бы. Пару дней вкуривания манов, ога, пишем... и... десяток юнит-тестов, неделя отладки.
А сколько там зависимостей может быть... Голым cpp прогнать, и то ужаснёшься.
Ну, и главное: мы не знаем почему они это сделали.
Могут
Хотят
твой вариант
нет, проблема не в этом. ниже уже написали. вместо того чтобы один раз переписать правильно либу теперь создана ситуация когда нужно полностью переписывать код под wuff, или продолжать использовать libpng. То есть полезность wuff варианта почти нулевая.
А что, вызов libpng настолько сложен, что переписать его на вызов другой библиотеки - это неделю займет?
Какая у тебя машина?
Красненькая
P.S что такое "вызов libpng" мне неведомо.
P.P.S.
typedef struct png_unknown_chunk_t
{
png_byte name[5]; /* Textual chunk name with '\0' terminator */
png_byte data; / Data, should not be modified on read! */
size_t size;
/* On write 'location' must be set using the flag values listed below.
* Notice that on read it is set by libpng however the values stored have
* more bits set than are listed below. Always treat the value as a
* bitmask. On write set only one bit - setting multiple bits may cause the
* chunk to be written in multiple places.
/ png_byte location; / mode of operation at read time */
}
png_unknown_chunk;
memory safety в Wuffs обеспечивается во время компиляции, а не с помощью проверок в рантайме (например, что индекс
i
при доступе кa[i]
не выходит за границы массива
А если значение i берётся из файла, то что делает компилятор?
Видимо проверяет, что все возможные значения i
не приводят к выходу за границы массива (тут не важно берётся i
из файла, или из чего-то другого). Например если значение i as u8
, значит массив должен иметь границы как минимум [0 ..= 255]
или больше, в противном случае ошибка компиляции. Подробней: wuffs --> README.md --> What Does Compile Time Checking Look Like?
Я, наверное, кощунственную мысль озвучить попытаюсь. А в каких задачах жизненно важно ускорять декодирование png? В браузере, имхо, не будет заметно, если показ картинок будет ускорен даже в 10 раз - больше будут сами данные загружаться. Декодировать png на 178 мегабайт - где такое вообще может быть нужно, кроме тестов?
думаю это больше нужно для игровых движков на мобильных устройствах и для серверов вэб. дома, когда я работаю с фото полноцветными в pmg меня не сильно напрягают 1-2 секунды при открытии файла.
Это больше похоже на рекламу wuf
Почему бы и нет. Просто пытаюсь понять, какое может быть практическое применение этого декодера. Вот есть, например, довольно быстрый кодек PicVideo Motion-JPEG. Его можно применять для сохранения видео высокого качества, без междукадровой зависимости. Тут понятно - чем быстрее кодек, тем быстрее такое видео будет обрабатываться. А здесь какой профит?
Например, в компьютерном зрении, причем и при обучении нейронных сетей, и при их деплое. Дело в том, что на текущий момент не существует оптимальных реализаций PNG декодера на GPU (по очевидным причинам). В результате эта работа всегда происходит на CPU, превращая шаг декодирования входных изображений в bottleneck, так как в большинстве случаев и обучение, и инференс моделей происходит на GPU. Так, например, у NVIDIA есть специальная библиотека DALI, которая как раз и нужна, чтобы минимизировать накладные расходы на декодирования и препроцессинг изображений, и библиотека nvJPEG - реализация JPEG декодера для GPU.
Так тем более - лучше уж картинку использовать в том формате, который GPU поддерживает. Зачем здесь PNG?
Можно JPG сжимать так, чтобы артефакты были минимальными. Всё равно объем файла наверняка будет меньше, чем PNG.
Не надо JPG предлагать. Это компромиссное решение: более быстрое, но жертвующее качеством.
Я видел как нейронку обучили на jpg, потом на webp с вроде бы хорошим качеством, а потом переделывали из-за генерируемых в некоторых случаях артефактов блочности.
Сначала нужно рассмотреть более быстрые декодеры - тот что в статье, например, без каких либо дополнительных проблем даст скорость. А уже потом другие форматы, держа в уме к каким компромиссам они приведут и допустимы ли они.
Значит, на плохих JPG обучали, просто взяв их готовые. Если сжимать JPG всего раза в 2-4, увидеть артефакты на них вряд ли возможно, разве что на очень специальных картинках.
Если хочется более быстрый декодер, и без потерь качества, проще взять вообще BMP.
Потому что картинки не из воздуха берутся. А собираются со всего интернета. И вам нужно так или иначе прочитать тот формат в котором они были изначально.
Самый быстрый и безопасный PNG декодер в мире