一、交叉编译libjpeg
# tar -xzvf libjpeg-turbo-1.2.1.tar.gz

#cd libjpeg-turbo-1.2.1

#mkdir tmp

# ./configure --prefix=$PWD/tmp --host=arm-linux
#make
#make install                /* 会安装在当前目录下面tmp目录里面 */

二、交叉编译jpg2rgb.c
方法一:编译器后面直接跟上头文件,库文件。路径是我们开始编译出来的路径。
arm-linux-gcc -o jpg2rgb jpg2rgb.c -I /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/include  -L /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/lib  -ljpeg
cp jpg2rgb /work/nfs_root/fs_mini_mdev_new
cp libjpeg-turbo-1.2.1/tmp/lib/*so* /work/nfs_root/fs_mini_mdev_new/lib/ -d

方法二:把库文件,头文件放在交叉编译里面库文件,头文件的路径下面。
把编译出来的头文件应该放入:/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include

cd  /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/include

cp  *   /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include

把编译出来的库文件应该放入:/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib

cd  /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/lib
cp *so*  -d   /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib

cp *so* /work/nfs_root/      /* 把库文件复制到开发板lib目录下,我们用的是动态库所以需要拷贝 */

arm-linux-gcc -o jpg2rgb jpg2rgb.c -ljpeg      /* 要指定jpeg库,数学库则指定m */

jpg2rgb.c文件如下:

#include <stdio.h>
#include "jpeglib.h"
#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <string.h>
#include <stdlib.h>

#define FB_DEVICE_NAME "/dev/fb0"   /* 指定lcd驱动自动创建的设别节点名 */
#define DBG_PRINTF  printf                /* 方便调试打印 */

static int g_fd;
static struct fb_var_screeninfo g_tFBVar;    /* lcd相关的参数,在这篇文章中重点是libjpeg */
static struct fb_fix_screeninfo g_tFBFix;
static unsigned char *g_pucFBMem;
static unsigned int g_dwScreenSize;

static unsigned int g_dwLineWidth;
static unsigned int g_dwPixelWidth;

static int FBDeviceInit(void)
{
int ret;

g_fd = open(FB_DEVICE_NAME, O_RDWR);
if (0 > g_fd)
{
DBG_PRINTF("can't open %s\n", FB_DEVICE_NAME);
}

ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar);
if (ret < 0)
{
DBG_PRINTF("can't get fb's var\n");
return -1;
}

ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix);
if (ret < 0)
{
DBG_PRINTF("can't get fb's fix\n");
return -1;
}

g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8;
g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);
if (0 > g_pucFBMem)
{
DBG_PRINTF("can't mmap\n");
return -1;
}

g_dwLineWidth  = g_tFBVar.xres * g_tFBVar.bits_per_pixel / 8;
g_dwPixelWidth = g_tFBVar.bits_per_pixel / 8;

return 0;
}

static int FBShowPixel(int iX, int iY, unsigned int dwColor)
{
unsigned char *pucFB;
unsigned short *pwFB16bpp;
unsigned int *pdwFB32bpp;
unsigned short wColor16bpp; /* 565 */
int iRed;
int iGreen;
int iBlue;

if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres))
{
DBG_PRINTF("out of region\n");
return -1;
}

pucFB      = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX;
pwFB16bpp  = (unsigned short *)pucFB;
pdwFB32bpp = (unsigned int *)pucFB;

switch (g_tFBVar.bits_per_pixel)
{
case 8:
{
*pucFB = (unsigned char)dwColor;
break;
}
case 16:
{
iRed   = (dwColor >> (16+3)) & 0x1f;
iGreen = (dwColor >> (8+2)) & 0x3f;
iBlue  = (dwColor >> 3) & 0x1f;
wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
*pwFB16bpp = wColor16bpp;
break;
}
case 32:
{
*pdwFB32bpp = dwColor;
break;
}
default :
{
DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);
return -1;
}
}

return 0;
}

static int FBCleanScreen(unsigned int dwBackColor)
{
unsigned char *pucFB;
unsigned short *pwFB16bpp;
unsigned int *pdwFB32bpp;
unsigned short wColor16bpp; /* 565 */
int iRed;
int iGreen;
int iBlue;
int i = 0;
pucFB      = g_pucFBMem;
pwFB16bpp  = (unsigned short *)pucFB;
pdwFB32bpp = (unsigned int *)pucFB;

switch (g_tFBVar.bits_per_pixel)
{
case 8:
{
memset(g_pucFBMem, dwBackColor, g_dwScreenSize);
break;
}
case 16:
{
iRed   = (dwBackColor >> (16+3)) & 0x1f;
iGreen = (dwBackColor >> (8+2)) & 0x3f;
iBlue  = (dwBackColor >> 3) & 0x1f;
wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
while (i < g_dwScreenSize)
{
*pwFB16bpp = wColor16bpp;
pwFB16bpp++;
i += 2;
}
break;
}
case 32:
{
while (i < g_dwScreenSize)
{
*pdwFB32bpp = dwBackColor;
pdwFB32bpp++;
i += 4;
}
break;
}
default :
{
DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);
return -1;
}
}

return 0;
}

static int FBShowLine(int iXStart, int iXEnd, int iY, unsigned char *pucRGBArray)
{
int i = iXStart * 3;
int iX;
unsigned int dwColor;

if (iY >= g_tFBVar.yres)
return -1;

if (iXStart >= g_tFBVar.xres)
return -1;

if (iXEnd >= g_tFBVar.xres)
{
iXEnd = g_tFBVar.xres;
}

for (iX = iXStart; iX < iXEnd; iX++)
{
/* 0xRRGGBB */
dwColor = (pucRGBArray[i]<<16) + (pucRGBArray[i+1]<<8) + (pucRGBArray[i+2]<<0);
i += 3;
FBShowPixel(iX, iY, dwColor);
}
return 0;
}

/* 下面才是本文的重点 */
/*
Allocate and initialize a JPEG decompression object    // 分配和初始化一个decompression结构体
Specify the source of the compressed data (eg, a file) // 指定源文件
Call jpeg_read_header() to obtain image info   // 用jpeg_read_header获得jpg信息
Set parameters for decompression   // 设置解压参数,比如放大、缩小
jpeg_start_decompress(...);   // 启动解压:jpeg_start_decompress
while (scan lines remain to be read)
jpeg_read_scanlines(...);   // 循环调用jpeg_read_scanlines
jpeg_finish_decompress(...);   // jpeg_finish_decompress
Release the JPEG decompression object   // 释放decompression结构体
*/

/* Uage: jpg2rgb <jpg_file>
 */

int main(int argc, char **argv)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * infile;
int row_stride;
unsigned char *buffer;

if (argc != 2)
{
printf("Usage: \n");
printf("%s <jpg_file>\n", argv[0]);
return -1;
}

if (FBDeviceInit())     /* 初始化Lcd */
{
return -1;
}

FBCleanScreen(0);      /* 清屏lcd */

// 分配和初始化一个decompression结构体
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);

// 指定源文件
if ((infile = fopen(argv[1], "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", argv[1]);
return -1;
}
jpeg_stdio_src(&cinfo, infile);

// 用jpeg_read_header获得jpg信息
jpeg_read_header(&cinfo, TRUE);
/* 源信息 */
printf("image_width = %d\n", cinfo.image_width);
printf("image_height = %d\n", cinfo.image_height);
printf("num_components = %d\n", cinfo.num_components);

// 设置解压参数,比如放大、缩小
printf("enter scale M/N:\n");
scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);
printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom);

// 启动解压:jpeg_start_decompress
jpeg_start_decompress(&cinfo);

/* 输出的图象的信息 */
printf("output_width = %d\n", cinfo.output_width);
printf("output_height = %d\n", cinfo.output_height);
printf("output_components = %d\n", cinfo.output_components);

// 一行的数据长度
row_stride = cinfo.output_width * cinfo.output_components;
buffer = malloc(row_stride);

// 循环调用jpeg_read_scanlines来一行一行地获得解压的数据
while (cinfo.output_scanline < cinfo.output_height) 
{
(void) jpeg_read_scanlines(&cinfo, &buffer, 1);

// 写到LCD去
FBShowLine(0, cinfo.output_width, cinfo.output_scanline, buffer);
}

free(buffer);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);

return 0;
}

上文中红色以下的才是本文的重点,lcd驱动才以前驱动部分已经讲得很明白了。

libjpeg编译使用详解相关推荐

  1. java 静态 编译_Java中的动态和静态编译实例详解

    Java中的动态和静态编译实例详解 首先,我们来说说动态和静态编译的问题. Q: java和javascript有什么区别? 总结了一下:有以下几点吧: 1.首先从运行环境来说java代码是在JVM上 ...

  2. java 编译 忽略错误_Maven在Java8下如何忽略Javadoc的编译错误详解

    javaDoc简介And基础知识 (一) Java注释类型 //用于单行注释. /*...*/用于多行注释,从/*开始,到*/结束,不能嵌套. /**...*/则是为支持jdk工具javadoc.ex ...

  3. java编译器源码详解_已更新至第8章 | LLVM 编译框架详解

    LLVM是什么? 我又不做编译器研究,干嘛要管它? 这是一些朋友想要对LLVM发起的提问,那么今天我们就来看看那款据说很酷炫的编译器--LLVM. LLVM是什么? LLVM是一个自由软件项目,它是一 ...

  4. Android编译过程详解(三)

    Android编译过程详解(一):http://www.cnblogs.com/mr-raptor/archive/2012/06/07/2540359.html Android编译过程详解(二):h ...

  5. 非常好的Linux编译内核详解 - -

    转载: http://blog.chinaunix.net/uid-263488-id-2138150.html 非常好的Linux编译内核详解 - - 一.内核简介  内核,是一个操作系统的核心.它 ...

  6. Linux卸载安装bind,Bind编译安装详解

    Bind编译安装详解 Bind是一款开放源码的DNS服务器软件,由美国加州大学Berkeley分校开发和维护的,全名为Berkeley Internet Name Domain它是目前世界上使用最为广 ...

  7. c语言的编译过程详解

    c语言的编译过程详解 IDE的使用让很多和我一样的人对C/C++可执行程序的底层生成一知半解,不利于我们深入理解原理.在这里小结一下,望路过的大神指正~ 前言:从一个源文件(.c文件)到可执行程序到底 ...

  8. U-Boot 之四 构建过程(Kconfig 配置 + Kbuild 编译)详解

      在之前的博文 Linux 之八 完整嵌入式 Linux 环境介绍及搭建过程详解 中我们说了要一步步搭建整个嵌入式 Linux 运行环境,今天继续介绍 U-Boot 相关的内容.我所使用的硬件平台及 ...

  9. MySQL5.6二进制软件包编译安装详解(三)

    一.软件环境 [root@localhost ~]# uname -r 3.10.0-862.el7.x86_64 [root@localhost ~]# cat /etc/redhat-releas ...

最新文章

  1. 计算机网络实验报告嗅探器,计算机网络实验(Wireshark)
  2. Geometry-enhanced molecular representation learning for property prediction|GeoGNN|将几何增强分子表示用于分子性质预测
  3. 跨境电商面临“寒冬”考验,如何转型升级入局新赛道(Starday)
  4. 【Python】程序员也可以很会撩:如何一键生成漂亮的生日快乐词云
  5. Android天气预报+百度天气接口
  6. linux ip route 命令详细解释
  7. 了解如何定义定义变量和调用函数
  8. 三天一题-20- Integer to Roman(Integer转成古罗马数字)
  9. 【历史上的今天】3 月 6 日:Unix 版权争夺战;豆瓣网上线;谷歌推出了 Google Play
  10. 01串状态压缩(位运算)
  11. 毕业设计第8周学习记录
  12. 关于TDOA算法的仿真及比较
  13. 新的JAVA基础第一天---数据类型等
  14. Edgecam2021数控车床编程加工视频教程
  15. Excel todolist制作
  16. 前端分页功能(封装好的组件)
  17. USB协议[转]__总结得很好
  18. 新思路全国计算机等级考试系列软件,新思路全国计算机等级考试系列软件——二级Visual FoxPro Uninstall Log...
  19. 蚂蚁金服@玉伯:我的前端成长之路
  20. 关于智能代还卡系统、聚合支付系统拙见

热门文章

  1. MobPush精准把握用户的使用时间
  2. Hadoop centos 6.5 配置
  3. window.external.JavaScriptCallCpp
  4. AngularJS 学习笔记 - $http.post 跟后台交互
  5. 一个关于js所有函数都报错的问题
  6. 使用java.util.zip对字符串进行压缩和解压缩
  7. 利用XML实现通用WEB报表打印(转载)
  8. 员工张三有两个主管线程_如何做好中层?想让领导满意、员工信服、自己轻松,这2技能必备...
  9. 关于引用与指针实现多态的一些记录
  10. 【转】Android studio安装与配置