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); }