# 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 */