继前面的文章,本文是一个测试例子,并给出测试结果。
将图片转换成目标文件命令与x86平台相类似,只需修改几个参数即可。 命令如下:
1
| $ arm-linux-objcopy -I binary -O elf32-littlearm -B arm logo.jpg logo.o
|
需要注意的是输出文件的格式,即-O选项的内容,这里是elf32-littlearm,原来是写elf32-little,但转换得到的目标文件没有机器类型,即便用-B arm指定也不行。
下面是完整的源文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| /**************************************************************** $ 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,会得到
1
| 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得到。为了去除编译器的警告,进行了类型转换。
1 2
| jpeg_buf = (unsigned char *)&_binary_logo_jpg_start; size = (unsigned long)&_binary_logo_jpg_size;
|
3、由于这个程序将会与其它程序合并,因此将图片放到合适的位置,代码:
1
| fb_pixel(x + 45, y + 200, color);
|
即图片起点在(45, 200)处。
效果图如下:

更正:原文后面的“合同”为笔误,已更正为“合并”,发表后约三天发现。