AllenYao 发表于 2006-11-20 15:26:50

参考EGui中的Demo程序显示JPG图像

对于JPG图像,好像是有专利问题……我并没有找到JPG图像格式详细说明。于是,参考EGui中的Demo程序,调用libjpeg.a库函数,在Framebuffer中显示JPG图像。

在编译libjpeg.a时出了点错,“ar rc rc”多了一个“rc”!在成功编译后,把libjpeg.a及所有的.h文件都拷贝到程序目录中,就可以使用了。

showjpeg.c

/******************************************************************************
* showjpeg.c - 调用库函数对JPG文件进行解码, 并在framebuffer中显示出来
*
* Author : allen
* Email: [email protected]
* Date   : 2006/11/20
******************************************************************************/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

char *fbp = 0;
int xres = 0;
int yres = 0;
int bits_per_pixel = 0;

extern unsigned char * decode_jpeg(char *filename, short *widthPtr, short *heightPtr);

intshow_jpg(char *bmpfile);
/******************************************************************************
*
******************************************************************************/
int main( int argc, char *argv[] )
{
    int fbfd = 0;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;

    if (argc != 2)
    {
            printf("usage: %s filename\n", argv[0]);
            return 0;
    }
    // Open the file for reading and writing
    fbfd = open("/dev/fb0", O_RDWR);
    if (!fbfd)
    {
      printf("Error: cannot open framebuffer device.\n");
      exit(1);
    }

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))
    {
      printf("Error reading fixed information.\n");
      exit(2);
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
    {
      printf("Error reading variable information.\n");
      exit(3);
    }

    printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
    xres = vinfo.xres;
    yres = vinfo.yres;
    bits_per_pixel = vinfo.bits_per_pixel;

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                     fbfd, 0);
    if ((int)fbp == -1)
    {
      printf("Error: failed to map framebuffer device to memory.\n");
      exit(4);
    }

        show_jpg(argv[1]);

    munmap(fbp, screensize);
    close(fbfd);
    return 0;
}

/******************************************************************************
*
******************************************************************************/
int show_jpg(char *filename)
{
        int i, j;
        short int width = 0, height = 0;
        unsigned char *jpeg = NULL;
        long location = 0, pos = 0;

        jpeg = decode_jpeg(filename, &width, &height);
        if (jpeg == NULL)
        {
                return -1;
        }

        /*显示图像信息*/
        for (i=0; i<height; i++)
        {
                for (j=0; j<width; j++)
                {
                        location = i * xres * bits_per_pixel / 8 + j * bits_per_pixel / 8;
                        pos = i * (width * 3) + (j * 3);
                        *(fbp + location + 0) = *(jpeg + pos + 2);
                        *(fbp + location + 1) = *(jpeg + pos + 1);
                        *(fbp + location + 2) = *(jpeg + pos + 0);
                        *(fbp + location + 3) = 0x00;
                }
        }

        free(jpeg);
        return 0;
}

jpeg.c

/*Copyright George Peter Staplin 2003*/

/*You may use/copy/modify/distribute this software for any purpose
*provided that I am given credit and you don't sue me for any bugs.
*/

/*Please contact me using [email protected] if you like this, or
*have questions.
*/
               
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "jpeglib.h"
#include "jerror.h"

#include <time.h>

#ifndef u_char
#define u_char unsigned char
#endif               


void jpeg_error_exit (j_common_ptr cinfo) {
cinfo->err->output_message (cinfo);
exit (EXIT_FAILURE);
}

/*This returns an array for a 24 bit image.*/
u_char *decode_jpeg (char *filename, short *widthPtr, short *heightPtr)
{
register JSAMPARRAY lineBuf;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr err_mgr;
int bytesPerPix;
FILE *inFile;
u_char *retBuf;
       
inFile = fopen (filename, "rb");
if (NULL == inFile)
    {
      printf ("Open file error %s\n",filename);
      return NULL;
    }

cinfo.err = jpeg_std_error (&err_mgr);
err_mgr.error_exit = jpeg_error_exit;       

jpeg_create_decompress (&cinfo);
jpeg_stdio_src (&cinfo, inFile);
jpeg_read_header (&cinfo, 1);
cinfo.do_fancy_upsampling = 0;
cinfo.do_block_smoothing = 0;
jpeg_start_decompress (&cinfo);

*widthPtr = cinfo.output_width;
*heightPtr = cinfo.output_height;
bytesPerPix = cinfo.output_components;

lineBuf = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, (*widthPtr * bytesPerPix), 1);
retBuf = (u_char *) malloc (3 * (*widthPtr * *heightPtr));
               
if (NULL == retBuf)
    {
      perror (NULL);
      return NULL;
    }
               

if (3 == bytesPerPix)
    {
      int x;
      int y;
      int i;
                       
      for (y = 0; y < cinfo.output_height; ++y)
        {       
          jpeg_read_scanlines (&cinfo, lineBuf, 1);
          memcpy ((retBuf + y * *widthPtr * 3),lineBuf[0],3 * *widthPtr);
        }
    } else if (1 == bytesPerPix)
      {
        unsigned int col;
        int lineOffset = (*widthPtr * 3);
        int lineBufIndex;
        int x ;
        int y;
                                               
        for (y = 0; y < cinfo.output_height; ++y)
          {
          jpeg_read_scanlines (&cinfo, lineBuf, 1);
                               
          lineBufIndex = 0;
          for (x = 0; x < lineOffset; ++x) {
              col = lineBuf[0][lineBufIndex];
                       
              retBuf[(lineOffset * y) + x] = col;
              ++x;
              retBuf[(lineOffset * y) + x] = col;
              ++x;
              retBuf[(lineOffset * y) + x] = col;
                               
              ++lineBufIndex;
          }                       
          }
      } else {
        fprintf (stderr, "Error: the number of color channels is %d.This program only handles 1 or 3\n", bytesPerPix);
        return NULL;
      }
jpeg_finish_decompress (&cinfo);
jpeg_destroy_decompress (&cinfo);
fclose (inFile);
                       
return retBuf;
}

Makefile


OBJ= showjpeg.o jpeg.o
TARGET=showjpeg

all: $(TARGET)

$(TARGET): $(OBJ)
        $(CC) $(OBJ) libjpeg.a -o $(TARGET)

.c.o:
        $(CC) -c -o $@ $<

clean:
        rm $(TARGET) -f
        rm *.o -f
        rm *~ -f

页: [1]
查看完整版本: 参考EGui中的Demo程序显示JPG图像