Skip to content

Commit

Permalink
convert: Use libpng for image output.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Mar 6, 2020
1 parent 99cc0bc commit 9ba6514
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 7 deletions.
29 changes: 29 additions & 0 deletions buildsystem/modules/FindLibpng.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2020-2020 the openage authors. See copying.md for legal info.

# - Find libpng library
# Find the native libpng headers and library.
# This module defines
# LIBPNG_INCLUDE_DIRS - where to find ogg/ogg.h etc.
# LIBPNG_LIBRARIES - List of libraries when using libogg
# LIBPNG_FOUND - True if ogg is found.

find_path(LIBPNG_INCLUDE_DIR
NAMES libpng/png.h
DOC "libpng include directory"
)

find_library(LIBPNG_LIBRARY
NAMES png
DOC "Path to libpng library"
)

# handle the QUIETLY and REQUIRED arguments and set LIBPNG_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libpng DEFAULT_MSG LIBPNG_INCLUDE_DIR LIBPNG_LIBRARY)

mark_as_advanced(LIBPNG_INCLUDE_DIR LIBPNG_LIBRARY)

# export the variables
set(LIBPNG_INCLUDE_DIRS "${LIBPNG_INCLUDE_DIR}")
set(LIBPNG_LIBRARIES "${LIBPNG_LIBRARY}")
1 change: 1 addition & 0 deletions openage/convert/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ add_subdirectory(hardcoded)
add_subdirectory(interface)
add_subdirectory(nyan)
add_subdirectory(opus)
add_subdirectory(png)
add_subdirectory(processor)
2 changes: 0 additions & 2 deletions openage/convert/opus/ogg.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ cdef extern from "ogg/ogg.h":
ogg_int64_t granulepos
ogg_int64_t packetno



int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op)
int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og)
int ogg_stream_flush(ogg_stream_state *os, ogg_page *og)
Expand Down
27 changes: 27 additions & 0 deletions openage/convert/png/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
find_package(Libpng REQUIRED)

# Currently there is no way to link cython modules to extra libraries.
# Since PYEXT_LINK_LIBRARY normally only includes libopenage (what
# opusenc doesn't need), we hijack this variable. This is ok, because
# there are no subdirectories, that will see the changed variable.
set(PYEXT_LINK_LIBRARY
${LIBPNG_LIBRARIES}
)

set(PYEXT_INCLUDE_DIRS
${PYEXT_INCLUDE_DIRS}
${LIBPNG_INCLUDE_DIRS}
)

add_cython_modules(
png_create.pyx
)

add_pxds(
__init__.pxd
libpng.pxd
)

add_py_modules(
__init__.py
)
Empty file.
5 changes: 5 additions & 0 deletions openage/convert/png/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2020-2020 the openage authors. See copying.md for legal info.

"""
Cython module to create png files using libpng.
"""
59 changes: 59 additions & 0 deletions openage/convert/png/libpng.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright 2020-2020 the openage authors. See copying.md for legal info.

from libc.stdio cimport FILE

cdef extern from "libpng/png.h":
const char PNG_LIBPNG_VER_STRING[]
const int PNG_COLOR_TYPE_RGBA = 6
const int PNG_INTERLACE_NONE = 0
const int PNG_COMPRESSION_TYPE_DEFAULT = 0
const int PNG_FILTER_TYPE_DEFAULT = 0
const int PNG_TRANSFORM_IDENTITY = 0

ctypedef unsigned char png_byte
ctypedef png_byte** png_bytepp
ctypedef unsigned long int png_uint_32

ctypedef struct png_struct
ctypedef png_struct* png_structp
ctypedef png_struct* png_structrp
ctypedef png_struct** png_structpp
ctypedef const png_struct* png_const_structrp

ctypedef struct png_info
ctypedef png_info* png_infop
ctypedef png_info* png_inforp
ctypedef png_info** png_infopp

ctypedef const char* png_const_charp
ctypedef void* png_voidp
ctypedef (png_structp, png_const_charp)* png_error_ptr
ctypedef FILE* png_FILE_p

png_structp png_create_write_struct(png_const_charp user_png_ver,
png_voidp error_ptr,
png_error_ptr error_fn,
png_error_ptr warn_fn)

png_infop png_create_info_struct(png_const_structrp png_ptr)

void png_set_IHDR(png_const_structrp png_ptr,
png_inforp info_ptr,
png_uint_32 width,
png_uint_32 height,
int bit_depth,
int color_type,
int interlace_method,
int compression_method,
int filter_method)
void png_init_io(png_structrp png_ptr,
png_FILE_p fp)
void png_set_rows(png_const_structrp png_ptr,
png_inforp info_ptr,
png_bytepp row_pointers)
void png_write_png(png_structrp png_ptr,
png_inforp info_ptr,
int transforms,
png_voidp params)
void png_destroy_write_struct(png_structpp png_ptr_ptr,
png_infopp info_ptr_ptr)
55 changes: 55 additions & 0 deletions openage/convert/png/png_create.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2020-2020 the openage authors. See copying.md for legal info.
#
# cython: profile=False

from libc.stdio cimport fopen, fclose
from libc.stdint cimport uint8_t
from libc.stdlib cimport realloc
from cpython.mem cimport PyMem_Malloc

from . cimport libpng

cimport cython
import numpy
cimport numpy


@cython.boundscheck(False)
@cython.wraparound(False)
def save(filename, numpy.ndarray[numpy.uint8_t, ndim=3, mode="c"] imagedata not None):
"""
Save an image as a PNG file.
"""
cdef numpy.uint8_t[:,:,::1] mview = imagedata
cdef unsigned char* image = &mview[0,0,0]
png_create(filename.encode('UTF-8'), image)


cdef void png_create(char* filename, unsigned char* imagedata):
"""
Create a PNG file with libpng and write it to file.
"""
cdef libpng.png_FILE_p fp = fopen(filename, "wb")

cdef libpng.png_structp png
cdef libpng.png_infop info

png = libpng.png_create_write_struct(libpng.PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)
info = libpng.png_create_info_struct(png)

libpng.png_init_io(png, fp)
libpng.png_set_IHDR(png,
info,
sizeof(imagedata),
sizeof(imagedata[0]),
8,
libpng.PNG_COLOR_TYPE_RGBA,
libpng.PNG_INTERLACE_NONE,
libpng.PNG_COMPRESSION_TYPE_DEFAULT,
libpng.PNG_FILTER_TYPE_DEFAULT)
libpng.png_set_rows(png, info, &imagedata)
libpng.png_write_png(png, info, libpng.PNG_TRANSFORM_IDENTITY, NULL)

fclose(fp)

libpng.png_destroy_write_struct(&png, &info)
2 changes: 1 addition & 1 deletion openage/convert/slp.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ cdef numpy.ndarray determine_rgba_matrix(vector[vector[pixel]] &image_matrix,
cdef size_t height = image_matrix.size()
cdef size_t width = image_matrix[0].size()

cdef numpy.ndarray[numpy.uint8_t, ndim=3] array_data = \
cdef numpy.ndarray[numpy.uint8_t, ndim=3, mode="c"] array_data = \
numpy.zeros((height, width, 4), dtype=numpy.uint8)

# micro optimization to avoid call to ColorTable.__getitem__()
Expand Down
4 changes: 2 additions & 2 deletions openage/convert/smp.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ cdef numpy.ndarray determine_rgba_matrix(vector[vector[pixel]] &image_matrix,
cdef size_t height = image_matrix.size()
cdef size_t width = image_matrix[0].size()

cdef numpy.ndarray[numpy.uint8_t, ndim=3] array_data = \
cdef numpy.ndarray[numpy.uint8_t, ndim=3, mode="c"] array_data = \
numpy.zeros((height, width, 4), dtype=numpy.uint8)

# micro optimization to avoid call to ColorTable.__getitem__()
Expand Down Expand Up @@ -790,7 +790,7 @@ cdef numpy.ndarray determine_damage_matrix(vector[vector[pixel]] &image_matrix):
cdef size_t height = image_matrix.size()
cdef size_t width = image_matrix[0].size()

cdef numpy.ndarray[numpy.uint8_t, ndim=3] array_data = \
cdef numpy.ndarray[numpy.uint8_t, ndim=3, mode="c"] array_data = \
numpy.zeros((height, width, 4), dtype=numpy.uint8)

cdef uint8_t r
Expand Down
4 changes: 2 additions & 2 deletions openage/convert/smx.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@ cdef numpy.ndarray determine_rgba_matrix(vector[vector[pixel]] &image_matrix,
cdef size_t height = image_matrix.size()
cdef size_t width = image_matrix[0].size()

cdef numpy.ndarray[numpy.uint8_t, ndim=3] array_data = \
cdef numpy.ndarray[numpy.uint8_t, ndim=3, mode="c"] array_data = \
numpy.zeros((height, width, 4), dtype=numpy.uint8)

# micro optimization to avoid call to ColorTable.__getitem__()
Expand Down Expand Up @@ -1104,7 +1104,7 @@ cdef numpy.ndarray determine_damage_matrix(vector[vector[pixel]] &image_matrix):
cdef size_t height = image_matrix.size()
cdef size_t width = image_matrix[0].size()

cdef numpy.ndarray[numpy.uint8_t, ndim=3] array_data = \
cdef numpy.ndarray[numpy.uint8_t, ndim=3, mode="c"] array_data = \
numpy.zeros((height, width, 4), dtype=numpy.uint8)

cdef uint8_t r
Expand Down
7 changes: 7 additions & 0 deletions openage/convert/texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ def __init__(self, input_data, main_palette=None,
raise Exception("cannot create Texture "
"from unknown source type: %s" % (type(input_data)))

self.test_frame = frames[0].data # ASDF: Replace

self.image_data, (self.width, self.height), self.image_metadata\
= merge_frames(frames)

Expand Down Expand Up @@ -214,6 +216,11 @@ def save(self, targetdir, filename, meta_formats=None):
with targetdir[filename].open("wb") as imagefile:
self.image_data.get_pil_image().save(imagefile, ext)

from .png import png_create

if not isinstance(self.test_frame, TextureImage):
png_create.save("/tmp/test.png", self.test_frame)

if meta_formats:
# generate formatted texture metadata
formatter = data_formatter.DataFormatter()
Expand Down

0 comments on commit 9ba6514

Please sign in to comment.