2020-06-14 11:14 AM
Hello
I am trying to encode an image of (160*120) in grayscale format - i.e a bmp file of 1bpp color depth.
Unfortunately, the encoder would not finish its conversion. and the `HAL_JPEG_EncodeCpltCallback` is not called.
My setup is based on the `JPEG_EncodingUsingFs_DMA` from ST, while this example is designed for 24bits pixel depth, I tried to modify it for my application - with changing the `ReadBmpRgbLines`to read only 1 color:
static void ReadBmpRgbLines(FIL *file, JPEG_ConfTypeDef Conf, uint8_t * pDataBuffer, uint32_t *BufferSize)
{
uint32_t bytesReadfile = 1;
uint32_t CurrentBlockLine = 1;
*BufferSize = 0;
while((CurrentLine <= Conf.ImageHeight) && (CurrentBlockLine <= MAX_INPUT_LINES))
{
f_lseek (file,BMP_HEADER_SIZE + Conf.ImageWidth *(Conf.ImageHeight - CurrentLine)*1);
f_read (file, pDataBuffer , Conf.ImageWidth*1 , (UINT*)(&bytesReadfile));
pDataBuffer += bytesReadfile;
*BufferSize += bytesReadfile;
CurrentLine +=1 ;
CurrentBlockLine += 1;
}
}
My encoder values are as follow:
#define JPEG_RGB_FORMAT JPEG_RGB888
#define JPEG_CHROMA_SAMPLING JPEG_444_SUBSAMPLING
#define JPEG_COLOR_SPACE JPEG_YCBCR_COLORSPACE\
#define JPEG_IMAGE_QUALITY 100
#define MAX_INPUT_WIDTH 800
#define MAX_INPUT_LINES 8
I have noticed the function that is called to generate a new MCU block is 'stuck` on the same bmp image line.
Can anyone send a hint about this problem? Do I have to set different parameters for the encoder?
Sincerely
Dan
Solved! Go to Solution.
2020-06-15 08:27 PM
Oh sorry, you are correct. I didn't noticed that they don't support proper conversion function.
Then, it would be easier to pretend as if you have RGB88 - just repeat the gray scale value three times.
static void ReadBmpRgbLines(FIL *file, JPEG_ConfTypeDef Conf, uint8_t * pDataBuffer, uint32_t *BufferSize)
{
uint32_t bytesReadfile = 1;
uint32_t CurrentBlockLine = 1;
*BufferSize = 0;
uint8_t workbuffer[200];
int i;
while((CurrentLine <= Conf.ImageHeight) && (CurrentBlockLine <= MAX_INPUT_LINES))
{
f_lseek (file,BMP_HEADER_SIZE + Conf.ImageWidth *(Conf.ImageHeight - CurrentLine)*1);
f_read (file, workbuffer , Conf.ImageWidth*1 , (UINT*)(&bytesReadfile));
for (i = 0; i < Conf.ImageWidth; i++)
{
*pDataBuffer++= workbuffer[i];
*pDataBuffer++= workbuffer[i];
*pDataBuffer++= workbuffer[i];
}
*BufferSize += bytesReadfile * 3;
CurrentLine +=1 ;
CurrentBlockLine += 1;
}
}
2020-06-14 05:16 PM
I believe you should use JPEG_GRAYSCALE_COLORSPACE instead of JPEG_YCBCR_COLORSACE.
#define JPEG_COLOR_SPACE JPEG_GRAYSCALE_COLORSPACE
Regards,
2020-06-14 10:45 PM
Dear sirius
Thank you for your response.
I tried also the GRAYSCALE_COLORSPACE, which gave in the same result - a non-finished conversion.
BTW I belive the colorspace relates to the convertion output, am I right?
Any other ideas about the convertor parameters?
Dan
2020-06-14 11:12 PM
JPEG encoder hardware expects MCU format -- where Grayscale MCU and YCBCR MCU formats are different.
In ST's example code, JPEG_GetEncodeColorConvertFunc() handles the difference of color space and returns associated conversion function pointer.
I checked ST's `JPEG_EncodingUsingFs_DMA` example code, and found that you also need to fix BMP_GetInfo() in main.c.
This function expects JPEG_YCBCR_COLORSPACE and 'stucks` at there.
2020-06-15 09:33 AM
Thank you for your reply
Tthe ` BMP_GetInfo()` can get stuck if the dimentions does not meet the size of (%8 for any color format or %16 for YCMCR format).
My image size (160x120) meets the condition of %8==0 than does not hangs there.
Regarding `JPEG_GetEncodeColorConvertFunc`, the HAL has only functions of convertion of the types: JPEG_ARGB_MCU_Gray_ConvertBlocks. i.e ARGB -> Gray MCU. And I could not find a Gray -> Gray MCU.
I think my only option is to manipulate the input to this MCU generator.
I would really appreciate if you could explain me other method, or reference me to a other MCU building functions.
Thanks
Dan
2020-06-15 08:27 PM
Oh sorry, you are correct. I didn't noticed that they don't support proper conversion function.
Then, it would be easier to pretend as if you have RGB88 - just repeat the gray scale value three times.
static void ReadBmpRgbLines(FIL *file, JPEG_ConfTypeDef Conf, uint8_t * pDataBuffer, uint32_t *BufferSize)
{
uint32_t bytesReadfile = 1;
uint32_t CurrentBlockLine = 1;
*BufferSize = 0;
uint8_t workbuffer[200];
int i;
while((CurrentLine <= Conf.ImageHeight) && (CurrentBlockLine <= MAX_INPUT_LINES))
{
f_lseek (file,BMP_HEADER_SIZE + Conf.ImageWidth *(Conf.ImageHeight - CurrentLine)*1);
f_read (file, workbuffer , Conf.ImageWidth*1 , (UINT*)(&bytesReadfile));
for (i = 0; i < Conf.ImageWidth; i++)
{
*pDataBuffer++= workbuffer[i];
*pDataBuffer++= workbuffer[i];
*pDataBuffer++= workbuffer[i];
}
*BufferSize += bytesReadfile * 3;
CurrentLine +=1 ;
CurrentBlockLine += 1;
}
}
2020-06-16 03:00 PM
That's seems to work
Thanks!