libjpeg turbo tjCompressFromYUV

libjpeg turbo tjCompressFromYUV

我想在 C 中使用 libturbojpeg 将平面 4:2:0 YUV 缓冲区压缩为 jpeg 图像,但我在使用 tjCompressFromYUV() 函数时遇到问题。

这是我的代码:

#define PADDING     2
tjhandle tjh;
unsigned long buf_size;
unsigned char *jpegBuf = NULL;
unsigned long jpegSize;
int width = 352;
int height = 288;
int quality = 70;
unsigned char *ucp_frame;
int j;
FILE *fp = NULL;

ucp_frame = malloc(width * height * 3 / 2);
if ( NULL == ucp_frame ) {
    printf("malloc error ucp_frame\n");
    return 0;
}

fp = fopen("planar_352x288.raw", "rb");
if( NULL == fp ) {
    printf("fopen error\n");
    return 0;
}

j = fread( ucp_frame, 1, width * height * 3 / 2, fp);
if( j != width * height * 3 / 2 ) {
    printf("fread error\n");
    return 0;
}
fclose(fp);

tjh = tjInitCompress();
if( NULL == tjh ) {
    printf("tjInitCompress error '%s'\n",  tjGetErrorStr() );
    return 0;
}

buf_size = tjBufSizeYUV2( width, PADDING, height, TJSAMP_420);
jpegBuf = tjAlloc(buf_size);

if( tjCompressFromYUV( tjh, ucp_frame, width, PADDING, height,
                       TJSAMP_420, &jpegBuf, &jpegSize, quality,
                       TJFLAG_NOREALLOC ) ) {
    printf("tjCompressFromYUV error '%s'\n",  tjGetErrorStr() );
}

tjGetErrorStr()返回的错误字符串是"Bogus input colorspace"。

我尝试链接 libturbojpeg 版本 1.4.2 和 1.4.90。

如有任何帮助,我们将不胜感激,

谢谢

好的,原来问题出在包含我发布的代码的程序中,在一个较小的测试程序中,tjBufSizeYUV2 调用按预期执行。

附带说明一下,如果 jpegBuf 在调用 tjBufSizeYUV2 之前预先分配,则传递给 tjBufSizeYUV2flag 参数必须包含 TJFLAG_NOREALLOC,否则即使稍后调用 tjFree(jpegBuf);jpegBuf 也不会被释放。

Turbojpeg API tjCompressFromYUV 允许您对 jpegBuf 进行这样的选择:

@param jpegBuf 指向将接收图像缓冲区的指针的地址 JPEG 图片。 TurboJPEG 能够将 JPEG 缓冲区重新分配给 适应 JPEG 图像的大小。因此,您可以选择:

  1. 使用#tjAlloc() 和任意大小预分配 JPEG 缓冲区 让 TurboJPEG 根据需要增加缓冲区,

  2. 将 *jpegBuf 设置为 NULL 以告知 TurboJPEG 分配缓冲区 为你,或

  3. 将缓冲区预分配为 "worst case" 大小,通过调用 tjBufSize()。这应该确保缓冲区永远不必 重新分配(设置#TJFLAG_NOREALLOC 保证这一点。)

    如果您选择选项 1,*jpegSize 应设置为您的尺寸 预分配缓冲区。无论如何,除非你设置了#TJFLAG_NOREALLOC, 你应该总是从这个函数中检查 return 上的 *jpegBuf,因为 它可能已经改变了。

因此,通过使用第二个选项,无需调用 tjBufSizeYUV2 和 tjAlloc,只需在调用 tjCompressFromYUV 之前设置 jpegBuf=NULL 并在压缩后执行 tjFree。

#define PADDING 4
jpegBuf = tjAlloc(width*height*3/2);