Search
lxdream.org :: lxdream/src/util.c
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 11:53:35 2007 +0000 (14 years ago)
permissions -rw-r--r--
last change Fix miscellaneous warnings
view annotate diff log raw
     1 /**
     2  * $Id: util.c,v 1.11 2007-10-31 09:10:23 nkeynes Exp $
     3  *
     4  * Miscellaneous utility functions.
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <assert.h>
    20 #include <ctype.h>
    21 #include <stdarg.h>
    22 #include <stdio.h>
    23 #include <stdlib.h>
    24 #include <time.h>
    25 #include <zlib.h>
    26 #include <glib.h>
    27 #include <png.h>
    28 #include "dream.h"
    29 #include "display.h"
    30 #include "sh4/sh4core.h"
    32 char *msg_levels[] = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };
    33 int global_msg_level = EMIT_WARN;
    35 void fwrite_string( const char *s, FILE *f )
    36 {
    37     uint32_t len = 0;
    38     if( s == NULL ) {
    39 	fwrite( &len, sizeof(len), 1, f );
    40     } else {
    41 	len = strlen(s)+1;
    42 	fwrite( &len, sizeof(len), 1, f );
    43 	fwrite( s, len, 1, f );
    44     }
    45 }
    47 int fread_string( char *s, int maxlen, FILE *f ) 
    48 {
    49     uint32_t len;
    50     fread( &len, sizeof(len), 1, f );
    51     if( len != 0 ) {
    52 	fread( s, len > maxlen ? maxlen : len, 1, f );
    53     }
    54     return len;
    55 }
    57 void fwrite_gzip( void *p, size_t sz, size_t count, FILE *f )
    58 {
    59     uLongf size = sz*count;
    60     uLongf csize = ((int)(size*1.001))+13;
    61     unsigned char *tmp = g_malloc0( csize );
    62     int status = compress( tmp, &csize, p, size );
    63     assert( status == Z_OK );
    64     fwrite( &csize, sizeof(csize), 1, f );
    65     fwrite( tmp, csize, 1, f );
    66     g_free(tmp);
    67 }
    69 int fread_gzip( void *p, size_t sz, size_t count, FILE *f )
    70 {
    71     uLongf size = sz*count;
    72     uLongf csize;
    73     unsigned char *tmp;
    75     fread( &csize, sizeof(csize), 1, f );
    76     assert( csize <= (size*2) );
    77     tmp = g_malloc0( csize );
    78     fread( tmp, csize, 1, f );
    79     int status = uncompress( p, &size, tmp, csize );
    80     g_free(tmp);
    81     if( status == Z_OK ) {
    82 	return count;
    83     } else {
    84 	fprintf( stderr, "Error reading compressed data\n" );
    85 	return 0;
    86     }
    87 }
    89 void fwrite_dump( unsigned char *data, unsigned int length, FILE *f ) 
    90 {
    91     unsigned int i, j;
    92     for( i =0; i<length; i+=16 ) {
    93 	fprintf( f, "%08X:", i);
    94 	for( j=i; j<i+16; j++ ) {
    95 	    if( (j % 4) == 0 )
    96 		fprintf( f, " " );
    97 	    if( j < length )
    98 		fprintf( f, " %02X", (unsigned int)(data[j]) );
    99 	    else
   100 		fprintf( f, "   " );
   101 	}
   102 	fprintf( f, "  " );
   103 	for( j=i; j<i+16 && j<length; j++ ) {
   104 	    fprintf( f, "%c", isprint(data[j]) ? data[j] : '.' );
   105 	}
   106 	fprintf( f, "\n" );
   107     }
   108 }
   110 void fwrite_dump32( unsigned int *data, unsigned int length, FILE *f ) 
   111 {
   112     fwrite_dump32v( data, length, 8, f );
   113 }
   115 void fwrite_dump32v( unsigned int *data, unsigned int length, int wordsPerLine, FILE *f ) 
   116 {
   117     unsigned int i, j;
   118     for( i =0; i<length>>2; i+=wordsPerLine ) {
   119 	fprintf( f, "%08X:", i);
   120 	for( j=i; j<i+wordsPerLine; j++ ) {
   121 	    if( j < length )
   122 		fprintf( f, " %08X", (unsigned int)(data[j]) );
   123 	    else
   124 		fprintf( f, "         " );
   125 	}
   126 	fprintf( f, "\n" );
   127     }
   128 }
   130 gboolean write_png_to_stream( FILE *f, frame_buffer_t buffer )
   131 {
   132     int coltype, i;
   133     png_bytep p;
   134     png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   135     if (!png_ptr) {
   136 	return FALSE;
   137     }
   139     png_infop info_ptr = png_create_info_struct(png_ptr);
   140     if (!info_ptr) {
   141 	png_destroy_write_struct(&png_ptr, NULL);
   142 	return FALSE;
   143     }
   145     if( setjmp(png_jmpbuf(png_ptr)) ) {
   146 	png_destroy_write_struct(&png_ptr, &info_ptr);
   147 	return FALSE;
   148     }
   149     png_init_io( png_ptr, f );
   150     switch( buffer->colour_format ) {
   151     case COLFMT_BGR888:
   152 	coltype = PNG_COLOR_TYPE_RGB;
   153 	break;
   154     case COLFMT_BGRA8888:
   155 	coltype = PNG_COLOR_TYPE_RGB_ALPHA;
   156 	break;
   157     case COLFMT_BGR0888:
   158 	coltype = PNG_COLOR_TYPE_RGB;
   159 	break;
   160     default:
   161 	coltype = PNG_COLOR_TYPE_RGB;
   162     }
   163     png_set_IHDR(png_ptr, info_ptr, buffer->width, buffer->height,
   164 		 8, coltype, PNG_INTERLACE_NONE, 
   165 		 PNG_COMPRESSION_TYPE_DEFAULT, 
   166 		 PNG_FILTER_TYPE_DEFAULT );
   167     png_write_info(png_ptr, info_ptr);
   168     if( buffer->colour_format == COLFMT_BGR0888 ) {
   169 	png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
   170     }
   171     png_set_bgr(png_ptr);
   172     if( buffer->inverted ) {
   173 	p = buffer->data + (buffer->height*buffer->rowstride) - buffer->rowstride;
   174 	for(i=0; i<buffer->height; i++ ) {
   175 	    png_write_row(png_ptr, p);
   176 	    p-=buffer->rowstride;
   177 	}
   178     } else {
   179 	p = buffer->data;
   180 	for(i=0; i<buffer->height; i++ ) {
   181 	    png_write_row(png_ptr, p);
   182 	    p+=buffer->rowstride;
   183 	}
   184     }
   185     png_write_end(png_ptr, info_ptr);
   186     png_destroy_write_struct(&png_ptr, &info_ptr);
   187     return TRUE;
   188 }
   190 frame_buffer_t read_png_from_stream( FILE *f )
   191 {
   192     png_bytep p;
   193     int i;
   194     png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 
   195 						 NULL, NULL, NULL);
   196     if (!png_ptr) {
   197 	return NULL;
   198     }
   200     png_infop info_ptr = png_create_info_struct(png_ptr);
   201     if (!info_ptr) {
   202 	png_destroy_read_struct(&png_ptr, NULL, NULL);
   203 	return NULL;
   204     }
   206     png_infop end_info = png_create_info_struct(png_ptr);
   207     if (!end_info) {
   208 	png_destroy_read_struct(&png_ptr, &info_ptr, NULL );
   209 	return NULL;
   210     }
   212     if( setjmp(png_jmpbuf(png_ptr)) ) {
   213 	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
   214 	return NULL;
   215     }
   217     png_init_io(png_ptr, f);
   218     png_read_info(png_ptr, info_ptr);
   220     png_uint_32 width, height;
   221     int bit_depth, color_type, interlace_type,
   222 	compression_type, filter_method;
   223     png_get_IHDR(png_ptr, info_ptr, &width, &height,
   224 		 &bit_depth, &color_type, &interlace_type,
   225 		 &compression_type, &filter_method);
   226     assert( interlace_type == PNG_INTERLACE_NONE );
   227     int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
   228     int channels = png_get_channels(png_ptr, info_ptr);
   229     frame_buffer_t buffer = g_malloc( sizeof(struct frame_buffer) + rowbytes*height );
   230     buffer->data = (char *)(buffer+1);
   231     buffer->width = width;
   232     buffer->height = height;
   233     buffer->rowstride = rowbytes;
   234     buffer->address = -1;
   235     buffer->size = rowbytes*height;
   236     buffer->inverted = FALSE;
   237     if( channels == 4 ) {
   238 	buffer->colour_format = COLFMT_BGRA8888;
   239     } else if( channels == 3 ) {
   240 	buffer->colour_format = COLFMT_RGB888;
   241     }
   243     p = buffer->data;
   244     for( i=0; i<height; i++ ) {
   245 	png_read_row(png_ptr, p, NULL );
   246 	p += rowbytes;
   247     }
   249     png_read_end(png_ptr, end_info);
   250     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
   251     return buffer;
   252 }
   254 void log_message( void *ptr, int level, const gchar *source, const char *msg, ... )
   255 {
   256     char buf[20], addr[10] = "", *p;
   257     const gchar *arr[4] = {buf, source, addr};
   258     int posn;
   259     time_t tm = time(NULL);
   260     va_list ap;
   262     if( level > global_msg_level ) {
   263 	return; // ignored
   264     }
   266     va_start(ap, msg);
   268     if( level <= EMIT_ERR ) {
   269 	gchar *text = g_strdup_vprintf( msg, ap );
   270 	if( gui_error_dialog( text ) ) {
   271 	    g_free(text);
   272 	    va_end(ap);
   273 	    return;
   274 	}
   275 	g_free(text);
   276     }
   279     strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
   280     fprintf( stderr, "%s %08X %-5s ", buf, sh4r.pc, msg_levels[level] );
   281     vfprintf( stderr, msg, ap );
   282     va_end(ap);
   283     fprintf( stderr, "\n" );
   284 }
.