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; }
HBITMAP CreateBitmapFromPNG(const TCHAR *szFilename) { double default_display_exponent = 2.2; int Channels; unsigned long Rowbytes; unsigned long *lpData; BITMAPINFOHEADER bmih = {0}; HBITMAP hbm; FILE *file = _tfopen(szFilename, _T("rb")); if (file == NULL) return NULL; readpng_init(file, &image_width, &image_height); bmih.biSize = sizeof(bmih); bmih.biWidth = image_width; bmih.biHeight = -image_height; bmih.biPlanes = 1; bmih.biBitCount = 32; bmih.biCompression = BI_RGB; bmih.biSizeImage = 0; bmih.biXPelsPerMeter = 0; bmih.biYPelsPerMeter = 0; bmih.biClrUsed = 0; bmih.biClrImportant = 0; lpData = readpng_get_image(default_display_exponent, &Channels, &Rowbytes); int i; for (i = 0; i < (image_width * image_height); i++) { unsigned char *rgb = &lpData[i]; if (rgb[3] != 0xFF) { double ratio = (double) rgb[3] / 255.0; unsigned char swap = rgb[0]; rgb[0] = 0xFF * (1.0 - ratio) + (rgb[2] * ratio); rgb[1] = 0xFF * (1.0 - ratio) + (rgb[1] * ratio); rgb[2] = 0xFF * (1.0 - ratio) + (swap * ratio); } else { unsigned char swap; swap = rgb[0]; rgb[0] = rgb[2]; rgb[2] = swap; } } hbm = CreateCompatibleBitmap(GetDC(NULL), image_width, image_height); SetDIBits(GetDC(NULL), hbm, 0, image_height, lpData, &bmih, DIB_RGB_COLORS); free(lpData); fclose(file); return hbm; }
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; }
int main( int argc, char **argv ) { target targets[512]; int number_of_targets = 0; char * filename = NULL; char * crop_specification_filename = NULL; FILE * infile; char line_buffer[512]; int rc; unsigned long image_width, image_height, image_rowbytes, image_depth; int image_channels; unsigned char *image_data; int i; if( argc != 3 ) { printf("Usage: crop-images <input-png-file-name> <crop-specification>\n"); return -1; } filename = argv[1]; crop_specification_filename = argv[2]; FILE * specification_file = fopen(crop_specification_filename,"r"); if( ! specification_file ) { fprintf(stderr,"Failed to open %s.\n",crop_specification_filename); return -1; } while( fgets(line_buffer,511,specification_file) ) { targets[number_of_targets].output_filename = malloc(512); if( ! targets[number_of_targets].output_filename ) { fprintf(stderr,"Failed to allocate 512 bytes.\n"); return -1; } int result = sscanf( line_buffer, "%s %lu %lu %lu %lu", targets[number_of_targets].output_filename, &(targets[number_of_targets].x), &(targets[number_of_targets].y), &(targets[number_of_targets].width), &(targets[number_of_targets].height) ); if( result != 5 ) { fprintf( stderr, "Standard input wasn't in the right input.\n" ); } /* printf( "%d:\n", number_of_targets ); printf( " filename: %s\n", targets[number_of_targets].output_filename ); printf( " x: %lu\n", targets[number_of_targets].x ); printf( " y: %lu\n", targets[number_of_targets].y ); printf( " width: %lu\n", targets[number_of_targets].width ); printf( " height: %lu\n", targets[number_of_targets].height ); */ ++ number_of_targets; } if(fclose(specification_file)) { fprintf(stderr, PROGNAME ": failed to close specification file [%s]\n", crop_specification_filename); return -1; } infile = fopen(filename, "rb"); if( !infile ) { fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); return -1; } if ((rc = readpng_init(infile, &image_width, &image_height, &image_depth)) != 0) { switch (rc) { case 1: fprintf(stderr, PROGNAME ": [%s] is not a PNG file: incorrect signature\n", filename); return -1; case 2: fprintf(stderr, PROGNAME ": [%s] has bad IHDR (libpng longjmp)\n", filename); return -1; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); return -1; default: fprintf(stderr, PROGNAME ": unknown readpng_init() error\n"); return -1; } } // printf(" %s is %lu by %lu\n", filename, image_width, image_height ); // printf(" %s has depth: %lu\n", filename, image_depth ); image_data = readpng_get_image(1.0, &image_channels, &image_rowbytes); // printf(" %s has row_bytes: %lu\n", filename, image_rowbytes ); for( i = 0; i < number_of_targets; ++i ) { png_bytepp rows = NULL; png_infop info_ptr = NULL; unsigned long width = targets[i].width; unsigned long height = targets[i].height; unsigned long x = targets[i].x; unsigned long y = targets[i].y; unsigned int pitch; char * output_filename = targets[i].output_filename; png_structp png_ptr; unsigned int j, k; FILE * fp = fopen( output_filename, "wb" ); if( ! fp ) { fprintf(stderr, PROGNAME ": can't open PNG file [%s] for output\n", output_filename); return -1; } rows = malloc( height * sizeof(png_bytep) ); png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); if( ! png_ptr ) { fprintf(stderr, PROGNAME "Failed to allocate a png_structp\n" ); free(rows); fclose(fp); return -1; } info_ptr = png_create_info_struct( png_ptr ); if( ! info_ptr ) { fprintf(stderr, PROGNAME "Failed to allocate a png_infop" ); png_destroy_write_struct( &png_ptr, 0 ); free(rows); fclose( fp ); return -1; } if( setjmp( png_ptr->jmpbuf ) ) { fprintf(stderr, PROGNAME "Failed to setjmp\n" ); png_destroy_write_struct( &png_ptr, 0 ); free(rows); fclose(fp); return -1; } png_init_io( png_ptr, fp ); png_set_compression_level( png_ptr, 3 ); png_set_IHDR( png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, // The only option... PNG_FILTER_TYPE_DEFAULT ); png_write_info(png_ptr, info_ptr); if( setjmp( png_ptr->jmpbuf ) ) { fprintf(stderr, PROGNAME "Failed to setjmp\n" ); png_destroy_write_struct( &png_ptr, 0 ); free(rows); fclose(fp); return -1; } pitch = png_get_rowbytes( png_ptr, info_ptr ); // printf( "pitch is: %d\n",pitch ); for( j = 0; j < height; ++j ) { unsigned char * row = malloc(pitch); if( ! row ) { int l; fprintf(stderr, PROGNAME "Failed to allocate a row\n" ); png_destroy_write_struct( &png_ptr, 0 ); for( l = 0; l < j; ++j ) { free(rows[l]); } free(rows); fclose(fp); return -1; } for( k = 0; k < width; ++k ) { row[k] = image_data[(y + j)*image_rowbytes + (3 * (x + k))]; rows[j] = row; } } png_write_image( png_ptr, rows ); png_write_end( png_ptr, 0 ); png_destroy_write_struct( &png_ptr, &info_ptr ); for( j = 0; j < height; ++j ) { free(rows[j]); } free( rows ); free( targets[number_of_targets].output_filename ); } return 0; }
FILE * readpng_or_exit(char *filename, png_store *pngdata){ FILE *f = fopen(filename,"r"); if(f == NULL){ DEBUG fprintf(stderr,"Error, could not open file: %s\n", filename); exit(1); } int ret = readpng_init(f,pngdata); if(ret != 0){ switch(ret){ case 1: perror("Invalid PNG file.\n"); break; case 4: perror("Out of memory.\n"); break; default: perror("Error, could not load image.\n"); } exit(1); } printf("Width: %ld\n", pngdata->width); printf("Height: %ld\n", pngdata->height); printf("Bitdepth: %d\n", pngdata->bitdepth); printf("Color Type: %d\n", pngdata->colortype); if(pngdata->bitdepth != 8){ fprintf(stderr,"Error: bit depth must be 8, is %d.\n",pngdata->bitdepth); exit(1); } if((pngdata->colortype != RGB) && (pngdata->colortype != RGBA)){ fprintf(stderr,"Error: color type must be 2 (RGB) or 6 (RGBA), instead is %d.\n",pngdata->colortype); exit(1); } switch(pngdata->colortype ){ case RGB: pngdata->pixelsize = 3; break; case RGBA: pngdata->pixelsize = 4; break; } unsigned char *imgdata = readpng_get_image(pngdata); if(imgdata == NULL){ perror("Invalid image.\n"); exit(1); } /* unsigned int avgr,avgg,avgb,avga; avgr=avgg=avgb=avga = 0; int cntx,cnty; for(cntx = 0; cntx< pngdata->width;cntx++) for(cnty = 0; cnty< pngdata->height;cnty++) { unsigned int pix = rgba_pixel(cntx,cnty,pngdata); avgr += (unsigned int)(pix & 0xff); avgg += (unsigned int)((pix >> 8) & 0xff); avgb += (unsigned int)((pix >> 16) & 0xff); avga += (unsigned int)((pix >> 24) & 0xff); // printf("%08x\n",pix); // printf("RGBA: %02x %02x %02x %02x\n", (pix & 0xff),((pix >> 8) & 0xff),( (pix >> 16) & 0xff), ((pix >> 24) & 0xff)); // printf("RGBA: %3d,%3d,%3d,%3d\n", (pix & 0xff),((pix >> 8) & 0xff),( (pix >> 16) & 0xff), ((pix >> 24) & 0xff)); } long tot = pngdata->width * pngdata->height; printf("R %ld\n", avgr/tot); printf("G %ld\n", avgg/tot); printf("B %ld\n", avgb/tot); printf("A %ld\n", avga/tot); */ return f; }
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; }