Memory jpeg无损转换-内存消耗?

Memory jpeg无损转换-内存消耗?,memory,jpeg,codec,imaging,libjpeg-turbo,Memory,Jpeg,Codec,Imaging,Libjpeg Turbo,我刚刚从下载了最新的win32jpegtran.exe,并观察到以下情况: 我已经准备了一个24 BPP的jpeg测试图像,14500 x 10000像素 文件系统中的压缩大小约为7.5 MB 解压缩到内存(使用一些图像查看器)会膨胀到大约450MB 在无损旋转(180)期间监控jpegtran.exe命令行工具的内存消耗,我可以看到进程消耗的内存高达900 MB 我假设这样的jpeg无损转换不需要将图像文件解码到内存中,而只需对编码文件本身执行一些数学转换,从而使内存占用非常低 那么以下哪

我刚刚从下载了最新的win32jpegtran.exe,并观察到以下情况:

我已经准备了一个24 BPP的jpeg测试图像,14500 x 10000像素

  • 文件系统中的压缩大小约为7.5 MB
  • 解压缩到内存(使用一些图像查看器)会膨胀到大约450MB
在无损旋转(180)期间监控jpegtran.exe命令行工具的内存消耗,我可以看到进程消耗的内存高达900 MB

我假设这样的jpeg无损转换不需要将图像文件解码到内存中,而只需对编码文件本身执行一些数学转换,从而使内存占用非常低

那么以下哪项是正确的

  • 此特定工具实现中的一些错误
  • 我错过了一些配置开关
  • 我这边有一些误解(例如jpeg无损转换也需要将图像解码到内存中?)
  • “数学运算”比“将图像解码为内存”消耗更多内存
编辑:

根据JasonD的回答,原因似乎是后者。因此,我将扩展我的问题:

是否有任何实现可以在小块中执行这些操作(以避免高内存使用)?还是说总的来说这件事需要去做,却没有办法解决

PS:

我不打算实现我自己的编解码器/算法。相反,我要问的是,是否有任何实现能够满足我的需求。或者,至少在理论上是这样的。

我不知道有问题的库,但是为了对jpeg图像执行无损旋转,您至少必须解压缩DCT系数以旋转它们,然后重新压缩

DCT系数完全展开后,将与原始图像数据大小相同或更大,因为它们具有更多的信息位

它是无损的,因为jpeg中的损失是由DCT系数的量化引起的。只要您不解码/重新编码/重新量化这些,就不会产生任何损失

但这将是内存密集型的

jpeg压缩的工作原理大致如下:

  • 将图像转换为YCbCr颜色空间
  • 可选地对一些通道进行下采样(颜色误差比亮度误差更不易察觉,因此通常对色度通道进行2倍下采样)。这显然是有损的,但非常可预测/稳定
  • 通过离散余弦变换(DCT)变换图像的8x8块,将图像移动到频率空间。DCT系数也在8x8块中,并且比8位图像数据使用更多的位进行存储
  • 通过可变量量化DCT系数(这是大多数软件包中的质量设置)。其目的是产生尽可能多的小系数,尤其是零系数。这是jpeg压缩的主要“有损”方面
  • 对二维数据进行之字形处理,将其转换为大致按频率顺序排列的一维系数流。高频更可能是零输出,因此许多数据包在理想情况下会以可以被截断的零流结束
  • 使用哈夫曼编码(非无损)压缩(现在相当可压缩)数据

因此,“无损耗”变换希望尽可能避免这样做-尤其是DCT量化之外的任何事情,但这并不能避免扩展数据。

DCT系数将大于最终(或原始)解压缩图像。+1,我建议OP也看看压缩方法。顺便说一句:
libjpeg.txt
中的
内存使用
部分提供了有关内存要求的更多详细信息。对于DCT系数:“这需要2个字节/系数。在典型的2x2采样时,彩色图像每像素3个字节。最坏的情况(1x1采样)需要6个字节/像素。对于灰度,图2个字节/像素。”。是的,我忽略了下采样方面,我可能应该提到这一点。我已经修改了我的答案来澄清这一点。好的方面。尝试在小块中这样做的问题是,输出块需要根据输入重新排序,并且块的长度是可变的(因为压缩),因此您不能轻易地随机访问其中任何一个。也许,您可以对输入文件进行初始传递,而无需实际扩展它,以确定每个块在输入流中的起始位置,然后按输出顺序进行处理。不过,不知道是否有人编写过这样的解决方案。