STM32完全学习——使用LIBJPEG库解码图片

news2025/3/12 22:11:56

一、有关配置

这个库的移植可以说是,很简单,直接使用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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2271472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

验证码识别插件 - captcha-killer

验证码识别插件 - captcha-killer 简介 captcha-killer 是一款用于 Burpsuite 的验证码识别插件。它的主要功能是调用各种验证码识别接口&#xff0c;以便在进行渗透测试时能够自动识别和绕过验证码。这个插件本身并不直接进行验证码的识别&#xff0c;而是通过调用外部的 OC…

unity团结云下载项目

今天开plastic scm发现它云服务好像停了哈&#xff0c;在hub里下载云端项目也不会出现在项目列表里&#xff0c;之前也有发邮件说让提前迁移到团结云。打开云仓库会弹这个&#xff0c;大概就是plastic scm无法解析域名地址吧 研究了一下团结云咋使&#xff0c;官方手册看半天也…

【VUE】使用create-vue快速创建一个vue + vite +vue-route 等其他查看的工程

create-vue 简介 GitHub:https://github.com/vuejs/create-vue 创建的选项有多个,具体的可以看下方截图,当创建完成的时候可以发现工程中是自带vite的。 下面对其中的各种内容进行简单的说明 JSX (可以选择,但是我感觉没什么必要) 全称:JavaScript XML 允许你在 Java…

RIP配置实验

RIP配置实验 案例简介 天一公司下属三个分公司&#xff0c;属于不同的地区&#xff0c;三个公司之间用路由器连接&#xff0c;路由器名称分别为分别为 Router0、Router1、Router2&#xff0c;请把一公司的部门pc0,通过二公司路由器&#xff0c;连接三公司的部门pc1,公司之间通…

video.js视频播放上手

html案例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>videojs视频播放</title> </head> <link href"https://cdnjs.cloudflare.com/ajax/libs/video.js/7.3.0/video-js.min.cs…

Introducing Optimization

Chapter6&#xff1a;Introducing Optimization 声明&#xff1a;本篇博客笔记来源于《Neural Networks from scratch in Python》&#xff0c;作者的youtube 其实关于神经网络的入门博主已经写过几篇了&#xff0c;这里就不再赘述&#xff0c;附上链接。 1.一文窥见神经网络 2…

解决Git中没有小绿勾与红叉叉的问题

一、检查自己的软件 必须安装Git和Tortoisegit&#xff08;也就是俗称的小乌龟&#xff09;这两个软件。 Git的下载地址&#xff1a; CNPM Binaries Mirrorhttps://registry.npmmirror.com/binary.html?pathgit-for-windows/ 寻找与自己电脑相配的软件版本就可以了。 Tor…

向量数据库技术

前言 这里有一些狗&#xff0c;熟悉犬类的朋友应该能很快区分出它们的品种&#xff0c;我们之所以能做到这一点&#xff0c;是因为我们会从不同的角度来观察它们的特征。 比如体型的大小&#xff0c;如果我们使用一个坐标轴来表示这个特征&#xff0c;这些狗将落在不同的坐标点…

算法攻略:顺序表的进阶之路——移除元素

题目如下&#xff1a; 思路&#xff1a; 双指针法 nums[src] val&#xff0c;srcnums[src] ! val&#xff0c;src的值赋值给dst&#xff0c;src和dst都 注&#xff1a; 1&#xff09;双指针法&#xff1a;只是抽象出了两个指向数组的变量&#xff0c;并不是真的指针。 2&#…

docker Error response from daemon

问题 Error response from daemon: Get "https://index.docker.io/v1/search?qnginx&n25": read tcp 192.168.50.233:54354->54.198.86.24:443: read: connection reset by peer Unable to find image redis:latest locally docker: Error response from d…

【HTML】Day02

【HTML】Day02 1. 列表标签1.1 无序列表1.2 有序列表1.3 定义列表 2. 表格标签2.1 合并单元格 3. 表单标签3.1 input标签基本使用3.2 上传多个文件 4. 下拉菜单、文本域5. label标签6. 按钮button7. div与span、字符实体字符实体 1. 列表标签 作用&#xff1a;布局内容排列整齐…

iOS 11 中的 HEIF 图像格式 - 您需要了解的内容

HEIF&#xff0c;也称为高效图像格式&#xff0c;是iOS 11 之后发布的新图像格式&#xff0c;以能够在不压缩图像质量的情况下以较小尺寸保存照片而闻名。换句话说&#xff0c;HEIF 图像格式可以具有相同或更好的照片质量&#xff0c;同时比 JPEG、PNG、GIF、TIFF 占用更少的设…

【MATLAB APP Designer】小波阈值去噪(第一期)

代码原理及流程 小波阈值去噪是一种信号处理方法&#xff0c;用于从信号中去除噪声。这种方法基于小波变换&#xff0c;它通过将信号分解到不同的尺度和频率上来实现。其基本原理可以分为以下几个步骤&#xff1a; &#xff08;1&#xff09;小波变换&#xff1a;首先对含噪信…

NCCL源码解读3.1:double binary tree双二叉树构建算法,相比ring环算法的优势

目录 一、双二叉树出现的原因 二、双二叉树介绍 三、双二叉树大规模性能 四、双二叉树源码解读 双二叉树注意事项 核心逻辑 源码速递 视频分享在这&#xff0c;未完待补充&#xff1a; 3.1 NCCL源码解读双二叉树构建算法&#xff0c;double binary tree相比ring环算法的…

Linux部署web项目【保姆级别详解,Ubuntu,mysql8.0,tomcat9,jdk8 附有图文】

文章目录 部署项目一.安装jdk1.1 官网下载jdk81.2 上传到Linux1.3 解压1.4 配置环境变量1.5 查看是jdk是否安装成功 二.安装TomCat2.1 官网下载2.2 上传到Linux2.3 解压2.4配置2.5 启动Tomcat2.6 验证是否成功 三.安装mysql四.部署javaweb项目4.1 打包4.2 启动tomcat 部署项目 …

unity中的UI系统---GUI

一、工作原理和主要作用 1.GUI是什么&#xff1f; 即即时模式游戏用户交互界面&#xff08;IMGUI&#xff09;&#xff0c;在unity中一般简称为GUI&#xff0c;它是一个代码驱动的UI系统。 2.GUI的主要作用 2.1作为程序员的调试工具&#xff0c;创建游戏内调测试工具 2.2为…

MySQL 【多表查询】

一 . 概述 多表关系&#xff1a; 一对多(多对一) &#xff0c; 多对多 &#xff0c;一对一 1&#xff09; 一对一 案例: 用户 与 用户详情的关系 关系: 一对一关系&#xff0c;多用于单表拆分&#xff0c;将一张表的基础字段放在一张表中&#xff0c;其他详情字段放在另 一张表…

【大模型】ChatGPT 数据分析与处理使用详解

目录 一、前言 二、AI 大模型数据分析介绍 2.1 什么是AI数据分析 2.2 AI数据分析与传统数据分析对比 2.2.1 差异分析 2.2.2 优劣势对比 2.3 AI大模型工具数据分析应用场景 三、AI大模型工具数据分析操作实践 3.1 ChatGPT 常用数据分析技巧操作演示 3.1.1 快速生成数据…

【面试系列】深入浅出 Spring Boot

熟悉SpringBoot&#xff0c;对常用注解、自动装配原理、Jar启动流程、自定义Starter有一定的理解&#xff1b; 面试题 Spring Boot 的核心注解是哪个&#xff1f;它主要由哪几个注解组成的&#xff1f;Spring Boot的自动配置原理是什么&#xff1f;你如何理解 Spring Boot 配置…