Возникла проблема со скоростью декодирования JPEG. Размеры изображений 1280x800 (100kb).
Прикрутил к проекту библиотеку libjpeg. Работает, но очень медленно (~ 1 кадр в сек)
Делаю все следующим образом...
libjpeg.h
CODE
typedef enum _EJpegInput
{
/** error/unspecified */
JPG_DATA_UNKNOWN,
/** monochrome */
JPG_DATA_GRAYSCALE,
/** red/green/blue */
JPG_DATA_RGB,
/** Y/Cb/Cr (also known as YUV) */
JPG_DATA_YCbCr,
/** C/M/Y/K */
JPG_DATA_CMYK,
/** Y/Cb/Cr/K */
JPG_DATA_YCCK
} EJpegInput;
typedef enum _EJpegMethod
{
/** slow but accurate integer algorithm */
JPG_METHOD_ISLOW,
/** faster, less accurate integer method */
JPG_METHOD_IFAST,
/** floating-point: accurate, fast on fast HW */
JPG_METHOD_FLOAT
} EJpegMethod;
typedef struct _SJPEGData
{
// Source
uint8_t* pucSrc;
uint32_t dwSrcLength;
// Destination
uint8_t* pucDst;
uint32_t dwDstLength;
// Dimensions
uint32_t dwHeight;
uint32_t dwWidth;
uint32_t dwBPP;
// JPEG algo parameters
uint32_t dwQuality;
EJpegInput eInput;
EJpegMethod eMethod;
uint32_t (*cbk)( uint8_t*, uint32_t, uint32_t, uint32_t);
} SJpegData;
typedef struct IMAGE_DATA
{
unsigned char *pixels;
long len;
long width;
long height;
}ImageData;
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
extern uint32_t JpegData_Init( SJpegData* pData );
extern uint32_t JpegData_SetSource( SJpegData* pData, uint8_t* pucSrc, uint32_t dwSrcLength );
extern uint32_t JpegData_SetDestination( SJpegData* pData, uint8_t* pucDst, uint32_t dwDstLength );
extern uint32_t JpegData_SetDimensions( SJpegData* pData, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwBPP );
extern uint32_t JpegData_SetParameters( SJpegData* pData, uint32_t dwQuality, EJpegInput eInput, EJpegMethod eMethod );
extern uint32_t JpegData_SetCallback( SJpegData* pData, uint32_t (*cbk)( uint8_t*, uint32_t, uint32_t, uint32_t ));
extern uint32_t ijg_compress( SJpegData* pData );
extern uint32_t ijg_compress_raw_no_padding( SJpegData* pData );
extern uint32_t ijg_decompress( SJpegData* pData );
{
/** error/unspecified */
JPG_DATA_UNKNOWN,
/** monochrome */
JPG_DATA_GRAYSCALE,
/** red/green/blue */
JPG_DATA_RGB,
/** Y/Cb/Cr (also known as YUV) */
JPG_DATA_YCbCr,
/** C/M/Y/K */
JPG_DATA_CMYK,
/** Y/Cb/Cr/K */
JPG_DATA_YCCK
} EJpegInput;
typedef enum _EJpegMethod
{
/** slow but accurate integer algorithm */
JPG_METHOD_ISLOW,
/** faster, less accurate integer method */
JPG_METHOD_IFAST,
/** floating-point: accurate, fast on fast HW */
JPG_METHOD_FLOAT
} EJpegMethod;
typedef struct _SJPEGData
{
// Source
uint8_t* pucSrc;
uint32_t dwSrcLength;
// Destination
uint8_t* pucDst;
uint32_t dwDstLength;
// Dimensions
uint32_t dwHeight;
uint32_t dwWidth;
uint32_t dwBPP;
// JPEG algo parameters
uint32_t dwQuality;
EJpegInput eInput;
EJpegMethod eMethod;
uint32_t (*cbk)( uint8_t*, uint32_t, uint32_t, uint32_t);
} SJpegData;
typedef struct IMAGE_DATA
{
unsigned char *pixels;
long len;
long width;
long height;
}ImageData;
/*------------------------------------------------------------------------------
* Exported functions
*------------------------------------------------------------------------------*/
extern uint32_t JpegData_Init( SJpegData* pData );
extern uint32_t JpegData_SetSource( SJpegData* pData, uint8_t* pucSrc, uint32_t dwSrcLength );
extern uint32_t JpegData_SetDestination( SJpegData* pData, uint8_t* pucDst, uint32_t dwDstLength );
extern uint32_t JpegData_SetDimensions( SJpegData* pData, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwBPP );
extern uint32_t JpegData_SetParameters( SJpegData* pData, uint32_t dwQuality, EJpegInput eInput, EJpegMethod eMethod );
extern uint32_t JpegData_SetCallback( SJpegData* pData, uint32_t (*cbk)( uint8_t*, uint32_t, uint32_t, uint32_t ));
extern uint32_t ijg_compress( SJpegData* pData );
extern uint32_t ijg_compress_raw_no_padding( SJpegData* pData );
extern uint32_t ijg_decompress( SJpegData* pData );
libjpeg.c
CODE
// Функция декодирования
extern uint32_t ijg_decompress(SJpegData* pData)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
uint32_t dwSourceLength;
int row_stride;
long counter=0;
JSAMPROW aLines[2];
assert( pData != NULL );
cinfo.err=jpeg_std_error( &jerr );
jpeg_create_decompress( &cinfo );
dwSourceLength=pData->dwSrcLength;
jpeg_mem_src( &cinfo, (uint8_t*)pData->pucSrc, dwSourceLength );
jpeg_read_header( &cinfo, TRUE );
cinfo.dct_method = pData->eMethod;
jpeg_start_decompress( &cinfo );
row_stride = cinfo.output_width * cinfo.output_components;
imageData = malloc(sizeof(ImageData));
imageData->width = cinfo.output_width;
imageData->height = cinfo.output_height;
imageData->len = cinfo.output_width * cinfo.output_height * cinfo.output_components;
imageData->pixels = malloc(imageData->len);
memset(imageData->pixels, 0, imageData->len);
aLines[0] = (JSAMPROW)malloc(sizeof(JSAMPLE) * row_stride);
for (;cinfo.output_scanline < cinfo.image_height;)
{
jpeg_read_scanlines( &cinfo, aLines, 1 );
memcpy(imageData->pixels+counter, aLines[i], row_stride);
counter += row_stride;
}
(*pData->cbk)(imageData->pixels, imageData->len, imageData->width, imageData->height);
jpeg_finish_decompress( &cinfo );
jpeg_destroy_decompress( &cinfo );
free(imageData->pixels);
free(imageData);
free(aLines[0]);
return 0;
}
extern uint32_t ijg_decompress(SJpegData* pData)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
uint32_t dwSourceLength;
int row_stride;
long counter=0;
JSAMPROW aLines[2];
assert( pData != NULL );
cinfo.err=jpeg_std_error( &jerr );
jpeg_create_decompress( &cinfo );
dwSourceLength=pData->dwSrcLength;
jpeg_mem_src( &cinfo, (uint8_t*)pData->pucSrc, dwSourceLength );
jpeg_read_header( &cinfo, TRUE );
cinfo.dct_method = pData->eMethod;
jpeg_start_decompress( &cinfo );
row_stride = cinfo.output_width * cinfo.output_components;
imageData = malloc(sizeof(ImageData));
imageData->width = cinfo.output_width;
imageData->height = cinfo.output_height;
imageData->len = cinfo.output_width * cinfo.output_height * cinfo.output_components;
imageData->pixels = malloc(imageData->len);
memset(imageData->pixels, 0, imageData->len);
aLines[0] = (JSAMPROW)malloc(sizeof(JSAMPLE) * row_stride);
for (;cinfo.output_scanline < cinfo.image_height;)
{
jpeg_read_scanlines( &cinfo, aLines, 1 );
memcpy(imageData->pixels+counter, aLines[i], row_stride);
counter += row_stride;
}
(*pData->cbk)(imageData->pixels, imageData->len, imageData->width, imageData->height);
jpeg_finish_decompress( &cinfo );
jpeg_destroy_decompress( &cinfo );
free(imageData->pixels);
free(imageData);
free(aLines[0]);
return 0;
}
main.c
Код
SJpegData pData;
......
JpegData_Init(&pData);
JpegData_SetSource(&pData, (uint8_t*)data, len);
JpegData_SetDimensions(&pData, 1280, 800, 24);
JpegData_SetParameters(&pData, 12, JPG_DATA_YCbCr, JPG_METHOD_IFAST);
JpegData_SetCallback(&pData, &DataImage);
ijg_decompress(&pData);
......
JpegData_Init(&pData);
JpegData_SetSource(&pData, (uint8_t*)data, len);
JpegData_SetDimensions(&pData, 1280, 800, 24);
JpegData_SetParameters(&pData, 12, JPG_DATA_YCbCr, JPG_METHOD_IFAST);
JpegData_SetCallback(&pData, &DataImage);
ijg_decompress(&pData);