将图片嵌入程序文件的测试

 继前面的文章,本文是一个测试例子,并给出测试结果。

将图片转换成目标文件命令与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)处。
效果图如下:
将图片嵌入程序文件的测试_第1张图片

 

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

你可能感兴趣的:(测试,header,File,buffer,编译器,Components)