SDL_Surface *TCOD_sys_read_png(const char *filename) {
	unsigned error;
	unsigned char* image;
	unsigned width, height, y, bpp;
	unsigned char* png;
	size_t pngsize;
	LodePNGState state;
	SDL_Surface *bitmap;
	unsigned char *source;
	unsigned int rowsize;

	lodepng_state_init(&state);
	/*optionally customize the state*/
	if (!TCOD_sys_read_file(filename,&png,&pngsize)) return NULL;

	lodepng_inspect(&width,&height,&state, png, pngsize);
	bpp=lodepng_get_bpp(&state.info_png.color);

	if ( bpp == 24 ) {
		/* don't convert to 32 bits because libtcod's 24bits renderer is faster */
		state.info_raw.colortype=LCT_RGB;
	} else if (  bpp != 24 && bpp != 32 ) { 
		/* paletted png. convert to 24 bits */
		state.info_raw.colortype=LCT_RGB;
		state.info_raw.bitdepth=8;
		bpp=24;
	}
	error = lodepng_decode(&image, &width, &height, &state, png, pngsize);
	free(png);
	if(error) {
		printf("error %u: %s\n", error, lodepng_error_text(error));
		lodepng_state_cleanup(&state);
		return NULL;
	}
		
	/* create the SDL surface */
	bitmap=TCOD_sys_get_surface(width,height,bpp==32);
	source=image;
	rowsize=width*bpp/8;
	for (y=0; y<  height; y++ ) {
		Uint8 *row_pointer=(Uint8 *)(bitmap->pixels) + y * bitmap->pitch;
		memcpy(row_pointer,source,rowsize);
		source+=rowsize;
	}

	lodepng_state_cleanup(&state);
	free(image);	
	return bitmap;
}
Beispiel #2
0
void *TCOD_sys_create_bitmap_for_console(TCOD_console_t console) {
	int w,h;
	w = TCOD_console_get_width(console) * fontWidth;
	h = TCOD_console_get_height(console) * fontHeight;
	return TCOD_sys_get_surface(w,h,false);
}
Beispiel #3
0
SDL_Surface *TCOD_sys_read_png(const char *filename) {
	png_uint_32 png_width,png_height,y;
	int png_bit_depth,png_color_type,png_interlace_type;
	png_structp png_ptr;
	png_infop info_ptr;
	FILE *fp;
	SDL_Surface *bitmap;
	png_bytep *row_pointers;

	if ((fp = fopen(filename, "rb")) == NULL)
		return NULL;
	/* Create and initialize the png_struct with the desired error handler
	* functions.  If you want to use the default stderr and longjump method,
	* you can supply NULL for the last three parameters.  We also supply the
	* the compiler header file version, so that we know if the application
	* was compiled with a compatible version of the library.  REQUIRED
	*/
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL);

	if (png_ptr == NULL)
	{
		fclose(fp);
		return NULL;
	}

	/* Allocate/initialize the memory for image information.  REQUIRED. */
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		fclose(fp);
		png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
		return NULL;
	}

	/* Set error handling if you are using the setjmp/longjmp method (this is
	* the normal method of doing things with libpng).  REQUIRED unless you
	* set up your own error handlers in the png_create_read_struct() earlier.
	*/

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		/* Free all of the memory associated with the png_ptr and info_ptr */
		png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
		fclose(fp);
		/* If we get here, we had a problem reading the file */
		return NULL;
	}

	png_init_io(png_ptr, fp);

	/*
	* If you have enough memory to read in the entire image at once,
	* and you need to specify only transforms that can be controlled
	* with one of the PNG_TRANSFORM_* bits (this presently excludes
	* dithering, filling, setting background, and doing gamma
	* adjustment), then you can read the entire image (including
	* pixels) into the info structure with this call:
	*/
	/*png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); */

	/* get info about the image */
	png_read_info(png_ptr,info_ptr);
	png_get_IHDR(png_ptr,info_ptr,&png_width,&png_height,&png_bit_depth,&png_color_type,
		&png_interlace_type,NULL,NULL);

	/* convert the image to a format suitable with libtcod */
	png_set_strip_16(png_ptr); /* 16 bits channels => 8 bits channels */
	png_set_packing(png_ptr); /* 1,2,4 bits depth => 24/32 bits depth */
	if ( png_color_type == PNG_COLOR_TYPE_GRAY ) png_set_expand(png_ptr); /* grayscale => color */
	if ( png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) png_set_gray_to_rgb(png_ptr);

	/* update the image information */
	png_read_update_info(png_ptr,info_ptr);
	png_get_IHDR(png_ptr,info_ptr,&png_width,&png_height,&png_bit_depth,&png_color_type,
		&png_interlace_type,NULL,NULL);

	/* create the SDL surface */
	bitmap=TCOD_sys_get_surface(png_width,png_height,info_ptr->channels == 4);

	/* get row data */
	row_pointers=(png_bytep *)malloc(sizeof(png_bytep)*png_height);
	for (y=0; y<  png_height; y++ ) {
		row_pointers[y]=(png_bytep)(Uint8 *)(bitmap->pixels) + y * bitmap->pitch;
	}

	/* read png data directly into the SDL surface */
	png_read_image(png_ptr,row_pointers);

	/* clean up after the read, and free any memory allocated - REQUIRED */
	png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
	free(row_pointers);

	/* close the file */
	fclose(fp);
	return bitmap;
}
Beispiel #4
0
void TCOD_sys_load_font() {
	int i;
	bool hasTransparent=false;
	int x,y;

	charmap=TCOD_sys_load_image(font_file);
	if (charmap == NULL ) TCOD_fatal("SDL : cannot load %s",font_file);
	if ( (float)(charmap->w / fontNbCharHoriz) != charmap->w / fontNbCharHoriz
		|| (float)(charmap->h / fontNbCharVertic) != charmap->h / fontNbCharVertic ) TCOD_fatal(" %s size is not a multiple of font layout (%dx%d)\n",
		font_file,fontNbCharHoriz,fontNbCharVertic);
	fontWidth=charmap->w/fontNbCharHoriz;
	fontHeight=charmap->h/fontNbCharVertic;
	check_ascii_to_tcod();
	// figure out what kind of font we have
	// check if the alpha layer is actually used
	if ( charmap->format->BytesPerPixel == 4 )
	for (x=0; !hasTransparent && x < charmap->w; x ++ ) {
		for (y=0;!hasTransparent && y < charmap->h; y++ ) {
			Uint8 *pixel=(Uint8 *)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel;
			Uint8 alpha=*((pixel)+charmap->format->Ashift/8);
			if ( alpha < 255 ) {
				hasTransparent=true;
			}
		}
	}
	if (! hasTransparent ) {
		// 24 bit font. check if greyscale
		int x,y,keyx,keyy;
        Uint8 *pixel;
		// the key color is found on the character corresponding to space ' '
		if ( fontTcodLayout ) {
			keyx = fontWidth/2;
			keyy = fontHeight/2;
		} else if (fontInRow) {
			keyx = ((int)(' ') % fontNbCharHoriz ) * fontWidth + fontWidth/2;
			keyy = ((int)(' ') / fontNbCharHoriz ) * fontHeight + fontHeight/2;
		} else {
			keyx = ((int)(' ') / fontNbCharVertic ) * fontWidth + fontWidth/2;
			keyy = ((int)(' ') % fontNbCharVertic ) * fontHeight + fontHeight/2;
		}
		pixel=(Uint8 *)(charmap->pixels) + keyy * charmap->pitch + keyx * charmap->format->BytesPerPixel;
		fontKeyCol.r=*((pixel)+charmap->format->Rshift/8);
		fontKeyCol.g=*((pixel)+charmap->format->Gshift/8);
		fontKeyCol.b=*((pixel)+charmap->format->Bshift/8);
		// convert greyscale to font with alpha layer
		if ( fontIsGreyscale ) {
			bool invert=( fontKeyCol.r > 128 ); // black on white font ?
			// convert it to 32 bits if needed
			if ( charmap->format->BytesPerPixel != 4 ) {
				SDL_Surface *temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,true);
				SDL_BlitSurface(charmap,NULL,temp,NULL);
				SDL_FreeSurface(charmap);
				charmap=temp;
			}
			for (x=0; x < charmap->w; x ++ ) {
				for (y=0;y < charmap->h; y++ ) {
					Uint8 *pixel=(Uint8 *)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel;
					Uint8 r=*((pixel)+charmap->format->Rshift/8);
					*((pixel)+charmap->format->Ashift/8) = (invert ? 255-r : r);
					*((pixel)+charmap->format->Rshift/8)=255;
					*((pixel)+charmap->format->Gshift/8)=255;
					*((pixel)+charmap->format->Bshift/8)=255;
				}
			}
		} else {
			// alpha layer not used. convert to 24 bits (faster)
			SDL_Surface *temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,false);
			SDL_BlitSurface(charmap,NULL,temp,NULL);
			SDL_FreeSurface(charmap);
			charmap=temp;
		}
	}
	/*
	charmap=SDL_CreateRGBSurface(SDL_SWSURFACE,charmap->w,charmap->h,24,0xFF0000, 0xFF00, 0xFF, 0);
	if ( SDL_MUSTLOCK( charmap ) ) SDL_LockSurface( charmap );
	SDL_BlitSurface(charmap,NULL,charmap,NULL);
	*/
	sdl_key=SDL_MapRGB(charmap->format,fontKeyCol.r,fontKeyCol.g,fontKeyCol.b);
	rgb_mask=charmap->format->Rmask|charmap->format->Gmask|charmap->format->Bmask;
	nrgb_mask = ~ rgb_mask;
	sdl_key &= rgb_mask; // remove the alpha part
	if ( charmap->format->BytesPerPixel == 3 ) SDL_SetColorKey(charmap,SDL_SRCCOLORKEY|SDL_RLEACCEL,sdl_key);
	for (i=0; i < fontNbCharHoriz*fontNbCharVertic; i++ ) {
		charcols[i]=fontKeyCol;
		first_draw[i]=true;
	}
	check_ascii_to_tcod();
	if (!fontTcodLayout) {
		// apply standard ascii mapping
		for (i=0; i < TCOD_max_font_chars; i++ ) ascii_to_tcod[i]=i;
	}
}