sweetfish
Still Fresh
Hello
I have been trying to get a function that loads PNG files working tonight, to use with rlyeh's minilib, but without much success... bbull found me a nice snipped that was coded for GP32, http://www.gp32.co.nz/snippet_view.php?snippet_id=23, even though it was ment to be used with Mr.Mirko's SDK it should be fixable.
But the problem is that it doesn't seem that to include libpng or something, here's what I get:
And my current code (png_loader.c):
Does anyone know what I could be doing wrong? And has anyone else got libpng working (I heard there was some problems with SDL_image, which is also using libpng)? Or do someone else have any sweet PNG loading function that they would want to share?
I have been trying to get a function that loads PNG files working tonight, to use with rlyeh's minilib, but without much success... bbull found me a nice snipped that was coded for GP32, http://www.gp32.co.nz/snippet_view.php?snippet_id=23, even though it was ment to be used with Mr.Mirko's SDK it should be fixable.
But the problem is that it doesn't seem that to include libpng or something, here's what I get:
Code:
C:\devkitGP2X\vid_test_01>arm-linux-gcc minimal.c png_loader.c main.c -static -l
pthread
png_loader.c: In function 'gp_canvasCreateFromPngBuf':
png_loader.c:139: warning: incompatible implicit declaration of built-in functio
n 'malloc'
png_loader.c: In function 'gp_canvasCreateFromPng':
png_loader.c:210: warning: assignment from incompatible pointer type
png_loader.c:218: warning: incompatible implicit declaration of built-in functio
n 'malloc'
png_loader.c:219: warning: passing argument 4 of 'fread' from incompatible point
er type
png_loader.c:222: warning: passing argument 1 of 'fclose' from incompatible poin
ter type
C:\DOCUME~1\work\LOKALA~1\Temp/ccukcaaa.o: In function `pngReadBufferFunc':
png_loader.c:(.text+0x20): undefined reference to `png_get_io_ptr'
C:\DOCUME~1\work\LOKALA~1\Temp/ccukcaaa.o: In function `gp_canvasCreateFromPngBuf':
png_loader.c:(.text+0xd0): undefined reference to `png_create_read_struct'
png_loader.c:(.text+0x100): undefined reference to `png_create_info_struct'
png_loader.c:(.text+0x114): undefined reference to `png_create_info_struct'
png_loader.c:(.text+0x134): undefined reference to `png_set_read_fn'
png_loader.c:(.text+0x14c): undefined reference to `png_read_info'
png_loader.c:(.text+0x19c): undefined reference to `png_get_IHDR'
png_loader.c:(.text+0x1b8): undefined reference to `png_get_gAMA'
png_loader.c:(.text+0x204): undefined reference to `png_set_gamma'
png_loader.c:(.text+0x228): undefined reference to `png_set_gamma'
png_loader.c:(.text+0x240): undefined reference to `png_read_update_info'
png_loader.c:(.text+0x24c): undefined reference to `png_set_expand'
png_loader.c:(.text+0x258): undefined reference to `png_set_gray_to_rgb'
png_loader.c:(.text+0x270): undefined reference to `png_get_rowbytes'
png_loader.c:(.text+0x32c): undefined reference to `png_read_image'
png_loader.c:(.text+0x3a4): undefined reference to `gp_colorRGB24to16'
png_loader.c:(.text+0x544): undefined reference to `gp_colorRGB24to16'
png_loader.c:(.text+0x69c): undefined reference to `png_read_end'
png_loader.c:(.text+0x6c0): undefined reference to `png_destroy_read_struct'
C:\DOCUME~1\work\LOKALA~1\Temp/ccukcaaa.o: In function `exitClean.3928':
png_loader.c:(.text+0x728): undefined reference to `png_destroy_read_struct'
png_loader.c:(.text+0x734): undefined reference to `gp_canvasFree'
C:\DOCUME~1\work\LOKALA~1\Temp/ccukcaaa.o: In function `gp_canvasCreateFromPng':
png_loader.c:(.text+0x79c): undefined reference to `smc_filesize'
And my current code (png_loader.c):
Code:
/*
* PNG loader library for GP32
* by PEA (www.pea.co.nz)
* ---
* based on a stripped down version of:
* PNG loader library for OpenGL v1.45 (10/07/00)
* by Ben Wyatt ben@wyatt100.freeserve.co.uk
* Using LibPNG 1.0.2 and ZLib 1.1.3
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the author be held liable for any damages arising from the
* use of this software.
*
* Permission is hereby granted to use, copy, modify, and distribute this
* source code, or portions hereof, for any purpose, without fee, subject to
* the following restrictions:
*
* 1. The origin of this source code must not be misrepresented. You must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered versions must be plainly marked as such and must not be
* misrepresented as being the original source.
* 3. This notice must not be removed or altered from any source distribution.
* ---
* 2005/01/22 - Remove unneeded functions, includes and GL references
* and format for use with Mr.Mirko SDK.
*/
//#include <gp32.h>
#include "C:/devkitGP2X/include/png.h"
// screenGamma = displayGamma/viewingGamma
// displayGamma = CRT has gamma of ~2.2
// viewingGamma depends on platform.
// PC is 1.0,
// Mac is 1.45,
// SGI defaults to 1.7
static double screenGamma = 2.2 / 1.0;
static char gammaExplicit = 0;
typedef struct tGP_pngFileBuffer{
unsigned char *buffer;
int pos;
} tGP_pngFileBuffer;
typedef struct {
char path[256];
char mode;
unsigned int pos;
unsigned int size;
char *wbuffer;
} GPFILE;
typedef struct tGP_canvas{
unsigned short width;
unsigned short height;
unsigned short *data;
unsigned char *mask;
unsigned char frames;
}tGP_canvas;
void pngReadBufferFunc(png_struct *png, png_bytep buf, png_size_t size){
tGP_pngFileBuffer *pngFileBuffer=(tGP_pngFileBuffer*)png_get_io_ptr(png);
memcpy(buf,pngFileBuffer->buffer+pngFileBuffer->pos,size);
pngFileBuffer->pos+=size;
}
tGP_canvas* gp_canvasCreateFromPngBuf( unsigned char *pngdata, char rotate90, unsigned char frames, int *outError ){
unsigned char header[8];
png_structp png;
png_infop info;
png_infop endinfo;
png_bytep data;
png_bytep *row_p;
double fileGamma;
unsigned long width, height;
int depth, color;
unsigned long i, x, y;
unsigned long rowbytes, channels, pcount;
tGP_pngFileBuffer pngFileBuffer;
tGP_canvas *canvas = NULL;
unsigned short *pdata;
unsigned char *praw;
unsigned char *pmask;
int res;
void exitClean( void ){
png_destroy_read_struct(&png, &info, &endinfo);
gp_canvasFree( canvas );
}
// Init the file buffer
pngFileBuffer.pos = 0;
pngFileBuffer.buffer = pngdata;
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (*outError){
return NULL;
}
info = png_create_info_struct(png);
endinfo = png_create_info_struct(png);
// Set a custom read function, and read/process all PNG data up
// until the IDAT (image data) chunk.
png_set_read_fn(png,(png_voidp)&pngFileBuffer,(png_rw_ptr)pngReadBufferFunc);
png_read_info(png, info);
// Get the image data
png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
// Create the canvas
//if (frames<1){ frames=1; }
//canvas = gp_canvasCreate( height, width, frames, GPC_BLACK );
// Gamma correction. See if file contains gamma info and use that
// or else use user defined value.
if (png_get_gAMA(png, info, &fileGamma) && (!gammaExplicit))
png_set_gamma(png, screenGamma, fileGamma);
else
png_set_gamma(png, screenGamma, 1.0/2.2);
// Update the 'info' struct with the new gamma information
png_read_update_info(png, info);
// Set expand function to expand paletted images, gray scale images, and
// palletted alpha channels to full channels
png_set_expand(png);
// Set strip function to reduce 16bpp down to 8bpp if applicable
//png_set_strip_16(png);
// Set function to convert grayscale (single channel) image to full RGB channels
png_set_gray_to_rgb(png);
// Allocate a row of pointers to store the image data
rowbytes = png_get_rowbytes(png, info);
//channels = png_get_channels(png, info);
channels = rowbytes/width;
data = (png_bytep)malloc(rowbytes*height);
row_p = (png_bytep*)malloc(sizeof(png_bytep)*height);
for (i=0; i<height; i++){ row_p[i] = data+i*rowbytes; }
// Read the image data
png_read_image(png, row_p);
free(row_p);
// Copy image data to the canvas
pcount = width*height;
if (!rotate90){
// Copy image as-is
pdata = canvas->data;
praw = data;
for (i=0; i<pcount; i++){
*pdata = gp_colorRGB24to16( *praw, *(praw+1), *(praw+2) );
praw += channels; pdata++;
}
// Create alpha mask if required
if (channels==4){
canvas->mask=(unsigned char*)malloc( pcount );
praw = data+3;
pmask = canvas->mask;
for (i=0; i<pcount; i++){
*pmask = (*praw)>>3;
praw += channels; pmask++;
}
}
}else{
canvas->width = width;
canvas->height = height;
// Copy image with rotation
pdata = canvas->data;
for(x=0; x<width; x++){
for(y=0; y<height; y++){
praw = data + ((height-y-1)*width+x)*channels;
*pdata = gp_colorRGB24to16( *praw, *(praw+1), *(praw+2) );
pdata++;
}
}
// Create alpha mask if required
if (channels==4){
canvas->mask=(unsigned char*)malloc( pcount );
pmask = canvas->mask;
for(x=0; x<width; x++){
for(y=0; y<height; y++){
praw = data + ((height-y-1)*width+x)*channels + 3;
*pmask = (*praw)>>3;
pmask++;
}
}
}
}
// Destroy raw image
free( data );
// Check the rest of the image for additional tags
png_read_end(png, endinfo);
// Clean up and return the canvas
png_destroy_read_struct(&png, &info, &endinfo);
return canvas;
}
tGP_canvas* gp_canvasCreateFromPng( char *filename, char rotate90, unsigned char frames, int *outError ){
int pngsize, readsize;
GPFILE *pngfile;
unsigned char *file;
tGP_canvas *canvas;
// Attempt to open the file in read mode. Return error on fail
pngfile = fopen(filename,"r");
if (pngfile==NULL){
printf("PNG_ERROR_CANTOPENFILE");
return NULL;
}
// Get the raw PNG filesize, allocate memory for it, and load the file
pngsize = smc_filesize( pngfile );
file = (unsigned char *)malloc( pngsize );
readsize = fread( (void *)file, pngsize, 1, pngfile );
// Close the file
fclose(pngfile);
// If the full PNG wasn't read properly, return error
if(readsize-pngsize){
free( file );
printf("PNG_ERROR_READSIZE");
return NULL;
}
// Read PNG
canvas = gp_canvasCreateFromPngBuf( file, rotate90, frames, outError );
// Free file and return canvas
free( file );
return canvas;
}
void gp_canvasSetPngGamma(double viewingGamma) {
if(viewingGamma > 0){
gammaExplicit = 1;
screenGamma = 2.2/viewingGamma;
}else {
gammaExplicit = 0;
screenGamma = 2.2;
}
}
Does anyone know what I could be doing wrong? And has anyone else got libpng working (I heard there was some problems with SDL_image, which is also using libpng)? Or do someone else have any sweet PNG loading function that they would want to share?