Using Libpng library to display PNG images on Tiny6410

Publisher:快乐飞翔Latest update time:2024-09-20 Source: cnblogs Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Linux kernel version number: linux 2.6.39


Cross-compilation tool: arm-linux-gcc 4.5.1


Development board: Friendly Arm Tiny6410


LCD: Friendly Arm S70


Libpng version: libpng-1.5.14


Zlib version: zlib-1.2.8


1. Cross-compile Zlib


Zlib is a file compression library. Its header files and libraries are needed when cross-compiling Libpng, so compile it first. zlib-1.2.8.tar.gz Download path: http://pan.baidu.com/s/1miKXynY


1. Download and unzip zlib-1.2.8.tar.gz


tar xzvf zlib-1.2.8.tar.gz

2. Create a new tmp directory under the zlib-1.2.8 directory to save the lib and include files generated after cross compilation


mkdir tmp

3. Open the Makefile file and modify CC=arm-linux-gcc


4. Execute the configuration command to specify the storage path of the generated file


./configure --prefix=$PWD/tmp

5. Execute make


6. Execute make install and check whether include, lib and other directories are generated in the tmp directory


2. Cross-compile Libpng


libpng-1.5.14.tar.gz Download path: http://pan.baidu.com/s/1qYgnIyC


1. Download and unzip libpng-1.5.14.tar.gz


tar xzvf libpng-1.5.14.tar.gz

2. Also create a tmp directory in the libpng-1.5.14 directory to save the lib and include files generated after cross compilation


mkdir tmp

3. Execute the configuration command to specify the generated file storage path and Zlib library file directory


./configure --prefix=/home/ming/windowssshar/libpng-1.5.14/tmp --host=arm-linux LIBS=-L/home/ming/windowsshar/zlib-1.2.8/tmp/lib CPPFLAGS=-I/home/ming/windowsshar/zlib-1.2.8/tmp/include

4. Execute make


5. Execute make install and check whether include, lib and other directories are generated in the tmp directory


3. Decode pictures using Libpng


int read_png(char* filename, char IsDoAlphaBlend)

{

FILE *fp;

png_structp png_ptr;

png_infop info_ptr;

png_uint_32 width, height;

png_uint_32 row;

int bit_depth, color_type, interlace_type, number_passes;

int pass,y;

char* cpPngDispAddr = NULL;

char* RGB_Data = NULL;

unsigned int x = 0;

unsigned int pos = 0;

unsigned int i = 0;

int iXres = 0, iYres = 0;


if ((fp = fopen(filename, "rb")) == NULL)

{

DEBUG_Print("open %s failedn",filename);

return 0;

}


/* Create and initialize the png_struct with the desired error handler

* functions.  If you want to use the default stderr and longjump method,

* you can supply NULL for the last three parameters.  We also supply the

* the compiler header file version, so that we know if the application

* was compiled with a compatible version of the library.  REQUIRED

*/

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,

NULL, NULL, NULL);


if (png_ptr == NULL)

{

fclose(fp);

return (FALSE);

}


/* Allocate/initialize the memory for image information.  REQUIRED. */

info_ptr = png_create_info_struct(png_ptr);

if (info_ptr == NULL)

{

fclose(fp);

png_destroy_read_struct(&png_ptr, NULL, NULL);

return (FALSE);

}



/* One of the following I/O initialization methods is REQUIRED */

/* Set up the input control if you are using standard C streams */

png_init_io(png_ptr, fp);


/* Get video memory address */

cpPngDispAddr = GetDispVedioMemAddr();

GetDispResolution(&iXres,&iYres);


/* OK, you're doing it the hard way, with the lower-level functions */


/* The call to png_read_info() gives us all of the information from the

* PNG file before the first IDAT (image data chunk).  REQUIRED

*/

png_read_info(png_ptr, info_ptr);


png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,

&interlace_type, NULL, NULL);

DEBUG_Print("width          ---- > [%4d]n",width);

DEBUG_Print("height         ---- > [%4d]n",height);

DEBUG_Print("bit_depth      ---- > [%4d]n",bit_depth);

DEBUG_Print("color_type     ---- > [%4d]n",color_type);

DEBUG_Print("interlace_type ---- > [%4d]n",interlace_type);


/* Turn on interlace handling.  REQUIRED if you are not using

* png_read_image().  To see how to handle interlacing passes,

* see the png_read_row() method below:

*/

number_passes = png_set_interlace_handling(png_ptr);


DEBUG_Print("number_passes  ---- > [%4d]n",number_passes);


/* The easiest way to read the image: */

png_bytep row_pointers[height];


/* Clear the pointer array */

for (row = 0; row < height; row++)

row_pointers[row] = NULL;


for (row = 0; row < height; row++)

row_pointers[row] = malloc(width * 4);  /* RGBA */

for (row = 0; row < height; row++)

memset(row_pointers[row], 0, width * 4);


/* Allocate RGB memory space */

RGB_Data = (char*)malloc(width * 3);

memset(RGB_Data, 0, width * 3);

DEBUG_Print("1 RGB_Data -- > [0x%x]n",RGB_Data);


/* Now it's time to read the image.  One of these methods is REQUIRED */

/* Read the image one or more scanlines at a time */

/* The other way to read images - deal with interlacing: */


if(width > iXres)      width = iXres;

if(height > iYres)   height = iYres;


for (pass = 0; pass < number_passes; pass++)

{

/* Read and display line by line*/

for (y = 0; y < height; y++)

{

png_read_rows(png_ptr, &row_pointers[y], NULL, 1);

WriteOneLineToMem(cpPngDispAddr, (iXres - width)/2, (iXres - width)/2 + width, (iYres - height)/2 + y, &row_pointers[y][0], IsDoAlphaBlend);

}

}


/* Read rest of file, and get additional chunks in info_ptr - REQUIRED */

png_read_end(png_ptr, info_ptr);


/* At this point you have read the entire image */


/* Clean up after the read, and free any memory allocated - REQUIRED */

png_destroy_read_struct(&png_ptr, &info_ptr, NULL);


/* Release memory uniformly*/

for (row = 0; row < height; row++)

{

free(row_pointers[row]);

}

free(RGB_Data);


/* Close the file */

fclose(fp);


/* That's it */

return (TRUE);

}


This code is basically ported from the example file in Libpng, and there is a detailed explanation in libpng_manual.txt.


4. Display on the display


1. Alpha Blending


In order to make the PNG image display transparent, you need to perform AlphaBlend on the foreground and background colors.


Simple AlphaBlend algorithm: Assume that the foreground color (PNG image to be displayed) RGBA is r1 g1 b1 alpha and the background color RGB is r2 g2 b2. The mixed RGB is rgb


r = r1 x alpha/255.0 + r2 x (255 - alpha)/255.0


g = g1 x alpha/255.0 + g2 x (255 - alpha)/255.0


b = b1 x alpha/255.0 + b2 x (255 - alpha)/255.0


static unsigned int AlphaBlend(PT_PNG_INFO PngRGBA, PT_PNG_INFO PngBkRGB, char IsDoAlphaBlend)

{

unsigned char r = 0, g = 0, b = 0;


r = (unsigned char)(PngRGBA->R * (PngRGBA->A / 255.0) + (PngBkRGB->R * (255 - PngRGBA->A)) / 255.0);

g = (unsigned char)(PngRGBA->G * (PngRGBA->A / 255.0) + (PngBkRGB->G * (255 - PngRGBA->A)) / 255.0);

b = (unsigned char)(PngRGBA->B * (PngRGBA->A / 255.0) + (PngBkRGB->B * (255 - PngRGBA->A)) / 255.0);

return ((r << 16) | (g << 8) | (b));

}


PngRGBA is the foreground color RGBA data structure, PngBKRGB is the background color RGB data structure, and the return value is the mixed RGB value.


2. Display pictures on LCD


static void WriteOneLineToMem(char* ptVedioMem, int iXStart, int iXEnd, int iY, unsigned char* ucpDispBuff, char IsDoAlphaBlend)

{

int iX = 0, iPoint = 0;

unsigned int udwData = 0;

int iXres, iYres;

unsigned int location;

T_PNG_INFO tPngRGBA = {0};

T_PNG_INFO tPngBkRGB = {0};

GetDispResolution(&iXres,&iYres);


if(iXEnd > iXres)    return -1;

if(iY > iYres) return -1;

for(iX = iXStart; iX < iXEnd; iX++)

{

location = iX * 4 + iY * iXres* 4;


/* Get foreground color RGBA */

tPngRGBA.R = ucpDispBuff[iPoint + 0];

tPngRGBA.G = ucpDispBuff[iPoint + 1];

tPngRGBA.B = ucpDispBuff[iPoint + 2];

tPngRGBA.A = ucpDispBuff[iPoint + 3];

/* Get the background color RGB */

udwData = *((unsigned int*)(ptVedioMem + location));

tPngBkRGB.R = (udwData >> 16) & 0xFF;

tPngBkRGB.G = (udwData >> 8)  & 0xFF;

tPngBkRGB.B = udwData         & 0xFF;

udwData = AlphaBlend(&tPngRGBA, &tPngBkRGB, IsDoAlphaBlend);


*((unsigned int*)(ptVedioMem + location)) = udwData;


iPoint += 4;  /* RGBA */

}

return 0;

}


Prepare two pictures:

Background Image

Foreground image


The effect after display:

Complete code: http://pan.baidu.com/s/1boD7ZSr


Reference address:Using Libpng library to display PNG images on Tiny6410

Previous article:S3C6410 bare metal - external interrupt program
Next article:A segmentation fault occurs when the application calls tslib

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号