Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Для png у них вроде есть свой юнит, но для jpg нету и работа TJpegImage или TPicture в потоке - это лотерея во время Bmp32.Assign(jpg/pic).

Кто решал эту проблему без TThread.Synchronize?

Сообщение было отредактировано: 20 ноя 21, 01:53
20 ноя 21, 01:52    [22398234]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
asviridenkov
Member

Откуда:
Сообщений: 4054
rgreat,

я бы через GDI+ или DX декодировал.
20 ноя 21, 02:03    [22398236]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
В итоге воспользовался jpegdec.pas из synopse.

https://blog.synopse.info/?post/2010/03/14/Fast-JPEG-decoder-using-SSE/SSE2

Допилил только чуть-чуть для работы с TBitmap32.

function TJpegDecode.ToBitmap32(bmp: TBitmap32): boolean;
var BMI: TBitmapInfo;
    DC: HDC;
begin
  if bmp=nil then
    Exit(false);
  if bmp.Width<>width then
    bmp.Width := width;
  if bmp.Height<>height then
    bmp.Height := height;

  Move(pRGB^,Bmp.Bits^,Width*Height*4);
  Result:=True;
end;
20 ноя 21, 04:33    [22398242]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Для PNG взял TPortableNetworkGraphic32.

Теперь не глючит в потоках.
20 ноя 21, 04:37    [22398243]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
rgreat,

libjpeg-turbo же.
Правда, официальных дельфийских заголовков нет, есть модуль из статьи на Хабре и у меня примерно такой же (тоже под TFastDIB).
JpegDec от Synopse я когда-то пробовал, и вроде бы он не все jpeg-и открывает - впрочем, уже плохо помню.
Png у меня через GDI+, можно и jpeg через неё же, от libjpeg-turbo по скорости отстаёт, но не так сильно, как стандартный модуль.
20 ноя 21, 19:26    [22398404]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Sapersky,

Там небось dll надо с собой подтягивать?

А это решение этого не требует.
20 ноя 21, 19:29    [22398407]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
Да, но для меня dll не проблема.
Проверил - прогрессивные файлы JpegDec не грузит.
Битые (недокачанные) файлы тож, хотя это не всегда нужно, тем не менее GDI+ как правило показывает целую часть.

К сообщению приложен файл. Размер - 140Kb


Сообщение было отредактировано: 20 ноя 21, 19:45
20 ноя 21, 19:44    [22398417]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
Пытался приложить прогрессивный файл для примера, но форум его пережал, так что он уже не прогрессивный. Ну найдёте пример самостоятельно.
20 ноя 21, 19:47    [22398418]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Мне не надо открывать "любые" jpeg. Только "обычные".
Конкретно растры географической подложки.

Сообщение было отредактировано: 20 ноя 21, 20:11
20 ноя 21, 20:06    [22398424]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Вообще КМК, progressive jpeg был актуален во времена dal-up и 2G интернета.

Нафига он нужен сейчас - вопрос.

Сообщение было отредактировано: 20 ноя 21, 20:12
20 ноя 21, 20:08    [22398425]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
Ну ладно, не нужен так не нужен.
Но и по скорости JpegDec рекордов не ставит, уступает даже GDI+ (на Win7). Возможно на XP со старой GDI+ будет наоборот, но где ж сейчас найдёшь эту XP.
То есть единственное достоинство - нет зависимости от внешних DLL. И то GdiPlus.dll уже скорее системная, а не внешняя.
20 ноя 21, 20:34    [22398434]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
Потестировал ещё - нашёл 1 картинку, где JpegDec быстрее. Но на большинстве медленнее.
Разница там не 10 раз, конечно, как со стандартным модулем, а процентов 20-40.
20 ноя 21, 20:47    [22398437]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3954
rgreat,

мы у себя вот эту либу юзаем:
https://www.simdesign.nl/nativejpg.html
полностью на делфе, в потоках тоже работает.

Сообщение было отредактировано: 20 ноя 21, 20:50
20 ноя 21, 20:49    [22398440]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
NativeJpg когда-то щупал - вроде была медленная, ближе к стандартному модулю по скорости.
20 ноя 21, 21:20    [22398448]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3954
Sapersky,

Скорость примерно одинаковая. Зато фич больше, есть критичные для нас. Плюс более всеядная чем встроенная, она увы не всё далеко открывает.
20 ноя 21, 21:30    [22398455]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
Одинаковая со стандартным модулем - это медленно :) Хотя если больших картинок нет, то может и норм.
Собрал пример к NativeJpg, получилось чуть быстрее стандарта, 16 мп файл грузит 820 мс. Прочие методы см. картинку.

К сообщению приложен файл. Размер - 4Kb
20 ноя 21, 22:16    [22398486]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Aniskin
Member

Откуда:
Сообщений: 341
makhaon
мы у себя вот эту либу юзаем

Я перепиливал NativeJpg под свои нужды. Самая медленная часть любого jpeg декодера - это непосредственно DCT преобразования. А поскольку NativeJpg хранит все MCU блоки в памяти, то DCT отлично распараллеливается, что собственно я и сделал. И теперь у меня скорость декодирования зависит от количества ядер. Не знаю, почему автор библиотеки это изначально не сделал.
21 ноя 21, 06:23    [22398523]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Aniskin,

Распараллеливать декодирование одного файла - это оверкилл.

Часто стоит задача одновременного декодирования многих файлов. Сколько же тогда потоков будет? :)
21 ноя 21, 06:28    [22398524]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3954
Aniskin,

о как! интересно. есть шанс расшарить? я то и сам, возможно найду концы, но дабы не заниматься велоспидостроительством...
можно лично, если не в паблик
21 ноя 21, 13:40    [22398633]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Aniskin
Member

Откуда:
Сообщений: 341
rgreat
Распараллеливать декодирование одного файла - это оверкилл.

Зависит от решаемой задачи.

makhaon
есть шанс расшарить?

Дело в том, что от исходной библиотеки остались лишь процедуры FDCT/IDCT одного DU блока и процедуры перевода цветов из разных цветовых пространств, все остальное переделано/переписано. Поэтому мой код в чистом виде не поможет.

У меня была идея оформить все это в красивом виде и выложить на github, может быть когда-нибудь реализую.
21 ноя 21, 16:10    [22398675]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 15425
А использовать Vampyre Imaging не пробовал?
21 ноя 21, 16:29    [22398682]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3954
Aniskin,

понял. хотя бы в каком модуле/месте копать скажи, дабы долго не рыться? сам может гляну.
21 ноя 21, 16:43    [22398690]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Aniskin
Member

Откуда:
Сообщений: 341
makhaon
хотя бы в каком модуле/месте копать скажи, дабы долго не рыться? сам может гляну.


Можешь начать с TsdJpegBlockCoder.SamplesToImage из sdJpegBlockCoder.pas. Есть цикл от 0 до FInfo.VertMcuCount - 1, его и надо распараллеливать.
21 ноя 21, 17:48    [22398717]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
Sapersky
Member

Откуда:
Сообщений: 96
rgreat
Aniskin,
Распараллеливать декодирование одного файла - это оверкилл.
В некоторых случаях может быть полезно, типа картиночный вьюер должен грузить картинку как можно быстрее.
Мне попадалась многопоточная сишная библиотека, утверждается, что быстрее libjpeg-turbo:
https://t0rakka.silvrback.com/jpeg-decoding-benchmark
сейчас автор убрал её из открытого доступа, сохранилась только версия 2017-го года
https://github.com/galek/mango
Но пока у меня нет большой необходимости ещё ускорять jpeg, так что лень разбираться со сборкой сишных исходников.

Сообщение было отредактировано: 22 ноя 21, 12:04
22 ноя 21, 12:02    [22398992]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить jpeg в Graphics32.TBitmap32 потокобезопасно?  [new]
rgreat
Member

Откуда:
Сообщений: 7024
Sapersky,

В идеале вообще бы конвеер иметь. Что бы он сам распараллеливал нагрузку, будь то 1 jpeg или 10 за раз.
22 ноя 21, 12:05    [22398994]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить