#include #include #include #include #include "swft.h" #include #include #include #include "readpng.h" #include #define TMP_STRLEN 0xff // outLength should contain the allocated size, // will be updated with the actual size bool compress( unsigned char *inputBuffer, int inLength, unsigned char *outputBuffer, int *outLength ) { z_stream stream; int status, count; stream.avail_in = inLength; stream.next_in = inputBuffer; stream.next_out = outputBuffer; stream.zalloc = (alloc_func) NULL; stream.zfree = (free_func) NULL; stream.opaque = (voidpf) 0; stream.avail_out = *outLength; status = deflateInit( &stream, Z_BEST_COMPRESSION ); if( status != Z_OK ) { fprintf( stderr, "ERROR: compressing PNG (1): %s\n", stream.msg ); return false; } while( true ) { if( stream.avail_in == 0 ) break; status = deflate( &stream, Z_NO_FLUSH ); if( status != Z_OK ) { fprintf( stderr, "ERROR: compressing PNG (2): %s\n", stream.msg ); return false; } } do { status = deflate( &stream, Z_FINISH ); } while( status == Z_OK ); if( status != Z_STREAM_END ) { fprintf( stderr, "ERROR: compressing PNG (3): %s\n", stream.msg ); return false; } status = deflateEnd(&stream); if( status != Z_OK ) { fprintf( stderr, "ERROR: compressing PNG (4): %s\n", stream.msg ); return false; } *outLength -= stream.avail_out; return true; } void swft_import_png( xmlXPathParserContextPtr ctx, int nargs ) { xsltTransformContextPtr tctx; xmlChar *filename; xsltDocumentPtr xsltdoc; xmlDocPtr doc = NULL; xmlNodePtr node; xmlXPathObjectPtr obj; char tmp[TMP_STRLEN]; png_colorp palette; int n_pal; xmlXPathStringFunction(ctx, 1); if (ctx->value->type != XPATH_STRING) { xsltTransformError(xsltXPathGetTransformContext(ctx), NULL, NULL, "swft:import-png() : invalid arg expecting a string\n"); ctx->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctx); if (obj->stringval == NULL) { valuePush(ctx, xmlXPathNewNodeSet(NULL)); return; } tctx = xsltXPathGetTransformContext(ctx); filename = swft_get_filename(obj->stringval); bool quiet = true; xmlXPathObjectPtr quietObj = xsltVariableLookup( tctx, (const xmlChar*)"quiet", NULL ); if( quietObj && quietObj->stringval ) { quiet = !strcmp("true",(const char*)quietObj->stringval ); }; FILE *fp = fopen( (const char *)filename, "rb" ); if( !fp ) { xsltTransformError(xsltXPathGetTransformContext(ctx), NULL, NULL, "swft:import-png() : failed to read file '%s'\n", (const char *)filename); valuePush(ctx, xmlXPathNewNodeSet(NULL)); return; } doc = xmlNewDoc( (const xmlChar *)"1.0"); doc->xmlRootNode = xmlNewDocNode( doc, NULL, (const xmlChar *)"png", NULL ); node = doc->xmlRootNode; swft_addFileName( node, (const char *)filename ); // add data rewind(fp); unsigned char *data, *compressed; unsigned long w, h, rowbytes; int channels; int compressed_size; int format = 5; int data_size = 0; if( !fp ) goto fail; if( readpng_init( fp, &w, &h ) ) goto fail; // add w/h snprintf(tmp,TMP_STRLEN,"%i", w); xmlSetProp( node, (const xmlChar *)"width", (const xmlChar *)&tmp ); snprintf(tmp,TMP_STRLEN,"%i", h); xmlSetProp( node, (const xmlChar *)"height", (const xmlChar *)&tmp ); data = readpng_get_image( 2.2, &channels, &rowbytes, &palette, &n_pal ); if( !quiet ) { fprintf(stderr,"Importing PNG: '%s' (%i bit/pixel)\n", filename, (rowbytes*8)/w ); } if( channels == 4 && rowbytes == (4*w) ) { int c; float a; unsigned char r,g,b; for( int i=0; i