2 * $Id: util.c,v 1.12 2007-10-31 12:05:23 nkeynes Exp $
4 * Miscellaneous utility functions.
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
31 #include "sh4/sh4core.h"
33 char *msg_levels[] = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };
34 int global_msg_level = EMIT_WARN;
36 void fwrite_string( const char *s, FILE *f )
40 fwrite( &len, sizeof(len), 1, f );
43 fwrite( &len, sizeof(len), 1, f );
44 fwrite( s, len, 1, f );
48 int fread_string( char *s, int maxlen, FILE *f )
51 fread( &len, sizeof(len), 1, f );
53 fread( s, len > maxlen ? maxlen : len, 1, f );
58 void fwrite_gzip( void *p, size_t sz, size_t count, FILE *f )
60 uLongf size = sz*count;
61 uLongf csize = ((int)(size*1.001))+13;
62 unsigned char *tmp = g_malloc0( csize );
63 int status = compress( tmp, &csize, p, size );
64 assert( status == Z_OK );
65 fwrite( &csize, sizeof(csize), 1, f );
66 fwrite( tmp, csize, 1, f );
70 int fread_gzip( void *p, size_t sz, size_t count, FILE *f )
72 uLongf size = sz*count;
76 fread( &csize, sizeof(csize), 1, f );
77 assert( csize <= (size*2) );
78 tmp = g_malloc0( csize );
79 fread( tmp, csize, 1, f );
80 int status = uncompress( p, &size, tmp, csize );
82 if( status == Z_OK ) {
85 fprintf( stderr, "Error reading compressed data\n" );
90 void fwrite_dump( unsigned char *data, unsigned int length, FILE *f )
93 for( i =0; i<length; i+=16 ) {
94 fprintf( f, "%08X:", i);
95 for( j=i; j<i+16; j++ ) {
99 fprintf( f, " %02X", (unsigned int)(data[j]) );
104 for( j=i; j<i+16 && j<length; j++ ) {
105 fprintf( f, "%c", isprint(data[j]) ? data[j] : '.' );
111 void fwrite_dump32( unsigned int *data, unsigned int length, FILE *f )
113 fwrite_dump32v( data, length, 8, f );
116 void fwrite_dump32v( unsigned int *data, unsigned int length, int wordsPerLine, FILE *f )
119 for( i =0; i<length>>2; i+=wordsPerLine ) {
120 fprintf( f, "%08X:", i);
121 for( j=i; j<i+wordsPerLine; j++ ) {
123 fprintf( f, " %08X", (unsigned int)(data[j]) );
131 gboolean write_png_to_stream( FILE *f, frame_buffer_t buffer )
135 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
140 png_infop info_ptr = png_create_info_struct(png_ptr);
142 png_destroy_write_struct(&png_ptr, NULL);
146 if( setjmp(png_jmpbuf(png_ptr)) ) {
147 png_destroy_write_struct(&png_ptr, &info_ptr);
150 png_init_io( png_ptr, f );
151 switch( buffer->colour_format ) {
153 coltype = PNG_COLOR_TYPE_RGB;
155 case COLFMT_BGRA8888:
156 coltype = PNG_COLOR_TYPE_RGB_ALPHA;
159 coltype = PNG_COLOR_TYPE_RGB;
162 coltype = PNG_COLOR_TYPE_RGB;
164 png_set_IHDR(png_ptr, info_ptr, buffer->width, buffer->height,
165 8, coltype, PNG_INTERLACE_NONE,
166 PNG_COMPRESSION_TYPE_DEFAULT,
167 PNG_FILTER_TYPE_DEFAULT );
168 png_write_info(png_ptr, info_ptr);
169 if( buffer->colour_format == COLFMT_BGR0888 ) {
170 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
172 png_set_bgr(png_ptr);
173 if( buffer->inverted ) {
174 p = (png_bytep)(buffer->data + (buffer->height*buffer->rowstride) - buffer->rowstride);
175 for(i=0; i<buffer->height; i++ ) {
176 png_write_row(png_ptr, p);
177 p-=buffer->rowstride;
180 p = (png_bytep)buffer->data;
181 for(i=0; i<buffer->height; i++ ) {
182 png_write_row(png_ptr, p);
183 p+=buffer->rowstride;
186 png_write_end(png_ptr, info_ptr);
187 png_destroy_write_struct(&png_ptr, &info_ptr);
191 frame_buffer_t read_png_from_stream( FILE *f )
195 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
201 png_infop info_ptr = png_create_info_struct(png_ptr);
203 png_destroy_read_struct(&png_ptr, NULL, NULL);
207 png_infop end_info = png_create_info_struct(png_ptr);
209 png_destroy_read_struct(&png_ptr, &info_ptr, NULL );
213 if( setjmp(png_jmpbuf(png_ptr)) ) {
214 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
218 png_init_io(png_ptr, f);
219 png_read_info(png_ptr, info_ptr);
221 png_uint_32 width, height;
222 int bit_depth, color_type, interlace_type,
223 compression_type, filter_method;
224 png_get_IHDR(png_ptr, info_ptr, &width, &height,
225 &bit_depth, &color_type, &interlace_type,
226 &compression_type, &filter_method);
227 assert( interlace_type == PNG_INTERLACE_NONE );
228 int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
229 int channels = png_get_channels(png_ptr, info_ptr);
230 frame_buffer_t buffer = g_malloc( sizeof(struct frame_buffer) + rowbytes*height );
231 buffer->data = (char *)(buffer+1);
232 buffer->width = width;
233 buffer->height = height;
234 buffer->rowstride = rowbytes;
235 buffer->address = -1;
236 buffer->size = rowbytes*height;
237 buffer->inverted = FALSE;
238 if( channels == 4 ) {
239 buffer->colour_format = COLFMT_BGRA8888;
240 } else if( channels == 3 ) {
241 buffer->colour_format = COLFMT_RGB888;
244 p = (png_bytep)buffer->data;
245 for( i=0; i<height; i++ ) {
246 png_read_row(png_ptr, p, NULL );
250 png_read_end(png_ptr, end_info);
251 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
255 void log_message( void *ptr, int level, const gchar *source, const char *msg, ... )
258 time_t tm = time(NULL);
261 if( level > global_msg_level ) {
267 if( level <= EMIT_ERR ) {
268 gchar *text = g_strdup_vprintf( msg, ap );
269 if( gui_error_dialog( text ) ) {
278 strftime( buf, sizeof(buf), "%H:%M:%S", localtime(&tm) );
279 fprintf( stderr, "%s %08X %-5s ", buf, sh4r.pc, msg_levels[level] );
280 vfprintf( stderr, msg, ap );
282 fprintf( stderr, "\n" );
.