The following C code is for painting a PNG file in 24 bit colours = alpha channel on the ((uint32*)0x800000) screen latch (virtual framebuffer.) This uint32 (unsigned integer) is found in devkitarm of http://devkitpro.org libgba, in its header files. You can compile this file with 'gcc -c <file> -o pnglatchoutput -lpng'. As you can see, you need libpng compiled or installed on your box.
The file is taken out of the libpng examples and hacked by --Silverhawk.rogue (talk) 23:56, 7 October 2013 (UTC)
Start of code :
/*
* Copyright (C) silverhawk 2009-2013
*/
/* example.c - an example of using libpng
* Last changed in libpng 1.2.35 [February 14, 2009]
* This file has been placed in the public domain by the authors.
* Maintained 1998-2009 Glenn Randers-Pehrson
* Maintained 1996, 1997 Andreas Dilger)
* Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/
/* This is an example of how to use libpng to read and write PNG files.
* The file libpng.txt is much more verbose then this. If you have not
* read it, do so first. This was designed to be a starting point of an
* implementation. This is not officially part of libpng, is hereby placed
* in the public domain, and therefore does not require a copyright notice.
*
* This file does not currently compile, because it is missing certain
* parts, like allocating memory to hold an image. You will have to
* supply these parts to get it to compile. For an example of a minimal
* working PNG reader/writer, see pngtest.c, included in this distribution;
* see also the programs in the contrib directory.
*/
#include "png.h"
#define RGB(r,g,b) ((unsigned short)(r | (g<<5) | (b<<10)))
int main(int argc, char *argv[])
{
read_png("./link.png");
}
/* The png_jmpbuf() macro, used in error handling, became available in
* libpng version 1.0.6. If you want to be able to run your code with older
* versions of libpng, you must define the macro yourself (but only if it
* is not already defined by libpng!).
*/
#ifndef png_jmpbuf
# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
#endif
/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
* returns zero if the image is a PNG and nonzero if it isn't a PNG.
*
* The function check_if_png() shown here, but not used, returns nonzero (true)
* if the file can be opened and is a PNG, 0 (false) otherwise.
*
* If this call is successful, and you are going to keep the file open,
* you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
* you have created the png_ptr, so that libpng knows your application
* has read that many bytes from the start of the file. Make sure you
* don't call png_set_sig_bytes() with more than 8 bytes read or give it
* an incorrect number of bytes read, or you will either have read too
* many bytes (your fault), or you are telling libpng to read the wrong
* number of magic bytes (also your fault).
*
* Many applications already read the first 2 or 4 bytes from the start
* of the image to determine the file type, so it would be easiest just
* to pass the bytes to png_sig_cmp() or even skip that if you know
* you have a PNG file, and call png_set_sig_bytes().
*/
#define PNG_BYTES_TO_CHECK 4
int check_if_png(char *file_name, FILE **fp)
{
char buf[PNG_BYTES_TO_CHECK];
/* Open the prospective PNG file. */
if ((*fp = fopen(file_name, "rb")) == NULL)
return 0;
/* Read in some of the signature bytes */
if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
return 0;
/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
Return nonzero (true) if they match */
return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
}
/* Read a PNG file. You may want to return an error code if the read
* fails (depending upon the failure). There are two "prototypes" given
* here - one where we are given the filename, and we need to open the
* file, and the other where we are given an open file (possibly with
* some or all of the magic bytes read - see comments above).
*/
void read_png(char *file_name) /* We need to open the file */
{
int counter= 0;
int flag = 0;
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
// png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
FILE *fp;
if ((fp = fopen(file_name, "rb")) == NULL){
fprintf(stdout, "no open !");
return (-1);
}
png_voidp user_error_ptr, user_error_fn, user_warning_fn;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
//png_voidp --tullaris
user_error_ptr,
user_error_fn,
user_warning_fn);
if (png_ptr == NULL)
{
fclose(fp);
fprintf(stdout, "no png ptr !\n");
return (-1);
}
/* Allocate/initialize the memory for image information. REQUIRED. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
fprintf(stdout, "no info ptr !\n");
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return (-1);
}
/* Set error handling if you are using the setjmp/longjmp method (this is
* the normal method of doing things with libpng). REQUIRED unless you
* set up your own error handlers in the png_create_read_struct() earlier.
*/
/* If we have already read some of the signature */
//png_set_sig_bytes(png_ptr, sig_read);
// png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
//png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
png_init_io(png_ptr, fp);
png_read_info(png_ptr, info_ptr);
fprintf(stdout, "w=%d, h=%d\n", info_ptr->width, info_ptr->height);
png_read_update_info(png_ptr, info_ptr);//--tullaris
png_bytep row_pointers[info_ptr->height];
int row = 0;
for (row = 0; row < info_ptr->height; row++) {
fprintf(stdout, "read row\n");
row_pointers[row] = NULL;
}
for (row = 0; row < info_ptr->height; row++)
row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
info_ptr));
//#ifdef entire
png_read_image(png_ptr, row_pointers);
FILE *fp2 = fopen("./out","w");
//fprintf(fp2, "add r0, r0, #300\n");
fprintf(fp2, "[] = {\n");
int col = 0;
for (row = 0; row < info_ptr->height; row++) {
// fprintf(fp2, "add r0, r0, #380\n");//#860 #380
for (col = 0; col < info_ptr->width*3; col+=3) {
/* if ((row_pointers[row][col]/(8*2)
+
row_pointers[row][col+1]/(16*2)
+
row_pointers[row][col+2]/(24*2)) == 0) {
*/
//fprintf(fp2,"mov r1, r8\n");//NOTE r8 contains transparency value
/*FIXME --tullaris */
if (col % 42 == 0)
{
fprintf(fp2, "x += 226;\n");
}
if (RGB(row_pointers[row][col]/8,row_pointers[row][col+1]/8,row_pointers[row][col+2]/8) == 0)
{
//fprintf(fp2, "x++;\n");
counter ++;
flag = 1;
}
else {
if (counter > 1 && flag == 1) {
fprintf(fp2, "x+=%d;\n", counter);
flag = 0;
counter = 0;
} else if (counter > 0 && flag == 1) {
}
fprintf(fp2, "FrontBuffer[x] = %d;\nx++;\n", RGB(row_pointers[row][col]/8,row_pointers[row][col+1]/8,row_pointers[row][col+2]/8));
}
//fprintf(fp2, "*(u16 *)(0x05000000) = c;\n");
/*
if (RGB(row_pointers[row][col]/8,row_pointers[row][col+1]/8,row_pointers[row][col+2]/8) == 0)
{
fprintf(fp2, "x++;\n");
}
else {
fprintf(fp2, "FrontBuffer[x] = %d;\nx++;\n", RGB(row_pointers[row][col]/8,row_pointers[row][col+1]/8,row_pointers[row][col+2]/8));
}
*///fprintf(fp2, "*(u16 *)(0x05000000) = c;\n");
/* fprintf(fp2, "*videobuf++ = %d;\n",
row_pointers[row][col]/(8*2)
+
row_pointers[row][col+1]/(16*2)+64
+
row_pointers[row][col+2]/(24*2)+64
);
*/ // } else {
/* fprintf(fp2,"mov r1, ");
fprintf(fp2,"#%d\n",
row_pointers[row][col]/(8*2)
+
row_pointers[row][col+1]/(16*2)+64
+
row_pointers[row][col+2]/(24*2)+64
);
*///}
//fprintf(fp2, "lsl r1, #");
//fprintf(fp2, "%d\n", 2);
//fprintf(fp2, "lsr r1, #");
//fprintf(fp2, "%d\n",2);
/*fprintf(fp2, "lsl r1, #");
fprintf(fp2, "%d\n",8);
*/
// fprintf(fp2,"mov r2, #0x9600\n");
//fprintf(fp2,"strh r1, [r0],#2\n");
}
}
// png_read_end(png_ptr, info_ptr);
/* clean up after the read, and free any memory allocated - REQUIRED */
// png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
/* close the file */
fclose(fp);
/* that's it */
return (1);
}