splash.cpp

00001 /* $Id: splash.cpp 11692 2007-12-25 11:26:07Z rubidium $ */
00002 
00003 #include "../../stdafx.h"
00004 #include "../../openttd.h"
00005 #include "../../variables.h"
00006 #include "../../debug.h"
00007 #include "../../gfx_func.h"
00008 #include "../../fileio.h"
00009 #include "../../blitter/factory.hpp"
00010 
00011 #include "splash.h"
00012 
00013 #ifdef WITH_PNG
00014 
00015 #include <png.h>
00016 
00017 static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message)
00018 {
00019   DEBUG(misc, 0, "[libpng] error: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
00020   longjmp(png_ptr->jmpbuf, 1);
00021 }
00022 
00023 static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message)
00024 {
00025   DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (char *)png_get_error_ptr(png_ptr));
00026 }
00027 
00028 void DisplaySplashImage()
00029 {
00030   png_byte header[8];
00031   FILE *f;
00032   png_structp png_ptr;
00033   png_infop info_ptr, end_info;
00034   uint width, height, bit_depth, color_type;
00035   png_colorp palette;
00036   int num_palette;
00037   png_bytep *row_pointers;
00038   uint8 *src;
00039   uint y;
00040   uint xoff, yoff;
00041   int i;
00042 
00043   f = FioFOpenFile(SPLASH_IMAGE_FILE);
00044   if (f == NULL) return;
00045 
00046   fread(header, 1, 8, f);
00047   if (png_sig_cmp(header, 0, 8) != 0) {
00048     fclose(f);
00049     return;
00050   }
00051 
00052   png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning);
00053 
00054   if (png_ptr == NULL) {
00055     fclose(f);
00056     return;
00057   }
00058 
00059   info_ptr = png_create_info_struct(png_ptr);
00060   if (info_ptr == NULL) {
00061     png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
00062     fclose(f);
00063     return;
00064   }
00065 
00066   end_info = png_create_info_struct(png_ptr);
00067   if (end_info == NULL) {
00068     png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
00069     fclose(f);
00070     return;
00071   }
00072 
00073   if (setjmp(png_jmpbuf(png_ptr))) {
00074     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00075     fclose(f);
00076     return;
00077   }
00078 
00079   png_init_io(png_ptr, f);
00080   png_set_sig_bytes(png_ptr, 8);
00081 
00082   png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
00083 
00084   width            = png_get_image_width(png_ptr, info_ptr);
00085   height           = png_get_image_height(png_ptr, info_ptr);
00086   bit_depth        = png_get_bit_depth(png_ptr, info_ptr);
00087   color_type       = png_get_color_type(png_ptr, info_ptr);
00088 
00089   if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) {
00090     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00091     fclose(f);
00092     return;
00093   }
00094 
00095   if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) {
00096     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00097     fclose(f);
00098     return;
00099   }
00100 
00101   png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
00102 
00103   row_pointers = png_get_rows(png_ptr, info_ptr);
00104 
00105   if (width > (uint) _screen.width) width = _screen.width;
00106   if (height > (uint) _screen.height) height = _screen.height;
00107 
00108   xoff = (_screen.width - width) / 2;
00109   yoff = (_screen.height - height) / 2;
00110 
00111   switch (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth()) {
00112     case 8: {
00113         uint8 *dst;
00114 
00115         memset(_screen.dst_ptr, 0xff, _screen.pitch * _screen.height);
00116 
00117         for (y = 0; y < height; y++) {
00118           src = row_pointers[y];
00119           dst = ((uint8 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff;
00120 
00121           memcpy(dst, src, width);
00122         }
00123 
00124         for (i = 0; i < num_palette; i++) {
00125           _cur_palette[i].r = palette[i].red;
00126           _cur_palette[i].g = palette[i].green;
00127           _cur_palette[i].b = palette[i].blue;
00128         }
00129 
00130         _cur_palette[0xff].r = 0;
00131         _cur_palette[0xff].g = 0;
00132         _cur_palette[0xff].b = 0;
00133 
00134         _pal_first_dirty = 0;
00135         _pal_count_dirty = 256;
00136       }
00137       break;
00138     case 32: {
00139         uint32 *dst;
00140         uint x;
00141 
00142         memset(_screen.dst_ptr, 0xff000000, _screen.pitch * _screen.height * 4);
00143 
00144         for (y = 0; y < height; y++) {
00145           src = row_pointers[y];
00146           dst = ((uint32 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff;
00147 
00148           for (x = 0; x < width; x++)
00149             dst[x] = palette[src[x]].blue | (palette[src[x]].green << 8) | (palette[src[x]].red << 16) | 0xff000000;
00150         }
00151       }
00152       break;
00153   }
00154 
00155   png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00156   fclose(f);
00157   return;
00158 }
00159 
00160 
00161 
00162 #else /* WITH_PNG */
00163 
00164 void DisplaySplashImage() {}
00165 
00166 #endif /* WITH_PNG */

Generated on Wed Oct 1 17:03:22 2008 for openttd by  doxygen 1.5.6