27 #include "precompiled.h"
43 # pragma warning(disable: 4611)
56 : data(data), size(size),
pos(0)
80 static void io_read(png_struct* png_ptr,
rpU8 data, png_size_t size)
85 png_error(png_ptr,
"PNG: not enough input");
89 stream->
CopyTo(data, size);
94 static void io_write(png_struct* png_ptr,
u8* data, png_size_t length)
98 png_error(png_ptr,
"io_write failed");
123 png_set_read_fn(png_ptr, stream,
io_read);
126 png_read_info(png_ptr, info_ptr);
128 int bit_depth, colour_type;
129 png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &colour_type, 0, 0, 0);
130 const size_t pitch = png_get_rowbytes(png_ptr, info_ptr);
131 const u32 bpp = (
u32)(pitch/w * 8);
136 if(colour_type == PNG_COLOR_TYPE_GRAY)
142 if(colour_type & PNG_COLOR_MASK_PALETTE)
145 const size_t img_size = pitch * h;
150 png_read_image(png_ptr, (png_bytepp)&rows[0]);
151 png_read_end(png_ptr, info_ptr);
173 const png_uint_32 w = (png_uint_32)t->
w, h = (png_uint_32)t->
h;
174 const size_t pitch = w * t->
bpp / 8;
180 colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
183 colour_type = PNG_COLOR_TYPE_GRAY;
186 colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
189 colour_type = PNG_COLOR_TYPE_RGB;
194 png_set_IHDR(png_ptr, info_ptr, w, h, 8, colour_type,
195 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
201 const int png_transforms = (t->
flags &
TEX_BGR)? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY;
203 png_set_rows(png_ptr, info_ptr, (png_bytepp)&rows[0]);
204 png_write_png(png_ptr, info_ptr, png_transforms, 0);
215 return *(
u32*)file ==
FOURCC(
'\x89',
'P',
'N',
'G');
221 return extension == L
".png";
238 png_infop info_ptr = 0;
241 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
244 info_ptr = png_create_info_struct(png_ptr);
247 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
251 if(setjmp(png_jmpbuf(png_ptr)))
254 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
261 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
271 png_infop info_ptr = 0;
274 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
277 info_ptr = png_create_info_struct(png_ptr);
282 if(setjmp(png_jmpbuf(png_ptr)))
292 png_destroy_write_struct(&png_ptr, &info_ptr);
const Status TEX_INVALID_COLOR_TYPE
static bool png_is_hdr(const u8 *file)
size_t ofs
offset to image data in file.
static const size_t pageSize
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
const Status TEX_CODEC_CANNOT_HANDLE
size_t RemainingSize() const
static Status png_decode_impl(MemoryStream *stream, png_structp png_ptr, png_infop info_ptr, Tex *t)
void CopyTo(rpU8 dst, size_t dstSize)
indicates the image contains an alpha channel.
provides a memory range that can be expanded but doesn't waste physical memory or relocate itself...
shared_ptr< u8 > data
file buffer or image data.
indicates the image is 8bpp greyscale.
#define ASSERT(expr)
same as ENSURE in debug mode, does nothing in release mode.
static Status png_encode(Tex *RESTRICT t, DynArray *RESTRICT da)
static void io_write(png_struct *png_ptr, u8 *data, png_size_t length)
indicates B and R pixel components are exchanged.
#define TIMER_ACCRUE(client)
Measure the time taken to execute code up until end of the current scope; bill it to the given TimerC...
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
#define FOURCC(a, b, c, d)
convert 4 characters to u32 (at compile time) for easy comparison.
std::vector< RowPtr > tex_codec_alloc_rows(const u8 *data, size_t h, size_t pitch, size_t src_flags, size_t dst_orientation)
const Status TEX_NOT_8BIT_PRECISION
static Status png_encode_impl(Tex *t, png_structp png_ptr, png_infop info_ptr, DynArray *da)
u8 * tex_get_data(const Tex *t)
rationale: since Tex is a struct, its fields are accessible to callers.
static bool png_is_ext(const OsPath &extension)
Status da_append(DynArray *da, const void *data, size_t size)
"write" to array, i.e.
i64 Status
Error handling system.
stores all data describing an image.
static Status png_decode(rpU8 data, size_t size, Tex *RESTRICT t)
#define TIMER_ADD_CLIENT(id)
"allocate" a new TimerClient that will keep track of the total time billed to it, along with a descri...
static Status AllocateAligned(shared_ptr< T > &p, size_t size, size_t alignment=cacheLineSize)
MemoryStream(rpU8 data, size_t size)
static size_t png_hdr_size(const u8 *file)
#define TEX_CODEC_REGISTER(name)
build codec vtbl and register it.
#define WARN_RETURN(status)
static void io_read(png_struct *png_ptr, rpU8 data, png_size_t size)
static Status png_transform(Tex *t, size_t transforms)
size_t flags
see TexFlags and "Format Conversion" in docs.
static void io_flush(png_structp png_ptr)