Add PNG support
This commit is contained in:
@@ -261,12 +261,13 @@ WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \
|
|||||||
../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \
|
../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \
|
||||||
../win/X11/winval.c ../win/X11/winlabel.c \
|
../win/X11/winval.c ../win/X11/winlabel.c \
|
||||||
../win/share/tileset.c ../win/share/bmptiles.c ../win/share/giftiles.c \
|
../win/share/tileset.c ../win/share/bmptiles.c ../win/share/giftiles.c \
|
||||||
$(GENTILECFILE)
|
../win/share/pngtiles.c $(GENTILECFILE)
|
||||||
WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \
|
WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \
|
||||||
$(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \
|
$(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \
|
||||||
$(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \
|
$(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \
|
||||||
$(TARGETPFX)winval.o $(TARGETPFX)winlabel.o \
|
$(TARGETPFX)winval.o $(TARGETPFX)winlabel.o \
|
||||||
$(TARGETPFX)tileset.o $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o
|
$(TARGETPFX)tileset.o $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \
|
||||||
|
$(TARGETPFX)pngtiles.o
|
||||||
#
|
#
|
||||||
# Files for a Qt 3 interface (renamed since nethack 3.6.x)
|
# Files for a Qt 3 interface (renamed since nethack 3.6.x)
|
||||||
#
|
#
|
||||||
@@ -1113,6 +1114,9 @@ $(TARGETPFX)bmptiles.o: ../win/share/bmptiles.c $(CONFIG_H) \
|
|||||||
$(TARGETPFX)giftiles.o: ../win/share/giftiles.c $(CONFIG_H) \
|
$(TARGETPFX)giftiles.o: ../win/share/giftiles.c $(CONFIG_H) \
|
||||||
../include/objclass.h ../include/tileset.h
|
../include/objclass.h ../include/tileset.h
|
||||||
$(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/giftiles.c
|
$(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/giftiles.c
|
||||||
|
$(TARGETPFX)pngtiles.o: ../win/share/pngtiles.c $(CONFIG_H) \
|
||||||
|
../include/objclass.h ../include/tileset.h
|
||||||
|
$(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/pngtiles.c
|
||||||
$(TARGETPFX)wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H)
|
$(TARGETPFX)wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H)
|
||||||
$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainin.c
|
$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainin.c
|
||||||
$(TARGETPFX)wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H)
|
$(TARGETPFX)wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H)
|
||||||
|
|||||||
@@ -398,6 +398,7 @@ endif # MAKEFILE_SRC
|
|||||||
ifdef WANT_WIN_X11
|
ifdef WANT_WIN_X11
|
||||||
USE_XPM=1
|
USE_XPM=1
|
||||||
USE_XFT=1
|
USE_XFT=1
|
||||||
|
USE_PNG=1
|
||||||
WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11
|
WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11
|
||||||
VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm
|
VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm
|
||||||
ifndef CROSSCOMPILE
|
ifndef CROSSCOMPILE
|
||||||
@@ -419,6 +420,10 @@ CFLAGS += -DUSE_XPM
|
|||||||
WINX11LIB += -lXpm
|
WINX11LIB += -lXpm
|
||||||
VARDATND0 += rip.xpm
|
VARDATND0 += rip.xpm
|
||||||
endif
|
endif
|
||||||
|
ifdef USE_PNG
|
||||||
|
CFLAGS += -DUSE_PNG
|
||||||
|
WINX11LIB += -lpng
|
||||||
|
endif
|
||||||
WINLIB += $(WINX11LIB)
|
WINLIB += $(WINX11LIB)
|
||||||
LFLAGS+=-L/opt/X11/lib
|
LFLAGS+=-L/opt/X11/lib
|
||||||
endif # WANT_WIN_X11
|
endif # WANT_WIN_X11
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ endif # WANT_WIN_CHAIN
|
|||||||
ifdef WANT_WIN_X11
|
ifdef WANT_WIN_X11
|
||||||
USE_XFT=1
|
USE_XFT=1
|
||||||
USE_XPM=1
|
USE_XPM=1
|
||||||
|
USE_PNG=1
|
||||||
WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11
|
WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11
|
||||||
VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm
|
VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm
|
||||||
GENTILEOFILE = $(SRCDIR)/tile.o
|
GENTILEOFILE = $(SRCDIR)/tile.o
|
||||||
@@ -298,6 +299,10 @@ CFLAGS += -DUSE_XPM
|
|||||||
WINX11LIB += -lXpm
|
WINX11LIB += -lXpm
|
||||||
VARDATND0 += rip.xpm
|
VARDATND0 += rip.xpm
|
||||||
endif
|
endif
|
||||||
|
ifdef USE_PNG
|
||||||
|
CFLAGS += -DUSE_PNG
|
||||||
|
WINX11LIB += -lpng
|
||||||
|
endif
|
||||||
WINLIB += $(WINX11LIB)
|
WINLIB += $(WINX11LIB)
|
||||||
LFLAGS += -L/opt/X11/lib
|
LFLAGS += -L/opt/X11/lib
|
||||||
endif # WANT_WIN_X11
|
endif # WANT_WIN_X11
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
#include "config.h"
|
||||||
|
#include "tileset.h"
|
||||||
|
|
||||||
|
#ifdef USE_PNG
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
boolean
|
||||||
|
read_png_tiles(const char *filename, struct TileSetImage *image)
|
||||||
|
{
|
||||||
|
png_structp read_png_ptr = NULL; /* custodial */
|
||||||
|
png_infop read_info_ptr = NULL; /* custodial */
|
||||||
|
png_infop read_end_info = NULL; /* custodial */
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
unsigned char header[8];
|
||||||
|
size_t size, num_pixels;
|
||||||
|
unsigned x, y;
|
||||||
|
png_bytepp pixels;
|
||||||
|
png_byte color_type;
|
||||||
|
int palette_size = 0;
|
||||||
|
png_textp text_chunks;
|
||||||
|
int num_text_chunks, i;
|
||||||
|
|
||||||
|
image->width = 0;
|
||||||
|
image->height = 0;
|
||||||
|
image->indexes = NULL; /* custodial, returned */
|
||||||
|
image->pixels = NULL; /* custodial, returned */
|
||||||
|
image->image_desc = NULL; /* custodial, returned */
|
||||||
|
image->tile_width = 0;
|
||||||
|
image->tile_height = 0;
|
||||||
|
|
||||||
|
/* Open the file */
|
||||||
|
fp = fopen(filename, "rb");
|
||||||
|
if (fp == NULL) goto error;
|
||||||
|
|
||||||
|
/* Check for PNG format */
|
||||||
|
memset(header, 0, sizeof(header));
|
||||||
|
size = fread(header, 1, sizeof(header), fp);
|
||||||
|
if (size < sizeof(header)) goto error;
|
||||||
|
if (png_sig_cmp(header, 0, sizeof(header)) != 0) goto error;
|
||||||
|
|
||||||
|
/* Create read info structures */
|
||||||
|
read_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
if (read_png_ptr == NULL) goto error;
|
||||||
|
if (setjmp(png_jmpbuf(read_png_ptr)) != 0) goto error;
|
||||||
|
read_info_ptr = png_create_info_struct(read_png_ptr);
|
||||||
|
read_end_info = png_create_info_struct(read_png_ptr);
|
||||||
|
|
||||||
|
/* Link the file we opened to the read info */
|
||||||
|
png_init_io(read_png_ptr, fp);
|
||||||
|
png_set_sig_bytes(read_png_ptr, sizeof(header));
|
||||||
|
|
||||||
|
/* Read the image */
|
||||||
|
png_read_png(read_png_ptr, read_info_ptr,
|
||||||
|
PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16, NULL);
|
||||||
|
|
||||||
|
pixels = png_get_rows(read_png_ptr, read_info_ptr);
|
||||||
|
image->width = png_get_image_width(read_png_ptr, read_info_ptr);
|
||||||
|
image->height = png_get_image_height(read_png_ptr, read_info_ptr);
|
||||||
|
color_type = png_get_color_type(read_png_ptr, read_info_ptr);
|
||||||
|
|
||||||
|
/* Read the palette, if there is one */
|
||||||
|
if (color_type & PNG_COLOR_MASK_PALETTE) {
|
||||||
|
png_colorp palette = NULL;
|
||||||
|
png_bytep trans_alpha;
|
||||||
|
int num_trans;
|
||||||
|
|
||||||
|
png_get_PLTE(read_png_ptr, read_info_ptr, &palette, &palette_size);
|
||||||
|
for (i = 0; i < 256; ++i) {
|
||||||
|
image->palette[i].r = palette[i].red;
|
||||||
|
image->palette[i].g = palette[i].green;
|
||||||
|
image->palette[i].b = palette[i].blue;
|
||||||
|
image->palette[i].a = 255;
|
||||||
|
}
|
||||||
|
if (png_get_tRNS(read_png_ptr, read_info_ptr, &trans_alpha, &num_trans,
|
||||||
|
NULL) != 0) {
|
||||||
|
for (i = 0; i < num_trans; ++i) {
|
||||||
|
image->palette[i].a = trans_alpha[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate pixel area; watch out for overflow */
|
||||||
|
num_pixels = (size_t) image->width * (size_t) image->height;
|
||||||
|
if (num_pixels / image->width != image->height) goto error; /* overflow */
|
||||||
|
size = num_pixels * sizeof(image->pixels[0]);
|
||||||
|
if (size / sizeof(image->pixels[0]) != num_pixels) goto error; /* overflow */
|
||||||
|
image->pixels = (struct Pixel *) alloc(size);
|
||||||
|
if (color_type & PNG_COLOR_MASK_PALETTE) {
|
||||||
|
image->indexes = (unsigned char *) alloc(num_pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the pixels */
|
||||||
|
for (y = 0; y < image->height; ++y) {
|
||||||
|
png_bytep png_row = pixels[y];
|
||||||
|
size_t index = y * image->width;
|
||||||
|
for (x = 0; x < image->width; ++x) {
|
||||||
|
if (color_type & PNG_COLOR_MASK_PALETTE) {
|
||||||
|
png_byte b = *png_row++;
|
||||||
|
image->indexes[index] = b;
|
||||||
|
image->pixels[index] = image->palette[b];
|
||||||
|
} else {
|
||||||
|
if (color_type & PNG_COLOR_MASK_COLOR) {
|
||||||
|
image->pixels[index].r = *png_row++;
|
||||||
|
image->pixels[index].g = *png_row++;
|
||||||
|
image->pixels[index].b = *png_row++;
|
||||||
|
} else {
|
||||||
|
image->pixels[index].r = *png_row++;
|
||||||
|
image->pixels[index].g = image->pixels[index].r;
|
||||||
|
image->pixels[index].b = image->pixels[index].r;
|
||||||
|
}
|
||||||
|
if (color_type & PNG_COLOR_MASK_ALPHA) {
|
||||||
|
image->pixels[index].a = *png_row++;
|
||||||
|
} else {
|
||||||
|
image->pixels[index].a = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for the tile information */
|
||||||
|
png_get_text(read_png_ptr, read_info_ptr, &text_chunks, &num_text_chunks);
|
||||||
|
for (i = 0; i < num_text_chunks; ++i) {
|
||||||
|
if (strcmp(text_chunks[i].key, "NH_image_desc") == 0) {
|
||||||
|
image->image_desc = (char *) alloc(text_chunks[i].text_length + 1);
|
||||||
|
memcpy(image->image_desc, text_chunks[i].text, text_chunks[i].text_length);
|
||||||
|
text_chunks[i].text[text_chunks[i].text_length] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
png_destroy_read_struct(&read_png_ptr, &read_info_ptr, &read_end_info);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (read_png_ptr) {
|
||||||
|
png_destroy_read_struct(&read_png_ptr, &read_info_ptr, &read_end_info);
|
||||||
|
}
|
||||||
|
free(image->indexes);
|
||||||
|
image->indexes = NULL;
|
||||||
|
free(image->pixels);
|
||||||
|
image->pixels = NULL;
|
||||||
|
free(image->image_desc);
|
||||||
|
image->image_desc = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user