libjpeg turbo tjCompressFromYUV

Я хотел бы сжать плоский буфер YUV 4:2:0 в изображение JPEG, используя libturbojpeg в C, но у меня возникают проблемы с использованием 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() это "Поддельное входное цветовое пространство".

Я попытался связать libturbojpeg версий 1.4.2 и 1.4.90.

Любая помощь будет оценена по достоинству,

Спасибо

2 ответа

Turbojpeg API tjCompressFromYUV позволяет использовать такие параметры для jpegBuf:

@param jpegBuf адрес указателя на буфер изображения, который будет получать изображение JPEG. TurboJPEG имеет возможность перераспределения буфера JPEG в соответствии с размером изображения JPEG. Таким образом, вы можете выбрать:

  1. предварительно выделите буфер JPEG произвольного размера, используя #tjAlloc(), и позвольте TurboJPEG увеличить буфер по мере необходимости,

  2. установите *jpegBuf в NULL, чтобы сказать TurboJPEG выделить буфер для вас, или

  3. предварительно выделить буфер для размера "наихудшего случая", определенного путем вызова tjBufSize(). Это должно гарантировать, что буфер никогда не должен быть перераспределен (установка #TJFLAG_NOREALLOC гарантирует это.)

    Если вы выберете опцию 1, *jpegSize должен быть установлен на размер вашего предварительно выделенного буфера. В любом случае, если вы не установили #TJFLAG_NOREALLOC, вы всегда должны проверять *jpegBuf по возвращении из этой функции, так как она могла измениться.

Таким образом, при использовании 2-й опции нет необходимости вызывать tjBufSizeYUV2 и tjAlloc, просто имейте jpegBuf=NULL перед вызовом tjCompressFromYUV и делайте tjFree после сжатия.

Хорошо, оказалось, что проблема была в программе, содержащей код, который я разместил, в меньшей тестовой программе tjBufSizeYUV2 вызов выполняется, как ожидалось.

С другой стороны, кажется, что если jpegBuf предварительно назначается перед вызовом tjBufSizeYUV2, flag аргумент передан tjBufSizeYUV2 должен содержать TJFLAG_NOREALLOCили jpegBuf не будет освобожден, даже если tjFree(jpegBuf); позже называется.

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

Другие вопросы по тегам