简体   繁体   English

libjpeg turbo tjCompressFromYUV

[英]libjpeg turbo tjCompressFromYUV

I'd like to compress a planar 4:2:0 YUV buffer to a jpeg image using libturbojpeg in C, but I'm having trouble using the tjCompressFromYUV() function.我想在 C 中使用 libturbojpeg 将平面 4:2:0 YUV 缓冲区压缩为 jpeg 图像,但是我在使用tjCompressFromYUV()函数时遇到了问题。

This is my code:这是我的代码:

#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() );
}

The error string returned by tjGetErrorStr() is "Bogus input colorspace". tjGetErrorStr()返回的错误字符串是“Bogus input colorspace”。

I tried linking libturbojpeg versions 1.4.2 and 1.4.90.我尝试链接 libturbojpeg 版本 1.4.2 和 1.4.90。

Any help wolud be appreciated,任何帮助将不胜感激,

Thanks谢谢

Turbojpeg API tjCompressFromYUV allows you such options for jpegBuf: Turbojpeg API tjCompressFromYUV 允许您为 jpegBuf 提供以下选项:

@param jpegBuf address of a pointer to an image buffer that will receive the JPEG image. @param jpegBuf 指向将接收 JPEG 图像的图像缓冲区的指针的地址。 TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. TurboJPEG 能够重新分配 JPEG 缓冲区以适应 JPEG 图像的大小。 Thus, you can choose to:因此,您可以选择:

  1. pre-allocate the JPEG buffer with an arbitrary size using #tjAlloc() and let TurboJPEG grow the buffer as needed,使用 #tjAlloc() 预先分配任意大小的 JPEG 缓冲区,并让 TurboJPEG 根据需要增加缓冲区,

  2. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or将 *jpegBuf 设置为 NULL 以告诉 TurboJPEG 为您分配缓冲区,或者

  3. pre-allocate the buffer to a "worst case" size determined by calling tjBufSize().将缓冲区预先分配到通过调用 tjBufSize() 确定的“最坏情况”大小。 This should ensure that the buffer never has to be re-allocated (setting #TJFLAG_NOREALLOC guarantees this.)这应该确保永远不必重新分配缓冲区(设置 #TJFLAG_NOREALLOC 可以保证这一点。)

    If you choose option 1, *jpegSize should be set to the size of your pre-allocated buffer.如果选择选项 1,*jpegSize 应设置为预分配缓冲区的大小。 In any case, unless you have set #TJFLAG_NOREALLOC, you should always check *jpegBuf upon return from this function, as it may have changed.在任何情况下,除非您设置了#TJFLAG_NOREALLOC,否则您应该在从该函数返回时始终检查 *jpegBuf,因为它可能已更改。

So by using 2-nd option, there is no need to call tjBufSizeYUV2 and tjAlloc, simply have jpegBuf=NULL before calling tjCompressFromYUV and do tjFree after compressing.因此,通过使用第二个选项,无需调用 tjBufSizeYUV2 和 tjAlloc,只需在调用 tjCompressFromYUV 之前设置 jpegBuf=NULL 并在压缩后执行 tjFree。

Ok it turned out the problem was in the program containing the code I posted, in a smaller test program the tjBufSizeYUV2 call performs as expected.好吧,原来问题出在包含我发布的代码的程序中,在一个较小的测试程序中, tjBufSizeYUV2调用按预期执行。

On a side note it seems that if jpegBuf is pre-allocated before calling tjBufSizeYUV2 , the flag argument passed to tjBufSizeYUV2 must contain TJFLAG_NOREALLOC , or else jpegBuf won't be freed even if tjFree(jpegBuf);在一个侧面说明看来,如果jpegBuf是预先分配的呼叫前tjBufSizeYUV2flag传递给说法tjBufSizeYUV2必须包含TJFLAG_NOREALLOC ,否则jpegBuf不会被释放,即使tjFree(jpegBuf); is later called.后来被称为。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM