123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #include "PNGWriter.h"
- #include "api__png.h"
- #include <png.h>
- #include <wchar.h>
- #include <bfc/platform/strcmp.h>
- int PNGWriter::setConfig(const wchar_t * item, const wchar_t * value) {
- return 0;
- }
- int PNGWriter::getConfig(const wchar_t * item, wchar_t * value, int valuelen) {
- if(!_wcsicmp(item,L"lossless")) lstrcpynW(value,L"1",valuelen);
- else return 0;
- return 1;
- }
- typedef struct {
- BYTE * data;
- unsigned int len;
- unsigned int alloc;
- } pngWrite;
- extern "C" static void PNGAPI png_write(png_structp png_ptr, png_bytep data, png_size_t len) {
- pngWrite * p = (pngWrite *)png_get_io_ptr(png_ptr);
- while (len + p->len > p->alloc) {
- int d = ((p->alloc / 4) & 0xffffff00) + 0x100;
- if(d < 4096) d = 4096;
- p->alloc+=d;
- p->data = (BYTE*)WASABI_API_MEMMGR->sysRealloc(p->data,p->alloc);
- }
- memcpy(p->data+p->len,data,len);
- p->len += int(len);
- }
- extern "C" static void PNGAPI png_flush(png_structp png_ptr) {}
- int PNGWriter::bitDepthSupported(int depth) {
- if(depth == 32 || depth == 24) return 1;
- return 0;
- }
- void * PNGWriter::convert(const void *pixels0, int bitDepth, int w, int h, int *length) {
- if(bitDepth != 32 && bitDepth != 24) return 0;
- BYTE * pixels = (BYTE*)pixels0;
- png_structp png_ptr;
- png_infop info_ptr;
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- (png_voidp*)NULL, NULL, NULL);
- if (png_ptr == NULL)
- return 0;
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- {
- png_destroy_write_struct(&png_ptr, NULL);
- return 0;
- }
- pngWrite writer={0};
-
- if (setjmp(png_jmpbuf(png_ptr)))
- {
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
- if(writer.data) WASABI_API_MEMMGR->sysFree(writer.data);
- return 0;
- }
- writer.alloc = (int(double(w*h)*1.25) & 0xffffff00) + 0x100;
- if (writer.alloc < 4096) writer.alloc = 4096;
- writer.data = (BYTE*)WASABI_API_MEMMGR->sysMalloc(writer.alloc);
-
-
- png_set_write_fn(png_ptr, (void *)&writer, png_write,
- png_flush);
-
- int colortype = (bitDepth == 32) ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB;
- png_set_IHDR(png_ptr, info_ptr, w, h, 8, colortype,
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
-
- png_color_8 sig_bit;
-
- sig_bit.gray = 8;
-
- sig_bit.red = 8;
- sig_bit.green = 8;
- sig_bit.blue = 8;
-
- sig_bit.alpha = (bitDepth==32)?8:0;
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
- png_write_info(png_ptr, info_ptr);
-
-
- png_set_invert_mono(png_ptr);
-
- png_set_shift(png_ptr, &sig_bit);
-
- png_set_packing(png_ptr);
-
- png_set_bgr(png_ptr);
-
- png_set_swap(png_ptr);
-
- png_set_packswap(png_ptr);
-
- png_uint_32 number_passes = 1;
-
- int bytes_per_pixel = bitDepth / 8;
-
- for (png_uint_32 pass = 0; pass < number_passes; pass++)
- {
- BYTE * row = pixels;
- for (int y = 0; y < h; y++) {
-
- png_write_rows(png_ptr, &row, 1);
- row += w*bytes_per_pixel;
- }
- }
-
- png_write_end(png_ptr, info_ptr);
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- if(length) *length = writer.len;
- return writer.data;
- }
- #define CBCLASS PNGWriter
- START_DISPATCH;
- CB(GETIMAGETYPENAME, getImageTypeName);
- CB(GETEXTENSIONS, getExtensions);
- CB(SETCONFIG, setConfig);
- CB(GETCONFIG, getConfig);
- CB(BITDEPTHSUPPORTED, bitDepthSupported);
- CB(CONVERT, convert);
- END_DISPATCH;
- #undef CBCLASS
|