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. Таким образом, вы можете выбрать:
предварительно выделите буфер JPEG произвольного размера, используя #tjAlloc(), и позвольте TurboJPEG увеличить буфер по мере необходимости,
установите *jpegBuf в NULL, чтобы сказать TurboJPEG выделить буфер для вас, или
предварительно выделить буфер для размера "наихудшего случая", определенного путем вызова 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);
позже называется.