Search
lxdream.org :: lxdream/src/util.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/util.c
changeset 477:9a373f2ff009
prev447:3e095bfcb476
next481:3b2d6c5a19ad
author nkeynes
date Wed Oct 31 09:10:23 2007 +0000 (14 years ago)
permissions -rw-r--r--
last change Add save/restore of render buffers in save states
Gzip memory blocks in save states
Move front-buffer management back to pvr2
Add screenshot preview when loading save states
Various minor fixes and cleanups
file annotate diff log raw
1.1 --- a/src/util.c Tue Oct 16 12:36:29 2007 +0000
1.2 +++ b/src/util.c Wed Oct 31 09:10:23 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: util.c,v 1.10 2007-10-16 12:36:29 nkeynes Exp $
1.6 + * $Id: util.c,v 1.11 2007-10-31 09:10:23 nkeynes Exp $
1.7 *
1.8 * Miscellaneous utility functions.
1.9 *
1.10 @@ -16,12 +16,17 @@
1.11 * GNU General Public License for more details.
1.12 */
1.13
1.14 +#include <assert.h>
1.15 #include <ctype.h>
1.16 #include <stdarg.h>
1.17 #include <stdio.h>
1.18 #include <stdlib.h>
1.19 #include <time.h>
1.20 +#include <zlib.h>
1.21 +#include <glib.h>
1.22 +#include <png.h>
1.23 #include "dream.h"
1.24 +#include "display.h"
1.25 #include "sh4/sh4core.h"
1.26
1.27 char *msg_levels[] = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };
1.28 @@ -49,6 +54,38 @@
1.29 return len;
1.30 }
1.31
1.32 +void fwrite_gzip( void *p, size_t sz, size_t count, FILE *f )
1.33 +{
1.34 + uLongf size = sz*count;
1.35 + uLongf csize = ((int)(size*1.001))+13;
1.36 + unsigned char *tmp = g_malloc0( csize );
1.37 + int status = compress( tmp, &csize, p, size );
1.38 + assert( status == Z_OK );
1.39 + fwrite( &csize, sizeof(csize), 1, f );
1.40 + fwrite( tmp, csize, 1, f );
1.41 + g_free(tmp);
1.42 +}
1.43 +
1.44 +int fread_gzip( void *p, size_t sz, size_t count, FILE *f )
1.45 +{
1.46 + uLongf size = sz*count;
1.47 + uLongf csize;
1.48 + unsigned char *tmp;
1.49 +
1.50 + fread( &csize, sizeof(csize), 1, f );
1.51 + assert( csize <= (size*2) );
1.52 + tmp = g_malloc0( csize );
1.53 + fread( tmp, csize, 1, f );
1.54 + int status = uncompress( p, &size, tmp, csize );
1.55 + g_free(tmp);
1.56 + if( status == Z_OK ) {
1.57 + return count;
1.58 + } else {
1.59 + fprintf( stderr, "Error reading compressed data\n" );
1.60 + return 0;
1.61 + }
1.62 +}
1.63 +
1.64 void fwrite_dump( unsigned char *data, unsigned int length, FILE *f )
1.65 {
1.66 unsigned int i, j;
1.67 @@ -90,6 +127,129 @@
1.68 }
1.69 }
1.70
1.71 +gboolean write_png_to_stream( FILE *f, frame_buffer_t buffer )
1.72 +{
1.73 + int coltype, i;
1.74 + png_bytep p;
1.75 + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1.76 + if (!png_ptr) {
1.77 + return FALSE;
1.78 + }
1.79 +
1.80 + png_infop info_ptr = png_create_info_struct(png_ptr);
1.81 + if (!info_ptr) {
1.82 + png_destroy_write_struct(&png_ptr, NULL);
1.83 + return FALSE;
1.84 + }
1.85 +
1.86 + if( setjmp(png_jmpbuf(png_ptr)) ) {
1.87 + png_destroy_write_struct(&png_ptr, &info_ptr);
1.88 + return FALSE;
1.89 + }
1.90 + png_init_io( png_ptr, f );
1.91 + switch( buffer->colour_format ) {
1.92 + case COLFMT_BGR888:
1.93 + coltype = PNG_COLOR_TYPE_RGB;
1.94 + break;
1.95 + case COLFMT_BGRA8888:
1.96 + coltype = PNG_COLOR_TYPE_RGB_ALPHA;
1.97 + break;
1.98 + case COLFMT_BGR0888:
1.99 + coltype = PNG_COLOR_TYPE_RGB;
1.100 + break;
1.101 + default:
1.102 + coltype = PNG_COLOR_TYPE_RGB;
1.103 + }
1.104 + png_set_IHDR(png_ptr, info_ptr, buffer->width, buffer->height,
1.105 + 8, coltype, PNG_INTERLACE_NONE,
1.106 + PNG_COMPRESSION_TYPE_DEFAULT,
1.107 + PNG_FILTER_TYPE_DEFAULT );
1.108 + png_write_info(png_ptr, info_ptr);
1.109 + if( buffer->colour_format == COLFMT_BGR0888 ) {
1.110 + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
1.111 + }
1.112 + png_set_bgr(png_ptr);
1.113 + if( buffer->inverted ) {
1.114 + p = buffer->data + (buffer->height*buffer->rowstride) - buffer->rowstride;
1.115 + for(i=0; i<buffer->height; i++ ) {
1.116 + png_write_row(png_ptr, p);
1.117 + p-=buffer->rowstride;
1.118 + }
1.119 + } else {
1.120 + p = buffer->data;
1.121 + for(i=0; i<buffer->height; i++ ) {
1.122 + png_write_row(png_ptr, p);
1.123 + p+=buffer->rowstride;
1.124 + }
1.125 + }
1.126 + png_write_end(png_ptr, info_ptr);
1.127 + png_destroy_write_struct(&png_ptr, &info_ptr);
1.128 + return TRUE;
1.129 +}
1.130 +
1.131 +frame_buffer_t read_png_from_stream( FILE *f )
1.132 +{
1.133 + png_bytep p;
1.134 + int i;
1.135 + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
1.136 + NULL, NULL, NULL);
1.137 + if (!png_ptr) {
1.138 + return NULL;
1.139 + }
1.140 +
1.141 + png_infop info_ptr = png_create_info_struct(png_ptr);
1.142 + if (!info_ptr) {
1.143 + png_destroy_read_struct(&png_ptr, NULL, NULL);
1.144 + return NULL;
1.145 + }
1.146 +
1.147 + png_infop end_info = png_create_info_struct(png_ptr);
1.148 + if (!end_info) {
1.149 + png_destroy_read_struct(&png_ptr, &info_ptr, NULL );
1.150 + return NULL;
1.151 + }
1.152 +
1.153 + if( setjmp(png_jmpbuf(png_ptr)) ) {
1.154 + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1.155 + return NULL;
1.156 + }
1.157 +
1.158 + png_init_io(png_ptr, f);
1.159 + png_read_info(png_ptr, info_ptr);
1.160 +
1.161 + png_uint_32 width, height;
1.162 + int bit_depth, color_type, interlace_type,
1.163 + compression_type, filter_method;
1.164 + png_get_IHDR(png_ptr, info_ptr, &width, &height,
1.165 + &bit_depth, &color_type, &interlace_type,
1.166 + &compression_type, &filter_method);
1.167 + assert( interlace_type == PNG_INTERLACE_NONE );
1.168 + int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
1.169 + int channels = png_get_channels(png_ptr, info_ptr);
1.170 + frame_buffer_t buffer = g_malloc( sizeof(struct frame_buffer) + rowbytes*height );
1.171 + buffer->data = (char *)(buffer+1);
1.172 + buffer->width = width;
1.173 + buffer->height = height;
1.174 + buffer->rowstride = rowbytes;
1.175 + buffer->address = -1;
1.176 + buffer->size = rowbytes*height;
1.177 + buffer->inverted = FALSE;
1.178 + if( channels == 4 ) {
1.179 + buffer->colour_format = COLFMT_BGRA8888;
1.180 + } else if( channels == 3 ) {
1.181 + buffer->colour_format = COLFMT_RGB888;
1.182 + }
1.183 +
1.184 + p = buffer->data;
1.185 + for( i=0; i<height; i++ ) {
1.186 + png_read_row(png_ptr, p, NULL );
1.187 + p += rowbytes;
1.188 + }
1.189 +
1.190 + png_read_end(png_ptr, end_info);
1.191 + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1.192 + return buffer;
1.193 +}
1.194
1.195 void log_message( void *ptr, int level, const gchar *source, const char *msg, ... )
1.196 {
.