00001
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
00163
00164 void DisplaySplashImage() {}
00165
00166 #endif