[FrameBuffer驱动]利用Libjpeg库通过C语言向tiny4412开发板刷一幅jpg图片



网上那么多类似的文章了,为什么还要写这篇文章?

答:上一代人的努力,正是为了下一代人不用重复自己的苦难。

原句出自知乎(见下图)



到官网http://www.ijg.org/下载最新版的库

Independent JPEG Group

IJG is an informal group that writes and distributes a widely used free library for JPEG image compression. The first version was released on 7-Oct-1991.

The current version is release 9b of 17-Jan-2016. This is a stable and solid foundation for many application's JPEG support.

You can find our original code and some supporting documentation in the directory files. There is a Windows format package in zip archive format jpegsr9b.zip and a Unix format package in tar.gz archive format jpegsrc.v9b.tar.gz. A collection of modified versions with adaptions and error fixes for system maintenance is available on jpegclub.org in the directory support.

To learn more about how to use JPEG, see the JPEG FAQ. If you'd like to learn about how JPEG works, start with the comp.compression FAQ.

The ISO/IEC JTC1/SC29/WG1 standards committee (previously known as JPEG, together with ITU-T SG16) had their own web site. IJG was not affiliated with the ISO committee.

IJG development continues. Advanced features are being prepared for coming releases...

The development site for new versions is at InfAI.org.


阅读官方首页可知jpegsrc.v9b.tar.gz是我们要的。

把库文件复制到你的Linux(如果直接从Linux系统下载的,跳过),解压库文件,得到一个jpeg-9b的文件夹,进入此文件夹


运行

./configure --prefix=/usr/local/lib --host=arm-linux CC=arm-linux-gcc LD=arm-linux-ld --enable-shared --enable-static


注意:/usr/local/lib 是你的库安装路径,可以根据自己的情况自行建设,例如在家目录下安装,我们可以在加目录下mkdir exp创建一个exp文件夹,假设你的Linux用户名是google 那你的路径就是 /home/google/exp

在上面命令中用你的自定义路径 /home/google/exp 替换 /usr/local/lib (怎么没听课应该也能看懂了吧^_^o~ 努力!)

如果提示configure没有权限,可以chmod 777 configure给予权限

成功的话如上图所示

接着

运行

make


成功的话如上图所示


接着

运行

make install


成功的话如上图所示


查看一下exp下生成的文件


include文件夹下面是我们编译需要的头文件


lib文件夹下面是我们编译好的库文件


交叉编译:


如果不想把include下的头文件拷到系统头文件所放的地方


那就把测试程序和include下的头文件放在同一个文件夹下,我这里直接把测试程序放在include文件里面

接着

执行(test.c 源码下文会贴出)

arm-linux-gcc test.c -o test -l:libjpeg.so.8 -L/home/google/exp/lib

注意:

-ljpeg 编译器会链接libjpeg6的库

-l:libjpeg.so.8 //这是指定8的库

同理

-l:libjpeg.so.9 //就是指定9的库


-L/home/google/exp/lib
这个指定库路径,如上面所说,根据自己的情况修改


成功的话如上图所示


把test文件下载到你的开发板,给予执行权限chmod 777 test


如果你用的是8以前的库,直接

运行(这里存入的参数是你的图片文件,根据你开发板剪裁好规格大小,否则会出现段错误)

./test hello.jpg
即可

如果你用的是v9的库,请把exp文件夹下的lib文件夹里面的所有文件打包下载到开发板的/lib/文件夹里面


运行

./test hello.jpg

图片完美显示


---------------------------------------------------------------------------------------------------------------------------------------------------------

下面说测试程序test.c

首先请通读Independent JPEG Group给我们提供的说明书example.c


read_JPEG_file (char * filename)
{
  /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct jpeg_decompress_struct cinfo;
  /* We use our private extension JPEG error handler.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  struct my_error_mgr jerr;
  /* More stuff */
  FILE * infile;		/* source file */
  JSAMPARRAY buffer;		/* Output row buffer */
  int row_stride;		/* physical row width in output buffer */

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */

  if ((infile = fopen(filename, "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
  }

  /* Step 1: allocate and initialize JPEG decompression object */

  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp(jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error.
     * We need to clean up the JPEG object, close the input file, and return.
     */
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    return 0;
  }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src(&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header(&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.txt for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  (void) jpeg_start_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */ 
  /* JSAMPLEs per row in output buffer */
  row_stride = cinfo.output_width * cinfo.output_components;
  /* Make a one-row-high sample array that will go away when done with image */
  buffer = (*cinfo.mem->alloc_sarray)
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height) {
    /* jpeg_read_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could ask for
     * more than one scanline at a time if that's more convenient.
     */
    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
    /* Assume put_scanline_someplace wants a pointer and sample count. */
    put_scanline_someplace(buffer[0], row_stride);
  }

  /* Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress(&cinfo);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose(infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
   */

  /* And we're done! */
  return 1;
}
重点是上面这里

test.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include "jpeglib.h"
#include "jerror.h"

int main(int argc,char **argv)
{
	int dest_file = 0;
	unsigned char *buffer = NULL;
	unsigned long *lcd_buf = NULL;
	int row_stride = 0;
	 /* This struct contains the JPEG decompression parameters and pointers to
   * working space (which is allocated as needed by the JPEG library).
   */
  struct jpeg_decompress_struct cinfo;
  /* We use our private extension JPEG error handler.
   * Note that this struct must live as long as the main JPEG parameter
   * struct, to avoid dangling-pointer problems.
   */
  struct my_error_mgr jerr;
  /* More stuff */
  FILE * infile;		/* source file */
  JSAMPARRAY buffer;		/* Output row buffer */
  int row_stride;		/* physical row width in output buffer */
  
  /* Step 1: allocate and initialize JPEG decompression object */
  /* We set up the normal JPEG error routines, then override error_exit. */
  cinfo.err = jpeg_std_error(&jerr.pub);
 
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress(&cinfo);

  /* In this example we want to open the input file before doing anything else,
   * so that the setjmp() error recovery below can assume the file is open.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to read binary files.
   */

  if ((infile = fopen(argv[1], "rb")) == NULL) {
    fprintf(stderr, "can't open %s\n", filename);
    return 0;
  }
  	dest_file = open("/dev/fb0",O_RDWR);
	lcd_buf = (unsigned long *)mmap(lcd_buf,800*480*4,PROT_WRITE|PROT_READ,MAP_SHARED,dest_file,0);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src(&cinfo, infile);
  	
  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header(&cinfo, TRUE);
  	
  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  (void) jpeg_start_decompress(&cinfo);
  	
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */ 
  /* JSAMPLEs per row in output buffer */
  row_stride = cinfo.output_width * cinfo.output_components;
  	
  	buffer = (unsigned char *)malloc(row_stride);
	  /* Step 6: while (scan lines remain to be read) */
      /* jpeg_read_scanlines(...); */
  	int i = 0;
  	while(cinfo.output_scanline < cinfo.output_height)
  	{
  		int j,y ;
  		(void) jpeg_read_scanlines(&cinfo, &buffer, 1);
		for(j=0,y=0;j<800*3;j+=3,y++)
			*(lcd_buf+i*800+y) = buffer[j]|buffer[j+1]<<8|buffer[j+2]<<16;
		i++;
  	}
  	
   /* Step 7: Finish decompression */

  (void) jpeg_finish_decompress(&cinfo);
  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress(&cinfo);

  	
  	fclose(infile);
  	close(dest_file);
	munmap(lcd_buf,800*480*4);
  	 	
	return 0;
}
  /* And we're done! */

转载请著名出处并附带原链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值