void pgeTextureSave(pgeTexture *texture, const char* filename) { if(texture == 0) return; if(texture->data == 0 || texture->width == 0 || texture->height == 0) return; int swizzled = texture->swizzled; if(swizzled) pgeTextureUnswizzle(texture); png_structp png_ptr; png_infop info_ptr; FILE* fp; unsigned char* line; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) return; info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return; } unsigned int col_type = PNG_COLOR_TYPE_RGBA; fp = fopen(filename, "wb"); if (!fp) return; png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, texture->width, texture->height, 8, col_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); line = (unsigned char*) pgeMalloc(texture->width * 4); if(line == 0) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fp); return; } unsigned char* src = (unsigned char*)texture->data; unsigned char* src8 = (unsigned char*)src; unsigned short* src16 = (unsigned short*)src; unsigned int* src32 = (unsigned int*)src; unsigned int i, x, y; for(y = 0; y < texture->height; y++) { unsigned int swap = 0; src8 = (unsigned char*)src; src16 = (unsigned short*)src; src32 = (unsigned int*)src; for(i = 0, x = 0; x < texture->width; x++) { unsigned int r = 0, g = 0, b = 0, a = 0; unsigned short col16; unsigned int col32; unsigned char col8; switch(texture->format) { case PGE_PIXEL_FORMAT_5650: col16 = *src16++; RGBA5650(col16,r,g,b,a); break; case PGE_PIXEL_FORMAT_5551: col16 = *src16++; RGBA5551(col16,r,g,b,a); break; case PGE_PIXEL_FORMAT_4444: col16 = *src16++; RGBA4444(col16,r,g,b,a); break; case PGE_PIXEL_FORMAT_8888: col32 = *src32++; RGBA8888(col32,r,g,b,a); break; case PGE_PIXEL_FORMAT_T4: col8 = *src8; if(swap == 0) col8 &= 0xF; else { col8 >>= 4; src8++; } swap ^= 1; pgeTexturePaletteGet(texture, col8, &r, &g, &b, &a); break; case PGE_PIXEL_FORMAT_T8: col8 = *src8++; pgeTexturePaletteGet(texture, col8, &r, &g, &b, &a); break; case PGE_PIXEL_FORMAT_T16: case PGE_PIXEL_FORMAT_T32: default: break; } line[i++] = r; line[i++] = g; line[i++] = b; line[i++] = a; } png_write_row(png_ptr, line); src += ((texture->textureWidth*texture->bits) >> 3); } pgeFree(line); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fp); if(swizzled) pgeTextureSwizzle(texture); }
int read_png_file(const char *file, int32 *pwidth, int32 *pheight, uint8 **image_data_ptr) { FILE *infile; /* PNG file pointer */ png_structp png_ptr; /* internally used by libpng */ png_infop info_ptr; /* user requested transforms */ uint8 *image_data; /* raw png image data */ char sig[8]; /* PNG signature array */ /*char **row_pointers; */ int bit_depth; int color_type; png_uint_32 width; /* PNG image width in pixels */ png_uint_32 height; /* PNG image height in pixels */ unsigned int rowbytes; /* raw bytes at row n in image */ image_data = NULL; int i; png_bytepp row_pointers = NULL; /* Open the file. */ infile = fopen(file, "rb"); if (!infile) { return 0; } /* * 13.3 readpng_init() */ /* Check for the 8-byte signature */ fread(sig, 1, 8, infile); if (png_sig_cmp((unsigned char *) sig, 0, 8) != 0) { fclose(infile); return 0; } /* * Set up the PNG structs */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(infile); return 4; /* out of memory */ } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); fclose(infile); return 4; /* out of memory */ } /* * block to handle libpng errors, * then check whether the PNG file had a bKGD chunk */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(infile); return 0; } /* * takes our file stream pointer (infile) and * stores it in the png_ptr struct for later use. */ /* png_ptr->io_ptr = (png_voidp)infile;*/ png_init_io(png_ptr, infile); /* * lets libpng know that we already checked the 8 * signature bytes, so it should not expect to find * them at the current file pointer location */ png_set_sig_bytes(png_ptr, 8); /* Read the image info.*/ /* * reads and processes not only the PNG file's IHDR chunk * but also any other chunks up to the first IDAT * (i.e., everything before the image data). */ /* read all the info up to the image data */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); *pwidth = width; *pheight = height; if (bit_depth > 8) { png_set_strip_16(png_ptr); } #if defined(__DAVAENGINE_WIN32__) if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); #endif if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(png_ptr); png_set_filler(png_ptr, 0xFFFF, PNG_FILLER_AFTER); } if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); png_set_filler(png_ptr, 0xFFFF, PNG_FILLER_AFTER); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); if (CommandLineParser::Instance()->GetVerbose()) printf("*** TOCHECK: convert tRNS to alpha\n"); } if (color_type == PNG_COLOR_TYPE_RGB) { if (CommandLineParser::Instance()->GetVerbose()) printf("*** Converting %s from RGB to RGBA\n", file); png_set_filler(png_ptr, 0xFFFF, PNG_FILLER_AFTER); } /* Update the png info struct.*/ png_read_update_info(png_ptr, info_ptr); /* Rowsize in bytes. */ rowbytes = png_get_rowbytes(png_ptr, info_ptr); char string_format[16]; strcpy(string_format, "undefined"); if (color_type == PNG_COLOR_TYPE_RGBA) { strcpy(string_format, "RGBA"); } if (CommandLineParser::Instance()->GetVerbose()) { printf("* Reading PNG file: %s format: %s bit_depth:%d bytes_per_pixel:%d\n", file, string_format, bit_depth, rowbytes / width); } /* Allocate the image_data buffer. */ // printf("r/w: %d %d\n" , rowbytes / width, bit_depth); if ((image_data = new uint8 [rowbytes * height]) ==NULL) { memset(image_data, 0, rowbytes * height); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 4; } if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); delete [] (image_data); image_data = NULL; return 4; } /* set the individual row_pointers to point at the correct offsets */ for (i = 0; i < (int)height; ++i) row_pointers[i] = image_data + i*rowbytes; /* now we can go ahead and just read the whole image */ png_read_image(png_ptr, row_pointers); /* and we're done! (png_read_end() can be omitted if no processing of * post-IDAT text/time/etc. is desired) */ /* Clean up. */ free(row_pointers); /* Clean up. */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(infile); *image_data_ptr = image_data; return 1; }
/* Read a PNG file. You may want to return an error code if the read * fails (depending upon the failure). There are two "prototypes" given * here - one where we are given the filename, and we need to open the * file, and the other where we are given an open file (possibly with * some or all of the magic bytes read - see comments above). */ #ifdef open_file /* prototype 1 */ void read_png(char *file_name) /* We need to open the file */ { png_structp png_ptr; png_infop info_ptr; unsigned int sig_read = 0; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE *fp; if ((fp = fopen(file_name, "rb")) == NULL) return (ERROR); #else no_open_file /* prototype 2 */ void read_png(FILE *fp, unsigned int sig_read) /* File is already open */ { png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; #endif no_open_file /* Only use one prototype! */ /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { fclose(fp); return (ERROR); } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return (ERROR); } /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return (ERROR); } /* One of the following I/O initialization methods is REQUIRED */ #ifdef streams /* PNG file I/O method 1 */ /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, fp); #else no_streams /* PNG file I/O method 2 */ /* If you are using replacement read functions, instead of calling * png_init_io() here you would call: */ png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn); /* where user_io_ptr is a structure you want available to the callbacks */ #endif no_streams /* Use only one I/O method! */ /* If we have already read some of the signature */ png_set_sig_bytes(png_ptr, sig_read); #ifdef hilevel /* * If you have enough memory to read in the entire image at once, * and you need to specify only transforms that can be controlled * with one of the PNG_TRANSFORM_* bits (this presently excludes * dithering, filling, setting background, and doing gamma * adjustment), then you can read the entire image (including * pixels) into the info structure with this call: */ png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL); #else /* OK, you're doing it the hard way, with the lower-level functions */ /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). REQUIRED */ png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); /* Set up the data transformations you want. Note that these are all * optional. Only call them if you want/need them. Many of the * transformations only work on specific types of images, and many * are mutually exclusive. */ /* Tell libpng to strip 16 bit/color files down to 8 bits/color */ png_set_strip_16(png_ptr); /* Strip alpha bytes from the input data without combining with the * background (not recommended). */ png_set_strip_alpha(png_ptr); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ png_set_packing(png_ptr); /* Change the order of packed pixels to least significant bit first * (not useful if you are using png_set_packing). */ png_set_packswap(png_ptr); /* Expand paletted colors into true RGB triplets */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr); /* Expand paletted or RGB images with transparency to full alpha channels * so the data will be available as RGBA quartets. */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); /* Set the background color to draw transparent and alpha images over. * It is possible to set the red, green, and blue components directly * for paletted images instead of supplying a palette index. Note that * even if the PNG file supplies a background, you are not required to * use it - you should use the (solid) application background if it has one. */ png_color_16 my_background, *image_background; if (png_get_bKGD(png_ptr, info_ptr, &image_background)) png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); /* Some suggestions as to how to get a screen gamma value * * Note that screen gamma is the display_exponent, which includes * the CRT_exponent and any correction for viewing conditions */ if (/* We have a user-defined screen gamma value */) { screen_gamma = user-defined screen_gamma; } /* This is one way that applications share the same screen gamma value */ else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
pngdata_t * loadpng(const char * path, int cutoff) { png_structp png_ptr; png_infop info_ptr; png_bytep * row_pointers; int width, height, rowbytes; int x, y; unsigned char header[8]; // 8 is the maximum size that can be checked png_byte* ptr; FILE *fp; int type = 0; int lb; uint8_t * bitmap; /* open file and test for it being a png */ fp = fopen(path, "rb"); if (!fp) abort_("[read_png_file] File %s could not be opened for reading", path); fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) abort_("[read_png_file] File %s is not recognized as a PNG file", path); /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[read_png_file] png_create_read_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[read_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); if (png_get_channels(png_ptr, info_ptr) == 1 && png_get_bit_depth(png_ptr, info_ptr) == 1) { type = 1; } else if (png_get_channels(png_ptr, info_ptr) == 4 && png_get_bit_depth(png_ptr, info_ptr) == 8) { type = 2; } if (type == 0) { fprintf(stderr, "Invalid PNG! Only mono or 4x8-bit RGBA PNG files are allowed\n"); exit(1); } width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image"); row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); rowbytes = type == 1 ? (width / 8) + (width % 8 > 0) : width << 2; for (y=0; y<height; y++) row_pointers[y] = (png_byte*) malloc(rowbytes); png_read_image(png_ptr, row_pointers); fclose(fp); lb = (height / 8) + (height % 8 > 0); bitmap = malloc(width*lb); memset(bitmap, 0, width*lb); #define heat_on(x, y) bitmap[(x*lb)+(y/8)] |= 1 << (7-(y%8)) for (y=0; y<height; y++) { png_byte* row = row_pointers[y]; for (x=0; x<width; x++) { if (type == 1) { ptr = &(row[x/8]); if ((ptr[0] & (1 << (7-(x%8)))) == 0) { heat_on(x, y); } } else { // Color 0 (red?) ptr = &(row[(x<<2)]); if (ptr[0] < cutoff) { // Adjust the cutoff (0 to 255). Any pixel darker (lower) than this will be black. Higher will be white. This can be used to turn anti-aliased pngs into monochrome with some desirable cutoff for black and white. heat_on(x, y); } // Color 1 (green?) ptr = &(row[(x<<2)+1]); if (ptr[0] < cutoff) { heat_on(x, y); } // Color 2 (blue?) ptr = &(row[(x<<2)+2]); if (ptr[0] < cutoff) { heat_on(x, y); } // if ((ptr[0] & (1 << (7-(x%8)))) == 0) { // heat_on(x, y); /// } } } } /* for (y=0; y<height; y++) { png_byte* row = row_pointers[y+height*2]; for (x=0; x<width; x++) { ptr = &(row[(x<<2)]); if ((ptr[0] & (1 << (7-(x%8)))) == 0) { heat_on(x, y+height*2); } } } */ pngdata_t * ret = malloc(sizeof(pngdata_t)); ret->w = height; ret->h = width; ret->data = bitmap; return ret; }
void CachedTexture::reload() { //..... load file ...... GLenum internal_format = GL_RGB; GLenum data_format = GL_RGB; unsigned char *data = NULL; if (filename.size() >= 4 && filename.substr(filename.size()-4,4) == ".png") { //Load a png file, as per the libpng docs: FILE *fp = fopen(filename.c_str(), "rb"); if (!fp) { cerr << " cannot open file." << endl; return; } png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL); if (!png) { cerr << " cannot alloc read struct." << endl; fclose(fp); return; } png_infop info = png_create_info_struct(png); if (!info) { cerr << " cannot alloc info struct." << endl; png_destroy_read_struct(&png, (png_infopp)NULL, (png_infopp)NULL); fclose(fp); return; } png_bytep *row_pointers = NULL; if (setjmp(png_jmpbuf(png))) { cerr << " png interal error." << endl; png_destroy_read_struct(&png, &info, (png_infopp)NULL); if (data != NULL) delete[] data; if (row_pointers != NULL) delete[] row_pointers; fclose(fp); return; } png_init_io(png, fp); png_read_info(png, info); w = png_get_image_width(png, info); h = png_get_image_height(png, info); { //find power-of-two dimensions... tw = 1; while (tw < w) tw *= 2; th = 1; while (th < h) th *= 2; } if (!pad && (tw != w || th != h)) { if (!have_ARB_texture_non_power_of_two()) { cerr << "WARNING: trying to load texture of size " << w << " x " << h << ", but non-power-of-two textures not supported." << endl; } tw = w; th = h; } if (png_get_color_type(png, info) == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); if (png_get_bit_depth(png, info) < 8) png_set_packing(png); if (png_get_bit_depth(png,info) == 16) png_set_strip_16(png); png_read_update_info(png, info); unsigned int rowbytes = png_get_rowbytes(png, info); //Make sure it's the format we think it is... bool problem = false; if (png_get_color_type(png, info) == PNG_COLOR_TYPE_GRAY) { data_format = internal_format = GL_LUMINANCE; if (rowbytes != w*1) problem = true; } else if (png_get_color_type(png, info) == PNG_COLOR_TYPE_GRAY_ALPHA) { data_format = internal_format = GL_LUMINANCE_ALPHA; if (rowbytes != w*2) problem = true; } else if (png_get_color_type(png, info) == PNG_COLOR_TYPE_PALETTE || png_get_color_type(png, info) == PNG_COLOR_TYPE_RGB) { data_format = internal_format = GL_RGB; if (rowbytes != w*3) problem = true; } else if (png_get_color_type(png, info) == PNG_COLOR_TYPE_RGB_ALPHA) { data_format = internal_format = GL_RGBA; if (rowbytes != w*4) problem = true; } else { cerr << " unknown color format." << endl; problem = true; } if (problem) { cerr << " color format problem. (rowbytes: " << rowbytes << " w:" << w << ")" << endl; png_destroy_read_struct(&png, &info, NULL); fclose(fp); return; } unsigned int pixelbytes = rowbytes / w; assert(rowbytes == pixelbytes * w); //sanity check, should have bailed earlier if this was the case. data = new uint8_t[th*tw*pixelbytes]; row_pointers = new png_bytep[th]; if (flip) { //texture origin goes top-left, as in most images: for (unsigned int r = 0; r < th; ++r) { row_pointers[r] = (png_bytep)(data + r*pixelbytes*tw); } } else { //texture origin goes bottom-left, as GL says: for (unsigned int r = 0; r < th; ++r) { row_pointers[th-1-r] = (png_bytep)(data + r*tw*pixelbytes); } } png_read_image(png, row_pointers); png_destroy_read_struct(&png, &info, NULL); fclose(fp); delete[] row_pointers; if (pad && h != 0 && w != 0) { //duplicate the last column accross the texture: for (unsigned int r = 0; r < h; ++r) { for (unsigned int c = w; c < tw; ++c) { memcpy(&(data[(r*tw+c)*pixelbytes]), &(data[(r*tw+w-1)*pixelbytes]),pixelbytes); } } //duplicate the last row down the texture: for (unsigned int r = h; r < th; ++r) { memcpy(&(data[r*pixelbytes*tw]), &(data[(h-1)*pixelbytes*tw]), pixelbytes*tw); } } } else { //well, not a supported image type I'm afraid. cerr << " unknown image type." << endl; return; } glGenTextures(1, &obj); glBindTexture(GL_TEXTURE_2D, obj); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, tw, th, 0, data_format, GL_UNSIGNED_BYTE, data); glBindTexture(GL_TEXTURE_2D, 0); glPopClientAttrib(); delete[] data; loaded = true; gl_errors("CachedTexture::reload()"); }
void savePNG(const char* file_name) { png_structp png_ptr; png_infop info_ptr; /* create file */ FILE *fp = fopen(file_name, "wb"); if (!fp) abort_("[write_png_file] File %s could not be opened for writing", file_name); /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[write_png_file] png_create_write_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[write_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during init_io"); png_init_io(png_ptr, fp); /* write header */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, pictureWidth, pictureHeight, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); /* write bytes */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing bytes"); png_bytep * row_pointers; unsigned char *array = new unsigned char[pictureWidth * pictureHeight * 4]; for (int i = pictureWidth * pictureHeight; i >= 0; --i) { array[i*4+0] = ((unsigned char*)pictureWriteOut)[i*4+0]; array[i*4+1] = ((unsigned char*)pictureWriteOut)[i*4+1]; array[i*4+2] = ((unsigned char*)pictureWriteOut)[i*4+2]; array[i*4+3] = ((unsigned char*)pictureWriteOut)[i*4+3]; } // Allocate pointers... row_pointers = new png_bytep[pictureHeight]; for (int i = 0; i < pictureHeight; i ++) row_pointers[i] = (png_bytep)(array + (i) * pictureWidth * 4); // we flip it png_write_image(png_ptr, row_pointers); /* end write */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); /* cleanup heap allocation */ free(row_pointers); fclose(fp); }
int readpng_init(FILE *infile, png_store *pngdata) { unsigned char sig[8]; long width,height; int bit_depth, color_type; /* first do a quick check that the file really is a PNG image; could * have used slightly more general png_sig_cmp() function instead */ size_t fr = fread(sig, 1, 8, infile); if(fr != 1*8) return 1; /* bad signature */ if (!png_check_sig(sig, 8)) return 1; /* bad signature */ /* could pass pointers to user-defined error handlers instead of NULLs: */ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return 4; /* out of memory */ png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return 4; /* out of memory */ } /* we could create a second info struct here (end_info), but it's only * useful if we want to keep pre- and post-IDAT chunk info separated * (mainly for PNG-aware image editors and converters) */ /* setjmp() must be called in every function that calls a PNG-reading * libpng function */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 2; } png_init_io(png_ptr, infile); png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ /* alternatively, could make separate calls to png_get_image_width(), * etc., but want bit_depth and color_type for later [don't care about * compression_type and filter_type => NULLs] */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); pngdata->width = width; pngdata->height = height; pngdata->bitdepth = bit_depth; pngdata->colortype = color_type; pngdata->png_ptr = png_ptr; pngdata->info_ptr = info_ptr; /* OK, that's all we need for now; return happy */ return 0; }
Py::Object _image_module::readpng(const Py::Tuple& args) { args.verify_length(1); std::string fname = Py::String(args[0]); png_byte header[8]; // 8 is the maximum size that can be checked FILE *fp = fopen(fname.c_str(), "rb"); if (!fp) throw Py::RuntimeError(Printf("_image_module::readpng could not open PNG file %s for reading", fname.c_str()).str()); fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) throw Py::RuntimeError("_image_module::readpng: file not recognized as a PNG file"); /* initialize stuff */ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) throw Py::RuntimeError("_image_module::readpng: png_create_read_struct failed"); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) throw Py::RuntimeError("_image_module::readpng: png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) throw Py::RuntimeError("_image_module::readpng: error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_uint_32 width = info_ptr->width; png_uint_32 height = info_ptr->height; // convert misc color types to rgb for simplicity if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); int bit_depth = info_ptr->bit_depth; if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); bool rgba = info_ptr->color_type == PNG_COLOR_TYPE_RGBA; if ( (info_ptr->color_type != PNG_COLOR_TYPE_RGB) && !rgba) { std::cerr << "Found color type " << (int)info_ptr->color_type << std::endl; throw Py::RuntimeError("_image_module::readpng: cannot handle color_type"); } /* read file */ if (setjmp(png_jmpbuf(png_ptr))) throw Py::RuntimeError("_image_module::readpng: error during read_image"); png_bytep row_pointers[height]; for (png_uint_32 row = 0; row < height; row++) row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr,info_ptr)]; png_read_image(png_ptr, row_pointers); int dimensions[3]; dimensions[0] = height; //numrows dimensions[1] = width; //numcols dimensions[2] = 4; PyArrayObject *A = (PyArrayObject *) PyArray_FromDims(3, dimensions, PyArray_FLOAT); for (png_uint_32 y = 0; y < height; y++) { png_byte* row = row_pointers[y]; for (png_uint_32 x = 0; x < width; x++) { png_byte* ptr = (rgba) ? &(row[x*4]) : &(row[x*3]); size_t offset = y*A->strides[0] + x*A->strides[1]; //if ((y<10)&&(x==10)) std::cout << "r = " << ptr[0] << " " << ptr[0]/255.0 << std::endl; *(float*)(A->data + offset + 0*A->strides[2]) = ptr[0]/255.0; *(float*)(A->data + offset + 1*A->strides[2]) = ptr[1]/255.0; *(float*)(A->data + offset + 2*A->strides[2]) = ptr[2]/255.0; *(float*)(A->data + offset + 3*A->strides[2]) = rgba ? ptr[3]/255.0 : 1.0; } } //free the png memory png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); for (png_uint_32 row = 0; row < height; row++) delete [] row_pointers[row]; return Py::asObject((PyObject*)A); }
int load_png_graphics (char *txt_filename, char *png_filename) { png_uint_32 row; png_structp png_ptr; png_infop info_ptr; unsigned int sig_read = 0; png_uint_32 width, height; int bit_depth, color_type, interlace_type; FILE *fp, *txt_fp; png_bytep *row_pointers; if ((fp = fopen(png_filename, "rb")) == NULL) return (ERROR); if ((txt_fp = fopen(txt_filename, "r")) == NULL) return (ERROR); /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) user_error_ptr, user_error_fn, user_warning_fn); if (png_ptr == NULL) { fclose(fp); return (ERROR); } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); #if defined (commentout) png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); #endif png_destroy_read_struct(&png_ptr, NULL, NULL); return (ERROR); } /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ #if defined (commentout) png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); #endif png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return (ERROR); } /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, fp); /* If we have already read some of the signature */ png_set_sig_bytes(png_ptr, sig_read); /* OK, you're doing it the hard way, with the lower-level functions */ /* The call to png_read_info() gives us all of the information from the * PNG file before the first IDAT (image data chunk). REQUIRED */ png_read_info(png_ptr, info_ptr); #if defined (commentout) png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); #endif png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); printf ("PNG Header: %d x %d, bd=%d, ct=%d\n", height, width, bit_depth, color_type); /* Set up the data transformations you want. Note that these are all * optional. Only call them if you want/need them. Many of the * transformations only work on specific types of images, and many * are mutually exclusive. */ /* tell libpng to strip 16 bit/color files down to 8 bits/color */ // png_set_strip_16(png_ptr); /* Strip alpha bytes from the input data without combining with the * background (not recommended). */ // png_set_strip_alpha(png_ptr); /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ // png_set_packing(png_ptr); /* Change the order of packed pixels to least significant bit first * (not useful if you are using png_set_packing). */ // png_set_packswap(png_ptr); /* Require color fmt w/ palette */ if (color_type != PNG_COLOR_TYPE_PALETTE) { printf ("Error - png image wasn't PNG_COLOR_TYPE_PALETTE\n"); /* Free all of the memory associated with the png_ptr and info_ptr */ #if defined (commentout) png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); #endif png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return (ERROR); } /* Require 1 byte per pixel */ if (bit_depth != 8) { printf ("Error - png image wasn't bit_depth = 8\n"); /* Free all of the memory associated with the png_ptr and info_ptr */ #if defined (commentout) png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); #endif png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return (ERROR); } /* The easiest way to read the image: */ row_pointers = malloc (sizeof(void*)*height); for (row = 0; row < height; row++) { row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); } png_read_image(png_ptr, row_pointers); #if defined (commentout) for (col = 0; col < 16; col++) { printf (" %02x ",row_pointers[0][col]); } printf ("\n"); for (col = 0; col < 16; col++) { printf ("%3d ",row_pointers[0][col]); } printf ("\n"); #endif /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); /* close the png file */ fclose(fp); /* get the icons out of the png */ #ifdef LG #undef LG #endif #define LG(typ,grp,id) load_png_graphic(typ,grp,id,txt_fp,row_pointers,height,width) LG(CST_GREEN,GROUP_BARE,LCT_GREEN_G); LG(CST_FIRE_1,GROUP_FIRE,LCT_FIRE_1_G); LG(CST_FIRE_2,GROUP_FIRE,LCT_FIRE_2_G); LG(CST_FIRE_3,GROUP_FIRE,LCT_FIRE_3_G); LG(CST_FIRE_4,GROUP_FIRE,LCT_FIRE_4_G); LG(CST_FIRE_5,GROUP_FIRE,LCT_FIRE_5_G); LG(CST_FIRE_DONE1,GROUP_FIRE,LCT_FIRE_DONE1_G); LG(CST_FIRE_DONE2,GROUP_FIRE,LCT_FIRE_DONE2_G); LG(CST_FIRE_DONE3,GROUP_FIRE,LCT_FIRE_DONE3_G); LG(CST_FIRE_DONE4,GROUP_FIRE,LCT_FIRE_DONE4_G); LG(CST_BURNT,GROUP_BURNT,LCT_BURNT_G); LG(CST_PARKLAND_PLANE,GROUP_PARKLAND,LCT_PARKLAND_PLANE_G); LG(CST_PARKLAND_LAKE,GROUP_PARKLAND,LCT_PARKLAND_LAKE_G); LG(CST_POWERL_H_L,GROUP_POWER_LINE,LCT_POWERL_H_L_G); LG(CST_POWERL_V_L,GROUP_POWER_LINE,LCT_POWERL_V_L_G); LG(CST_POWERL_LD_L,GROUP_POWER_LINE,LCT_POWERL_LD_L_G); LG(CST_POWERL_RD_L,GROUP_POWER_LINE,LCT_POWERL_RD_L_G); LG(CST_POWERL_LU_L,GROUP_POWER_LINE,LCT_POWERL_LU_L_G); LG(CST_POWERL_RU_L,GROUP_POWER_LINE,LCT_POWERL_RU_L_G); LG(CST_POWERL_LDU_L,GROUP_POWER_LINE,LCT_POWERL_LDU_L_G); LG(CST_POWERL_LDR_L,GROUP_POWER_LINE,LCT_POWERL_LDR_L_G); LG(CST_POWERL_LUR_L,GROUP_POWER_LINE,LCT_POWERL_LUR_L_G); LG(CST_POWERL_UDR_L,GROUP_POWER_LINE,LCT_POWERL_UDR_L_G); LG(CST_POWERL_LUDR_L,GROUP_POWER_LINE,LCT_POWERL_LUDR_L_G); LG(CST_POWERL_H_D,GROUP_POWER_LINE,LCT_POWERL_H_D_G); LG(CST_POWERL_V_D,GROUP_POWER_LINE,LCT_POWERL_V_D_G); LG(CST_POWERL_LD_D,GROUP_POWER_LINE,LCT_POWERL_LD_D_G); LG(CST_POWERL_RD_D,GROUP_POWER_LINE,LCT_POWERL_RD_D_G); LG(CST_POWERL_LU_D,GROUP_POWER_LINE,LCT_POWERL_LU_D_G); LG(CST_POWERL_RU_D,GROUP_POWER_LINE,LCT_POWERL_RU_D_G); LG(CST_POWERL_LDU_D,GROUP_POWER_LINE,LCT_POWERL_LDU_D_G); LG(CST_POWERL_LDR_D,GROUP_POWER_LINE,LCT_POWERL_LDR_D_G); LG(CST_POWERL_LUR_D,GROUP_POWER_LINE,LCT_POWERL_LUR_D_G); LG(CST_POWERL_UDR_D,GROUP_POWER_LINE,LCT_POWERL_UDR_D_G); LG(CST_POWERL_LUDR_D,GROUP_POWER_LINE,LCT_POWERL_LUDR_D_G); LG(CST_RAIL_LR,GROUP_RAIL,LCT_RAIL_LR_G); LG(CST_RAIL_LU,GROUP_RAIL,LCT_RAIL_LU_G); LG(CST_RAIL_LD,GROUP_RAIL,LCT_RAIL_LD_G); LG(CST_RAIL_UD,GROUP_RAIL,LCT_RAIL_UD_G); LG(CST_RAIL_UR,GROUP_RAIL,LCT_RAIL_UR_G); LG(CST_RAIL_DR,GROUP_RAIL,LCT_RAIL_DR_G); LG(CST_RAIL_LUR,GROUP_RAIL,LCT_RAIL_LUR_G); LG(CST_RAIL_LDR,GROUP_RAIL,LCT_RAIL_LDR_G); LG(CST_RAIL_LUD,GROUP_RAIL,LCT_RAIL_LUD_G); LG(CST_RAIL_UDR,GROUP_RAIL,LCT_RAIL_UDR_G); LG(CST_RAIL_LUDR,GROUP_RAIL,LCT_RAIL_LUDR_G); LG(CST_ROAD_LR,GROUP_ROAD,LCT_ROAD_LR_G); LG(CST_ROAD_LU,GROUP_ROAD,LCT_ROAD_LU_G); LG(CST_ROAD_LD,GROUP_ROAD,LCT_ROAD_LD_G); LG(CST_ROAD_UD,GROUP_ROAD,LCT_ROAD_UD_G); LG(CST_ROAD_UR,GROUP_ROAD,LCT_ROAD_UR_G); LG(CST_ROAD_DR,GROUP_ROAD,LCT_ROAD_DR_G); LG(CST_ROAD_LUR,GROUP_ROAD,LCT_ROAD_LUR_G); LG(CST_ROAD_LDR,GROUP_ROAD,LCT_ROAD_LDR_G); LG(CST_ROAD_LUD,GROUP_ROAD,LCT_ROAD_LUD_G); LG(CST_ROAD_UDR,GROUP_ROAD,LCT_ROAD_UDR_G); LG(CST_ROAD_LUDR,GROUP_ROAD,LCT_ROAD_LUDR_G); LG(CST_TRACK_LR,GROUP_TRACK,LCT_TRACK_LR_G); LG(CST_TRACK_LU,GROUP_TRACK,LCT_TRACK_LU_G); LG(CST_TRACK_LD,GROUP_TRACK,LCT_TRACK_LD_G); LG(CST_TRACK_UD,GROUP_TRACK,LCT_TRACK_UD_G); LG(CST_TRACK_UR,GROUP_TRACK,LCT_TRACK_UR_G); LG(CST_TRACK_DR,GROUP_TRACK,LCT_TRACK_DR_G); LG(CST_TRACK_LUR,GROUP_TRACK,LCT_TRACK_LUR_G); LG(CST_TRACK_LDR,GROUP_TRACK,LCT_TRACK_LDR_G); LG(CST_TRACK_LUD,GROUP_TRACK,LCT_TRACK_LUD_G); LG(CST_TRACK_UDR,GROUP_TRACK,LCT_TRACK_UDR_G); LG(CST_TRACK_LUDR,GROUP_TRACK,LCT_TRACK_LUDR_G); LG(CST_WATER,GROUP_WATER,LCT_WATER_G); LG(CST_WATER_D,GROUP_WATER,LCT_WATER_D_G); LG(CST_WATER_R,GROUP_WATER,LCT_WATER_R_G); LG(CST_WATER_U,GROUP_WATER,LCT_WATER_U_G); LG(CST_WATER_L,GROUP_WATER,LCT_WATER_L_G); LG(CST_WATER_LR,GROUP_WATER,LCT_WATER_LR_G); LG(CST_WATER_UD,GROUP_WATER,LCT_WATER_UD_G); LG(CST_WATER_LD,GROUP_WATER,LCT_WATER_LD_G); LG(CST_WATER_RD,GROUP_WATER,LCT_WATER_RD_G); LG(CST_WATER_LU,GROUP_WATER,LCT_WATER_LU_G); LG(CST_WATER_UR,GROUP_WATER,LCT_WATER_UR_G); LG(CST_WATER_LUD,GROUP_WATER,LCT_WATER_LUD_G); LG(CST_WATER_LRD,GROUP_WATER,LCT_WATER_LRD_G); LG(CST_WATER_LUR,GROUP_WATER,LCT_WATER_LUR_G); LG(CST_WATER_URD,GROUP_WATER,LCT_WATER_URD_G); LG(CST_WATER_LURD,GROUP_WATER,LCT_WATER_LURD_G); LG(CST_BLACKSMITH_0,GROUP_BLACKSMITH,LCT_BLACKSMITH_0_G); LG(CST_BLACKSMITH_1,GROUP_BLACKSMITH,LCT_BLACKSMITH_1_G); LG(CST_BLACKSMITH_2,GROUP_BLACKSMITH,LCT_BLACKSMITH_2_G); LG(CST_BLACKSMITH_3,GROUP_BLACKSMITH,LCT_BLACKSMITH_3_G); LG(CST_BLACKSMITH_4,GROUP_BLACKSMITH,LCT_BLACKSMITH_4_G); LG(CST_BLACKSMITH_5,GROUP_BLACKSMITH,LCT_BLACKSMITH_5_G); LG(CST_BLACKSMITH_6,GROUP_BLACKSMITH,LCT_BLACKSMITH_6_G); LG(CST_CRICKET_1,GROUP_CRICKET,LCT_CRICKET_1_G); LG(CST_CRICKET_2,GROUP_CRICKET,LCT_CRICKET_2_G); LG(CST_CRICKET_3,GROUP_CRICKET,LCT_CRICKET_3_G); LG(CST_CRICKET_4,GROUP_CRICKET,LCT_CRICKET_4_G); LG(CST_CRICKET_5,GROUP_CRICKET,LCT_CRICKET_5_G); LG(CST_CRICKET_6,GROUP_CRICKET,LCT_CRICKET_6_G); LG(CST_CRICKET_7,GROUP_CRICKET,LCT_CRICKET_7_G); LG(CST_FIRESTATION_1,GROUP_FIRESTATION,LCT_FIRESTATION_1_G); LG(CST_FIRESTATION_2,GROUP_FIRESTATION,LCT_FIRESTATION_2_G); LG(CST_FIRESTATION_3,GROUP_FIRESTATION,LCT_FIRESTATION_3_G); LG(CST_FIRESTATION_4,GROUP_FIRESTATION,LCT_FIRESTATION_4_G); LG(CST_FIRESTATION_5,GROUP_FIRESTATION,LCT_FIRESTATION_5_G); LG(CST_FIRESTATION_6,GROUP_FIRESTATION,LCT_FIRESTATION_6_G); LG(CST_FIRESTATION_7,GROUP_FIRESTATION,LCT_FIRESTATION_7_G); LG(CST_FIRESTATION_8,GROUP_FIRESTATION,LCT_FIRESTATION_8_G); LG(CST_FIRESTATION_9,GROUP_FIRESTATION,LCT_FIRESTATION_9_G); LG(CST_FIRESTATION_10,GROUP_FIRESTATION,LCT_FIRESTATION_10_G); LG(CST_HEALTH,GROUP_HEALTH,LCT_HEALTH_G); LG(CST_MARKET_EMPTY,GROUP_MARKET,LCT_MARKET_EMPTY_G); LG(CST_MARKET_LOW,GROUP_MARKET,LCT_MARKET_LOW_G); LG(CST_MARKET_MED,GROUP_MARKET,LCT_MARKET_MED_G); LG(CST_MARKET_FULL,GROUP_MARKET,LCT_MARKET_FULL_G); LG(CST_MILL_0,GROUP_MILL,LCT_MILL_0_G); LG(CST_MILL_1,GROUP_MILL,LCT_MILL_1_G); LG(CST_MILL_2,GROUP_MILL,LCT_MILL_2_G); LG(CST_MILL_3,GROUP_MILL,LCT_MILL_3_G); LG(CST_MILL_4,GROUP_MILL,LCT_MILL_4_G); LG(CST_MILL_5,GROUP_MILL,LCT_MILL_5_G); LG(CST_MILL_6,GROUP_MILL,LCT_MILL_6_G); LG(CST_MONUMENT_0,GROUP_MONUMENT,LCT_MONUMENT_0_G); LG(CST_MONUMENT_1,GROUP_MONUMENT,LCT_MONUMENT_1_G); LG(CST_MONUMENT_2,GROUP_MONUMENT,LCT_MONUMENT_2_G); LG(CST_MONUMENT_3,GROUP_MONUMENT,LCT_MONUMENT_3_G); LG(CST_MONUMENT_4,GROUP_MONUMENT,LCT_MONUMENT_4_G); LG(CST_MONUMENT_5,GROUP_MONUMENT,LCT_MONUMENT_5_G); LG(CST_POTTERY_0,GROUP_POTTERY,LCT_POTTERY_0_G); LG(CST_POTTERY_1,GROUP_POTTERY,LCT_POTTERY_1_G); LG(CST_POTTERY_2,GROUP_POTTERY,LCT_POTTERY_2_G); LG(CST_POTTERY_3,GROUP_POTTERY,LCT_POTTERY_3_G); LG(CST_POTTERY_4,GROUP_POTTERY,LCT_POTTERY_4_G); LG(CST_POTTERY_5,GROUP_POTTERY,LCT_POTTERY_5_G); LG(CST_POTTERY_6,GROUP_POTTERY,LCT_POTTERY_6_G); LG(CST_POTTERY_7,GROUP_POTTERY,LCT_POTTERY_7_G); LG(CST_POTTERY_8,GROUP_POTTERY,LCT_POTTERY_8_G); LG(CST_POTTERY_9,GROUP_POTTERY,LCT_POTTERY_9_G); LG(CST_POTTERY_10,GROUP_POTTERY,LCT_POTTERY_10_G); LG(CST_RECYCLE,GROUP_RECYCLE,LCT_RECYCLE_G); LG(CST_SCHOOL,GROUP_SCHOOL,LCT_SCHOOL_G); LG(CST_SHANTY,GROUP_SHANTY,LCT_SHANTY_G); LG(CST_SUBSTATION_R,GROUP_SUBSTATION,LCT_SUBSTATION_R_G); LG(CST_SUBSTATION_G,GROUP_SUBSTATION,LCT_SUBSTATION_G_G); LG(CST_SUBSTATION_RG,GROUP_SUBSTATION,LCT_SUBSTATION_RG_G); LG(CST_WINDMILL_1_G,GROUP_WINDMILL,LCT_WINDMILL_1_G_G); LG(CST_WINDMILL_2_G,GROUP_WINDMILL,LCT_WINDMILL_2_G_G); LG(CST_WINDMILL_3_G,GROUP_WINDMILL,LCT_WINDMILL_3_G_G); LG(CST_WINDMILL_1_RG,GROUP_WINDMILL,LCT_WINDMILL_1_RG_G); LG(CST_WINDMILL_2_RG,GROUP_WINDMILL,LCT_WINDMILL_2_RG_G); LG(CST_WINDMILL_3_RG,GROUP_WINDMILL,LCT_WINDMILL_3_RG_G); LG(CST_WINDMILL_1_R,GROUP_WINDMILL,LCT_WINDMILL_1_R_G); LG(CST_WINDMILL_2_R,GROUP_WINDMILL,LCT_WINDMILL_2_R_G); LG(CST_WINDMILL_3_R,GROUP_WINDMILL,LCT_WINDMILL_3_R_G); LG(CST_WINDMILL_1_W,GROUP_WINDMILL,LCT_WINDMILL_1_W_G); LG(CST_WINDMILL_2_W,GROUP_WINDMILL,LCT_WINDMILL_2_W_G); LG(CST_WINDMILL_3_W,GROUP_WINDMILL,LCT_WINDMILL_3_W_G); LG(CST_INDUSTRY_L_C,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_C_G); LG(CST_INDUSTRY_L_Q1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q1_G); LG(CST_INDUSTRY_L_Q2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q2_G); LG(CST_INDUSTRY_L_Q3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q3_G); LG(CST_INDUSTRY_L_Q4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_Q4_G); LG(CST_INDUSTRY_L_L1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L1_G); LG(CST_INDUSTRY_L_L2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L2_G); LG(CST_INDUSTRY_L_L3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L3_G); LG(CST_INDUSTRY_L_L4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_L4_G); LG(CST_INDUSTRY_L_M1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M1_G); LG(CST_INDUSTRY_L_M2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M2_G); LG(CST_INDUSTRY_L_M3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M3_G); LG(CST_INDUSTRY_L_M4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_M4_G); LG(CST_INDUSTRY_L_H1,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H1_G); LG(CST_INDUSTRY_L_H2,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H2_G); LG(CST_INDUSTRY_L_H3,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H3_G); LG(CST_INDUSTRY_L_H4,GROUP_INDUSTRY_L,LCT_INDUSTRY_L_H4_G); LG(CST_RESIDENCE_LL,GROUP_RESIDENCE_LL,LCT_RESIDENCE_LL_G); LG(CST_RESIDENCE_ML,GROUP_RESIDENCE_ML,LCT_RESIDENCE_ML_G); LG(CST_RESIDENCE_HL,GROUP_RESIDENCE_HL,LCT_RESIDENCE_HL_G); LG(CST_RESIDENCE_LH,GROUP_RESIDENCE_LH,LCT_RESIDENCE_LH_G); LG(CST_RESIDENCE_MH,GROUP_RESIDENCE_MH,LCT_RESIDENCE_MH_G); LG(CST_RESIDENCE_HH,GROUP_RESIDENCE_HH,LCT_RESIDENCE_HH_G); LG(CST_UNIVERSITY,GROUP_UNIVERSITY,LCT_UNIVERSITY_G); LG(CST_COALMINE_EMPTY,GROUP_COALMINE,LCT_COALMINE_EMPTY_G); LG(CST_COALMINE_LOW,GROUP_COALMINE,LCT_COALMINE_LOW_G); LG(CST_COALMINE_MED,GROUP_COALMINE,LCT_COALMINE_MED_G); LG(CST_COALMINE_FULL,GROUP_COALMINE,LCT_COALMINE_FULL_G); LG(CST_COMMUNE_1,GROUP_COMMUNE,LCT_COMMUNE_1_G); LG(CST_COMMUNE_2,GROUP_COMMUNE,LCT_COMMUNE_2_G); LG(CST_COMMUNE_3,GROUP_COMMUNE,LCT_COMMUNE_3_G); LG(CST_COMMUNE_4,GROUP_COMMUNE,LCT_COMMUNE_4_G); LG(CST_COMMUNE_5,GROUP_COMMUNE,LCT_COMMUNE_5_G); LG(CST_COMMUNE_6,GROUP_COMMUNE,LCT_COMMUNE_6_G); LG(CST_COMMUNE_7,GROUP_COMMUNE,LCT_COMMUNE_7_G); LG(CST_COMMUNE_8,GROUP_COMMUNE,LCT_COMMUNE_8_G); LG(CST_COMMUNE_9,GROUP_COMMUNE,LCT_COMMUNE_9_G); LG(CST_COMMUNE_10,GROUP_COMMUNE,LCT_COMMUNE_10_G); LG(CST_COMMUNE_11,GROUP_COMMUNE,LCT_COMMUNE_11_G); LG(CST_COMMUNE_12,GROUP_COMMUNE,LCT_COMMUNE_12_G); LG(CST_COMMUNE_13,GROUP_COMMUNE,LCT_COMMUNE_13_G); LG(CST_COMMUNE_14,GROUP_COMMUNE,LCT_COMMUNE_14_G); LG(CST_EX_PORT,GROUP_PORT,LCT_EX_PORT_G); LG(CST_FARM_O0,GROUP_ORGANIC_FARM,LCT_FARM_O0_G); LG(CST_FARM_O1,GROUP_ORGANIC_FARM,LCT_FARM_O1_G); LG(CST_FARM_O2,GROUP_ORGANIC_FARM,LCT_FARM_O2_G); LG(CST_FARM_O3,GROUP_ORGANIC_FARM,LCT_FARM_O3_G); LG(CST_FARM_O4,GROUP_ORGANIC_FARM,LCT_FARM_O4_G); LG(CST_FARM_O5,GROUP_ORGANIC_FARM,LCT_FARM_O5_G); LG(CST_FARM_O6,GROUP_ORGANIC_FARM,LCT_FARM_O6_G); LG(CST_FARM_O7,GROUP_ORGANIC_FARM,LCT_FARM_O7_G); LG(CST_FARM_O8,GROUP_ORGANIC_FARM,LCT_FARM_O8_G); LG(CST_FARM_O9,GROUP_ORGANIC_FARM,LCT_FARM_O9_G); LG(CST_FARM_O10,GROUP_ORGANIC_FARM,LCT_FARM_O10_G); LG(CST_FARM_O11,GROUP_ORGANIC_FARM,LCT_FARM_O11_G); LG(CST_FARM_O12,GROUP_ORGANIC_FARM,LCT_FARM_O12_G); LG(CST_FARM_O13,GROUP_ORGANIC_FARM,LCT_FARM_O13_G); LG(CST_FARM_O14,GROUP_ORGANIC_FARM,LCT_FARM_O14_G); LG(CST_FARM_O15,GROUP_ORGANIC_FARM,LCT_FARM_O15_G); LG(CST_FARM_O16,GROUP_ORGANIC_FARM,LCT_FARM_O16_G); LG(CST_INDUSTRY_H_C,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_C_G); LG(CST_INDUSTRY_H_L1,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L1_G); LG(CST_INDUSTRY_H_L2,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L2_G); LG(CST_INDUSTRY_H_L3,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L3_G); LG(CST_INDUSTRY_H_L4,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L4_G); LG(CST_INDUSTRY_H_L5,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L5_G); LG(CST_INDUSTRY_H_L6,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L6_G); LG(CST_INDUSTRY_H_L7,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L7_G); LG(CST_INDUSTRY_H_L8,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_L8_G); LG(CST_INDUSTRY_H_M1,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M1_G); LG(CST_INDUSTRY_H_M2,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M2_G); LG(CST_INDUSTRY_H_M3,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M3_G); LG(CST_INDUSTRY_H_M4,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M4_G); LG(CST_INDUSTRY_H_M5,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M5_G); LG(CST_INDUSTRY_H_M6,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M6_G); LG(CST_INDUSTRY_H_M7,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M7_G); LG(CST_INDUSTRY_H_M8,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_M8_G); LG(CST_INDUSTRY_H_H1,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H1_G); LG(CST_INDUSTRY_H_H2,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H2_G); LG(CST_INDUSTRY_H_H3,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H3_G); LG(CST_INDUSTRY_H_H4,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H4_G); LG(CST_INDUSTRY_H_H5,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H5_G); LG(CST_INDUSTRY_H_H6,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H6_G); LG(CST_INDUSTRY_H_H7,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H7_G); LG(CST_INDUSTRY_H_H8,GROUP_INDUSTRY_H,LCT_INDUSTRY_H_H8_G); LG(CST_OREMINE_1,GROUP_OREMINE,LCT_OREMINE_1_G); LG(CST_OREMINE_2,GROUP_OREMINE,LCT_OREMINE_2_G); LG(CST_OREMINE_3,GROUP_OREMINE,LCT_OREMINE_3_G); LG(CST_OREMINE_4,GROUP_OREMINE,LCT_OREMINE_4_G); LG(CST_OREMINE_5,GROUP_OREMINE,LCT_OREMINE_5_G); LG(CST_OREMINE_6,GROUP_OREMINE,LCT_OREMINE_6_G); LG(CST_OREMINE_7,GROUP_OREMINE,LCT_OREMINE_7_G); LG(CST_OREMINE_8,GROUP_OREMINE,LCT_OREMINE_8_G); LG(CST_POWERS_COAL_EMPTY,GROUP_COAL_POWER,LCT_POWERS_COAL_EMPTY_G); LG(CST_POWERS_COAL_LOW,GROUP_COAL_POWER,LCT_POWERS_COAL_LOW_G); LG(CST_POWERS_COAL_MED,GROUP_COAL_POWER,LCT_POWERS_COAL_MED_G); LG(CST_POWERS_COAL_FULL,GROUP_COAL_POWER,LCT_POWERS_COAL_FULL_G); LG(CST_POWERS_SOLAR,GROUP_SOLAR_POWER,LCT_POWERS_SOLAR_G); LG(CST_ROCKET_1,GROUP_ROCKET,LCT_ROCKET_1_G); LG(CST_ROCKET_2,GROUP_ROCKET,LCT_ROCKET_2_G); LG(CST_ROCKET_3,GROUP_ROCKET,LCT_ROCKET_3_G); LG(CST_ROCKET_4,GROUP_ROCKET,LCT_ROCKET_4_G); LG(CST_ROCKET_5,GROUP_ROCKET,LCT_ROCKET_5_G); LG(CST_ROCKET_6,GROUP_ROCKET,LCT_ROCKET_6_G); LG(CST_ROCKET_7,GROUP_ROCKET,LCT_ROCKET_7_G); LG(CST_ROCKET_FLOWN,GROUP_ROCKET,LCT_ROCKET_FLOWN_G); LG(CST_TIP_0,GROUP_TIP,LCT_TIP_0_G); LG(CST_TIP_1,GROUP_TIP,LCT_TIP_1_G); LG(CST_TIP_2,GROUP_TIP,LCT_TIP_2_G); LG(CST_TIP_3,GROUP_TIP,LCT_TIP_3_G); LG(CST_TIP_4,GROUP_TIP,LCT_TIP_4_G); LG(CST_TIP_5,GROUP_TIP,LCT_TIP_5_G); LG(CST_TIP_6,GROUP_TIP,LCT_TIP_6_G); LG(CST_TIP_7,GROUP_TIP,LCT_TIP_7_G); LG(CST_TIP_8,GROUP_TIP,LCT_TIP_8_G); // main_t #undef LG #if defined (commentout) /* PROCESS IMAGE HERE */ while (!feof(txt_fp)) { char buf[128]; char *fnp,*rip,*cip; int ri,ci; /* Get line from text file */ fgets (buf,128,txt_fp); /* Tokenize */ fnp = strtok(buf," \t"); if (!fnp || *fnp == '#') continue; if (*fnp == '@') break; rip = strtok(NULL," \t"); if (!rip) continue; cip = strtok(NULL," \t"); if (!cip) continue; ri = atoi(rip); ci = atoi(cip); /* Copy icon */ if (!strcmp(fnp,LCT_GREEN_G)) { int r,c; char* p; main_types[CST_GREEN].graphic=malloc(16*16); p = main_types[CST_GREEN].graphic; for (r=ri*16;r<ri*16+16;r++) { for (c=ci*16;c<ci*16+16;c++) { *p++ = row_pointers[r][c]; } } } } #endif /* Free the memory */ for (row = 0; row < height; row++) { png_free(png_ptr, row_pointers[row]); } free(row_pointers); /* clean up after the read, and free any memory allocated - REQUIRED */ #if defined (commentout) png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); #endif png_destroy_read_struct(&png_ptr, &info_ptr, NULL); /* that's it */ return (OK); }
unsigned char *_loadImageRGBApng(char *fileName, int *width, int *height) { // open the file FILE *fp = fopen(fileName, "rb"); if (!fp) return _loadImgError(width, height); // read the header const int HEADER_LENGTH = 8; png_byte header[HEADER_LENGTH]; fread(header, 1, HEADER_LENGTH, fp); if (png_sig_cmp(header, 0, HEADER_LENGTH)) return _loadImgError(width, height); // try to create the loading structures png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (!png_ptr) { fclose(fp); return _loadImgError(width, height); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) 0, (png_infopp) 0); fclose(fp); return _loadImgError(width, height); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0); fclose(fp); return _loadImgError(width, height); } if (setjmp(png_ptr->jmpbuf)) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return _loadImgError(width, height); } // start the io png_init_io(png_ptr, fp); // indicate that we have already read some of the hearder png_set_sig_bytes(png_ptr, HEADER_LENGTH); // read the image info, get some info png_read_info(png_ptr, info_ptr); *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); int bit_depth = png_get_bit_depth(png_ptr, info_ptr); png_byte color_type = png_get_color_type(png_ptr, info_ptr); // force the image into RGBA, 8 bits per channel if (color_type != PNG_COLOR_TYPE_RGBA) png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth < 8) png_set_packing(png_ptr); else if (bit_depth == 16) png_set_strip_16(png_ptr); if (color_type != PNG_COLOR_TYPE_RGBA) png_set_filler(png_ptr, 255, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); // make sure we're actually in rgba mode if (png_get_rowbytes(png_ptr, info_ptr) != ((*width) * 4)) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return _loadImgError(width, height); } // finally, read the file unsigned char *buffer = (unsigned char *) malloc((*width) * (*height) * 4); png_bytep row_pointers[*height]; for (int y = 0 ; y < (*height) ; y++) row_pointers[y] = (png_byte *) (buffer + ((*height) - 1 - y) * (*width) * 4); png_read_rows(png_ptr, row_pointers, 0, (long unsigned int) (*height)); // deallocate memory and return fclose(fp); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); return buffer; }
Py::Object Image::write_png(const Py::Tuple& args) { //small memory leak in this function - JDH 2004-06-08 _VERBOSE("Image::write_png"); args.verify_length(1); std::string fileName = Py::String(args[0]); const char *file_name = fileName.c_str(); FILE *fp; png_structp png_ptr; png_infop info_ptr; struct png_color_8_struct sig_bit; png_uint_32 row; //todo: allocate on heap png_bytep row_pointers[rowsOut]; for (row = 0; row < rowsOut; ++row) { row_pointers[row] = bufferOut + row * colsOut * 4; } fp = fopen(file_name, "wb"); if (fp == NULL) throw Py::RuntimeError(Printf("Could not open file %s", file_name).str()); png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); throw Py::RuntimeError("Could not create write struct"); } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_write_struct(&png_ptr, &info_ptr); throw Py::RuntimeError("Could not create info struct"); } if (setjmp(png_ptr->jmpbuf)) { fclose(fp); png_destroy_write_struct(&png_ptr, &info_ptr); throw Py::RuntimeError("Error building image"); } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, colsOut, rowsOut, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); // this a a color image! sig_bit.gray = 0; sig_bit.red = 8; sig_bit.green = 8; sig_bit.blue = 8; /* if the image has an alpha channel then */ sig_bit.alpha = 8; png_set_sBIT(png_ptr, info_ptr, &sig_bit); png_write_info(png_ptr, info_ptr); png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return Py::Object(); }
int res_create_surface(const char* name, gr_surface* pSurface) { char resPath[256]; GGLSurface* surface = NULL; int result = 0; unsigned char header[8]; png_structp png_ptr = NULL; png_infop info_ptr = NULL; *pSurface = NULL; snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name); resPath[sizeof(resPath)-1] = '\0'; FILE* fp = fopen(resPath, "rb"); if (fp == NULL) { result = -1; goto exit; } size_t bytesRead = fread(header, 1, sizeof(header), fp); if (bytesRead != sizeof(header)) { result = -2; goto exit; } if (png_sig_cmp(header, 0, sizeof(header))) { result = -3; goto exit; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { result = -4; goto exit; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { result = -5; goto exit; } if (setjmp(png_jmpbuf(png_ptr))) { result = -6; goto exit; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, sizeof(header)); png_read_info(png_ptr, info_ptr); int color_type = info_ptr->color_type; int bit_depth = info_ptr->bit_depth; int channels = info_ptr->channels; if (!(bit_depth == 8 && ((channels == 3 && color_type == PNG_COLOR_TYPE_RGB) || (channels == 4 && color_type == PNG_COLOR_TYPE_RGBA) || (channels == 1 && (color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_GRAY))))) { return -7; goto exit; } size_t width = info_ptr->width; size_t height = info_ptr->height; size_t stride = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4) * width; size_t pixelSize = stride * height; surface = malloc(sizeof(GGLSurface) + pixelSize); if (surface == NULL) { result = -8; goto exit; } unsigned char* pData = (unsigned char*) (surface + 1); surface->version = sizeof(GGLSurface); surface->width = width; surface->height = height; surface->stride = width; /* Yes, pixels, not bytes */ surface->data = pData; surface->format = (channels == 3) ? GGL_PIXEL_FORMAT_RGBX_8888 : ((color_type == PNG_COLOR_TYPE_PALETTE ? GGL_PIXEL_FORMAT_RGBA_8888 : GGL_PIXEL_FORMAT_L_8)); int alpha = 0; if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); alpha = 1; } if (color_type == PNG_COLOR_TYPE_GRAY) { alpha = 1; } unsigned int y; if (channels == 3 || (channels == 1 && !alpha)) { for (y = 0; y < height; ++y) { unsigned char* pRow = pData + y * stride; png_read_row(png_ptr, pRow, NULL); int x; for(x = width - 1; x >= 0; x--) { int sx = x * 3; int dx = x * 4; unsigned char r = pRow[sx]; unsigned char g = pRow[sx + 1]; unsigned char b = pRow[sx + 2]; unsigned char a = 0xff; pRow[dx ] = r; // r pRow[dx + 1] = g; // g pRow[dx + 2] = b; // b pRow[dx + 3] = a; } } } else { for (y = 0; y < height; ++y) { unsigned char* pRow = pData + y * stride; png_read_row(png_ptr, pRow, NULL); } } *pSurface = (gr_surface) surface; exit: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (fp != NULL) { fclose(fp); } if (result < 0) { if (surface) { free(surface); } } return result; }
int res_create_localized_surface(const char* name, gr_surface* pSurface) { char resPath[256]; GGLSurface* surface = NULL; int result = 0; unsigned char header[8]; png_structp png_ptr = NULL; png_infop info_ptr = NULL; *pSurface = NULL; snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name); resPath[sizeof(resPath)-1] = '\0'; FILE* fp = fopen(resPath, "rb"); if (fp == NULL) { result = -1; goto exit; } size_t bytesRead = fread(header, 1, sizeof(header), fp); if (bytesRead != sizeof(header)) { result = -2; goto exit; } if (png_sig_cmp(header, 0, sizeof(header))) { result = -3; goto exit; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { result = -4; goto exit; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { result = -5; goto exit; } if (setjmp(png_jmpbuf(png_ptr))) { result = -6; goto exit; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, sizeof(header)); png_read_info(png_ptr, info_ptr); size_t width = info_ptr->width; size_t height = info_ptr->height; size_t stride = 4 * width; int color_type = info_ptr->color_type; int bit_depth = info_ptr->bit_depth; int channels = info_ptr->channels; if (!(bit_depth == 8 && (channels == 1 && color_type == PNG_COLOR_TYPE_GRAY))) { return -7; goto exit; } unsigned char* row = malloc(width); int y; for (y = 0; y < height; ++y) { png_read_row(png_ptr, row, NULL); int w = (row[1] << 8) | row[0]; int h = (row[3] << 8) | row[2]; int len = row[4]; char* loc = row+5; if (y+1+h >= height || matches_locale(loc)) { printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y); surface = malloc(sizeof(GGLSurface)); if (surface == NULL) { result = -8; goto exit; } unsigned char* pData = malloc(w*h); surface->version = sizeof(GGLSurface); surface->width = w; surface->height = h; surface->stride = w; /* Yes, pixels, not bytes */ surface->data = pData; surface->format = GGL_PIXEL_FORMAT_A_8; int i; for (i = 0; i < h; ++i, ++y) { png_read_row(png_ptr, row, NULL); memcpy(pData + i*w, row, w); } *pSurface = (gr_surface) surface; break; } else { int i; for (i = 0; i < h; ++i, ++y) { png_read_row(png_ptr, row, NULL); } } } exit: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (fp != NULL) { fclose(fp); } if (result < 0) { if (surface) { free(surface); } } return result; }
void pgeTextureScreenshot(const char* filename) { png_structp png_ptr; png_infop info_ptr; FILE* fp; unsigned char* line; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) return; info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return; } unsigned int col_type = PNG_COLOR_TYPE_RGBA; fp = fopen(filename, "wb"); if (!fp) return; png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, 480, 272, 8, col_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); line = (unsigned char*) pgeMalloc(480 * 4); if(line == 0) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fp); return; } unsigned char* src = (unsigned char*)pgeGfxGetFramebuffer(); unsigned char* src8 = (unsigned char*)src; unsigned short* src16 = (unsigned short*)src; unsigned int* src32 = (unsigned int*)src; int x, y, i; for(y = 0; y < 272; y++) { src8 = (unsigned char*)src; src16 = (unsigned short*)src; src32 = (unsigned int*)src; for (i = 0, x = 0; x < 480; x++) { unsigned int r = 0, g = 0, b = 0, a = 0; unsigned int col32; col32 = *src32++; RGBA8888(col32, r, g, b, a); line[i++] = r; line[i++] = g; line[i++] = b; line[i++] = 255; } png_write_row(png_ptr, line); src += ((512*32) >> 3); } pgeFree(line); png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fp); }
bool IGN_Create_PNG_JPR(LPCSTR mapname, long minx, long miny, long maxx, long maxy) { char tstring[256]; long bitmap_width = TILE_WIDTH*(maxx-minx)/1000; long bitmap_size = bitmap_width*TILE_WIDTH; unsigned char * bitmap_memory = (unsigned char *)malloc(bitmap_size); CIGNTileDatabase db; if (bitmap_memory == NULL) { printf("Couldn't allocate %d bytes of memory\n"); return false; } // Create PNG header and write out palette sprintf(tstring, "%s.png", mapname); FILE * fp_png = fopen(tstring, "wb"); if (fp_png == NULL) { printf("Couldn't open %s\n", tstring); return false; } // Create and initialize the png_struct with the desired error handler functions. png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp_png); return false; } /* Allocate/initialize the image information data. REQUIRED */ png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fp_png); return false; } /* Set error handling. REQUIRED */ if (setjmp(png_jmpbuf(png_ptr))) { /* If we get here, we had a problem reading the file */ png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp_png); return false; } /* set up the output control if you are using standard C streams */ png_init_io(png_ptr, fp_png); /* Set the image information here. Width and height are up to 2^31, * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED */ png_set_IHDR(png_ptr, info_ptr, TILE_WIDTH*(maxx-minx)/1000, TILE_WIDTH*((maxy-miny)/1000), 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* set the palette if there is one. REQUIRED for indexed-color images */ png_colorp png_palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * sizeof (png_color)); int i; BYTE * pal_ptr = (BYTE *)png_palette; BYTE * palette = ign_palette; for (i=0; i<256; i++) { *pal_ptr++ = palette[i*4 + 2]; *pal_ptr++ = palette[i*4 + 1]; *pal_ptr++ = palette[i*4 + 0]; } /* ... set palette colors ... */ png_set_PLTE(png_ptr, info_ptr, png_palette, PNG_MAX_PALETTE_LENGTH); /* You must not free palette here, because png_set_PLTE only makes a link to * the palette that you malloced. Wait until you are about to destroy *the png structure. */ /* Write the file header information. REQUIRED */ png_write_info(png_ptr, info_ptr); CProgressWindow wndProgress; wndProgress.Initialize(); wndProgress.ResetProgressBar("Tile:", (maxy-miny)/500*(maxx-minx)/500); for (int y=maxy-1000; y>=miny; y-=1000) { memset(bitmap_memory, 0x00, bitmap_size); for (int x=minx; x<maxx; x+=1000) { IGN_read_bmp(y, x, &db, bitmap_memory+(x-minx)/1000*TILE_WIDTH, bitmap_width); } // write row of PNG to file for (int x=0; x<TILE_WIDTH; x++) { png_write_row(png_ptr, bitmap_memory + x*bitmap_width); if (!wndProgress.ProgressBar()) return false; } } /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); png_free(png_ptr, png_palette); /* clean up after the write, and free any memory allocated */ png_destroy_write_struct(&png_ptr, &info_ptr); /* close the file */ fclose(fp_png); // IGN_dumpjprfile(mapname, minx, miny, maxx, maxy, (maxx-minx)/1000 * TILE_WIDTH, (maxy-miny)/1000*TILE_WIDTH, NULL); free(bitmap_memory); return true; }
bool8 S9xDoScreenshot (int width, int height) { Settings.TakeScreenshot = FALSE; #ifdef HAVE_LIBPNG FILE *fp; png_structp png_ptr; png_infop info_ptr; png_color_8 sig_bit; int imgwidth, imgheight; const char *fname; fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR); fp = fopen(fname, "wb"); if (!fp) { S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); remove(fname); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); fclose(fp); remove(fname); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); remove(fname); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } imgwidth = width; imgheight = height; if (Settings.StretchScreenshots == 1) { if (width > SNES_WIDTH && height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; } else if (Settings.StretchScreenshots == 2) { if (width <= SNES_WIDTH) imgwidth = width << 1; if (height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); sig_bit.red = 5; sig_bit.green = 5; sig_bit.blue = 5; png_set_sBIT(png_ptr, info_ptr, &sig_bit); png_set_shift(png_ptr, &sig_bit); png_write_info(png_ptr, info_ptr); png_set_packing(png_ptr); png_byte *row_pointer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; uint16 *screen = GFX.Screen; for (int y = 0; y < height; y++, screen += GFX.RealPPL) { png_byte *rowpix = row_pointer; for (int x = 0; x < width; x++) { uint32 r, g, b; DECOMPOSE_PIXEL(screen[x], r, g, b); *(rowpix++) = r; *(rowpix++) = g; *(rowpix++) = b; if (imgwidth != width) { *(rowpix++) = r; *(rowpix++) = g; *(rowpix++) = b; } } png_write_row(png_ptr, row_pointer); if (imgheight != height) png_write_row(png_ptr, row_pointer); } delete [] row_pointer; png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); fprintf(stderr, "%s saved.\n", fname); const char *base = S9xBasename(fname); sprintf(String, "Saved screenshot %s", base); S9xMessage(S9X_INFO, 0, String); return (TRUE); #else fprintf(stderr, "Screenshot support not available (libpng was not found at build time).\n"); return (FALSE); #endif }
/** The constructor loads the named PNG image from the given png filename. <P>The destructor free all memory and server resources that are used by the image. */ void LoadPNG(const char *png) // I - File to read { int i; // Looping var FILE *fp; // File pointer int channels; // Number of color channels png_structp pp; // PNG read pointer png_infop info; // PNG info pointers png_bytep *rows; // PNG row pointers // Open the PNG file... if ((fp = fopen(png, "rb")) == NULL) return; // Setup the PNG data structures... pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info = png_create_info_struct(pp); if (setjmp(pp->jmpbuf)) { int debug = 1; return; } // Initialize the PNG read "engine"... png_init_io(pp, fp); // Get the image dimensions and convert to grayscale or RGB... png_read_info(pp, info); if (info->color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(pp); if (info->color_type & PNG_COLOR_MASK_COLOR) channels = 3; else channels = 1; if ((info->color_type & PNG_COLOR_MASK_ALPHA) || info->num_trans) channels ++; int w = (int)(info->width); int h = (int)(info->height); int d = channels; pictureWidth = w; pictureHeight = h; if (info->bit_depth < 8) { png_set_packing(pp); png_set_expand(pp); } else if (info->bit_depth == 16) png_set_strip_16(pp); # if defined(HAVE_PNG_GET_VALID) && defined(HAVE_PNG_SET_TRNS_TO_ALPHA) // Handle transparency... if (png_get_valid(pp, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(pp); # endif // HAVE_PNG_GET_VALID && HAVE_PNG_SET_TRNS_TO_ALPHA unsigned char *array = (unsigned char *)pictureS; // Allocate pointers... rows = new png_bytep[h]; for (i = 0; i < h; i ++) rows[i] = (png_bytep)(array + i * w * d); // we flip it // Read the image, handling interlacing as needed... for (i = png_set_interlace_handling(pp); i > 0; i --) png_read_rows(pp, rows, NULL, h); #ifdef WIN32 // Some Windows graphics drivers don't honor transparency when RGB == white if (channels == 4) { // Convert RGB to 0 when alpha == 0... unsigned char *ptr = (unsigned char *)array; for (i = w * h; i > 0; i --, ptr += 4) if (!ptr[3]) ptr[0] = ptr[1] = ptr[2] = 0; } #endif // WIN32 if (channels == 3) { unsigned char *array2 = new unsigned char[pictureWidth * pictureHeight * 4]; for (int i = w * h - 1; i >= 0; --i) { array2[i*4+0] = array[i*3+0]; array2[i*4+1] = array[i*3+1]; array2[i*4+2] = array[i*3+2]; array2[i*4+3] = 255; } memcpy(array, array2, w * h * 4); delete[] array2; } // Free memory and return... delete[] rows; png_read_end(pp, info); png_destroy_read_struct(&pp, &info, NULL); fclose(fp); }
static int qrwrap_writePNG(const char *outfile, QRcode *qrcode) { static FILE *fp; png_structp png_ptr; png_infop info_ptr; unsigned char *row, *p, *q; int x, y, xx, yy, bit; int realwidth; const int margin = 0; const int size = 8; const int width = qrcode->width; realwidth = (width + margin * 2) * size; row = (unsigned char *)vj_malloc((realwidth + 7) / 8); if(row == NULL) { return 0; } fp = fopen(outfile, "wb"); if(fp == NULL) { veejay_msg(VEEJAY_MSG_ERROR, "Unable to write QR code to file:%s", outfile); return 0; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(png_ptr == NULL) { fclose(fp); return 0; } info_ptr = png_create_info_struct(png_ptr); if(info_ptr == NULL) { fclose(fp); return 0; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return 0; } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, realwidth, realwidth, 1, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); /* top margin */ veejay_memset(row, 0xff, (realwidth + 7) / 8); for(y=0; y<margin * size; y++) { png_write_row(png_ptr, row); } /* data */ p = qrcode->data; for(y=0; y<width; y++) { bit = 7; veejay_memset(row, 0xff, (realwidth + 7) / 8); q = row; q += margin * size / 8; bit = 7 - (margin * size % 8); for(x=0; x<width; x++) { for(xx=0; xx<size; xx++) { *q ^= (*p & 1) << bit; bit--; if(bit < 0) { q++; bit = 7; } } p++; } for(yy=0; yy<size; yy++) { png_write_row(png_ptr, row); } } /* bottom margin */ veejay_memset(row, 0xff, (realwidth + 7) / 8); for(y=0; y<margin * size; y++) { png_write_row(png_ptr, row); } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); free(row); return 0; }
int writepng(char* filename, png_store *pngdata) { int code = 0; FILE *fp; png_structp png_ptr; png_infop info_ptr; png_bytep row; int width = pngdata->width; int height = pngdata->height; // float *buffer = pngdata->image_data; // Open file for writing (binary mode) fp = fopen(filename, "wb"); if (fp == NULL) { fprintf(stderr, "Could not open file %s for writing\n", filename); code = 1; exit(1); } // Initialize write structure png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fprintf(stderr, "Could not allocate write struct\n"); code = 1; exit(1); } // Initialize info structure info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fprintf(stderr, "Could not allocate info struct\n"); code = 1; exit(1); } // Setup Exception handling if (setjmp(png_jmpbuf(png_ptr))) { fprintf(stderr, "Error during png creation\n"); code = 1; exit(1); } png_init_io(png_ptr, fp); // Write header (8 bit colour depth) png_set_IHDR(png_ptr, info_ptr, width, height, pngdata->bitdepth, pngdata->colortype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); png_write_image(png_ptr,pngdata->row_pointers); // End write png_write_end(png_ptr, NULL); /* finalise: if (fp != NULL) fclose(fp); if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL); if (row != NULL) free(row); */ return code; }
pointer PNG_READ_IMAGE(register context *ctx, int n, register pointer *argv) { char *file_name; pointer ret, image_ptr; ckarg(1); if (isstring(argv[0])) file_name = argv[0]->c.str.chars; else error(E_NOSTRING); FILE *fp = fopen(file_name, "rb"); if (!fp) { error(E_OPENFILE); return(NIL); } png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); info_ptr = png_create_info_struct(png_ptr); if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fp); error(E_EOF); return(NIL); } png_init_io(png_ptr, fp); png_read_info(png_ptr, info_ptr); int width = png_get_image_width(png_ptr, info_ptr); int height = png_get_image_height(png_ptr, info_ptr); int bit_depth = png_get_bit_depth(png_ptr, info_ptr); int channels = png_get_channels(png_ptr, info_ptr); int color_type = png_get_color_type(png_ptr, info_ptr); //fprintf(stderr, "bit_depth = %d, channels %d, color_type =%d (pal:%d,gray:%d,rgb:%d,rgba:%d)\n", bit_depth, channels, color_type, PNG_COLOR_TYPE_PALETTE,PNG_COLOR_TYPE_GRAY,PNG_COLOR_TYPE_RGB,PNG_COLOR_TYPE_RGB_ALPHA); switch (color_type) { case PNG_COLOR_TYPE_PALETTE: png_set_palette_to_rgb(png_ptr); break; case PNG_COLOR_TYPE_GRAY: #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED if ( bit_depth < 8) png_set_gray_to_rgb(png_ptr); #else if ( bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); #endif break; case PNG_COLOR_TYPE_RGB: //png_set_bgr(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); // 16bit -> 8bit break; case PNG_COLOR_TYPE_RGB_ALPHA: if (bit_depth == 16) png_set_strip_16(png_ptr); // 16bit -> 8bit png_set_invert_alpha(png_ptr); //png_set_bgr(png_ptr); //png_set_strip_alpha(png_ptr); // RGBA -> rgb , GA -> g png_color_16 my_background = {0xff, 0xff, 0xff, 0xff, 0xff}; png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); break; } png_read_update_info(png_ptr, info_ptr); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr);; bit_depth = png_get_bit_depth(png_ptr, info_ptr); channels = png_get_channels(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); png_bytep * row_pointers = (png_bytep *)malloc(height*sizeof(png_bytep)); int y, byte_per_scanline = png_get_rowbytes(png_ptr, info_ptr); image_ptr = makebuffer(height*byte_per_scanline); for(y=0;y<height;y++){ row_pointers[y] = image_ptr->c.str.chars+y*byte_per_scanline; } png_read_image(png_ptr, row_pointers); free(row_pointers); png_read_end(png_ptr,info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(fp); ret=cons(ctx,image_ptr,NIL); ret=cons(ctx,makeint(channels),ret); ret=cons(ctx,makeint(height),ret); ret=cons(ctx,makeint(width),ret); return (ret); }
int load_png_image(const char *filepath, struct pngload_attribute *png_attr) { FILE *fp; png_structp png_ptr; png_infop info_ptr; png_bytep* row_pointers; char buf[PNG_BYTES_TO_CHECK]; int w, h, x, y, temp, color_type; fp = fopen( filepath, "rb" ); if( fp == NULL ) { return -1; } png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); info_ptr = png_create_info_struct( png_ptr ); setjmp( png_jmpbuf(png_ptr) ); /* 读取PNG_BYTES_TO_CHECK个字节的数据 */ temp = fread( buf, 1, PNG_BYTES_TO_CHECK, fp ); /* 若读到的数据并没有PNG_BYTES_TO_CHECK个字节 */ if( temp < PNG_BYTES_TO_CHECK ) { fclose(fp); png_destroy_read_struct( &png_ptr, &info_ptr, 0); return -3; } /* 检测数据是否为PNG的签名 */ temp = png_sig_cmp( (png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK ); /* 如果不是PNG的签名,则说明该文件不是PNG文件 */ if( temp != 0 ) { fclose(fp); png_destroy_read_struct( &png_ptr, &info_ptr, 0); return -4; } /* 复位文件指针 */ rewind( fp ); /* 开始读文件 */ png_init_io( png_ptr, fp ); /* 读取PNG图片信息 */ png_read_png( png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0 ); /* 获取图像的色彩类型 */ color_type = png_get_color_type( png_ptr, info_ptr ); /* 获取图像的宽高 */ png_attr->width = w = png_get_image_width( png_ptr, info_ptr ); png_attr->height = h = png_get_image_height( png_ptr, info_ptr ); printf("w=%d,h=%d\n", w, h); /* 获取图像的所有行像素数据,row_pointers里边就是rgba数据 */ row_pointers = png_get_rows( png_ptr, info_ptr ); unsigned char *data; int index = 0; /* 根据不同的色彩类型进行相应处理 */ png_attr->color_type = color_type; switch( color_type ) { case PNG_COLOR_TYPE_RGB_ALPHA: printf("rgba\n"); data = malloc(w*h*4); png_attr->buf = data; for( y=0; y<h; ++y ) { for( x=0; x<w*4; ) { /* 以下是RGBA数据,需要自己补充代码,保存RGBA数据 */ data[index++] = row_pointers[y][x++]; // red data[index++] = row_pointers[y][x++]; // green data[index++] = row_pointers[y][x++]; // blue data[index++] = row_pointers[y][x++]; // alpha } } break; case PNG_COLOR_TYPE_RGB: printf("rgb\n"); data = malloc(w*h*3); png_attr->buf = data; for( y=0; y<h; ++y ) { for( x=0; x<w*3; ) { data[index++] = row_pointers[y][x++]; // red data[index++] = row_pointers[y][x++]; // green data[index++] = row_pointers[y][x++]; // blue } } break; /* 其它色彩类型的图像就不读了 */ default: fclose(fp); png_destroy_read_struct( &png_ptr, &info_ptr, 0); return -2; } png_destroy_read_struct( &png_ptr, &info_ptr, 0); return 0; }
static int save_png_to_file (bitmap_t *bitmap, const char *path) { FILE * fp; png_structp png_ptr = NULL; png_infop info_ptr = NULL; size_t x, y; png_byte ** row_pointers = NULL; /* "status" contains the return value of this function. At first it is set to a value which means 'failure'. When the routine has finished its work, it is set to a value which means 'success'. */ int status = -1; /* The following number is set by trial and error only. I cannot see where it it is documented in the libpng manual. */ int pixel_size = 3; int depth = 8; fp = fopen (path, "wb"); if (! fp) { goto fopen_failed; } png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { goto png_create_write_struct_failed; } info_ptr = png_create_info_struct (png_ptr); if (info_ptr == NULL) { goto png_create_info_struct_failed; } /* Set up error handling. */ if (setjmp (png_jmpbuf (png_ptr))) { goto png_failure; } /* Set image attributes. */ png_set_IHDR (png_ptr, info_ptr, bitmap->width, bitmap->height, depth, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* Initialize rows of PNG. */ row_pointers = png_malloc (png_ptr, bitmap->height * sizeof (png_byte *)); for (y = 0; y < bitmap->height; ++y) { png_byte *row = png_malloc (png_ptr, sizeof (uint8_t) * bitmap->width * pixel_size); row_pointers[y] = row; for (x = 0; x < bitmap->width; ++x) { pixel_t * pixel = pixel_at (bitmap, x, y); *row++ = pixel->red; *row++ = pixel->green; *row++ = pixel->blue; } } /* Write the image data to "fp". */ png_init_io (png_ptr, fp); png_set_rows (png_ptr, info_ptr, row_pointers); png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); /* The routine has successfully written the file, so we set "status" to a value which indicates success. */ status = 0; for (y = 0; y < bitmap->height; y++) { png_free (png_ptr, row_pointers[y]); } png_free (png_ptr, row_pointers); png_failure: png_create_info_struct_failed: png_destroy_write_struct (&png_ptr, &info_ptr); png_create_write_struct_failed: fclose (fp); fopen_failed: return status; }
int GImageWrite_Png(GImage *gi, FILE *fp, int progressive) { struct _GImage *base = gi->list_len==0?gi->u.image:gi->u.images[0]; png_structp png_ptr; png_infop info_ptr; png_byte **rows; int i; int bit_depth; int color_type; int num_palette; png_bytep trans_alpha = NULL; png_color_16p trans_color = NULL; png_colorp palette = NULL; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (void *)NULL, user_error_fn, user_warning_fn); if (!png_ptr) { return(false); } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return(false); } #if (PNG_LIBPNG_VER < 10500) if (setjmp(png_ptr->jmpbuf)) #else if (setjmp(*png_set_longjmp_fn(png_ptr, longjmp, sizeof (jmp_buf)))) #endif { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return(false); } png_init_io(png_ptr, fp); bit_depth = 8; num_palette = base->clut==NULL?2:base->clut->clut_len; if ( base->image_type==it_index || base->image_type==it_bitmap ) { color_type = PNG_COLOR_TYPE_PALETTE; if ( num_palette<=2 ) bit_depth=1; else if ( num_palette<=4 ) bit_depth=2; else if ( num_palette<=16 ) bit_depth=4; } else { color_type = PNG_COLOR_TYPE_RGB; if ( base->image_type == it_rgba ) color_type = PNG_COLOR_TYPE_RGB_ALPHA; } png_set_IHDR(png_ptr, info_ptr, base->width, base->height, bit_depth, color_type, progressive, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if ( base->image_type==it_index || base->image_type==it_bitmap ) { palette = (png_color *) galloc(num_palette*sizeof(png_color)); if ( base->clut==NULL ) { palette[0].red = palette[0].green = palette[0].blue = 0; palette[1].red = palette[1].green = palette[1].blue = 0xff; } else { for ( i=0; i<num_palette; ++i ) { long col = base->clut->clut[i]; palette[i].red = COLOR_RED(col); palette[i].green = COLOR_GREEN(col); palette[i].blue = COLOR_BLUE(col); } } png_set_PLTE(png_ptr, info_ptr, palette, num_palette); if ( num_palette<=16 ) png_set_packing(png_ptr); if ( base->trans!=-1 ) { trans_alpha = galloc(1); trans_alpha[0] = base->trans; } } else { if ( base->trans!=-1 ) { trans_color = galloc(sizeof(png_color_16)); trans_color->red = COLOR_RED(base->trans); trans_color->green = COLOR_GREEN(base->trans); trans_color->blue = COLOR_BLUE(base->trans); } } if ( base->trans!=-1 ) { png_set_tRNS(png_ptr, info_ptr, trans_alpha, 1, trans_color); } png_write_info(png_ptr, info_ptr); if (color_type == PNG_COLOR_TYPE_RGB) png_set_filler(png_ptr, '\0', PNG_FILLER_BEFORE); rows = galloc(base->height*sizeof(png_byte *)); for ( i=0; i<base->height; ++i ) rows[i] = (png_byte *) (base->data + i*base->bytes_per_line); png_write_image(png_ptr,rows); png_write_end(png_ptr, info_ptr); if ( trans_alpha!=NULL ) gfree(trans_alpha); if ( trans_color!=NULL ) gfree(trans_color); if ( palette!=NULL ) gfree(palette); png_destroy_write_struct(&png_ptr, &info_ptr); gfree(rows); return( 1 ); }
int read_png(FILE *file, int filetype, F_pic *pic) { register int i, j; png_structp png_ptr; png_infop info_ptr; png_infop end_info; png_uint_32 w, h, rowsize; int bit_depth, color_type, interlace_type; int compression_type, filter_type; png_bytep *row_pointers; char *ptr; int num_palette; png_colorp palette; png_color_16 background; /* make scale factor smaller for metric */ float scale = (appres.INCHES ? (float)PIX_PER_INCH : 2.54*PIX_PER_CM)/(float)DISPLAY_PIX_PER_INCH; /* read the png file here */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, NULL, NULL); if (!png_ptr) { close_picfile(file,filetype); return FileInvalid; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); close_picfile(file,filetype); return FileInvalid; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); close_picfile(file,filetype); return FileInvalid; } /* set long jump recovery here */ if (setjmp(png_ptr->jmpbuf)) { /* if we get here there was a problem reading the file */ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); close_picfile(file,filetype); return FileInvalid; } /* set up the input code */ png_init_io(png_ptr, file); /* now read the file info */ png_read_info(png_ptr, info_ptr); /* get width, height etc */ png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); if (info_ptr->valid & PNG_INFO_gAMA) png_set_gamma(png_ptr, 2.2, info_ptr->gamma); else png_set_gamma(png_ptr, 2.2, 0.45); if (info_ptr->valid & PNG_INFO_bKGD) /* set the background to the one supplied */ png_set_background(png_ptr, &info_ptr->background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); else { /* blend the canvas background using the alpha channel */ background.red = x_bg_color.red >> 8; background.green = x_bg_color.green >> 8; background.blue = x_bg_color.blue >> 8; background.gray = 0; png_set_background(png_ptr, &background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 2.2); } /* set order to BGR (default is RGB) */ if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_bgr(png_ptr); /* strip 16-bit RGB values down to 8-bit */ if (bit_depth == 16) png_set_strip_16(png_ptr); /* force to 8-bits per pixel if less than 8 */ if (bit_depth < 8) png_set_packing(png_ptr); /* dither rgb files down to 8 bit palette */ num_palette = 0; pic->pic_cache->transp = TRANSP_NONE; if (color_type & PNG_COLOR_MASK_COLOR) { png_uint_16p histogram; #ifdef USE_ALPHA /* we need to somehow give libpng a background color that it can combine with the alpha information in each pixel to make the image */ if (color_type & PNG_COLOR_MASK_ALPHA) pic->pic_cache->transp = TRANSP_BACKGROUND; #endif /* USE_ALPHA */ if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { png_get_hIST(png_ptr, info_ptr, &histogram); png_set_dither(png_ptr, palette, num_palette, 256, histogram, 0); } } if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* expand to full range */ png_set_expand(png_ptr); /* make a gray colormap */ num_palette = 256; for (i = 0; i < num_palette; i++) pic->pic_cache->cmap[i].red = pic->pic_cache->cmap[i].green = pic->pic_cache->cmap[i].blue = i; } else { /* transfer the palette to the object's colormap */ for (i=0; i<num_palette; i++) { pic->pic_cache->cmap[i].red = palette[i].red; pic->pic_cache->cmap[i].green = palette[i].green; pic->pic_cache->cmap[i].blue = palette[i].blue; } } rowsize = w; if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) rowsize = w*3; /* allocate the row pointers and rows */ row_pointers = (png_bytep *) malloc(h*sizeof(png_bytep)); for (i=0; i<h; i++) { if ((row_pointers[i] = malloc(rowsize)) == NULL) { for (j=0; j<i; j++) free(row_pointers[j]); close_picfile(file,filetype); return FileInvalid; } } /* finally, read the file */ png_read_image(png_ptr, row_pointers); /* allocate the bitmap */ if ((pic->pic_cache->bitmap=malloc(rowsize*h))==NULL) { close_picfile(file,filetype); return FileInvalid; } /* copy it to our bitmap */ ptr = pic->pic_cache->bitmap; for (i=0; i<h; i++) { bcopy(row_pointers[i], ptr, rowsize); ptr += rowsize; } /* put in width, height */ pic->pic_cache->bit_size.x = w; pic->pic_cache->bit_size.y = h; if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { /* no palette, must use neural net to reduce to 256 colors with palette */ if (!map_to_palette(pic)) { close_picfile(file,filetype); return FileInvalid; /* out of memory or something */ } pic->pic_cache->numcols = 256; } else { pic->pic_cache->numcols = num_palette; } /* clean up */ png_read_end(png_ptr, end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); for (i=0; i<h; i++) free(row_pointers[i]); pic->pic_cache->subtype = T_PIC_PNG; pic->pixmap = None; pic->hw_ratio = (float) pic->pic_cache->bit_size.y / pic->pic_cache->bit_size.x; pic->pic_cache->size_x = pic->pic_cache->bit_size.x * scale; pic->pic_cache->size_y = pic->pic_cache->bit_size.y * scale; /* if monochrome display map bitmap */ if (tool_cells <= 2 || appres.monochrome) map_to_mono(pic); close_picfile(file,filetype); return PicSuccess; }
void write_png_file(const char* file_name, int32 width, int32 height, uint8 * data) { if (CommandLineParser::Instance()->GetVerbose()) printf("* Writing PNG file (%d x %d): %s\n", width, height, file_name); png_byte color_type = PNG_COLOR_TYPE_RGBA; png_byte bit_depth = 8; png_color_8 sig_bit; png_structp png_ptr; png_infop info_ptr; png_bytep * row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); for (int y = 0; y < height; y++) { row_pointers[y] = (png_byte*) &data[y * width * 4]; } /* create file */ FILE *fp = fopen(file_name, "wb"); if (!fp) abort_("[write_png_file] File %s could not be opened for writing", file_name); /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[write_png_file] png_create_write_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[write_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during init_io"); png_init_io(png_ptr, fp); /* write header */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); sig_bit.red = 8; sig_bit.green = 8; sig_bit.blue = 8; sig_bit.alpha = 8; png_set_sBIT(png_ptr, info_ptr, &sig_bit); png_write_info(png_ptr, info_ptr); png_set_shift(png_ptr, &sig_bit); png_set_packing(png_ptr); /* write bytes */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing bytes"); png_write_image(png_ptr, row_pointers); /* end write */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); free(row_pointers); fclose(fp); }
int R2Image:: ReadPNG(const char *filename) { // Open file FILE *fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Unable to open PNG file %s\n", filename); return 0; } // Create and initialize the png_struct png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return 0; } // Allocate/initialize the memory for image information. png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, NULL, NULL); return 0; } // Set up the input control if you are using standard C streams png_init_io(png_ptr, fp); // Read the png info png_read_info(png_ptr, info_ptr); // Extract image info png_byte color_type = png_get_color_type(png_ptr, info_ptr); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); // Set nchannels nchannels = 0; if (color_type == PNG_COLOR_TYPE_GRAY) nchannels = 1; else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) nchannels = 2; else if (color_type == PNG_COLOR_TYPE_RGB) nchannels = 3; else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) nchannels = 4; else { fclose(fp); png_destroy_read_struct(&png_ptr, NULL, NULL); return 0; } // Allocate the pixels and row pointers int rowsize = png_get_rowbytes(png_ptr, info_ptr); assert(rowsize >= width * nchannels); png_bytep buffer = new unsigned char [ height * rowsize * png_sizeof(png_bytep) ]; png_bytep *row_pointers = (png_bytep *) png_malloc(png_ptr, height * png_sizeof(png_bytep)); for (int i = 0; i < height; i++) row_pointers[i] = &buffer[ (height - i - 1) * rowsize ]; // Read the pixels png_read_image(png_ptr, row_pointers); // Finish reading png_read_end(png_ptr, info_ptr); // Copy pixels from temporary buffer pixels = new double [ height * width * nchannels ]; for (int j = 0; j < height; j++) { for (int i = 0; i < width * nchannels; i++) { pixels[j*width*nchannels + i] = buffer[j*width*nchannels + i] / 255.0; } } // Free the row pointers png_free(png_ptr, row_pointers); // Clean up after the read, and free any memory allocated png_destroy_read_struct(&png_ptr, &info_ptr, NULL); // Close the file fclose(fp); // Delete temporary buffer delete [] buffer; // Return success return 1; }
int pixbuf2png(GdkPixbuf *pb, const char *output_png) { int i; int width = gdk_pixbuf_get_width(pb); int height = gdk_pixbuf_get_height(pb); int n_channels = gdk_pixbuf_get_n_channels(pb); int rowstride = gdk_pixbuf_get_rowstride(pb); guchar *pixels = gdk_pixbuf_get_pixels(pb); guchar *pixels_out = MALLOC(sizeof(guchar)*width*height*4); //printf("pixbuf2png> opening: %s\n", output_png); FILE *fout = FOPEN(output_png, "wb"); png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { asfPrintWarning("Couldn't open png file: %s\n", output_png); return FALSE; } //printf("pixbuf2png> png_create_info_struct\n"); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fclose(fout); asfPrintWarning("Couldn't open png info for %s\n", output_png); return FALSE; } //printf("pixbuf2png> setjmp\n"); if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fout); asfPrintWarning("Error writing the png: %s\n", output_png); return FALSE; } //printf("pixbuf2png> png_init_io\n"); png_init_io(png_ptr, fout); //printf("pixbuf2png> png_set_IHDR\n"); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); //printf("pixbuf2png> png_write_info\n"); png_write_info(png_ptr, info_ptr); // add a transparency byte to each pixel in the pixels_out buffer for (i=0; i<height; ++i) { int j; for (j=0; j<width; ++j) { // output: red=k, green=k+1, blue=k+2, alpha=k+3 int out_k = 4*(j + i*width); // input: red=k, green=k+1, blue=k+2 int in_k = j*n_channels + i*rowstride; // make it transparent, if the pixel is black // (i.e., all channels are 0) int trans = pixels[in_k] == 0 && pixels[in_k+1] == 0 && pixels[in_k+2] == 0; pixels_out[out_k] = pixels[in_k]; pixels_out[out_k+1] = pixels[in_k+1]; pixels_out[out_k+2] = pixels[in_k+2]; pixels_out[out_k+3] = trans ? 0 : 255; } } //printf("pixbuf2png> row_pointers\n"); png_bytep *row_pointers = MALLOC(sizeof(png_bytep)*height); for (i=0; i<height; ++i) row_pointers[i] = pixels_out + i*width*4; //printf("pixbuf2png> png_write_image\n"); png_write_image(png_ptr, row_pointers); //printf("pixbuf2png> png_write_end\n"); png_write_end(png_ptr, NULL); //printf("pixbuf2png> png_destroy_write_struct\n"); png_destroy_write_struct(&png_ptr, &info_ptr); //printf("pixbuf2png> fclose\n"); fclose(fout); //printf("pixbuf2png> freeing row pointers\n"); FREE(row_pointers); FREE(pixels_out); return TRUE; }
int R2Image:: WritePNG(const char *filename) const { // Open the file FILE *fp = fopen(filename, "wb"); if (fp == NULL) { fprintf(stderr, "Unable to open PNG file %s\n", filename); return 0; } // Create and initialize the png_struct png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return 0; } // Allocate/initialize the image information data. png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, NULL); fclose(fp); return 0; } // Determine color type png_byte color_type = 0; if (nchannels == 1) color_type = PNG_COLOR_TYPE_GRAY; else if (nchannels == 2) color_type = PNG_COLOR_TYPE_GRAY_ALPHA; else if (nchannels == 3) color_type = PNG_COLOR_TYPE_RGB; else if (nchannels == 4) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else { fprintf(stderr, "Invalid number of channels for %s\n", filename); return 0; } // Fill in the image data png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); // Set up the output control png_init_io(png_ptr, fp); // Write the png info png_write_info(png_ptr, info_ptr); // Copy pixels into temporary buffer int rowsize = width * nchannels; if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4; png_bytep buffer = (png_bytep) png_malloc(png_ptr, height * rowsize * png_sizeof(png_byte)); png_bytep *row_pointers = (png_bytep *) png_malloc(png_ptr, height * png_sizeof(png_bytep)); for (int j = 0; j < height; j++) { row_pointers[j] = &buffer[ (height - j - 1) * rowsize ]; for (int i = 0; i < width * nchannels; i++) { buffer[j*width*nchannels + i] = (png_byte) (255.0 * pixels[j*width*nchannels + i]); } } // Write the pixels png_write_image(png_ptr, row_pointers); // Finish writing png_write_end(png_ptr, info_ptr); // Free the temporary data png_free(png_ptr, row_pointers); png_free(png_ptr, buffer); // Clean up after the write, and free any memory allocated png_destroy_write_struct(&png_ptr, &info_ptr); // Close the file fclose(fp); // Return success return 1; }
short load_inp_png_file(ImageData& img, const std::string& fname_inp, ProgramOptions& opts) { FILE* pngfile = fopen(fname_inp.c_str(),"rb"); if (pngfile == NULL) { perror(fname_inp.c_str()); return ERR_CANT_OPEN; } png_byte header[8]; if (fread(header,8,1,pngfile) != 1) { perror(fname_inp.c_str()); fclose(pngfile); return ERR_FILE_READ; } if (png_sig_cmp(header,0,8)) { LogErr("%s: Not a PNG file",fname_inp.c_str()); fclose(pngfile); return ERR_BAD_FILE; } img.png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!img.png_ptr) { LogErr("%s: png_create_read_struct error",fname_inp.c_str()); fclose(pngfile); return ERR_BAD_FILE; } img.info_ptr=png_create_info_struct(img.png_ptr); if (!img.info_ptr) { png_destroy_read_struct(&img.png_ptr, (png_infopp)NULL, (png_infopp)NULL); LogErr("%s: png_create_info_struct error",fname_inp.c_str()); fclose(pngfile); return ERR_BAD_FILE; } img.end_info=png_create_info_struct(img.png_ptr); if (!img.end_info) { png_destroy_read_struct(&img.png_ptr, &img.info_ptr, (png_infopp)NULL); LogErr("%s: png_create_info_struct error",fname_inp.c_str()); fclose(pngfile); return ERR_BAD_FILE; } if (setjmp(png_jmpbuf(img.png_ptr))) { png_destroy_read_struct(&img.png_ptr, &img.info_ptr, &img.end_info); LogErr("%s: PNG error",fname_inp.c_str()); fclose(pngfile); exit(1); } png_init_io(img.png_ptr, pngfile); png_set_sig_bytes(img.png_ptr,8); int trafo=PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_EXPAND; png_read_png(img.png_ptr, img.info_ptr, trafo , NULL); int bit_depth, interlace_type, compression_type, filter_method; png_get_IHDR(img.png_ptr, img.info_ptr, &img.width, &img.height, &bit_depth, &img.color_type, &interlace_type, &compression_type, &filter_method); if ((img.color_type & PNG_COLOR_MASK_COLOR)==0) { LogErr("%s: Grayscale image not supported",fname_inp.c_str()); fclose(pngfile); return ERR_BAD_FILE; } fclose(pngfile); if (img.color_type==PNG_COLOR_TYPE_PALETTE) { LogErr("Invalid format. This shouldn't happen. PNG_TRANSFORM_EXPAND transforms image to RGB."); return ERR_BAD_FILE; } if (img.color_type & PNG_COLOR_MASK_ALPHA) { img.col_bits = 32; } else { img.col_bits = 24; } return ERR_OK; }
static void gst_snapshot_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstSnapshot *snapshot; guchar *data; gulong size; gint i; png_byte *row_pointers[MAX_HEIGHT]; FILE *fp; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); snapshot = GST_SNAPSHOT (GST_OBJECT_PARENT (pad)); data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); GST_DEBUG ("snapshot: have buffer of %d\n", GST_BUFFER_SIZE (buf)); snapshot->cur_frame++; if (snapshot->cur_frame == snapshot->frame || snapshot->snapshot_asked == TRUE) { snapshot->snapshot_asked = FALSE; GST_INFO ("dumpfile : %s\n", snapshot->location); fp = fopen (snapshot->location, "wb"); if (fp == NULL) g_warning (" Can not open %s\n", snapshot->location); else { snapshot->png_struct_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, user_error_fn, user_warning_fn); if (snapshot->png_struct_ptr == NULL) g_warning ("Failed to initialize png structure"); snapshot->png_info_ptr = png_create_info_struct (snapshot->png_struct_ptr); if (setjmp (snapshot->png_struct_ptr->jmpbuf)) png_destroy_write_struct (&snapshot->png_struct_ptr, &snapshot->png_info_ptr); png_set_filter (snapshot->png_struct_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE); png_init_io (snapshot->png_struct_ptr, fp); png_set_compression_level (snapshot->png_struct_ptr, 9); png_set_IHDR (snapshot->png_struct_ptr, snapshot->png_info_ptr, snapshot->width, snapshot->height, snapshot->to_bpp / 3, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); for (i = 0; i < snapshot->height; i++) row_pointers[i] = data + (snapshot->width * i * snapshot->to_bpp / 8); png_write_info (snapshot->png_struct_ptr, snapshot->png_info_ptr); png_write_image (snapshot->png_struct_ptr, row_pointers); png_write_end (snapshot->png_struct_ptr, NULL); png_destroy_info_struct (snapshot->png_struct_ptr, &snapshot->png_info_ptr); png_destroy_write_struct (&snapshot->png_struct_ptr, (png_infopp) NULL); fclose (fp); } } gst_pad_push (snapshot->srcpad, GST_DATA (buf)); }