1

我想在 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。

任何帮助将不胜感激,

谢谢

4

3 回答 3

1

Turbojpeg API tjCompressFromYUV 允许您为 jpegBuf 提供以下选项:

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

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

  2. 将 *jpegBuf 设置为 NULL 以告诉 TurboJPEG 为您分配缓冲区,或者

  3. 将缓冲区预分配到通过调用 tjBufSize() 确定的“最坏情况”大小。这应该确保永远不必重新分配缓冲区(设置 #TJFLAG_NOREALLOC 可以保证这一点。)

    如果选择选项 1,*jpegSize 应设置为预分配缓冲区的大小。在任何情况下,除非你设置了#TJFLAG_NOREALLOC,否则你应该总是在从这个函数返回时检查*jpegBuf,因为它可能已经改变了。

因此,通过使用 2-nd 选项,无需调用 tjBufSizeYUV2 和 tjAlloc,只需在调用 tjCompressFromYUV 之前让 jpegBuf=NULL 并在压缩之后执行 tjFree。

于 2018-07-23T17:09:37.267 回答
0

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

于 2020-09-19T09:41:13.057 回答
0

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

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

于 2016-03-24T08:28:28.473 回答