Распараллеливание создания файлов PNG с помощью C++, libpng и OpenMP

В настоящее время я пытаюсь реализовать кодировщик PNG на C++ на основе libpng, который использует OpenMP для ускорения процесса сжатия. Инструмент уже может генерировать файлы PNG из различных форматов изображений. Я загрузил полный исходный код на pastebin.com, чтобы вы могли увидеть, что я уже сделал: http://pastebin.com/8wiFzcgV

Пока все хорошо! Теперь моя проблема состоит в том, чтобы найти способ распараллелить создание фрагментов IDAT, содержащих сжатые данные изображения. Обычно функция libpng png_write_row вызывается в цикле for с указателем на структуру, содержащую всю информацию о файле PNG, и указателем строки с пиксельными данными одной строки изображения.

(строки 114-117 в файле Pastebin)

//Loop through image
for (i = 0, rp = info_ptr->row_pointers; i < png_ptr->height; i++, rp++) {
    png_write_row(png_ptr, *rp);
}

Затем Libpng сжимает одну строку за другой и заполняет внутренний буфер сжатыми данными. Как только буфер заполняется, сжатые данные сбрасываются блоком IDAT в файл изображения.

Мой подход заключался в том, чтобы разделить изображение на несколько частей и позволить одному потоку сжимать строку с 1 по 10, а другому потоку — с 11 по 20 и так далее. Но поскольку libpng использует внутренний буфер, это не так просто, как я сначала думал :) Мне каким-то образом нужно заставить libpng записывать сжатые данные в отдельный буфер для каждого потока.После этого мне нужен способ объединить буферы в правильном порядке, чтобы я мог записать их все вместе в выходной файл изображения.

Итак, у кого-нибудь есть идея, как это сделать с помощью OpenMP и некоторых настроек libpng? Большое спасибо!

9
задан Pascal 31 May 2012 в 04:12
поделиться