继前面的文章,本文是一个测试例子,并给出测试结果。
将图片转换成目标文件命令与x86平台相类似,只需修改几个参数即可。
命令如下:
$ arm-linux-objcopy -I binary -O elf32-littlearm -B arm logo.jpg logo.o
需要注意的是输出文件的格式,即-O选项的内容,这里是elf32-littlearm,原来是写elf32-little,但转换得到的目标文件没有机器类型,即便用-B arm指定也不行。
下面是完整的源文件:
/****************************************************************
$ arm-linux-objcopy -I binary -O elf32-littlearm -B arm logo.jpg logo.o
$ arm-linux-gcc jpeg_test.c fb_utils.c -o jpeg_test -I/your/jpeg/.h
-L/your/jpeg/lib -ljpeg
$ arm-linux-gcc jpeg_test.c fb_utils.c logo.o
-I/home/latelee/my2440/lib_pic/include -L/home/latelee/my2440/lib_pic/lib
-ljpeg -o jpeg_test
*****************************************************************/
#include <stdio
.h>
#include <stdlib
.h>
#include <string
.h>
#include <jpeglib
.h>
#include <jerror
.h>
#include
"fb_utils.h"
static
int fb_width;
static
int fb_height;
static
int fb_depth;
static
unsigned
char *fb_mem;
// test of pic
extern _binary_logo_jpg_start;
extern _binary_logo_jpg_end;
extern _binary_logo_jpg_size;
/**
* jpeg_init - init jpeg width height, etc.
*
* note:
* Must call fb_init() before this function.
*/
int jpeg_init(
void)
{
if (fb) {
fb_width = fb->width;
fb_height = fb->height;
fb_depth = fb->bytes_per_pixel*
8;
fb_mem = fb->fbmem;
return
0;
}
else {
// printf("init fb first\n");
return -
1;
}
}
/**
* draw_jpeg - Display a jpeg picture from (0, 0) on framebuffer
* @name: picture name(foo.jpg)
*/
int draw_jpeg()
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
unsigned
char *jpeg_buf;
unsigned
long size;
unsigned
char *buffer;
int x, y;
cinfo
.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
// come from logo.o, see detail with $ arm-linux-objdump -ht logo.o
jpeg_buf = (
unsigned
char *)&_binary_logo_jpg_start;
size = (
unsigned
long)&_binary_logo_jpg_size;
// memory
jpeg_mem_src(&cinfo, jpeg_buf, size);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
if ((cinfo
.output_width > fb_width) || (cinfo
.output_height > fb_height)) {
printf(
"too large JPEG file,cannot display\n");
return -
1;
}
buffer = (
unsigned
char *) malloc(cinfo
.output_width * cinfo
.output_components);
//printf("%d %d\n", cinfo.output_width, cinfo.output_components); /*eg, 240 3(rgb888)*/
x = y =
0;
while (cinfo
.output_scanline < cinfo
.output_height) {
jpeg_read_scanlines(&cinfo, &buffer,
1);
if (fb_depth ==
16) {
unsigned
short color;
for (x=
0; x < cinfo
.output_width; x++) {
color = make16color(buffer[x*
3], buffer[x*
3+
1], buffer[x*
3+
2]);
// the pic frome (45, 200)
fb_pixel(x +
45, y +
200, color);
}
}
else
if (fb_depth ==
24) {
// not test
memcpy((
unsigned
char *) fb_mem + y * fb_width *
3,
buffer, cinfo
.output_width * cinfo
.output_components);
}
y++;
// next scanline
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
free(buffer);
return
0;
}
int main(
int argc,
char *argv[])
{
fb_init();
// must call first
jpeg_init();
draw_jpeg();
fb_release();
return
0;
}
说明几点:
1、程序没有显式指定_binary_logo_jpg_start这几个符号的类型,编译器默认是int,如果用-Wall,会得到
warning: type defaults to 'int' in declaration of '_binary_logo_jpg_start'
的警告,如果要去掉警告,就将它们几个声明为int。
2、程序使用jpeg_mem_src函数指定图片在内存的位置及大小,两者从&_binary_logo_jpg_start和&_binary_logo_jpg_size得到。为了去除编译器的警告,进行了类型转换。
jpeg_buf = (unsigned char *)&_binary_logo_jpg_start;
size = (unsigned long)&_binary_logo_jpg_size;
3、由于这个程序将会与其它程序合并,因此将图片放到合适的位置,代码:
fb_pixel(x + 45, y + 200, color);
即图片起点在(45, 200)处。
效果图如下:
更正:原文后面的“合同”为笔误,已更正为“合并”,发表后约三天发现。