Add support for using libpng for png encoding (gives much smaller png files)

This commit is contained in:
Airy ANDRE 2012-05-07 19:00:06 +02:00
parent 78264501f4
commit d484615c6b
2 changed files with 119 additions and 5 deletions

View File

@ -9621,7 +9621,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "#!/bin/sh\nmkdir -p $DERIVED_FILE_DIR\necho \"\" > $DERIVED_FILE_DIR/O2Defines_FreeType.h\n\nif [ -d /Developer/Cocotron/1.0/Windows/i386/freetype-2.3.5 ]; then\n\techo \"FreeType 2.3.5 present.\"\n\techo \"#define FREETYPE_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_FreeType.h\nelse\n# Create empty libfreetype for link phase\n echo \"FreeType 2.3.5 not found\"\n touch $DERIVED_FILE_DIR/libfreetype.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/libfreetype.c -c -o $DERIVED_FILE_DIR/libfreetype.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libfreetype.a $DERIVED_FILE_DIR/libfreetype.o\nfi\n\necho \"\" > $DERIVED_FILE_DIR/O2Defines_libjpeg.h\nif [ -d /Developer/Cocotron/1.0/Windows/i386/libjpeg ]; then\n\techo \"libjpeg present.\"\n\techo \"#define LIBJPEG_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_libjpeg.h\nelse\n# Create empty libfreetype for link phase\n echo \"libjpeg not found\"\n touch $DERIVED_FILE_DIR/libjpeg.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/libjpeg.c -c -o $DERIVED_FILE_DIR/libjpeg.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libjpeg.a $DERIVED_FILE_DIR/libjpeg.o\nfi\n\necho \"\" > $DERIVED_FILE_DIR/O2Defines_zlib.h\nif [ -d /Developer/Cocotron/1.0/Windows/i386/zlib-1.2.5 ]; then\n\techo \"zlib present.\"\n\techo \"#define ZLIB_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_zlib.h\nelse\n# Create empty zlib for link phase\n echo \"zlib not found\"\n touch $DERIVED_FILE_DIR/zlib.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/zlib.c -c -o $DERIVED_FILE_DIR/zlib.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libz.a $DERIVED_FILE_DIR/zlib.o\nfi\n\n";
shellScript = "#!/bin/sh\nmkdir -p $DERIVED_FILE_DIR\necho \"\" > $DERIVED_FILE_DIR/O2Defines_FreeType.h\n\nif [ -d /Developer/Cocotron/1.0/Windows/i386/freetype-2.3.5 ]; then\n\techo \"FreeType 2.3.5 present.\"\n\techo \"#define FREETYPE_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_FreeType.h\nelse\n# Create empty libfreetype for link phase\n echo \"FreeType 2.3.5 not found\"\n touch $DERIVED_FILE_DIR/libfreetype.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/libfreetype.c -c -o $DERIVED_FILE_DIR/libfreetype.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libfreetype.a $DERIVED_FILE_DIR/libfreetype.o\nfi\n\necho \"\" > $DERIVED_FILE_DIR/O2Defines_libjpeg.h\nif [ -d /Developer/Cocotron/1.0/Windows/i386/libjpeg ]; then\n\techo \"libjpeg present.\"\n\techo \"#define LIBJPEG_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_libjpeg.h\nelse\n# Create empty libjpeg for link phase\n echo \"libjpeg not found\"\n touch $DERIVED_FILE_DIR/libjpeg.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/libjpeg.c -c -o $DERIVED_FILE_DIR/libjpeg.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libjpeg.a $DERIVED_FILE_DIR/libjpeg.o\nfi\n\necho \"\" > $DERIVED_FILE_DIR/O2Defines_zlib.h\nif [ -d /Developer/Cocotron/1.0/Windows/i386/zlib-1.2.5 ]; then\n\techo \"zlib present.\"\n\techo \"#define ZLIB_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_zlib.h\nelse\n# Create empty zlib for link phase\n echo \"zlib not found\"\n touch $DERIVED_FILE_DIR/zlib.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/zlib.c -c -o $DERIVED_FILE_DIR/zlib.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libz.a $DERIVED_FILE_DIR/zlib.o\nfi\n\necho \"\" > $DERIVED_FILE_DIR/O2Defines_libpng.h\nif [ -d /Developer/Cocotron/1.0/Windows/i386/libpng ]; then\n\techo \"libpng present.\"\n\techo \"#define LIBPNG_PRESENT 1\" >> $DERIVED_FILE_DIR/O2Defines_libpng.h\nelse\n# Create empty libpng for link phase\n echo \"libpng not found\"\n touch $DERIVED_FILE_DIR/libpng.c\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-gcc $DERIVED_FILE_DIR/libpng.c -c -o $DERIVED_FILE_DIR/libpng.o\n /Developer/Cocotron/1.0/Windows/i386/gcc-4.3.1/bin/i386-mingw32msvc-ar cr $DERIVED_FILE_DIR/libpng.a $DERIVED_FILE_DIR/libpng.o\nfi\n\n";
};
/* End PBXShellScriptBuildPhase section */
@ -11838,6 +11838,7 @@
HEADER_SEARCH_PATHS = "$(TARGET_BUILD_DIR)/usr/include";
INFOPLIST_FILE = Info.plist;
LIBRARY_SEARCH_PATHS = (
/Developer/Cocotron/1.0/Windows/i386/libpng/lib,
/Developer/Cocotron/1.0/Windows/i386/libjpeg/lib,
"$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
);
@ -11850,9 +11851,10 @@
"-DCGL_INSIDE_BUILD",
);
OTHER_LDFLAGS = (
"-lz",
"-static",
"-lpng",
"-ljpeg",
"-lz",
"-shared",
"-lmsimg32",
"-lole32",
@ -12121,6 +12123,7 @@
HEADER_SEARCH_PATHS = "$(TARGET_BUILD_DIR)/usr/include";
INFOPLIST_FILE = Info.plist;
LIBRARY_SEARCH_PATHS = (
/Developer/Cocotron/1.0/Windows/i386/libpng/lib,
"/Developer/Cocotron/1.0/Windows/i386/zlib-1.2.5/lib",
/Developer/Cocotron/1.0/Windows/i386/libjpeg/lib,
"$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
@ -12137,9 +12140,10 @@
"-DCGL_INSIDE_BUILD",
);
OTHER_LDFLAGS = (
"-lz",
"-static",
"-lpng",
"-ljpeg",
"-lz",
"-shared",
"-lmsimg32",
"-lole32",

View File

@ -1,5 +1,7 @@
#import <Onyx2D/O2Encoder_PNG.h>
#import "O2Defines_libpng.h"
O2PNGEncoderRef O2PNGEncoderCreate(O2DataConsumerRef consumer) {
O2PNGEncoderRef self=NSZoneCalloc(NULL,1,sizeof(struct O2PNGEncoder));
self->_consumer=(id)CFRetain(consumer);
@ -12,6 +14,115 @@ void O2PNGEncoderDealloc(O2PNGEncoderRef self) {
NSZoneFree(NULL,self);
}
#ifdef LIBPNG_PRESENT
#include <libpng/include/png.h>
#include <zlib-1.2.5/include/zlib.h>
static void o2png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
O2PNGEncoderRef self = (O2PNGEncoderRef)png_get_io_ptr(png_ptr);
O2DataConsumerPutBytes(self->_consumer,data,length);
}
void O2PNGEncoderWriteImage(O2PNGEncoderRef self,O2ImageRef image,CFDictionaryRef props)
{
// Note: only encoding 32 bits RGBA images have been tested
NSDictionary *properties = (NSDictionary *)props;
unsigned long length = 0;
size_t width = O2ImageGetWidth(image);
size_t height = O2ImageGetHeight(image);
int bpr = O2ImageGetBytesPerRow(image);
png_bytep *row_pointers = calloc(sizeof(void *), height);
const uint8_t *bytes = [image directBytes];
for (int i = 0; i < height; ++i) {
row_pointers[i] = (uint8_t *)(bytes + i*bpr);
}
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
if (setjmp(png_jmpbuf(png_ptr))) {
NSLog(@"Error initializing png encoder");
png_destroy_write_struct(&png_ptr, &info_ptr);
return;
}
png_set_write_fn(png_ptr, self, o2png_write_data, NULL);
png_byte color_type = PNG_COLOR_TYPE_RGB_ALPHA;
png_byte bit_depth = 8;
switch(O2ImageGetBitmapInfo(image)&kO2BitmapAlphaInfoMask){
case kO2ImageAlphaNone:
color_type = PNG_COLOR_TYPE_RGB;
break;
case kO2ImageAlphaNoneSkipLast:
png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
color_type = PNG_COLOR_TYPE_RGB;
break;
case kO2ImageAlphaNoneSkipFirst:
png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
color_type = PNG_COLOR_TYPE_RGB;
break;
default:
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
break;
}
png_set_IHDR(png_ptr, info_ptr, width, height,
bit_depth, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
if (setjmp(png_jmpbuf(png_ptr))) {
NSLog(@"Error writing png header");
png_destroy_write_struct(&png_ptr, &info_ptr);
return;
}
png_write_info(png_ptr, info_ptr);
switch (O2ImageGetBitmapInfo(image) & kO2BitmapByteOrderMask) {
case kO2BitmapByteOrder16Little:
bit_depth = 4;
png_set_bgr(png_ptr);
break;
case kO2BitmapByteOrder32Little:
png_set_bgr(png_ptr);
break;
case kO2BitmapByteOrder16Big:
bit_depth = 4;
break;
case kO2BitmapByteOrder32Big:
break;
case kO2BitmapByteOrderDefault:
default:
#ifdef __LITTLE_ENDIAN__
png_set_bgr(png_ptr);
#endif
break;
}
if (setjmp(png_jmpbuf(png_ptr))) {
NSLog(@"Error writing png image data");
png_destroy_write_struct(&png_ptr, &info_ptr);
return;
}
png_write_image(png_ptr, row_pointers);
if (setjmp(png_jmpbuf(png_ptr))) {
NSLog(@"Error finishing png image data");
png_destroy_write_struct(&png_ptr, &info_ptr);
return;
}
png_write_end(png_ptr, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
free(row_pointers);
}
#else
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
no warranty implied; use at your own risk
@ -401,7 +512,6 @@ unsigned char *stbi_write_png_to_mem(O2ImageRef image, int x, int y, int *out_le
return out;
}
/* Revision history
0.92 (2010-08-01)
@ -423,5 +533,5 @@ void O2PNGEncoderWriteImage(O2PNGEncoderRef self,O2ImageRef image,CFDictionaryRe
free(png);
}
#endif