gpt4 book ai didi

c - libjpeg-turbo-1.5.1-vc.exe 中的 TurboJPEG API 产生错误的输出

转载 作者:行者123 更新时间:2023-11-30 16:56:17 25 4
gpt4 key购买 nike

我在 Visual Studio 2015 中用 C 语言编写了一个测试程序,用于测试 libjpeg-turbo TurboJPEG-API。

在此测试程序中,我生成 800x800 RGB 像素的图像并将其写入磁盘。当我在 tjCompress2 函数中使用 TJSAMP_GRAY 时,磁盘上生成的图像看起来不错:

TJSAMP_GRAY output of TurboJPEG API from libjpeg-turbo version 1.5.1.

当我使用 TJSAMP_444 时,图像看起来很奇怪:

TJSAMP_444 output of TurboJPEG API from libjpeg-turbo version 1.5.1.

但是,这两个图像都无法在 Adob​​e Photoshop 中打开,只能在 MS-Paint、Chrome 或 Internet Explorer 中打开。除 TJSAMP_GRAY 之外的所有其他选项都会导致奇怪的图像,质量设置为 100 且 TJSAMP_GRAY 也会导致奇怪的输出。 (本文中的图像是通过屏幕截图复制的,并保存为 png 以获取较小的数据。) 我还通过 P-Invoke 使用 turbojpeg.dll 库编写了一个 C# 程序。该程序正在产生有效的输出。

问题:我的错在哪里?

有问题的源代码:

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "turbojpeg.h"

unsigned char buffer[800 * 800 * 3];

int main(int argc, char** argv)
{
unsigned long size = 0;

unsigned char* compressedImage = NULL;

for (int x = 0; x < 800; x++)
for (int y = 0; y < 800; y++)
{
switch ((x / 80) % 3)
{
case 0:
buffer[(y * 800 + x) * 3] = 255;
buffer[(y * 800 + x) * 3 + 1] = 0;
buffer[(y * 800 + x) * 3 + 2] = 0;
break;
case 1:
buffer[(y * 800 + x) * 3] = 0;
buffer[(y * 800 + x) * 3 + 1] = 255;
buffer[(y * 800 + x) * 3 + 2] = 0;
break;
case 2:
buffer[(y * 800 + x) * 3] = 0;
buffer[(y * 800 + x) * 3 + 1] = 0;
buffer[(y * 800 + x) * 3 + 2] = 255;
break;
}
}

tjhandle compressor = tjInitCompress();

compressedImage = tjAlloc(1024 * 1024 * 4);

size = 1024 * 1024 * 4;

tjCompress2(compressor, buffer, 800, 0, 800, TJPF_RGB, &compressedImage, &size, TJSAMP_444, 80, TJFLAG_NOREALLOC | TJFLAG_ACCURATEDCT);

tjDestroy(compressor);

int handle = _wopen(L"D:\\file.jpeg", _O_CREAT | _O_WRONLY | _O_TRUNC, _S_IREAD | _S_IWRITE);

printf("LENGTH=%ld\n", size);

if (_write(handle, compressedImage, size) != size)
printf("Write Error.\n");

_close(handle);

tjFree(compressedImage);

return 0;
}

为了完整起见,测试 C# 源代码,运行良好:

class Program
{
[DllImport("turbojpeg", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr tjInitCompress();

[DllImport("turbojpeg", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr tjAlloc(int bytes);

[DllImport("turbojpeg", CallingConvention = CallingConvention.Cdecl)]
private static extern int tjCompress2(IntPtr handle, IntPtr srcBuf, int width, int pitch, int height, int pixelFormat, ref IntPtr jpegBuf, ref ulong jpegSize, int jpegSubsamp, int jpegQual, int flags);

[DllImport("turbojpeg", CallingConvention = CallingConvention.Cdecl)]
private static extern int tjDestroy(IntPtr handle);

[DllImport("turbojpeg", CallingConvention = CallingConvention.Cdecl)]
private static extern void tjFree(IntPtr buffer);

static void Main(string[] args)
{
ulong size = 1024 * 1024 * 4;

byte[] buffer = new byte[800 * 800 * 3];

for (int x = 0; x < 800; x++)
for (int y = 0; y < 800; y++)
{
switch ((x / 80) % 3)
{
case 0:
buffer[(y * 800 + x) * 3] = 255;
buffer[(y * 800 + x) * 3 + 1] = 0;
buffer[(y * 800 + x) * 3 + 2] = 0;
break;
case 1:
buffer[(y * 800 + x) * 3] = 0;
buffer[(y * 800 + x) * 3 + 1] = 255;
buffer[(y * 800 + x) * 3 + 2] = 0;
break;
case 2:
buffer[(y * 800 + x) * 3] = 0;
buffer[(y * 800 + x) * 3 + 1] = 0;
buffer[(y * 800 + x) * 3 + 2] = 255;
break;
}
}

IntPtr umBuffer = Marshal.AllocHGlobal(800 * 800 * 3);
Marshal.Copy(buffer, 0, umBuffer, 800 * 800 * 3);

IntPtr compressor = tjInitCompress();

IntPtr compressedImage = tjAlloc(1024 * 1024 * 4);

tjCompress2(compressor, umBuffer, 800, 0, 800, 0, ref compressedImage, ref size, 0, 80, 5 * 1024);

byte[] mCPData = new byte[size];

Marshal.Copy(compressedImage, mCPData, 0, (int)size);

System.IO.File.WriteAllBytes("D:\\managed.jpeg", mCPData);

tjFree(compressedImage);

Marshal.FreeHGlobal(umBuffer);
}
}

最佳答案

_wopen 行缺少 _O_BINARY。因此,项目配置或 libjpeg-turbo TurboJPEG-API 中没有错误。只是写入光盘的输出被解释为编码文本,因此被 _write 函数或某些底层实例修改。

正确的源代码是:

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "turbojpeg.h"

unsigned char buffer[800 * 800 * 3];

int main(int argc, char** argv)
{
unsigned long size = 0;

unsigned char* compressedImage = NULL;

for (int x = 0; x < 800; x++)
for (int y = 0; y < 800; y++)
{
switch ((x / 80) % 3)
{
case 0:
buffer[(y * 800 + x) * 3] = 255;
buffer[(y * 800 + x) * 3 + 1] = 0;
buffer[(y * 800 + x) * 3 + 2] = 0;
break;
case 1:
buffer[(y * 800 + x) * 3] = 0;
buffer[(y * 800 + x) * 3 + 1] = 255;
buffer[(y * 800 + x) * 3 + 2] = 0;
break;
case 2:
buffer[(y * 800 + x) * 3] = 0;
buffer[(y * 800 + x) * 3 + 1] = 0;
buffer[(y * 800 + x) * 3 + 2] = 255;
break;
}
}

tjhandle compressor = tjInitCompress();

compressedImage = tjAlloc(1024 * 1024 * 4);

size = 1024 * 1024 * 4;

tjCompress2(compressor, buffer, 800, 0, 800, TJPF_RGB, &compressedImage, &size, TJSAMP_444, 80, TJFLAG_NOREALLOC | TJFLAG_ACCURATEDCT);

tjDestroy(compressor);

int handle = _wopen(L"D:\\file.jpeg", _O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY, _S_IREAD | _S_IWRITE);

printf("LENGTH=%ld\n", size);

if (_write(handle, compressedImage, size) != size)
printf("Write Error.\n");

_close(handle);

tjFree(compressedImage);

return 0;
}

关于c - libjpeg-turbo-1.5.1-vc.exe 中的 TurboJPEG API 产生错误的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39950457/

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