STM32全面学习指南:利用LIBJPEG库实现图片解码

一、有关配置

这个库的移植可以说是,很简单,直接使用CubMAX工具就可以帮我们生成移植好的代码,如果你想移植到其他平台,将CubMAX生成的那几个文件拷到你的工程里面就可以了。主要是这个如何使用起来,其实也不难,就是注意好细节接可以了。

 二、编写解码函数


struct my_error_mgr {
  struct jpeg_error_mgr pub;	/* "public" fields */

  jmp_buf setjmp_buffer;	/* for return to caller */
};

typedef struct my_error_mgr * my_error_ptr;
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  my_error_ptr myerr = (my_error_ptr) cinfo->err;
  /* Always display the message. */
  /* We could postpone this until after returning, if we chose. */
  (*cinfo->err->output_message) (cinfo);

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}
int read_JPEG_file (char * filename)
{
	struct jpeg_decompress_struct cinfo;
	
	struct my_error_mgr jerr;
//	
	JFILE fil;		/* target file */  这个其实就是文件系统里面的那个FILE
	
    JSAMPARRAY buffer;	/* pointer to JSAMPLE row[s] */
	int row_stride;		/* physical row width in image buffer */
	
	FRESULT  res;        //文件打开的返回参数
	uint16_t i = 0;
	
	//打开文件
	if ((res = f_open(&fil, filename, FA_READ)) != 0)
	{
		printf("can't open %s, res = %d\n", filename, res);
		return -1;
	}

	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	
	if (setjmp(jerr.setjmp_buffer)) 
	{
		jpeg_destroy_decompress(&cinfo);
		f_close(&fil);
		return -1;
	}
	
	//解码器作必要的内存分配 和数据结构的初始化
	jpeg_create_decompress(&cinfo);
	//将打开的原JPEG图片和我们的解码器相关联
	jpeg_stdio_src(&cinfo, &fil);
	
	(void) jpeg_read_header(&cinfo, TRUE);
	//启动解码器
	(void) jpeg_start_decompress(&cinfo);
	
	row_stride = cinfo.output_width * cinfo.output_components;
	
	buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
	while (cinfo.output_scanline < cinfo.output_height) 
	{
  
        jpeg_read_scanlines(&cinfo, buffer, 1);        //读取解码后的数据 一次读一行
        for(i=0; i<row_stride; i+=3)	//发送整个jpg文件
		{
			while((USART1->SR&0X40)==0);	//循环发送,直到发送完毕   
			USART1->DR = *((buffer[0])+i); 
		}
    }
	
	//解码结束做清理工
	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	f_close(&fil);
	return 0;
}

需要注意的就是,里面的文件打开函数和关闭函数,都是你的文件系统里面提供的函数,也就是说不同的文件系统你这个可能是不一样的,我使用的的FATFS文件管理系统。我这里给你代码不全,其他的没有必要这里给的都是重点,其他的它的源码里面有一个example.c文件里面就是示例代码,我这个也是按照这个改的。

三、注意事项

花了一天吸取的经验教训,如果你发现你的程序无缘无故就死了,一定要注意处理的图片不要太大,我刚开始处理的是480*800的RGB888的一张图片,然后程序就无缘无故的死了,这个受影响的主要是图片的宽和高,最后查找一圈才发现给的图片太大了,内部再申请内存的时候申请不到,就死了。也可以修改堆的大小,还可以使用外部SRAM,将内存分配到外步SRAM中。他这个解码库是会申请内存的,这一点很重要。所以移植的时候这个也要注意。下面的代码时那个工具帮我生成的移植好的代码。还有就是出了问题一定不要先怀疑这个库,先从自己的代码中找问题,还有一点就是栈和堆的内存空间你要从新分配一下;如果你使用的不是这个工具那么你就要在起始文件里面去找。

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
  * File Name          : jdata_conf.c
  * Description        : This file implements LibJPEG file based read/write functions.
  *
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
**/
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

/*FatFS is chosen for File storage*/
#include "jdata_conf.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

size_t read_file (FIL  *file, uint8_t *buf, uint32_t sizeofbuf)
{
static size_t BytesReadfile ;
f_read (file, buf , sizeofbuf, &BytesReadfile);
return BytesReadfile;
}

size_t write_file (FIL  *file, uint8_t *buf, uint32_t sizeofbuf)
{
static size_t BytesWritefile;
f_write (file, buf , sizeofbuf, &BytesWritefile);
return BytesWritefile;
}

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
  * File Name          : jdata_conf.h
  * Description        : This file provides header to "jdata_conf.h" module.
  *                      It implements also file based read/write functions.
  *
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
**/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/

/*FatFS is chosen for File storage*/
#include "ff.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/*This defines the memory allocation methods.*/
#define JMALLOC   malloc
#define JFREE     free

/*This defines the File data manager type.*/
#define JFILE            FIL

size_t read_file (FIL  *file, uint8_t *buf, uint32_t sizeofbuf);
size_t write_file (FIL  *file, uint8_t *buf, uint32_t sizeofbuf) ;

#define JFREAD(file,buf,sizeofbuf)  \
read_file (file,buf,sizeofbuf)

#define JFWRITE(file,buf,sizeofbuf)  \
write_file (file,buf,sizeofbuf)

作者:小A159

物联沃分享整理
物联沃-IOTWORD物联网 » STM32全面学习指南:利用LIBJPEG库实现图片解码

发表回复