Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C++;,libpng和OpenMP 我目前尝试在基于LIPPNG的C++中实现PNG编码器,使用OpenMP加速压缩过程。 该工具已经能够从各种图像格式生成PNG文件。 我已将完整的源代码上载到pastebin.com,以便您可以看到我迄今为止所做的工作:_C++_Parallel Processing_Png_Openmp_Libpng - Fatal编程技术网

用C++;,libpng和OpenMP 我目前尝试在基于LIPPNG的C++中实现PNG编码器,使用OpenMP加速压缩过程。 该工具已经能够从各种图像格式生成PNG文件。 我已将完整的源代码上载到pastebin.com,以便您可以看到我迄今为止所做的工作:

用C++;,libpng和OpenMP 我目前尝试在基于LIPPNG的C++中实现PNG编码器,使用OpenMP加速压缩过程。 该工具已经能够从各种图像格式生成PNG文件。 我已将完整的源代码上载到pastebin.com,以便您可以看到我迄今为止所做的工作:,c++,parallel-processing,png,openmp,libpng,C++,Parallel Processing,Png,Openmp,Libpng,到目前为止,一切都很好!现在,我的问题是找到一种方法来并行生成包含压缩图像数据的IDAT块。通常,libpng函数png_write_row在for循环中被调用,该循环使用指向包含png文件所有信息的结构的指针和带有单个图像行像素数据的行指针 (Pastebin文件中的第114-117行) //循环浏览图像 对于(i=0,rp=info\u ptr->行指针;i高度;i++,rp++){ png_写入_行(png_ptr,*rp); } 然后,Libpng压缩一行接一行,并用压缩数据填充内部缓

到目前为止,一切都很好!现在,我的问题是找到一种方法来并行生成包含压缩图像数据的IDAT块。通常,libpng函数png_write_row在for循环中被调用,该循环使用指向包含png文件所有信息的结构的指针和带有单个图像行像素数据的行指针

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

//循环浏览图像
对于(i=0,rp=info\u ptr->行指针;i高度;i++,rp++){
png_写入_行(png_ptr,*rp);
}
然后,Libpng压缩一行接一行,并用压缩数据填充内部缓冲区。缓冲区一满,压缩数据就会以IDAT块的形式刷新到图像文件中

我的方法是将图像分成多个部分,让一个线程压缩第1到10行,另一个线程压缩第11到20行,依此类推。但由于libpng使用的是内部缓冲区,这并不像我第一次想的那么简单:)我必须让libpng为每个线程将压缩数据写入一个单独的缓冲区。之后,我需要一种方法以正确的顺序连接缓冲区,以便将它们一起写入输出图像文件


那么,有人知道我如何使用OpenMP和一些对libpng的调整来实现这一点吗?多谢各位

这条评论太长,但也不是真正的答案--

我不确定在不修改libpng(或编写自己的编码器)的情况下是否可以做到这一点。在任何情况下,如果您了解PNG压缩是如何实现的,都会有所帮助:

在高层,图像是一组像素行(通常为代表RGBA元组的32位值)

每一行可以独立地应用一个过滤器——过滤器的唯一目的是使该行更“可压缩”。例如,“子”过滤器使每个像素的值成为其与左侧像素之间的差值。这种增量编码乍一看似乎很愚蠢,但如果相邻像素之间的颜色相似(通常情况下),那么不管它们代表的实际颜色如何,结果值都非常小。压缩这样的数据比较容易,因为它的重复性要大得多

往下看,图像数据可以被看作是字节流(行之间不再区分)。这些字节被压缩,产生另一个字节流。压缩数据被任意分解成段(任意位置!),每个段写入一个IDAT数据块(每个数据块都有一点簿记开销,包括CRC校验和)

最底层让我们进入有趣的部分,即压缩步骤本身。PNG格式使用压缩数据格式。zlib本身只是一个围绕真实压缩数据格式的包装器(具有更多簿记功能,包括Adler-32校验和)(zip文件也使用这种格式)。deflate支持两种压缩技术:Huffman编码(根据字符串中每个不同字节出现的频率,将表示某个字节字符串所需的位数减少到最佳位数)和LZ77编码(这允许引用已经发生的重复字符串,而不是将其写入输出两次)

并行化deflate压缩的棘手之处在于,一般来说,压缩输入流的一部分要求前一部分在需要引用时也可用。但是,就像PNG可以有多个IDAT块一样,deflate被分解为多个“块”。一个块中的数据可以引用另一个块中以前编码的数据,但不一定要引用(当然,如果不引用,可能会影响压缩比)

因此,并行deflate的一般策略是将输入分成多个大部分(以便压缩比保持较高),将每个部分压缩成一系列块,然后将这些块粘合在一起(这实际上很棘手,因为块并不总是以字节边界结束——但您可以在节之间放置一个空的非压缩块(类型00),该块将与字节边界对齐)。然而,这并不简单,需要控制非常低的压缩级别(手动创建deflate块),创建跨越所有块的正确zlib包装器,并将所有这些内容填充到IDAT块中

如果您想使用自己的实现,我建议您阅读(和),这是我专门为压缩PNG而创建的(它是用Haxe for Flash编写的,但应该比较容易移植到C++)。由于Flash是单线程的,我不做任何并行化,但我确实将编码分成了几乎独立的部分(“虚拟”是因为在多个帧上,节之间保留了分数字节状态,这在很大程度上是相同的


祝你好运!

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


如果你对结果感兴趣,你可以在

找到完整的概念证明,好吧,我想对我来说,并行化deflate压缩有点太复杂/太耗时了
//Loop through image
for (i = 0, rp = info_ptr->row_pointers; i < png_ptr->height; i++, rp++) {
    png_write_row(png_ptr, *rp);
}