PNG文件创建与C ++,libpng和OpenMP的并行化 [英] Parallelization of PNG file creation with C++, libpng and OpenMP

查看:388
本文介绍了PNG文件创建与C ++,libpng和OpenMP的并行化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正试图在基于libpng的C ++中实现一个PNG编码器,它使用OpenMP来加速压缩过程。
该工具已经能够从各种图像格式生成PNG文件。
我将完整的源代码上传到pastebin.com,以便您可以看到我迄今为止做了什么: http://pastebin.com/8wiFzcgV

I am currently trying to implement a PNG encoder in C++ based on libpng that uses OpenMP to speed up the compression process. The tool is already able to generate PNG files from various image formats. I uploaded the complete source code to pastebin.com so you can see what I have done so far: http://pastebin.com/8wiFzcgV

到目前为止,太棒了!现在,我的问题是找到一种如何并行化包含压缩图像数据的IDAT块的生成的方式。通常,libpng函数png_write_row在for循环中被调用,该指针指向包含有关PNG文件的所有信息的结构体,以及具有单个图像行的像素数据的行指针。

So far, so good! Now, my problem is to find a way how to parallelize the generation of the IDAT chunks containing the compressed image data. Usually, the libpng function png_write_row gets called in a for-loop with a pointer to the struct that contains all the information about the PNG file and a row pointer with the pixel data of a single image row.

(Pastebin文件中的第114-117行)

(Line 114-117 in the Pastebin file)

//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块中刷新到图像文件。

Libpng then compresses one row after another and fills an internal buffer with the compressed data. As soon as the buffer is full, the compressed data gets flushed in a IDAT chunk to the image file.

我的方法是将图像拆分为多个部分,线程压缩行1到10,另一个线程11到20等。但是由于libpng使用内部缓冲区,它不像我想的那么简单:)我不知何故有必要将压缩数据写入一个单独的缓冲区为每个线程。后来我需要一个方法,以正确的顺序连接缓冲区,所以我可以把它们一起写到输出图像文件。

My approach was to split the image into multiple parts and let one thread compress row 1 to 10 and another thread 11 to 20 and so on. But as libpng is using an internal buffer it is not as easy as I thought first :) I somehow have to make libpng write the compressed data to a separate buffer for every thread. Afterwards I need a way to concatenate the buffers in the right order so I can write them all together to the output image file.

所以,有人有一个想法如何可以做到这一点与OpenMP和一些调整到libpng?非常感谢!

So, does someone have an idea how I can do this with OpenMP and some tweaking to libpng? Thank you very much!

推荐答案

我终于得到了并行化压缩过程。
正如Cameron在对他的回答的评论中提到的,我不得不从zstreams剥离zlib标头以组合它们。不需要剥离页脚,因为zlib提供了一个称为Z_SYNC_FLUSH的选项,可以用于所有块(除了必须使用Z_FINISH写入的最后一个块)写入字节边界。所以你可以简单地连接流输出之后。最终,必须在所有线程上计算adler32校验和,并复制到组合的zstreams的末尾。

I finally got it to parallelize the compression process. As mentioned by Cameron in the comment to his answer I had to strip the zlib header from the zstreams to combine them. Stripping the footer was not required as zlib offers an option called Z_SYNC_FLUSH which can be used for all chunks (except the last one which has to be written with Z_FINISH) to write to a byte boundary. So you can simply concatenate the stream outputs afterwards. Eventually, the adler32 checksum has to be calculated over all threads and copied to the end of the combined zstreams.

如果你对结果感兴趣,你可以找到完整的证明在 https://github.com/anvio/png-parallel 上的概念

If you are interested in the result you can find the complete proof of concept at https://github.com/anvio/png-parallel

这篇关于PNG文件创建与C ++,libpng和OpenMP的并行化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆