diff --git a/contrib/pnglite/README.md b/contrib/pnglite/README.md index 4d2929600228..bbb5209b38b3 100644 --- a/contrib/pnglite/README.md +++ b/contrib/pnglite/README.md @@ -1,5 +1,5 @@ pnglite ==== #### A pretty small png library -Currently all documentation resides in pnglite.h. +Currently all documentation resides in pnglite.h. diff --git a/contrib/pnglite/pnglite.c b/contrib/pnglite/pnglite.c index 4899f24b6a85..e3cc2f866c6f 100644 --- a/contrib/pnglite/pnglite.c +++ b/contrib/pnglite/pnglite.c @@ -1,862 +1,628 @@ -/* pnglite.c - pnglite library - For conditions of distribution and use, see copyright notice in pnglite.h -*/ -#define DO_CRC_CHECKS 1 -#define USE_ZLIB 1 - -#if USE_ZLIB -#include +/* + * pnglite.c - pnglite library + * For conditions of distribution and use, see copyright notice in pnglite.h + */ + +/* + * Note: this source is updated to enable build for FreeBSD boot loader. + */ + +#ifdef _STANDALONE +#include +#include #else -#include "zlite.h" -#endif - #include #include -#include +#include +#include +#include +#endif +#include #include "pnglite.h" -static png_alloc_t png_alloc; -static png_free_t png_free; +#ifndef abs +#define abs(x) ((x) < 0? -(x):(x)) +#endif -static size_t file_read(png_t* png, void* out, size_t size, size_t numel) -{ - size_t result; - if(png->read_fun) - { - result = png->read_fun(out, size, numel, png->user_pointer); - } - else - { - if(!out) - { - result = fseek(png->user_pointer, (long)(size*numel), SEEK_CUR); - } - else - { - result = fread(out, size, numel, png->user_pointer); - } - } +#define PNG_32b(b, s) ((uint32_t)(b) << (s)) +#define PNG_U32(b1, b2, b3, b4) \ + (PNG_32b(b1, 24) | PNG_32b(b2, 16) | PNG_32b(b3, 8) | PNG_32b(b4, 0)) - return result; -} +#define png_IDAT PNG_U32(73, 68, 65, 84) +#define png_IEND PNG_U32(73, 69, 78, 68) -static size_t file_write(png_t* png, void* p, size_t size, size_t numel) +static ssize_t +file_read(png_t *png, void *out, size_t size, size_t numel) { - size_t result; + ssize_t result; + off_t offset = (off_t)(size * numel); - if(png->write_fun) - { - result = png->write_fun(p, size, numel, png->user_pointer); - } - else - { - result = fwrite(p, size, numel, png->user_pointer); + if (offset < 0) + return (PNG_FILE_ERROR); + + if (!out) { + result = lseek(png->fd, offset, SEEK_CUR); + } else { + result = read(png->fd, out, size * numel); } - return result; + return (result); } -static int file_read_ul(png_t* png, unsigned *out) +static int +file_read_ul(png_t *png, unsigned *out) { - unsigned char buf[4]; + uint8_t buf[4]; - if(file_read(png, buf, 1, 4) != 4) - return PNG_FILE_ERROR; + if (file_read(png, buf, 1, 4) != 4) + return (PNG_FILE_ERROR); *out = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3]; - return PNG_NO_ERROR; + return (PNG_NO_ERROR); } -static int file_write_ul(png_t* png, unsigned in) -{ - unsigned char buf[4]; - - buf[0] = (in>>24) & 0xff; - buf[1] = (in>>16) & 0xff; - buf[2] = (in>>8) & 0xff; - buf[3] = (in) & 0xff; - - if(file_write(png, buf, 1, 4) != 4) - return PNG_FILE_ERROR; - - return PNG_NO_ERROR; -} - -static unsigned get_ul(unsigned char* buf) +static unsigned +get_ul(uint8_t *buf) { unsigned result; - unsigned char foo[4]; + uint8_t foo[4]; memcpy(foo, buf, 4); result = (foo[0]<<24) | (foo[1]<<16) | (foo[2]<<8) | foo[3]; - return result; -} - -static unsigned set_ul(unsigned char* buf, unsigned in) -{ - buf[0] = (in>>24) & 0xff; - buf[1] = (in>>16) & 0xff; - buf[2] = (in>>8) & 0xff; - buf[3] = (in) & 0xff; - - return PNG_NO_ERROR; + return (result); } -int png_init(png_alloc_t pngalloc, png_free_t pngfree) -{ - if(pngalloc) - png_alloc = pngalloc; - else - png_alloc = &malloc; - - if(pngfree) - png_free = pngfree; - else - png_free = &free; - - return PNG_NO_ERROR; -} - -static int png_get_bpp(png_t* png) +static int +png_get_bpp(png_t *png) { int bpp; - switch(png->color_type) - { + switch (png->color_type) { case PNG_GREYSCALE: bpp = 1; break; case PNG_TRUECOLOR: bpp = 3; break; case PNG_INDEXED: bpp = 1; break; case PNG_GREYSCALE_ALPHA: bpp = 2; break; case PNG_TRUECOLOR_ALPHA: bpp = 4; break; default: - return PNG_FILE_ERROR; + return (PNG_FILE_ERROR); } - bpp *= png->depth/8; + bpp *= png->depth / 8; - return bpp; + return (bpp); } -static int png_read_ihdr(png_t* png) +static int +png_read_ihdr(png_t *png) { - unsigned length; -#if DO_CRC_CHECKS + unsigned length = 0; unsigned orig_crc; unsigned calc_crc; -#endif - unsigned char ihdr[13+4]; /* length should be 13, make room for type (IHDR) */ + uint8_t ihdr[13+4]; /* length should be 13, make room for type (IHDR) */ - file_read_ul(png, &length); + if (file_read_ul(png, &length) != PNG_NO_ERROR) + return (PNG_FILE_ERROR); - if(length != 13) - { - printf("%d\n", length); - return PNG_CRC_ERROR; - } + if (length != 13) + return (PNG_CRC_ERROR); + + if (file_read(png, ihdr, 1, 13+4) != 13+4) + return (PNG_EOF_ERROR); - if(file_read(png, ihdr, 1, 13+4) != 13+4) - return PNG_EOF_ERROR; -#if DO_CRC_CHECKS - file_read_ul(png, &orig_crc); + if (file_read_ul(png, &orig_crc) != PNG_NO_ERROR) + return (PNG_FILE_ERROR); - calc_crc = crc32(0L, 0, 0); + calc_crc = crc32(0L, Z_NULL, 0); calc_crc = crc32(calc_crc, ihdr, 13+4); - if(orig_crc != calc_crc) - return PNG_CRC_ERROR; -#else - file_read_ul(png); -#endif + if (orig_crc != calc_crc) { + return (PNG_CRC_ERROR); + } png->width = get_ul(ihdr+4); png->height = get_ul(ihdr+8); png->depth = ihdr[12]; png->color_type = ihdr[13]; png->compression_method = ihdr[14]; png->filter_method = ihdr[15]; png->interlace_method = ihdr[16]; - if(png->color_type == PNG_INDEXED) - return PNG_NOT_SUPPORTED; - - if(png->depth != 8 && png->depth != 16) - return PNG_NOT_SUPPORTED; + if (png->color_type == PNG_INDEXED) + return (PNG_NOT_SUPPORTED); - if(png->interlace_method) - return PNG_NOT_SUPPORTED; + if (png->depth != 8 && png->depth != 16) + return (PNG_NOT_SUPPORTED); - return PNG_NO_ERROR; -} - -static int png_write_ihdr(png_t* png) -{ - unsigned char ihdr[13+4]; - unsigned char *p = ihdr; - unsigned crc; - - file_write(png, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 1, 8); - - file_write_ul(png, 13); - - *p = 'I'; p++; - *p = 'H'; p++; - *p = 'D'; p++; - *p = 'R'; p++; - set_ul(p, png->width); p+=4; - set_ul(p, png->height); p+=4; - *p = png->depth; p++; - *p = png->color_type; p++; - *p = 0; p++; - *p = 0; p++; - *p = 0; p++; + if (png->interlace_method) + return (PNG_NOT_SUPPORTED); - file_write(png, ihdr, 1, 13+4); - - crc = crc32(0L, 0, 0); - crc = crc32(crc, ihdr, 13+4); - - file_write_ul(png, crc); - - return PNG_NO_ERROR; + return (PNG_NO_ERROR); } -void png_print_info(png_t* png) +void +png_print_info(png_t *png) { printf("PNG INFO:\n"); printf("\twidth:\t\t%d\n", png->width); printf("\theight:\t\t%d\n", png->height); printf("\tdepth:\t\t%d\n", png->depth); printf("\tcolor:\t\t"); - switch(png->color_type) - { - case PNG_GREYSCALE: printf("greyscale\n"); break; - case PNG_TRUECOLOR: printf("truecolor\n"); break; - case PNG_INDEXED: printf("palette\n"); break; - case PNG_GREYSCALE_ALPHA: printf("greyscale with alpha\n"); break; - case PNG_TRUECOLOR_ALPHA: printf("truecolor with alpha\n"); break; - default: printf("unknown, this is not good\n"); break; + switch (png->color_type) { + case PNG_GREYSCALE: + printf("greyscale\n"); break; + case PNG_TRUECOLOR: + printf("truecolor\n"); break; + case PNG_INDEXED: + printf("palette\n"); break; + case PNG_GREYSCALE_ALPHA: + printf("greyscale with alpha\n"); break; + case PNG_TRUECOLOR_ALPHA: + printf("truecolor with alpha\n"); break; + default: + printf("unknown, this is not good\n"); break; } - printf("\tcompression:\t%s\n", png->compression_method?"unknown, this is not good":"inflate/deflate"); - printf("\tfilter:\t\t%s\n", png->filter_method?"unknown, this is not good":"adaptive"); - printf("\tinterlace:\t%s\n", png->interlace_method?"interlace":"no interlace"); + printf("\tcompression:\t%s\n", + png->compression_method? + "unknown, this is not good":"inflate/deflate"); + printf("\tfilter:\t\t%s\n", + png->filter_method? "unknown, this is not good":"adaptive"); + printf("\tinterlace:\t%s\n", + png->interlace_method? "interlace":"no interlace"); } -int png_open_read(png_t* png, png_read_callback_t read_fun, void* user_pointer) +int +png_open(png_t *png, const char *filename) { char header[8]; int result; - png->read_fun = read_fun; - png->write_fun = 0; - png->user_pointer = user_pointer; - - if(!read_fun && !user_pointer) - return PNG_WRONG_ARGUMENTS; + png->image = NULL; + png->fd = open(filename, O_RDONLY); + if (png->fd == -1) + return (PNG_FILE_ERROR); - if(file_read(png, header, 1, 8) != 8) - return PNG_EOF_ERROR; + if (file_read(png, header, 1, 8) != 8) { + result = PNG_EOF_ERROR; + goto done; + } - if(memcmp(header, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) != 0) - return PNG_HEADER_ERROR; + if (memcmp(header, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) != 0) { + result = PNG_HEADER_ERROR; + goto done; + } result = png_read_ihdr(png); + if (result == PNG_NO_ERROR) { + result = png_get_bpp(png); + if (result > 0) { + png->bpp = (uint8_t)result; + result = PNG_NO_ERROR; + } + } - png->bpp = (unsigned char)png_get_bpp(png); - - return result; -} - -int png_open_write(png_t* png, png_write_callback_t write_fun, void* user_pointer) -{ - png->write_fun = write_fun; - png->read_fun = 0; - png->user_pointer = user_pointer; - - if(!write_fun && !user_pointer) - return PNG_WRONG_ARGUMENTS; - - return PNG_NO_ERROR; -} - -int png_open(png_t* png, png_read_callback_t read_fun, void* user_pointer) -{ - return png_open_read(png, read_fun, user_pointer); -} - -int png_open_file_read(png_t *png, const char* filename) -{ - FILE* fp = fopen(filename, "rb"); - - if(!fp) - return PNG_FILE_ERROR; - - return png_open_read(png, 0, fp); -} - -int png_open_file_write(png_t *png, const char* filename) -{ - FILE* fp = fopen(filename, "wb"); - - if(!fp) - return PNG_FILE_ERROR; +done: + if (result == PNG_NO_ERROR) { + uint64_t size = png->width * png->height * png->bpp; - return png_open_write(png, 0, fp); -} + if (size < UINT_MAX) + png->image = malloc(size); + if (png->image == NULL) + result = PNG_MEMORY_ERROR; + } -int png_open_file(png_t *png, const char* filename) -{ - return png_open_file_read(png, filename); -} + if (result == PNG_NO_ERROR) + result = png_get_data(png, png->image); -int png_close_file(png_t* png) -{ - fclose(png->user_pointer); + if (result != PNG_NO_ERROR) { + free(png->image); + (void) close(png->fd); + png->fd = -1; + return (result); + } - return PNG_NO_ERROR; + return (result); } -static int png_init_deflate(png_t* png, unsigned char* data, int datalen) +int +png_close(png_t *png) { - z_stream *stream; - png->zs = png_alloc(sizeof(z_stream)); - - stream = png->zs; - - if(!stream) - return PNG_MEMORY_ERROR; - - memset(stream, 0, sizeof(z_stream)); + (void) close(png->fd); + png->fd = -1; + free(png->image); + png->image = NULL; - if(deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) - return PNG_ZLIB_ERROR; - - stream->next_in = data; - stream->avail_in = datalen; - - return PNG_NO_ERROR; + return (PNG_NO_ERROR); } -static int png_init_inflate(png_t* png) +static int +png_init_inflate(png_t *png) { -#if USE_ZLIB z_stream *stream; - png->zs = png_alloc(sizeof(z_stream)); -#else - zl_stream *stream; - png->zs = png_alloc(sizeof(zl_stream)); -#endif + png->zs = calloc(1, sizeof (z_stream)); stream = png->zs; - if(!stream) - return PNG_MEMORY_ERROR; + if (!stream) + return (PNG_MEMORY_ERROR); -#if USE_ZLIB - memset(stream, 0, sizeof(z_stream)); - if(inflateInit(stream) != Z_OK) - return PNG_ZLIB_ERROR; -#else - memset(stream, 0, sizeof(zl_stream)); - if(z_inflateInit(stream) != Z_OK) - return PNG_ZLIB_ERROR; -#endif + if (inflateInit(stream) != Z_OK) { + free(png->zs); + png->zs = NULL; + return (PNG_ZLIB_ERROR); + } stream->next_out = png->png_data; stream->avail_out = png->png_datalen; - return PNG_NO_ERROR; + return (PNG_NO_ERROR); } -static int png_end_deflate(png_t* png) +static int +png_end_inflate(png_t *png) { z_stream *stream = png->zs; + int rc = PNG_NO_ERROR; - if(!stream) - return PNG_MEMORY_ERROR; + if (!stream) + return (PNG_MEMORY_ERROR); - deflateEnd(stream); - - png_free(png->zs); - - return PNG_NO_ERROR; -} - -static int png_end_inflate(png_t* png) -{ -#if USE_ZLIB - z_stream *stream = png->zs; -#else - zl_stream *stream = png->zs; -#endif - - if(!stream) - return PNG_MEMORY_ERROR; - -#if USE_ZLIB - if(inflateEnd(stream) != Z_OK) -#else - if(z_inflateEnd(stream) != Z_OK) -#endif - { + if (inflateEnd(stream) != Z_OK) { printf("ZLIB says: %s\n", stream->msg); - return PNG_ZLIB_ERROR; + rc = PNG_ZLIB_ERROR; } - png_free(png->zs); + free(png->zs); + png->zs = NULL; - return PNG_NO_ERROR; + return (rc); } -static int png_inflate(png_t* png, unsigned char* data, int len) +static int +png_inflate(png_t *png, uint8_t *data, int len) { int result; -#if USE_ZLIB z_stream *stream = png->zs; -#else - zl_stream *stream = png->zs; -#endif - if(!stream) - return PNG_MEMORY_ERROR; + if (!stream) + return (PNG_MEMORY_ERROR); stream->next_in = data; stream->avail_in = len; -#if USE_ZLIB result = inflate(stream, Z_SYNC_FLUSH); -#else - result = z_inflate(stream); -#endif - - if(result != Z_STREAM_END && result != Z_OK) - { - printf("%s\n", stream->msg); - return PNG_ZLIB_ERROR; - } - - if(stream->avail_in != 0) - return PNG_ZLIB_ERROR; - - return PNG_NO_ERROR; -} - -static int png_deflate(png_t* png, char* outdata, int outlen, int *outwritten) -{ - int result; - - z_stream *stream = png->zs; - - if(!stream) - return PNG_MEMORY_ERROR; - stream->next_out = (unsigned char*)outdata; - stream->avail_out = outlen; - - result = deflate(stream, Z_SYNC_FLUSH); - - *outwritten = outlen - stream->avail_out; - - if(result != Z_STREAM_END && result != Z_OK) - { + if (result != Z_STREAM_END && result != Z_OK) { printf("%s\n", stream->msg); - return PNG_ZLIB_ERROR; + return (PNG_ZLIB_ERROR); } - return result; -} + if (stream->avail_in != 0) + return (PNG_ZLIB_ERROR); -static int png_write_idats(png_t* png, unsigned char* data) -{ - unsigned char *chunk; - unsigned long written; - unsigned long crc; - unsigned size = png->width * png->height * png->bpp + png->height; - unsigned chunk_size = compressBound(size); - - (void)png_init_deflate; - (void)png_end_deflate; - (void)png_deflate; - - chunk = png_alloc(chunk_size + 4); - memcpy(chunk, "IDAT", 4); - - written = chunk_size; - compress(chunk+4, &written, data, size); - - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, chunk, written+4); - set_ul(chunk+written+4, crc); - file_write_ul(png, written); - file_write(png, chunk, 1, written+8); - png_free(chunk); - - file_write_ul(png, 0); - file_write(png, "IEND", 1, 4); - crc = crc32(0L, (const unsigned char *)"IEND", 4); - file_write_ul(png, crc); - - return PNG_NO_ERROR; + return (PNG_NO_ERROR); } -static int png_read_idat(png_t* png, unsigned length) +static int +png_read_idat(png_t *png, unsigned length) { -#if DO_CRC_CHECKS unsigned orig_crc; unsigned calc_crc; -#endif + ssize_t len = length; - if(!png->readbuf || png->readbuflen < length) - { - if (png->readbuf) - { - png_free(png->readbuf); - } - png->readbuf = png_alloc(length); + if (!png->readbuf || png->readbuflen < length) { + png->readbuf = realloc(png->readbuf, length); png->readbuflen = length; } - if(!png->readbuf) - { - return PNG_MEMORY_ERROR; - } + if (!png->readbuf) + return (PNG_MEMORY_ERROR); - if(file_read(png, png->readbuf, 1, length) != length) - { - return PNG_FILE_ERROR; - } + if (file_read(png, png->readbuf, 1, length) != len) + return (PNG_FILE_ERROR); -#if DO_CRC_CHECKS calc_crc = crc32(0L, Z_NULL, 0); - calc_crc = crc32(calc_crc, (unsigned char*)"IDAT", 4); - calc_crc = crc32(calc_crc, (unsigned char*)png->readbuf, length); + calc_crc = crc32(calc_crc, (uint8_t *)"IDAT", 4); + calc_crc = crc32(calc_crc, (uint8_t *)png->readbuf, length); - file_read_ul(png, &orig_crc); + if (file_read_ul(png, &orig_crc) != PNG_NO_ERROR) + return (PNG_FILE_ERROR); - if(orig_crc != calc_crc) - { - return PNG_CRC_ERROR; - } -#else - file_read_ul(png); -#endif + if (orig_crc != calc_crc) + return (PNG_CRC_ERROR); - return png_inflate(png, png->readbuf, length); + return (png_inflate(png, png->readbuf, length)); } -static int png_process_chunk(png_t* png) +static int +png_process_chunk(png_t *png) { int result = PNG_NO_ERROR; unsigned type; unsigned length; - file_read_ul(png, &length); - - if(file_read(png, &type, 1, 4) != 4) - return PNG_FILE_ERROR; - - if(type == *(unsigned int*)"IDAT") /* if we found an idat, all other idats should be followed with no other chunks in between */ - { - if(!png->png_data) /* first IDAT */ - { - png->png_datalen = png->width * png->height * png->bpp + png->height; - png->png_data = png_alloc(png->png_datalen); + if (file_read_ul(png, &length) != PNG_NO_ERROR) + return (PNG_FILE_ERROR); + + if (file_read_ul(png, &type) != PNG_NO_ERROR) + return (PNG_FILE_ERROR); + + /* + * if we found an idat, all other idats should be followed with no + * other chunks in between + */ + if (type == png_IDAT) { + if (!png->png_data) { /* first IDAT */ + png->png_datalen = png->width * png->height * + png->bpp + png->height; + png->png_data = malloc(png->png_datalen); } - if(!png->png_data) - return PNG_MEMORY_ERROR; + if (!png->png_data) + return (PNG_MEMORY_ERROR); - if(!png->zs) - { + if (!png->zs) { result = png_init_inflate(png); - if(result != PNG_NO_ERROR) - return result; + if (result != PNG_NO_ERROR) + return (result); } - return png_read_idat(png, length); - } - else if(type == *(unsigned int*)"IEND") - { - return PNG_DONE; - } + return (png_read_idat(png, length)); + } else if (type == png_IEND) + return (PNG_DONE); else - { - file_read(png, 0, 1, length + 4); /* unknown chunk */ - } + (void) file_read(png, 0, 1, length + 4); /* unknown chunk */ - return result; + return (result); } -static void png_filter_sub(int stride, unsigned char* in, unsigned char* out, int len) +static void +png_filter_sub(unsigned stride, uint8_t *in, uint8_t *out, unsigned len) { - int i; - unsigned char a = 0; + unsigned i; + uint8_t a = 0; - for(i = 0; i < len; i++) - { - if(i >= stride) + for (i = 0; i < len; i++) { + if (i >= stride) a = out[i - stride]; out[i] = in[i] + a; } } -static void png_filter_up(int stride, unsigned char* in, unsigned char* out, unsigned char* prev_line, int len) +static void +png_filter_up(unsigned stride __unused, uint8_t *in, uint8_t *out, + uint8_t *prev_line, unsigned len) { - int i; + unsigned i; - if(prev_line) - { - for(i = 0; i < len; i++) - out[i] = in[i] + prev_line[i]; - } - else + if (prev_line) { + for (i = 0; i < len; i++) + out[i] = in[i] + prev_line[i]; + } else memcpy(out, in, len); } -static void png_filter_average(int stride, unsigned char* in, unsigned char* out, unsigned char* prev_line, int len) +static void +png_filter_average(unsigned stride, uint8_t *in, uint8_t *out, + uint8_t *prev_line, unsigned len) { - int i; - unsigned char a = 0; - unsigned char b = 0; + unsigned int i; + uint8_t a = 0; + uint8_t b = 0; unsigned int sum = 0; - for(i = 0; i < len; i++) - { - if(prev_line) + for (i = 0; i < len; i++) { + if (prev_line) b = prev_line[i]; - if(i >= stride) + if (i >= stride) a = out[i - stride]; sum = a; sum += b; - out[i] = (char)(in[i] + sum/2); + out[i] = in[i] + sum/2; } } -static unsigned char png_paeth(unsigned char a, unsigned char b, unsigned char c) +static uint8_t +png_paeth(uint8_t a, uint8_t b, uint8_t c) { int p = (int)a + b - c; int pa = abs(p - a); int pb = abs(p - b); int pc = abs(p - c); int pr; - if(pa <= pb && pa <= pc) + if (pa <= pb && pa <= pc) pr = a; - else if(pb <= pc) + else if (pb <= pc) pr = b; else pr = c; - return (char)pr; + return (pr); } -static void png_filter_paeth(int stride, unsigned char* in, unsigned char* out, unsigned char* prev_line, int len) +static void +png_filter_paeth(unsigned stride, uint8_t *in, uint8_t *out, uint8_t *prev_line, + unsigned len) { - int i; - unsigned char a; - unsigned char b; - unsigned char c; - - for(i = 0; i < len; i++) - { - if(prev_line && i >= stride) - { + unsigned i; + uint8_t a; + uint8_t b; + uint8_t c; + + for (i = 0; i < len; i++) { + if (prev_line && i >= stride) { a = out[i - stride]; b = prev_line[i]; c = prev_line[i - stride]; - } - else - { - if(prev_line) + } else { + if (prev_line) b = prev_line[i]; else b = 0; - if(i >= stride) + if (i >= stride) a = out[i - stride]; else a = 0; c = 0; } out[i] = in[i] + png_paeth(a, b, c); } } -static int png_filter(png_t* png, unsigned char* data) -{ - return PNG_NO_ERROR; -} - -static int png_unfilter(png_t* png, unsigned char* data) +static int +png_unfilter(png_t *png, uint8_t *data) { unsigned i; unsigned pos = 0; unsigned outpos = 0; - unsigned char *filtered = png->png_data; - - int stride = png->bpp; + uint8_t *filtered = png->png_data; + unsigned stride = png->bpp; - while(pos < png->png_datalen) - { - unsigned char filter = filtered[pos]; + while (pos < png->png_datalen) { + uint8_t filter = filtered[pos]; pos++; - if(png->depth == 16) - { - for(i = 0; i < png->width * stride; i+=2) - { - *(short*)(filtered+pos+i) = (filtered[pos+i] << 8) | filtered[pos+i+1]; + if (png->depth == 16) { + for (i = 0; i < png->width * stride; i += 2) { + *(short *)(filtered+pos+i) = + (filtered[pos+i] << 8) | filtered[pos+i+1]; } } - switch(filter) - { + switch (filter) { case 0: /* none */ memcpy(data+outpos, filtered+pos, png->width * stride); break; case 1: /* sub */ - png_filter_sub(stride, filtered+pos, data+outpos, png->width * stride); + png_filter_sub(stride, filtered+pos, data+outpos, + png->width * stride); break; case 2: /* up */ - if(outpos) - png_filter_up(stride, filtered+pos, data+outpos, data + outpos - (png->width*stride), png->width*stride); - else - png_filter_up(stride, filtered+pos, data+outpos, 0, png->width*stride); + if (outpos) { + png_filter_up(stride, filtered+pos, data+outpos, + data + outpos - (png->width*stride), + png->width*stride); + } else { + png_filter_up(stride, filtered+pos, data+outpos, + 0, png->width*stride); + } break; case 3: /* average */ - if(outpos) - png_filter_average(stride, filtered+pos, data+outpos, data + outpos - (png->width*stride), png->width*stride); - else - png_filter_average(stride, filtered+pos, data+outpos, 0, png->width*stride); + if (outpos) { + png_filter_average(stride, filtered+pos, + data+outpos, + data + outpos - (png->width*stride), + png->width*stride); + } else { + png_filter_average(stride, filtered+pos, + data+outpos, 0, png->width*stride); + } break; case 4: /* paeth */ - if(outpos) - png_filter_paeth(stride, filtered+pos, data+outpos, data + outpos - (png->width*stride), png->width*stride); - else - png_filter_paeth(stride, filtered+pos, data+outpos, 0, png->width*stride); + if (outpos) { + png_filter_paeth(stride, filtered+pos, + data+outpos, + data + outpos - (png->width*stride), + png->width*stride); + } else { + png_filter_paeth(stride, filtered+pos, + data+outpos, 0, png->width*stride); + } break; default: - return PNG_UNKNOWN_FILTER; + return (PNG_UNKNOWN_FILTER); } outpos += png->width * stride; pos += png->width * stride; } - return PNG_NO_ERROR; + return (PNG_NO_ERROR); } -int png_get_data(png_t* png, unsigned char* data) +int +png_get_data(png_t *png, uint8_t *data) { int result = PNG_NO_ERROR; png->zs = NULL; png->png_datalen = 0; png->png_data = NULL; png->readbuf = NULL; png->readbuflen = 0; - while(result == PNG_NO_ERROR) - { + while (result == PNG_NO_ERROR) result = png_process_chunk(png); - } - if (png->readbuf) - { - png_free(png->readbuf); + if (png->readbuf) { + free(png->readbuf); png->readbuflen = 0; } if (png->zs) - { - png_end_inflate(png); - } + (void) png_end_inflate(png); - if(result != PNG_DONE) - { - png_free(png->png_data); - return result; + if (result != PNG_DONE) { + free(png->png_data); + return (result); } result = png_unfilter(png, data); - png_free(png->png_data); - - return result; -} - -int png_set_data(png_t* png, unsigned width, unsigned height, char depth, int color, unsigned char* data) -{ - int i; - unsigned char *filtered; - png->width = width; - png->height = height; - png->depth = depth; - png->color_type = color; - png->bpp = png_get_bpp(png); - - filtered = png_alloc(width * height * png->bpp + height); - - for(i = 0; i < png->height; i++) - { - filtered[i*png->width*png->bpp+i] = 0; - memcpy(&filtered[i*png->width*png->bpp+i+1], data + i * png->width*png->bpp, png->width*png->bpp); - } - - png_filter(png, filtered); - png_write_ihdr(png); - png_write_idats(png, filtered); - - png_free(filtered); + free(png->png_data); - return PNG_NO_ERROR; + return (result); } -char* png_error_string(int error) +char * +png_error_string(int error) { - switch(error) - { + switch (error) { case PNG_NO_ERROR: - return "No error"; + return ("No error"); case PNG_FILE_ERROR: - return "Unknown file error."; + return ("Unknown file error."); case PNG_HEADER_ERROR: - return "No PNG header found. Are you sure this is a PNG?"; + return ("No PNG header found. Are you sure this is a PNG?"); case PNG_IO_ERROR: - return "Failure while reading file."; + return ("Failure while reading file."); case PNG_EOF_ERROR: - return "Reached end of file."; + return ("Reached end of file."); case PNG_CRC_ERROR: - return "CRC or chunk length error."; + return ("CRC or chunk length error."); case PNG_MEMORY_ERROR: - return "Could not allocate memory."; + return ("Could not allocate memory."); case PNG_ZLIB_ERROR: - return "zlib reported an error."; + return ("zlib reported an error."); case PNG_UNKNOWN_FILTER: - return "Unknown filter method used in scanline."; + return ("Unknown filter method used in scanline."); case PNG_DONE: - return "PNG done"; + return ("PNG done"); case PNG_NOT_SUPPORTED: - return "The PNG is unsupported by pnglite, too bad for you!"; + return ("The PNG is unsupported by pnglite, too bad for you!"); case PNG_WRONG_ARGUMENTS: - return "Wrong combination of arguments passed to png_open. You must use either a read_function or supply a file pointer to use."; + return ("Wrong combination of arguments passed to png_open. " + "You must use either a read_function or supply a file " + "pointer to use."); default: - return "Unknown error."; + return ("Unknown error."); }; } diff --git a/contrib/pnglite/pnglite.h b/contrib/pnglite/pnglite.h index bbb207502409..3c3a3320c28b 100644 --- a/contrib/pnglite/pnglite.h +++ b/contrib/pnglite/pnglite.h @@ -1,232 +1,169 @@ -/* pnglite.h - Interface for pnglite library - Copyright (c) 2007 Daniel Karling - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. - - Daniel Karling - daniel.karling@gmail.com +/* + * pnglite.h - Interface for pnglite library + * Copyright (c) 2007 Daniel Karling + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + * Daniel Karling + * daniel.karling@gmail.com */ #ifndef _PNGLITE_H_ -#define _PNGLITE_H_ +#define _PNGLITE_H_ #include #ifdef __cplusplus -extern "C"{ +extern "C" { #endif /* - Enumerations for pnglite. - Negative numbers are error codes and 0 and up are okay responses. -*/ + * Enumerations for pnglite. + * Negative numbers are error codes and 0 and up are okay responses. + */ -enum -{ +enum { PNG_DONE = 1, PNG_NO_ERROR = 0, PNG_FILE_ERROR = -1, PNG_HEADER_ERROR = -2, PNG_IO_ERROR = -3, PNG_EOF_ERROR = -4, PNG_CRC_ERROR = -5, PNG_MEMORY_ERROR = -6, PNG_ZLIB_ERROR = -7, PNG_UNKNOWN_FILTER = -8, PNG_NOT_SUPPORTED = -9, PNG_WRONG_ARGUMENTS = -10 }; /* - The five different kinds of color storage in PNG files. -*/ + * The five different kinds of color storage in PNG files. + */ -enum -{ +enum { PNG_GREYSCALE = 0, PNG_TRUECOLOR = 2, PNG_INDEXED = 3, PNG_GREYSCALE_ALPHA = 4, PNG_TRUECOLOR_ALPHA = 6 }; -/* - Typedefs for callbacks. -*/ - -typedef unsigned (*png_write_callback_t)(void* input, size_t size, size_t numel, void* user_pointer); -typedef unsigned (*png_read_callback_t)(void* output, size_t size, size_t numel, void* user_pointer); -typedef void (*png_free_t)(void* p); -typedef void * (*png_alloc_t)(size_t s); - -typedef struct -{ - void* zs; /* pointer to z_stream */ - png_read_callback_t read_fun; - png_write_callback_t write_fun; - void* user_pointer; - - unsigned char* png_data; - unsigned png_datalen; - - unsigned width; - unsigned height; - unsigned char depth; - unsigned char color_type; - unsigned char compression_method; - unsigned char filter_method; - unsigned char interlace_method; - unsigned char bpp; - - unsigned char* readbuf; - unsigned readbuflen; +typedef struct { + void *zs; /* pointer to z_stream */ + int fd; + unsigned char *image; + + unsigned char *png_data; + unsigned png_datalen; + + unsigned width; + unsigned height; + unsigned char depth; + unsigned char color_type; + unsigned char compression_method; + unsigned char filter_method; + unsigned char interlace_method; + unsigned char bpp; + + unsigned char *readbuf; + unsigned readbuflen; } png_t; -/* - Function: png_init - - This function initializes pnglite. The parameters can be used to set your own memory allocation routines following these formats: - - > void* (*custom_alloc)(size_t s) - > void (*custom_free)(void* p) - Parameters: - pngalloc - Pointer to custom allocation routine. If 0 is passed, malloc from libc will be used. - pngfree - Pointer to custom free routine. If 0 is passed, free from libc will be used. - - Returns: - Always returns PNG_NO_ERROR. -*/ - -int png_init(png_alloc_t pngalloc, png_free_t pngfree); - -/* - Function: png_open_file - - This function is used to open a png file with the internal file IO system. This function should be used instead of - png_open if no custom read function is used. - - Parameters: - png - Empty png_t struct. - filename - Filename of the file to be opened. - - Returns: - PNG_NO_ERROR on success, otherwise an error code. -*/ - -int png_open_file(png_t *png, const char* filename); - -int png_open_file_read(png_t *png, const char* filename); -int png_open_file_write(png_t *png, const char* filename); /* - Function: png_open - - This function reads or writes a png from/to the specified callback. The callbacks should be of the format: - - > size_t (*png_write_callback_t)(void* input, size_t size, size_t numel, void* user_pointer); - > size_t (*png_read_callback_t)(void* output, size_t size, size_t numel, void* user_pointer). - - Only one callback has to be specified. The read callback in case of PNG reading, otherwise the write callback. - - Writing: - The callback will be called like fwrite. - - Reading: - The callback will be called each time pnglite needs more data. The callback should read as much data as requested, - or return 0. This should always be possible if the PNG is sane. If the output-buffer is a null-pointer the callback - should only skip ahead the specified number of elements. If the callback is a null-pointer the user_pointer will be - treated as a file pointer (use png_open_file instead). - - Parameters: - png - png_t struct - read_fun - Callback function for reading. - user_pointer - User pointer to be passed to read_fun. - - Returns: - PNG_NO_ERROR on success, otherwise an error code. -*/ - -int png_open(png_t* png, png_read_callback_t read_fun, void* user_pointer); + * Function: png_open + * + * This function is used to open a png file with the internal file + * IO system. + * + * Parameters: + * png - Empty png_t struct. + * filename - Filename of the file to be opened. + * + * Returns: + * PNG_NO_ERROR on success, otherwise an error code. + */ -int png_open_read(png_t* png, png_read_callback_t read_fun, void* user_pointer); -int png_open_write(png_t* png, png_write_callback_t write_fun, void* user_pointer); +int png_open(png_t *png, const char *filename); /* - Function: png_print_info - - This function prints some info about the opened png file to stdout. - - Parameters: - png - png struct to get info from. -*/ + * Function: png_print_info + * + * This function prints some info about the opened png file to stdout. + * + * Parameters: + * png - png struct to get info from. + */ -void png_print_info(png_t* png); +void png_print_info(png_t *png); /* - Function: png_error_string - - This function translates an error code to a human readable string. - - Parameters: - error - Error code. - - Returns: - Pointer to string. -*/ + * Function: png_error_string + * + * This function translates an error code to a human readable string. + * + * Parameters: + * error - Error code. + * + * Returns: + * Pointer to string. + */ -char* png_error_string(int error); +char *png_error_string(int error); /* - Function: png_get_data - - This function decodes the opened png file and stores the result in data. data should be big enough to hold the decoded png. Required size will be: - - > width*height*(bytes per pixel) - - Parameters: - data - Where to store result. - - Returns: - PNG_NO_ERROR on success, otherwise an error code. -*/ - -int png_get_data(png_t* png, unsigned char* data); + * Function: png_get_data + * + * This function decodes the opened png file and stores the result in data. + * data should be big enough to hold the decoded png. + * Required size will be: + * + * > width*height*(bytes per pixel) + * + * Parameters: + * data - Where to store result. + * + * Returns: + * PNG_NO_ERROR on success, otherwise an error code. + */ -int png_set_data(png_t* png, unsigned width, unsigned height, char depth, int color, unsigned char* data); +int png_get_data(png_t *png, uint8_t *data); /* - Function: png_close_file - - Closes an open png file pointer. Should only be used when the png has been opened with png_open_file. - - Parameters: - png - png to close. - - Returns: - PNG_NO_ERROR -*/ + * Function: png_close + * + * Closes an open png file pointer. + * + * Parameters: + * png - png to close. + * + * Returns: + * PNG_NO_ERROR + */ -int png_close_file(png_t* png); +int png_close(png_t *png); #ifdef __cplusplus } #endif -#endif + +#endif /* _PNGLITE_H_ */