2021-02-18 06:19 PM
If I try to encode blocks of colour using the hardware JPEG encode in an F7 from a BMP image (screen memory in this case) they fail if the colour is pure (e.g. all red, all blue) and they come out different shades of green.
By experiment, I have found that extra bits have to be set for the encode to succeed.
Colour Pure code Code that encodes correctly
red 0xff0000 0xff0202
green 0x00ff00 0x02ff02
blue 0x0000ff 0x0202ff
Attached is a jpeg captured by the hardware encoder where the first 3 blocks are 'pure' colours and the other 3 are with the extra bits set.
Is this a limitaion of the encoder or should I be using something other than
#define JPEG_CHROMA_SAMPLING JPEG_420_SUBSAMPLING
#define JPEG_COLOR_SPACE JPEG_YCBCR_COLORSPACE
#define JPEG_IMAGE_QUALITY 75
in the encoder config.
Thanks
2021-02-22 07:41 AM
Hi @frackers
It can be related to the JPEG memory requirement...
For more details about Hardware JPEG codec peripheral in STM32F7, you can refer to Application note AN4996.
Also, you may refer to the last STM32CubeF7 firmware package and have a look to the JPEG example under: STM32Cube_FW_F7_Vxx\Projects\STM32F769I_EVAL\Examples\JPEG
Bouraoui
2024-07-29 03:26 AM
you may have problems with converting RGB to YCbCr
if you are unlucky to use jpeg_utils.c from one of these beautiful stm examples, you should be aware that there is a bug in JPEG_InitPreProcColorTables function.
They add 1 for a nicer rounding: ((int32_t) 1 << (16 - 1)) but because of this 1 there is an overflow when RGB color component is close to the maximum: 255 or 254. Just replace ((int32_t) 1 << (16 - 1)) with ((int32_t) 0 << (16 - 1)) or find a better solution.
This one works better, did not test it hard enough though:
void JPEG_InitPreProcColorTables(void)
{
int32_t i;
for (i = 0; i <= 255; i++)
{
RED_Y_LUT[i] = (( ((int32_t) ((0.299 ) * (1L << 16))) * i) + ((int32_t) 0 << (16 - 1))) >> 16 ;
GREEN_Y_LUT[i] = (( ((int32_t) ((0.587 ) * (1L << 16))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ;
BLUE_Y_LUT[i] = (( ((int32_t) ((0.114 ) * (1L << 16))) * i) + ((int32_t) 0 << (16 - 1))) >> 16 ;
RED_CB_LUT[i] = (((-((int32_t) ((0.1687 ) * (1L << 16)))) * i) + ((int32_t) 0 << (16 - 1))) >> 16 ;
GREEN_CB_LUT[i] = (((-((int32_t) ((0.3313 ) * (1L << 16)))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ;
/* BLUE_CB_LUT and RED_CR_LUT are identical */
BLUE_CB_RED_CR_LUT[i] = (( ((int32_t) ((0.5 ) * (1L << 16))) * i) + ((int32_t) 0 << (16 - 1))) >> 16 ;
GREEN_CR_LUT[i] = (((-((int32_t) ((0.4187 ) * (1L << 16)))) * i) + ((int32_t) 1 << (16 - 1))) >> 16 ;
BLUE_CR_LUT[i] = (((-((int32_t) ((0.0813 ) * (1L << 16)))) * i) + ((int32_t) 0 << (16 - 1))) >> 16 ;
}
}