File: ImageLoader.cpp

package info (click to toggle)
freedink 109.6-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,956 kB
  • sloc: ansic: 27,668; cpp: 23,643; sh: 5,524; java: 1,224; makefile: 257; javascript: 106; xml: 103; perl: 52; python: 17; sed: 16
file content (83 lines) | stat: -rw-r--r-- 3,174 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "config.h"

#include "ImageLoader.h"

#include "SDL.h"
#include "SDL_image.h"
#include "log.h"

/* Reference palette: this is the canonical Dink palette, loaded from
   TS01.bmp (for freedink) and esplash.bmp (for freedinkedit). The
   physical screen may be changed (e.g. show_bmp()), but this
   canonical palette will stay constant. */
SDL_Color GFX_ref_pal[256];
/* Reference blit surface that all others should mimic to avoid palette dithering;
 * GFX_ref_pal may change, but not this surface's palette */
// TODO: make IOGfxDisplaySW->blit *not* do any palette conversion, so we can get rid of this global
SDL_Surface* ImageLoader::blitFormat = NULL;

void ImageLoader::initBlitFormat(Uint32 format) {
	Uint32 Rmask=0, Gmask=0, Bmask=0, Amask=0; int bpp=0;
	SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
	ImageLoader::blitFormat = SDL_CreateRGBSurface(0, 1, 1, bpp,
			Rmask, Gmask, Bmask, Amask);
	if (format == SDL_PIXELFORMAT_INDEX8) {
		SDL_SetPaletteColors(ImageLoader::blitFormat->format->palette, GFX_ref_pal, 0, 256);
	}
}

/**
 * Load image to the current display format (indexed or truecolor)
 * This isn't centralized in display->upload() because dir.ff are handled differently,
 * and this is done independently of the target display renderer.
 */
SDL_Surface* ImageLoader::loadToBlitFormat(FILE* in) {
	if (in == NULL)
		return NULL;

	SDL_RWops* rw = SDL_RWFromFP(in, /*autoclose=*/SDL_TRUE);
	SDL_Surface* image = IMG_Load_RW(rw, 1);
	if (blitFormat->format->format == SDL_PIXELFORMAT_INDEX8)
		image = convertToPaletteFormat(image);

	/* Disable alpha in 32bit BMPs, like the original engine */
	SDL_SetSurfaceBlendMode(image, SDL_BLENDMODE_NONE);

	return image;
}

/**
 * Make a copy of the surface using the screen format: same
 * palette (with dithering), and same color depth (needed when
 * importing 24bit graphics in 8bit mode).
 */
SDL_Surface* ImageLoader::convertToPaletteFormat(SDL_Surface* image) {
	SDL_Surface *converted = SDL_CreateRGBSurface(0, image->w, image->h, 8, 0,0,0,0);
	SDL_SetPaletteColors(converted->format->palette, GFX_ref_pal, 0, 256);
	SDL_BlitSurface(image, NULL, converted, NULL);
	Uint32 key;
	if (SDL_GetColorKey(image, &key) == 0)
		SDL_SetColorKey(converted, SDL_TRUE, key);
	SDL_FreeSurface(image);
	/* Disable palette conversion in future blits */
	SDL_SetPaletteColors(converted->format->palette, blitFormat->format->palette->colors, 0, 256);
	return converted;
}

SDL_Surface* ImageLoader::newWithBlitFormat(int w, int h) {
	SDL_Surface* image;
	if (blitFormat->format->format == SDL_PIXELFORMAT_INDEX8) {
		image = SDL_CreateRGBSurface(0, w, h, 8, 0,0,0,0);
		if (image == NULL) {
			log_error("ImageLoader::newWithPaletteFormat: %s", SDL_GetError());
			return NULL;
		}
		/* Disable palette conversion in future blits */
		SDL_SetPaletteColors(image->format->palette, blitFormat->format->palette->colors, 0, 256);
	} else {
		Uint32 Rmask=0, Gmask=0, Bmask=0, Amask=0; int bpp=0;
		SDL_PixelFormatEnumToMasks(blitFormat->format->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
		image = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
	}
	return image;
}