int png_to_img(const char * filename, uint32 mask, kos_img_t * rv) { uint16 *temp_tex; /* More stuff */ uint8 *buffer; /* Output row buffer */ uint32 row_stride; /* physical row width in output buffer */ uint32 channels; /* 3 for RGB 4 for RGBA */ FILE *infile; /* source file */ void *strs; /* internal structs */ assert( rv != NULL ); if ((infile = fopen(filename, "r")) == 0) { dbglog(DBG_ERROR, "png_to_texture: can't open %s\n", filename); return -1; } /* Step 1: Initialize loader */ strs = readpng_init(infile); if (!strs) { fclose(infile); return -2; } /* Step 1.5: Create output kos_img_t */ /* rv = (kos_img_t *)malloc(sizeof(kos_img_t)); */ /* Step 2: Read file */ buffer = readpng_get_image(strs,&channels, &row_stride, &rv->w, &rv->h); temp_tex = (uint16 *)malloc(sizeof(uint16) * rv->w * rv->h); rv->data = (void *)temp_tex; rv->byte_count = rv->w * rv->h * 2; _png_copy_texture(buffer, temp_tex, channels, row_stride, mask, rv->w, rv->h); switch (mask) { case PNG_NO_ALPHA: rv->fmt = KOS_IMG_FMT(KOS_IMG_FMT_RGB565, 0); break; case PNG_MASK_ALPHA: rv->fmt = KOS_IMG_FMT(KOS_IMG_FMT_ARGB1555, 0); break; case PNG_FULL_ALPHA: rv->fmt = KOS_IMG_FMT(KOS_IMG_FMT_ARGB4444, 0); break; } /* Step 3: Finish decompression */ free(buffer); readpng_cleanup(strs); fclose(infile); /* And we're done! */ return 0; }
int get_image_png(const char * filename, image_t * image) { uint8 *temp_tex; /* More stuff */ uint8 *buffer; /* Output row buffer */ uint32 row_stride; /* physical row width in output buffer */ uint32 channels; /* 3 for RGB 4 for RGBA */ FILE *infile; /* source file */ assert(image != NULL); if((infile = fopen(filename, "rb")) == 0) { printf("png_to_texture: can't open %s\n", filename); return -1; } /* Step 1: Initialize loader */ if(readpng_init(infile)) { fclose(infile); return -2; } /* Step 1.5: Create output kos_img_t */ /* rv = (kos_img_t *)malloc(sizeof(kos_img_t)); */ /* Step 2: Read file */ buffer = readpng_get_image(&channels, &row_stride, &image->w, &image->h); temp_tex = (uint8 *)malloc(sizeof(uint8) * 4 * image->w * image->h); image->data = (unsigned char *)temp_tex; image->bpp = 4; image->stride = image->w * 4; _png_copy_texture(buffer, temp_tex, channels, row_stride, image->w, image->h); /* Step 3: Finish decompression */ free(buffer); readpng_cleanup(); fclose(infile); /* And we're done! */ return 0; }
void swft_import_png( xmlXPathParserContextPtr ctx, int nargs ) { xsltTransformContextPtr tctx; char *filename; xsltDocumentPtr xsltdoc; xmlDocPtr doc = NULL; xmlNodePtr node; xmlXPathObjectPtr obj; char tmp[TMP_STRLEN]; png_colorp palette; int n_pal; int format = 5; int data_size = 0; 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, ctx->context->doc->URL); 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( filename, "rb" ); if( !fp ) { xsltTransformError(xsltXPathGetTransformContext(ctx), NULL, NULL, "swft:import-png() : failed to read file '%s'\n", filename); valuePush(ctx, xmlXPathNewNodeSet(NULL)); goto fail; } doc = xmlNewDoc( (const xmlChar *)"1.0"); doc->xmlRootNode = xmlNewDocNode( doc, NULL, (const xmlChar *)"png", NULL ); node = doc->xmlRootNode; swft_addFileName( node, filename ); // add data rewind(fp); unsigned char *data, *compressed; unsigned long w, h, rowbytes; int channels; int compressed_size; if( !fp ) goto fail; if( readpng_init( fp, &w, &h ) ) goto fail; // add w/h snprintf(tmp, TMP_STRLEN, "%lu", w); xmlSetProp( node, (const xmlChar *)"width", (const xmlChar *)&tmp ); snprintf(tmp,TMP_STRLEN,"%lu", 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' (%lu 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<w*h*4; i+=4 ) { a = data[i+3]/255.0; r = (unsigned char)((data[i+0])*a); g = (unsigned char)((data[i+1])*a); b = (unsigned char)((data[i+2])*a); data[i] = data[i+3]; data[i+1] = r; data[i+2] = g; data[i+3] = b; } data_size = w*h*4; } else if( channels == 3 && rowbytes == (3*w) ) { unsigned char *rgba = new unsigned char[ w*h*4 ]; for( int i=0; i<w*h; i++ ) { rgba[i*4] = 0xff; rgba[(i*4)+3] = data[(i*3)+2]; rgba[(i*4)+2] = data[(i*3)+1]; rgba[(i*4)+1] = data[(i*3)]; } data = rgba; data_size = w*h*4; } else if( channels == 1 && rowbytes == w ) { unsigned char *img_data = data; format = 3; int bpr = rowbytes; bpr += (rowbytes % 4) ? 4 - (rowbytes % 4) : 0; if( n_pal ) { data_size = (4*n_pal) + (bpr*h); data = new unsigned char[ data_size ]; for( int i=0; i<n_pal; i++ ) { unsigned char *entry = &data[(i*4)]; entry[2] = palette[i].blue; entry[1] = palette[i].green; entry[0] = palette[i].red; entry[3] = 0xff; } } else { n_pal = 0xff; data_size = (4*n_pal) + (bpr*h); data = new unsigned char[ data_size ]; for( int i=0; i<n_pal; i++ ) { unsigned char *entry = &data[(i*4)]; entry[2] = i; entry[1] = i; entry[0] = i; entry[3] = 0xff; } } /* copy row by row with 32bit alignment */ unsigned char *dst = &data[ (4*n_pal) ]; unsigned char *src = img_data; memset( dst, 0, bpr*h ); for( int y=0; y<h; y++ ) { memcpy( dst, src, rowbytes ); dst += bpr; src += rowbytes; } snprintf(tmp,TMP_STRLEN,"%i", n_pal-1 ); xmlSetProp( node, (const xmlChar *)"n_colormap", (const xmlChar *)&tmp ); } else { fprintf(stderr, "WARNING: can only import 8bit palette, 24 or 32bit " "RGB(A) PNGs (%s has %i channels, rowstride %lu)\n", filename, channels, rowbytes); goto fail; } // format is 5 for RGB(A), 3 for palette (4 for 16bit, unused) snprintf(tmp,TMP_STRLEN,"%i", format ); xmlSetProp( node, (const xmlChar *)"format", (const xmlChar *)&tmp ); compressed_size = data_size; if( compressed_size < 1024 ) compressed_size = 1024; compressed = new unsigned char[ compressed_size ]; if( compress( data, data_size, compressed, &compressed_size ) ) { swft_addData( node, (char*)compressed, compressed_size ); valuePush( ctx, xmlXPathNewNodeSet( (xmlNodePtr)doc ) ); } goto end; fail: fprintf( stderr, "WARNING: could not import %s\n", filename ); end: if (fp) { fclose(fp); } delete compressed; delete filename; readpng_cleanup( true ); }
int img_load_data(FILE *f, IMG_INFO *info, kos_img_t *img) { uint32 channels, rowBytes; uint8 *data = NULL; uint8 allocate = 0; if (info == NULL) { allocate = 1; info = (IMG_INFO *)malloc(sizeof(IMG_INFO)); memset(&info,0,sizeof(IMG_INFO)); } switch(info->type) { case IMG_FILE_GUESS: return -1; break; case IMG_FILE_JPEG: { readjpeg_init(f); data = readjpeg_get_image(&channels, &rowBytes, &img->w, &img->h); readjpeg_cleanup(); break; } case IMG_FILE_PNG: { readpng_init(f); data = readpng_get_image(&channels, &rowBytes, &img->w, &img->h); readpng_cleanup(); break; } case IMG_FILE_BMP: { readbmp_init(f); data = readbmp_get_image(&channels, &rowBytes, &img->w, &img->h); readbmp_cleanup(); break; } case IMG_FILE_PCX: { readpcx_init(f); data = readpcx_get_image(&channels, &rowBytes, &img->w, &img->h); readpcx_cleanup(); break; } } if (info->dither_width == 0) info->dither_width = img->w; if (info->dither_height == 0) info->dither_height = img->h; img->data = (uint16 *)malloc(sizeof(uint16)*img->w*img->h); img->byte_count = sizeof(uint16)*img->w*img->h; img_copy_texture(img->data, data, channels, rowBytes, info, img->w, img->h); free(data); if (allocate) { free(info); } switch(info->alpha) { case IMG_ALPHA_NONE: img->fmt = KOS_IMG_FMT(KOS_IMG_FMT_RGB565, 0); break; case IMG_ALPHA_MASK: img->fmt = KOS_IMG_FMT(KOS_IMG_FMT_ARGB1555, 0); break; case IMG_ALPHA_KEYED: img->fmt = KOS_IMG_FMT(KOS_IMG_FMT_ARGB1555, 0); break; case IMG_ALPHA_FULL: img->fmt = KOS_IMG_FMT(KOS_IMG_FMT_ARGB4444, 0); break; } return 0; }