gpt4 book ai didi

c - LodePNG 在编码大于 15000 * 15000 像素的 PNG 文件时崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 01:29:25 28 4
gpt4 key购买 nike

我一直在使用 LodePNG 的 lodepng_encode24_file 对一些 24 位 RGB 图像文件进行编码,到目前为止效果非常好。但是,我注意到当我向它提供大于 15360*15360 像素大小的数据集时它似乎崩溃了(14336*14336 像素图像编码良好)。

可以通过简单地替换行来获得 32 位情况下此行为的最小示例(其中崩溃前的最大大小略低)

  unsigned width = 512, height = 512;

  unsigned width = 1024*14, height = 1024*14;

LodePNG's example_encode.c file , 并执行它。

我以前遇到过 C 代码崩溃的问题,因为我将大型数组分配给堆栈内存(其最大大小通常在 2MB 左右)而不是堆内存,所以作为 C 的新用户,我的第一直觉是看看是否堆内存大小有上限。

然而,according to this answer ,堆内存没有限制,所以一定是其他地方出了问题。

我的第二个猜测是崩溃是由于 PNG 格式本身支持的最大图像尺寸的固有限制。然而,according to this answer及其下方的评论,PNG 支持的最大文件大小约为 4,000,000,000 * 4,000,000,000 像素,因此这也不是罪魁祸首。

有没有人猜到可能出了什么问题?其他人在尝试时是否能够重现此错误?

编辑:就 RAM 消耗而言,我有 8GB RAM,减去硬件保留、使用中、修改和备用内存(Windows 资源监视器实用程序使用的术语)我进行计算时大约有 4GB RAM 可用。对于 15000*15000 大小的 32 位图像,需要不到 1GB。同样,当我成功编码 14000*14000 24 位图像时,我的空闲 RAM 在编码过程的任何时候都不会低于 3GB,所以我认为 RAM 耗尽不是问题。

最佳答案

我相信您低估了程序使用的内存量。假设您在 Windows 上,那么您可能只有 2 GB 的内存可供进程使用(请参阅 here )。然后,您为 14336x14336 图像分配一个 882 MB 的大块。 LodePNG 代码然后进行更多分配,最有可能等于或大于此图像大小。

我只追踪了 LodePNG code手动但它似乎在内存中创建一个缓冲区并以 block 的形式写入该缓冲区。它在重新分配时进行最小调整(在 lodepng_chunk_append() 中,仅足以容纳数据加上 12 个字节),这意味着它将不得不进行大量重新分配。这可能(或最终将)将内存碎片化到无法使用非常大的缓冲区的程度。

即使堆内存没有碎片,想想当您尝试将 800MB 缓冲区 realloc() 到 801MB 缓冲区时可能会发生什么。如果堆管理器是“智能”的,它可能会起作用,但天真的一个将需要总共 1601MB ......如果您的堆大小为 2000MB 并且您已经使用了其中的 822MB,则这不可用。

其中很多(大部分)都是推测,但您可以自己做一些测试来模拟分配和重新分配几个大内存块,看看您是否可以重现内存不足的情况。

附录:虽然上述内容可能是正确的,但实际上并不是本例中崩溃的原因。从实际运行和跟踪代码来看,问题出在 LodePng.c 中的第 5558 行:

size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8;

lodepng_get_bpp() 返回 24 时,当 w * h 大于 178,956,970 时,此计算会导致整数溢出。对于方形图像,这是 13378 x 13378。这导致输出缓冲区被分配不正确的大小,从而在稍后写入时缓冲区溢出。

一个快速的解决方法是将这一行更改为:

 size_t size = (size_t) ((unsigned long long) w * h * lodepng_get_bpp(&info.color) / 8 + 1);

尽管我不确定这是否适用于所有 BPP 值并且它仍然存在溢出问题,尽管尺寸较大。我建议联系 LodePNG 的作者以实现适当的修复。

关于c - LodePNG 在编码大于 15000 * 15000 像素的 PNG 文件时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25490332/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com