bool YImage::save( const char* fname, bool fast ) const { FILE* fp = NULL ; bool rval = true ; png_structp png_ptr = NULL ; png_infop info_ptr = NULL ; // Open the file for reading in binary mode. fp = fopen( fname, "wb" ) ; if( !fp ) { fprintf( stderr, ERROR_STRING_OPEN, fname ) ; rval = false ; goto YImage_save_cleanup ; } // Allocate the png structs. png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) ; if( !png_ptr ) { fprintf( stderr, ERROR_STRING_WRITING, fname ) ; rval = false ; goto YImage_save_cleanup ; } info_ptr = png_create_info_struct( png_ptr ) ; if( !info_ptr ) { fprintf( stderr, ERROR_STRING_WRITING, fname ) ; rval = false ; goto YImage_save_cleanup ; } // Set up the png error routine. if( setjmp(png_jmpbuf(png_ptr)) ) { fprintf( stderr, ERROR_STRING_WRITING, fname ) ; rval = false ; goto YImage_save_cleanup ; } // Give libpng the FILE*. // png_init_io( png_ptr, fp ) ; // or // use our own write callback png_set_write_fn( png_ptr, fp, (png_rw_ptr) user_write_data, user_flush_data ) ; // We'll use the low-level interface since the high-level interface won't handle // png_set_filler() which we need to tell libpng to strip out the A from our // 4-byte pixels. // First we set and write the info struct. png_set_IHDR( png_ptr, info_ptr, m_width, m_height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ) ; png_write_info( png_ptr, info_ptr ) ; // If we've been asked to write quickly, speed up the compression. if( fast ) png_set_compression_level( png_ptr, Z_BEST_SPEED ); // Then we set up transforms. /* // 1. tell libpng to strip out the filler byte in our 4-byte pixels // if YPixel::a comes after any other member (b,g,r), we strip AFTER if( offsetof( YPixel, a ) > offsetof( YPixel, b ) ) { png_set_filler( png_ptr, 0, PNG_FILLER_AFTER ) ; // printf("alpha after\n"); } else { png_set_filler( png_ptr, 0, PNG_FILLER_BEFORE ) ; // printf("alpha before\n"); } */ if( offsetof( YPixel, a ) < offsetof( YPixel, b ) ) png_set_swap_alpha( png_ptr ) ; // 2. tell libpng how our color triples are stored (b < r or vice versa) if( offsetof( YPixel, b ) < offsetof( YPixel, r ) ) { png_set_bgr( png_ptr ) ; // printf("bgr\n") ; } // else { printf("rgb\n"); } // printf( "offsetof r, b: %d %d\n", offsetof( YPixel, r ), offsetof( YPixel, b ) ); // Finally we create a row_pointers[] pointing into our data* and write the png out to the FILE*. { // 1. allocate row pointers array png_bytep* row_pointers = (png_bytep*) png_malloc( png_ptr, m_height * sizeof(png_bytep) ) ; // 2. point row pointers into m_data for( int i = 0 ; i < m_height ; ++i ) { row_pointers[i] = (png_bytep) (m_data + i*m_width) ; } // 3. write the image data png_write_image( png_ptr, row_pointers ) ; // 4. free row pointers array png_free( png_ptr, row_pointers ) ; } // Write out end info. We're done. Fall through to cleanup. png_write_end( png_ptr, NULL ) ; YImage_save_cleanup: png_destroy_write_struct( png_ptr ? &png_ptr : NULL, info_ptr ? &info_ptr : NULL ) ; if( fp ) fclose( fp ) ; return rval ; }
int main(int argc, char *argv[]) { char infile[255]; char outfile[255] = ""; char fmt_s[255]; char window_s[255] = "blackman"; // Default args. format_t fmt = FORMAT_FLOAT32; int verbose = 0; uint64_t skip = 0; waterfall_params_t params; params.overlap = 0; params.fftsize = 2048; params.clip = 0; int c; struct option long_options[] = {/*These options set a flag.*/ {"verbose", no_argument, &verbose, 1}, {"brief", no_argument, &verbose, 0}, /*These options don’t set a flag.*/ /*We distinguish them by their indices.*/ {"help", no_argument, NULL, 'h'}, {"fftsize", required_argument, NULL, 'n'}, {"format", required_argument, NULL, 'f'}, {"window", required_argument, NULL, 'w'}, {"outfile", required_argument, NULL, 'o'}, {"offset", required_argument, NULL, 's'}, {"overlap", required_argument, NULL, 'l'}, {"clip", required_argument, NULL, 'c'}, {"beta", required_argument, NULL, 'b'}, {0, 0, 0, 0} }; int option_index; while ((c = getopt_long(argc, argv, "hvf:n:o:s:w:l:c:", long_options, &option_index)) != -1) { switch (c) { case 0: // Flag option break; case 'h': usage(argv[0]); return EXIT_SUCCESS; case 'v': verbose = true; break; case 'n': if (!parse_uint32_t(optarg, &(params.fftsize))) { fprintf(stderr, "Invalid fftsize: %s\n", optarg); return EXIT_FAILURE; } if (!is_power_of_2(params.fftsize)) { fprintf(stderr, "Invalid fftsize (must be power of 2): %s\n", optarg); return EXIT_FAILURE; } break; case 'l': if (!parse_uint32_t(optarg, &(params.overlap))) { fprintf(stderr, "Invalid overlap: %s\n", optarg); return EXIT_FAILURE; } break; case 'f': strcpy(fmt_s, optarg); if (parse_format(&fmt, fmt_s) < 0) { fprintf(stderr, "Unknown format: %s\n", optarg); return EXIT_FAILURE; } break; case 'w': strcpy(window_s, optarg); break; case 'o': strcpy(outfile, optarg); break; case 's': if (!parse_uint64_t(optarg, &skip)) { fprintf(stderr, "Invalid value for byte offset\n"); return EXIT_FAILURE; } break; case 'b': if (!parse_double(optarg, &beta)) { fprintf(stderr, "Invalid value for beta\n"); return EXIT_FAILURE; } break; case 'c': if (!parse_uint64_t(optarg, &(params.clip))) { fprintf(stderr, "Invalid value for clip\n"); return EXIT_FAILURE; } break; case '?': if (optopt == 'c') fprintf(stderr, "Option -%c requires an argument.\n", optopt); else if (isprint(optopt)) fprintf(stderr, "Unknown option `-%c'.\n", optopt); else fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); usage(argv[0]); return EXIT_FAILURE; default: fprintf(stderr, "Error parsing arguments.\n"); return EXIT_FAILURE; } } if ((argc - optind) > 1) { fprintf(stderr, "Excess arguments.\n"); usage(argv[0]); return EXIT_FAILURE; } else if ((argc - optind) < 1) { fprintf(stderr, "Must supply an input filename.\n"); usage(argv[0]); return EXIT_FAILURE; } window_t win; if (prepare_window(&win, window_s, params.fftsize, verbose) < 0) { fprintf(stderr, "Unknown window function: %s", window_s); return EXIT_FAILURE; } params.win = win; if (verbose) printf("Opening input file...\n"); strcpy(infile, argv[optind]); FILE *readfp = fopen(infile, "rb"); if (readfp == NULL) { fprintf(stderr, "Failed to open input file: %s\n", infile); return EXIT_FAILURE; } fseek(readfp, 0, SEEK_END); int size = ftell(readfp); fseek(readfp, skip, SEEK_SET); size_t sample_size; read_samples_fn reader; switch (fmt) { case FORMAT_INT8: sample_size = sizeof(int8_t) * 2; reader = read_samples_int8; break; case FORMAT_UINT8: sample_size = sizeof(uint8_t) * 2; reader = read_samples_uint8; break; case FORMAT_INT16: sample_size = sizeof(int16_t) * 2; reader = read_samples_int16; break; case FORMAT_UINT16: sample_size = sizeof(uint16_t) * 2; reader = read_samples_uint16; break; case FORMAT_INT32: sample_size = sizeof(int32_t) * 2; reader = read_samples_int32; break; case FORMAT_UINT32: sample_size = sizeof(uint32_t) * 2; reader = read_samples_uint32; break; case FORMAT_FLOAT32: sample_size = sizeof(float) * 2; reader = read_samples_float32; break; case FORMAT_FLOAT64: sample_size = sizeof(double) * 2; reader = read_samples_float64; break; } params.reader = reader; uint64_t nsamples = size / sample_size; if ((params.clip > 0) && (nsamples > params.clip)) { nsamples = params.clip; } if (params.overlap > params.fftsize) { fprintf(stderr, "Overlap of %d is greater than FFT frame size of %d.\n", params.overlap, params.fftsize); return EXIT_FAILURE; } params.frames = nsamples / (params.fftsize - params.overlap); if (!strcmp(outfile, "")) { strcpy(outfile, infile); strcat(outfile, ".png"); } if (verbose) { printf("Reading %s samples from %s...\n", fmt_s, infile); printf("Writing %d x %d output to %s...\n", params.fftsize, params.frames, outfile); } FILE *writefp = fopen(outfile, "wb"); if (!writefp) { fprintf(stderr, "Error: failed to write to %s.\n", outfile); return EXIT_FAILURE; } png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fprintf(stderr, "Error: could not initialize write struct.\n"); return EXIT_FAILURE; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { fprintf(stderr, "Error: could not initialize info struct.\n"); png_destroy_write_struct(&png_ptr, NULL); return EXIT_FAILURE; } if (setjmp(png_jmpbuf(png_ptr))) { fprintf(stderr, "Error: libpng error.\n"); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(writefp); return EXIT_FAILURE; } if (verbose) printf("Writing PNG header..\n"); png_init_io(png_ptr, writefp); png_set_IHDR(png_ptr, info_ptr, params.fftsize, params.frames, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); if (verbose) printf("Rendering (this may take a while)...\n"); waterfall(png_ptr, readfp, params); if (verbose) printf("Writing PNG footer...\n"); png_write_end(png_ptr, NULL); png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); png_destroy_write_struct(&png_ptr, NULL); if (verbose) printf("Cleaning up...\n"); fclose(writefp); fclose(readfp); destroy_window(win); if (verbose) print_scale_stats(); return EXIT_SUCCESS; }
char *sng_load_png_texture(const char *filename, int flipVertical, int flipHorizontal, int pre_multiply_alpha, int *w, int *h, int *hasAlpha, char *whynot, int whynotlen) { #ifndef WITHOUTOPENGL int i, j, bit_depth, color_type, row_bytes, image_data_row_bytes; png_byte header[8]; png_uint_32 tw, th; png_structp png_ptr = NULL; png_infop info_ptr = NULL; png_infop end_info = NULL; png_byte *image_data = NULL; FILE *fp = fopen(filename, "rb"); if (!fp) { snprintf(whynot, whynotlen, "Failed to open '%s': %s", filename, strerror(errno)); return 0; } if (fread(header, 1, 8, fp) != 8) { snprintf(whynot, whynotlen, "Failed to read 8 byte header from '%s'\n", filename); goto cleanup; } if (png_sig_cmp(header, 0, 8)) { snprintf(whynot, whynotlen, "'%s' isn't a png file.", filename); goto cleanup; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { snprintf(whynot, whynotlen, "png_create_read_struct() returned NULL"); goto cleanup; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { snprintf(whynot, whynotlen, "png_create_info_struct() returned NULL"); goto cleanup; } end_info = png_create_info_struct(png_ptr); if (!end_info) { snprintf(whynot, whynotlen, "2nd png_create_info_struct() returned NULL"); goto cleanup; } if (setjmp(png_jmpbuf(png_ptr))) { snprintf(whynot, whynotlen, "libpng encounted an error"); goto cleanup; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); /* * PNG_TRANSFORM_STRIP_16 | * PNG_TRANSFORM_PACKING forces 8 bit * PNG_TRANSFORM_EXPAND forces to expand a palette into RGB */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL); png_get_IHDR(png_ptr, info_ptr, &tw, &th, &bit_depth, &color_type, NULL, NULL, NULL); if (bit_depth != 8) { snprintf(whynot, whynotlen, "load_png_texture only supports 8-bit image channel depth"); goto cleanup; } if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA) { snprintf(whynot, whynotlen, "load_png_texture only supports RGB and RGBA"); goto cleanup; } if (w) *w = tw; if (h) *h = th; int has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA); if (hasAlpha) *hasAlpha = has_alpha; row_bytes = png_get_rowbytes(png_ptr, info_ptr); image_data_row_bytes = row_bytes; /* align to 4 byte boundary */ if (image_data_row_bytes & 0x03) image_data_row_bytes += 4 - (image_data_row_bytes & 0x03); png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); image_data = malloc(image_data_row_bytes * th * sizeof(png_byte) + 15); if (!image_data) { snprintf(whynot, whynotlen, "malloc failed in load_png_texture"); goto cleanup; } int bytes_per_pixel = (color_type == PNG_COLOR_TYPE_RGB_ALPHA ? 4 : 3); for (i = 0; i < th; i++) { png_byte *src_row; png_byte *dest_row = image_data + i * image_data_row_bytes; if (flipVertical) src_row = row_pointers[th - i - 1]; else src_row = row_pointers[i]; if (flipHorizontal) { for (j = 0; j < tw; j++) { png_byte *src = src_row + bytes_per_pixel * j; png_byte *dest = dest_row + bytes_per_pixel * (tw - j - 1); memcpy(dest, src, bytes_per_pixel); } } else { memcpy(dest_row, src_row, row_bytes); } if (has_alpha && pre_multiply_alpha) { for (j = 0; j < tw; j++) { png_byte *pixel = dest_row + bytes_per_pixel * j; float alpha = pixel[3] / 255.0; pixel[0] = pixel[0] * alpha; pixel[1] = pixel[1] * alpha; pixel[2] = pixel[2] * alpha; } } } png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return (char *)image_data; cleanup: if (image_data) free(image_data); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); #else snprintf(whynot, whynotlen, "load_png_texture: compiled without opengl support."); #endif return 0; }
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 GstFlowReturn gst_pngdec_chain (GstPad * pad, GstBuffer * buffer) { GstPngDec *pngdec; GstFlowReturn ret = GST_FLOW_OK; pngdec = GST_PNGDEC (gst_pad_get_parent (pad)); GST_LOG_OBJECT (pngdec, "Got buffer, size=%u", GST_BUFFER_SIZE (buffer)); if (G_UNLIKELY (!pngdec->setup)) goto not_configured; /* Something is going wrong in our callbacks */ ret = pngdec->ret; if (G_UNLIKELY (ret != GST_FLOW_OK)) { GST_WARNING_OBJECT (pngdec, "we have a pending return code of %d", ret); goto beach; } /* Let libpng come back here on error */ if (setjmp (png_jmpbuf (pngdec->png))) { GST_WARNING_OBJECT (pngdec, "error during decoding"); ret = GST_FLOW_ERROR; goto beach; } pngdec->in_timestamp = GST_BUFFER_TIMESTAMP (buffer); pngdec->in_duration = GST_BUFFER_DURATION (buffer); /* Progressive loading of the PNG image */ png_process_data (pngdec->png, pngdec->info, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)); if (pngdec->image_ready) { if (pngdec->framed) { /* Reset ourselves for the next frame */ gst_pngdec_libpng_clear (pngdec); gst_pngdec_libpng_init (pngdec); GST_LOG_OBJECT (pngdec, "setting up callbacks for next frame"); png_set_progressive_read_fn (pngdec->png, pngdec, user_info_callback, user_endrow_callback, user_end_callback); } else { GST_LOG_OBJECT (pngdec, "sending EOS"); pngdec->ret = gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ()); } pngdec->image_ready = FALSE; } /* grab new return code */ ret = pngdec->ret; /* And release the buffer */ gst_buffer_unref (buffer); beach: gst_object_unref (pngdec); return ret; /* ERRORS */ not_configured: { GST_LOG_OBJECT (pngdec, "we are not configured yet"); ret = GST_FLOW_WRONG_STATE; goto beach; } }
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()"); }
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; }
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; }
static GstFlowReturn gst_pngenc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame) { GstPngEnc *pngenc; gint row_index; png_byte **row_pointers; GstFlowReturn ret = GST_FLOW_OK; GstVideoInfo *info; GstVideoFrame vframe; pngenc = GST_PNGENC (encoder); info = &pngenc->input_state->info; GST_DEBUG_OBJECT (pngenc, "BEGINNING"); /* initialize png struct stuff */ pngenc->png_struct_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, user_error_fn, user_warning_fn); if (pngenc->png_struct_ptr == NULL) goto struct_init_fail; pngenc->png_info_ptr = png_create_info_struct (pngenc->png_struct_ptr); if (!pngenc->png_info_ptr) goto png_info_fail; /* non-0 return is from a longjmp inside of libpng */ if (setjmp (png_jmpbuf (pngenc->png_struct_ptr)) != 0) goto longjmp_fail; png_set_filter (pngenc->png_struct_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE); png_set_compression_level (pngenc->png_struct_ptr, pngenc->compression_level); png_set_IHDR (pngenc->png_struct_ptr, pngenc->png_info_ptr, GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), pngenc->depth, pngenc->png_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_set_write_fn (pngenc->png_struct_ptr, pngenc, (png_rw_ptr) user_write_data, user_flush_data); row_pointers = g_new (png_byte *, GST_VIDEO_INFO_HEIGHT (info)); if (!gst_video_frame_map (&vframe, &pngenc->input_state->info, frame->input_buffer, GST_MAP_READ)) { GST_ELEMENT_ERROR (pngenc, STREAM, FORMAT, (NULL), ("Failed to map video frame, caps problem?")); ret = GST_FLOW_ERROR; goto done; } for (row_index = 0; row_index < GST_VIDEO_INFO_HEIGHT (info); row_index++) { row_pointers[row_index] = GST_VIDEO_FRAME_COMP_DATA (&vframe, 0) + (row_index * GST_VIDEO_FRAME_COMP_STRIDE (&vframe, 0)); } /* allocate the output buffer */ pngenc->buffer_out = gst_buffer_new (); png_write_info (pngenc->png_struct_ptr, pngenc->png_info_ptr); png_write_image (pngenc->png_struct_ptr, row_pointers); png_write_end (pngenc->png_struct_ptr, NULL); g_free (row_pointers); gst_video_frame_unmap (&vframe); png_destroy_info_struct (pngenc->png_struct_ptr, &pngenc->png_info_ptr); png_destroy_write_struct (&pngenc->png_struct_ptr, (png_infopp) NULL); /* Set final size and store */ frame->output_buffer = pngenc->buffer_out; pngenc->buffer_out = NULL; if ((ret = gst_video_encoder_finish_frame (encoder, frame)) != GST_FLOW_OK) goto done; if (pngenc->snapshot) ret = GST_FLOW_EOS; done: GST_DEBUG_OBJECT (pngenc, "END, ret:%d", ret); return ret; /* ERRORS */ struct_init_fail: { GST_ELEMENT_ERROR (pngenc, LIBRARY, INIT, (NULL), ("Failed to initialize png structure")); return GST_FLOW_ERROR; } png_info_fail: { png_destroy_write_struct (&(pngenc->png_struct_ptr), (png_infopp) NULL); GST_ELEMENT_ERROR (pngenc, LIBRARY, INIT, (NULL), ("Failed to initialize the png info structure")); return GST_FLOW_ERROR; } longjmp_fail: { png_destroy_write_struct (&pngenc->png_struct_ptr, &pngenc->png_info_ptr); GST_ELEMENT_ERROR (pngenc, LIBRARY, FAILED, (NULL), ("returning from longjmp")); return GST_FLOW_ERROR; } }
void _mapcache_imageio_png_decode_to_image(mapcache_context *ctx, mapcache_buffer *buffer, mapcache_image *img) { int bit_depth,color_type,i; unsigned char **row_pointers; png_structp png_ptr = NULL; png_infop info_ptr = NULL; _mapcache_buffer_closure b; b.buffer = buffer; b.ptr = buffer->buf; png_uint_32 width, height; /* could pass pointers to user-defined error handlers instead of NULLs: */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { ctx->set_error(ctx, 500, "failed to allocate png_struct structure"); return; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); ctx->set_error(ctx, 500, "failed to allocate png_info structure"); return; } if (setjmp(png_jmpbuf(png_ptr))) { ctx->set_error(ctx, 500, "failed to setjmp(png_jmpbuf(png_ptr))"); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return; } png_set_read_fn(png_ptr,&b,_mapcache_imageio_png_read_func); png_read_info(png_ptr,info_ptr); if(!png_get_IHDR(png_ptr, info_ptr, &width, &height,&bit_depth, &color_type,NULL,NULL,NULL)) { ctx->set_error(ctx, 500, "failed to read png header"); return; } img->w = width; img->h = height; if(!img->data) { img->data = calloc(1,img->w*img->h*4*sizeof(unsigned char)); apr_pool_cleanup_register(ctx->pool, img->data, (void*)free, apr_pool_cleanup_null) ; img->stride = img->w * 4; } row_pointers = apr_pcalloc(ctx->pool,img->h * sizeof(unsigned char*)); unsigned char *rowptr = img->data; for(i=0;i<img->h;i++) { row_pointers[i] = rowptr; rowptr += img->stride; } png_set_expand(png_ptr); png_set_strip_16(png_ptr); png_set_gray_to_rgb(png_ptr); png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_read_image(png_ptr, row_pointers); png_read_end(png_ptr,NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); }
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); }
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; }
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 }
bool YImage::load(const char* fname) { FILE* fp = NULL ; bool rval = true; png_structp png_ptr = NULL ; png_infop info_ptr = NULL ; // for checking the png header const size_t PNG_BYTES_TO_CHECK = 4 ; // example.c uses 4 png_byte header[ PNG_BYTES_TO_CHECK ] ; // Open the file for reading in binary mode. fp = fopen( fname, "rb" ) ; if( !fp ) { fprintf( stderr, ERROR_STRING_OPEN, fname ) ; rval = false; goto YImage_load_cleanup ; } // Check some bytes at the beginning of the file to make sure it's a png. if( PNG_BYTES_TO_CHECK != fread( header, 1, PNG_BYTES_TO_CHECK, fp ) ) { fprintf( stderr, ERROR_STRING_INVALID_FILE, fname ) ; rval = false; goto YImage_load_cleanup ; } if( png_sig_cmp( header, 0, PNG_BYTES_TO_CHECK ) ) { fprintf( stderr, ERROR_STRING_INVALID_FILE, fname ) ; rval = false; goto YImage_load_cleanup ; } // Since it looks like we have a good png file, allocate the png structs. png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) ; if( !png_ptr ) { fprintf( stderr, ERROR_STRING_LIBERR ) ; rval = false; goto YImage_load_cleanup ; } info_ptr = png_create_info_struct( png_ptr ) ; if( !info_ptr ) { fprintf( stderr, ERROR_STRING_LIBERR ) ; rval = false; goto YImage_load_cleanup ; } // Set up the png error routine. if( setjmp(png_jmpbuf(png_ptr)) ) { fprintf( stderr, ERROR_STRING_MAYBE_FILE, fname ) ; rval = false; goto YImage_load_cleanup ; } // Give libpng the FILE*, tell it how many bytes we read. // png_init_io( png_ptr, fp ) ; // or // use our own read callback png_set_read_fn( png_ptr, fp, (png_rw_ptr) user_read_data ) ; png_set_sig_bytes( png_ptr, PNG_BYTES_TO_CHECK ) ; // We'll use the low-level interface since the high-level interface won't handle // png_set_filler() which we need to guarantee there'll be a filler "A" in our // 4-byte ARGB pixels. // Really the low-level interface isn't more complicated than the high-level interface. // To choose transform flags we have to query the png_info struct. // Instead of OR'ing in another transform flag (high-level interface), we call a set // method (low-level interface). // First we read the info struct. png_read_info( png_ptr, info_ptr ) ; // Now we set up transforms. // 1. convert gray and paletted to rgb (this guarantees 8 or 16 bit depths (rgb must be 8 or 16)). // also expand the alpha color to an alpha channel and convert 16 bit depths to 8. // 2. if we don't have alpha, add an opaque channel. also swap RGB and BGR depending on YPixel. // 3. ask libpng to deinterlace { png_byte color_type = png_get_color_type( png_ptr, info_ptr ) ; png_byte depth = png_get_bit_depth( png_ptr, info_ptr ) ; // 1 if( color_type == PNG_COLOR_TYPE_PALETTE ) png_set_expand( png_ptr ) ; if( color_type == PNG_COLOR_TYPE_GRAY && depth < 8 ) png_set_expand( png_ptr ) ; if( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) ) png_set_expand( png_ptr ) ; if( depth == 16 ) png_set_strip_16( png_ptr ) ; if( color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) png_set_gray_to_rgb( png_ptr ) ; // NOTE: This next step affects the layout of the channels in the pixel. // We turn the pixel into the format in YPixel, // with the restrication that alpha comes at the beginning or end // and green is sandwiched between red and blue. // The possibilities are: ARGB, ABGR, RGBA, BGRA. // 2 if( color_type != PNG_COLOR_TYPE_GRAY_ALPHA && color_type != PNG_COLOR_TYPE_RGB_ALPHA && !png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) ) png_set_filler( png_ptr, 0xFF, offsetof( YPixel, a ) < offsetof( YPixel, b ) ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER ) ; else if( offsetof( YPixel, a ) < offsetof( YPixel, b ) ) png_set_swap_alpha( png_ptr ) ; if( offsetof( YPixel, b ) < offsetof( YPixel, r ) ) png_set_bgr( png_ptr ) ; // 3 png_set_interlace_handling( png_ptr ) ; } // We're almost ready to copy over the png data. // First we must resize our data* and set our width & height. { png_uint_32 widthh = png_get_image_width( png_ptr, info_ptr ) ; png_uint_32 heightt = png_get_image_height( png_ptr, info_ptr ) ; // fprintf( stderr, "width: %d, height: %d\n", (int) widthh, (int) heightt ) ; resize( widthh, heightt ) ; } // Now we can create a rows[] pointing into our data* and read the png into our buffer. { // fprintf( stderr, "width: %d, height: %d\n", (int) m_width, (int) m_height ) ; /* png_byte channels = png_get_channels( png_ptr, info_ptr ) ; assert( 4 == channels ) ; png_byte depth = png_get_bit_depth( png_ptr, info_ptr ) ; assert( 8 == depth ) ; png_uint_32 rowbytes = png_get_rowbytes( png_ptr, info_ptr ) ; assert( sizeof(YPixel) * m_width == rowbytes ) ; */ // 1. allocate row pointers array png_bytep* row_pointers = (png_bytep*) png_malloc( png_ptr, m_height * sizeof(png_bytep) ) ; // 2. point row pointers into m_data for( int i = 0 ; i < m_height ; ++i ) row_pointers[i] = (png_bytep) (m_data + i*m_width ) ; // 3. read the image data png_read_image( png_ptr, row_pointers ) ; // 4. free row pointers array png_free( png_ptr, row_pointers ) ; } // Read the end info. We're done. Fall through to cleanup. png_read_end( png_ptr, NULL ) ; YImage_load_cleanup: // due to (what looks like) a bug in libpng-1.2.4, we can't pass NULL for the png_ptr arg if( png_ptr ) png_destroy_read_struct( &png_ptr, info_ptr ? &info_ptr : NULL, NULL ) ; if( fp ) fclose( fp ) ; return rval ; }
// Loads a PNG image // // filename - name of the targa file to load // image_data - allocated storage for the bitmap // // returns - true if succesful, false otherwise // int png_read_bitmap(char *real_filename, ubyte *image_data, ubyte *bpp, int dest_size, int cf_type) { char filename[MAX_FILENAME_LEN]; png_infop info_ptr; png_structp png_ptr; png_bytepp row_pointers; unsigned int i, len; png_file = NULL; strcpy_s( filename, real_filename ); char *p = strchr( filename, '.' ); if ( p ) *p = 0; strcat_s( filename, ".png" ); png_file = cfopen(filename, "rb", CFILE_NORMAL, cf_type); if (png_file == NULL) return PNG_ERROR_READING; /* 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, NULL, NULL, NULL); if (png_ptr == NULL) { mprintf(("png_read_bitmap: png_ptr went wrong\n")); cfclose(png_file); return PNG_ERROR_READING; } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { mprintf(("png_read_bitmap: info_ptr went wrong\n")); cfclose(png_file); png_destroy_read_struct(&png_ptr, NULL, NULL); return PNG_ERROR_READING; } if (setjmp(png_jmpbuf(png_ptr))) { mprintf(("png_read_bitmap: something went wrong\n")); /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); cfclose(png_file); /* If we get here, we had a problem reading the file */ return PNG_ERROR_READING; } png_set_read_fn(png_ptr, &png_file, png_scp_read_data); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_16, NULL); len = png_get_rowbytes(png_ptr, info_ptr); row_pointers = png_get_rows(png_ptr, info_ptr); if(bpp) *bpp = (ubyte)(len / png_get_image_width(png_ptr, info_ptr)) << 3; //copy row data to image unsigned int height = png_get_image_height(png_ptr, info_ptr); for (i = 0; i < height; i++) { memcpy(&image_data[i * len], row_pointers[i], len); } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); cfclose(png_file); return PNG_ERROR_NONE; }
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; }
// Reads header information from the PNG file into the bitmap pointer // // filename - name of the PNG bitmap file // w - (output) width of the bitmap // h - (output) height of the bitmap // bpp - (output) bits per pixel of the bitmap // // returns - PNG_ERROR_NONE if successful, otherwise error code // int png_read_header(char *real_filename, CFILE *img_cfp, int *w, int *h, int *bpp, ubyte *palette) { char filename[MAX_FILENAME_LEN]; png_infop info_ptr; png_structp png_ptr; png_file = NULL; //mprintf(("png_read_header: %s\n", real_filename)); if (img_cfp == NULL) { strcpy_s( filename, real_filename ); char *p = strchr( filename, '.' ); if ( p ) *p = 0; strcat_s( filename, ".png" ); png_file = cfopen( filename , "rb" ); if ( !png_file ) { return PNG_ERROR_READING; } } else { png_file = img_cfp; } Assert( png_file != NULL ); if (png_file == NULL) return PNG_ERROR_READING; /* 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, NULL, NULL, NULL); if (png_ptr == NULL) { mprintf(("png_read_header: error creating read struct\n")); cfclose(png_file); return PNG_ERROR_READING; } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { mprintf(("png_read_header: error creating info struct\n")); cfclose(png_file); png_destroy_read_struct(&png_ptr, NULL, NULL); return PNG_ERROR_READING; } if (setjmp(png_jmpbuf(png_ptr))) { mprintf(("png_read_header: something went wrong\n")); /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); cfclose(png_file); /* If we get here, we had a problem reading the file */ return PNG_ERROR_READING; } png_set_read_fn(png_ptr, &png_file, png_scp_read_data); png_read_info(png_ptr, info_ptr); if (w) *w = png_get_image_width(png_ptr, info_ptr); if (h) *h = png_get_image_height(png_ptr, info_ptr); // this turns out to be near useless, but meh if (bpp) *bpp = (png_get_channels(png_ptr, info_ptr) * png_get_bit_depth(png_ptr, info_ptr)); if (img_cfp == NULL) { cfclose(png_file); png_file = NULL; } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return PNG_ERROR_NONE; }
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); }
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 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; }
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; }
unsigned char *readpng_get_image( png_store* pngdata) { double gamma; png_uint_32 i, rowbytes; png_bytepp row_pointers = NULL; png_structp png_ptr = pngdata->png_ptr; png_infop info_ptr = pngdata->info_ptr; int color_type = pngdata->colortype; int bit_depth = pngdata->bitdepth; int height = pngdata->height; double display_exponent = DISPLAY_EXPONENT; int *pChannels = &(pngdata->channels); unsigned long *pRowbytes = &(pngdata->rowbytes); unsigned char * image_data; /* 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 NULL; } /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits, * transparency chunks to full alpha channel; strip 16-bit-per-sample * images to 8 bits per sample; and convert grayscale to RGB[A] */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); /* unlike the example in the libpng documentation, we have *no* idea where * this file may have come from--so if it doesn't have a file gamma, don't * do any correction ("do no harm") */ if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, display_exponent, gamma); /* all transformations have been registered; now update info_ptr data, * get rowbytes and channels, and allocate image memory */ png_read_update_info(png_ptr, info_ptr); *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); *pChannels = (int)png_get_channels(png_ptr, info_ptr); if ((image_data = (unsigned char *)malloc(rowbytes*height)) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(image_data); image_data = NULL; return NULL; } /* set the individual row_pointers to point at the correct offsets */ for (i = 0; i < 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) */ // free(row_pointers); // row_pointers = NULL; png_read_end(png_ptr, NULL); pngdata->image_data = image_data; pngdata->row_pointers = row_pointers; return image_data; }
static void gst_pngdec_task (GstPad * pad) { GstPngDec *pngdec; GstBuffer *buffer = NULL; size_t buffer_size = 0; gint i = 0; png_bytep *rows, inp; png_uint_32 rowbytes; GstFlowReturn ret = GST_FLOW_OK; pngdec = GST_PNGDEC (GST_OBJECT_PARENT (pad)); GST_LOG_OBJECT (pngdec, "read frame"); /* Let libpng come back here on error */ if (setjmp (png_jmpbuf (pngdec->png))) { ret = GST_FLOW_ERROR; goto pause; } /* Set reading callback */ png_set_read_fn (pngdec->png, pngdec, user_read_data); /* Read info */ png_read_info (pngdec->png, pngdec->info); /* Generate the caps and configure */ ret = gst_pngdec_caps_create_and_set (pngdec); if (ret != GST_FLOW_OK) { goto pause; } /* Allocate output buffer */ rowbytes = png_get_rowbytes (pngdec->png, pngdec->info); if (rowbytes > (G_MAXUINT32 - 3) || pngdec->height > G_MAXUINT32 / rowbytes) { ret = GST_FLOW_ERROR; goto pause; } rowbytes = GST_ROUND_UP_4 (rowbytes); buffer_size = pngdec->height * rowbytes; ret = gst_pad_alloc_buffer_and_set_caps (pngdec->srcpad, GST_BUFFER_OFFSET_NONE, buffer_size, GST_PAD_CAPS (pngdec->srcpad), &buffer); if (ret != GST_FLOW_OK) goto pause; rows = (png_bytep *) g_malloc (sizeof (png_bytep) * pngdec->height); inp = GST_BUFFER_DATA (buffer); for (i = 0; i < pngdec->height; i++) { rows[i] = inp; inp += rowbytes; } /* Read the actual picture */ png_read_image (pngdec->png, rows); g_free (rows); /* Push the raw RGB frame */ ret = gst_pad_push (pngdec->srcpad, buffer); if (ret != GST_FLOW_OK) goto pause; /* And we are done */ gst_pad_pause_task (pngdec->sinkpad); gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ()); return; pause: { GST_INFO_OBJECT (pngdec, "pausing task, reason %s", gst_flow_get_name (ret)); gst_pad_pause_task (pngdec->sinkpad); if (ret == GST_FLOW_UNEXPECTED) { gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ()); } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) { GST_ELEMENT_ERROR (pngdec, STREAM, FAILED, (_("Internal data stream error.")), ("stream stopped, reason %s", gst_flow_get_name (ret))); gst_pad_push_event (pngdec->srcpad, gst_event_new_eos ()); } } }
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; }
struct IplImage *ipl_readimg(char *path, int mode) { FILE *f; unsigned char head[8]; int numb = 8, w, h, nchans = 3, y; size_t sznumb; struct IplImage *res; png_bytep* rows; png_structp pngp; png_infop infop; if (!(f = fopen(path, "rb"))) { perror("error opening file\n"); return NULL; } sznumb = fread(head, sizeof(char), numb, f); if (png_sig_cmp(head, 0, 8)) { perror("is not png"); fclose(f); return NULL; } if (!(pngp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) { perror("can't create read struct"); fclose(f); return NULL; } if (!(infop = png_create_info_struct(pngp))) { perror("can't create info"); png_destroy_read_struct(&pngp, NULL, NULL); fclose(f); return NULL; } if (setjmp(png_jmpbuf(pngp))) { perror("error in jumpbuf"); png_destroy_read_struct(&pngp, &infop, NULL); fclose(f); return NULL; } png_init_io(pngp, f); png_set_sig_bytes(pngp, sznumb); png_read_info(pngp, infop); png_set_strip_alpha(pngp); png_set_strip_16(pngp); if (mode) { nchans = 3; png_set_palette_to_rgb(pngp); } else { nchans = 1; png_set_rgb_to_gray(pngp, 1, 0.0f, 0.0f); png_set_expand_gray_1_2_4_to_8(pngp); } png_set_interlace_handling(pngp); png_read_update_info(pngp, infop); w = png_get_image_width(pngp, infop); h = png_get_image_height(pngp, infop); rows = (png_bytep *)malloc(sizeof(png_bytep) * h); for (y = 0; y < h; y++) { rows[y] = (png_byte *)malloc(png_get_rowbytes(pngp, infop)); } png_read_image(pngp, rows); res = (struct IplImage *)malloc(sizeof(struct IplImage)); res->width = w; res->height = h; res->nchans = nchans; res->data = (unsigned char *)malloc(sizeof(unsigned char) * w * h * 3); for (y = 0; y < h; y++) memcpy(&(res->data[nchans * y * w]), rows[y], sizeof(png_byte) * png_get_rowbytes(pngp, infop)); for (y = 0; y < h; y++) free(rows[y]); free(rows); fclose(f); return res; }
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; }
/* 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_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_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; }
g_error png_load(hwrbitmap *hbmp, const u8 *data, u32 datalen) { png_structp png_ptr; png_infop info_ptr; struct datablock d; png_bytep *row_pointers; png_uint_32 width, height; int bit_depth,colortype,interlace; int x,y; u8 r,g,b,a; pgcolor c; png_bytep p; g_error e; png_colorp palette; int num_palette; png_colorp pp; png_bytep trans; int num_trans = 0; #ifdef CONFIG_DITHER hwrdither dither; #endif png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return mkerror(PG_ERRT_IO, 68); /* Error initializing libpng */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return mkerror(PG_ERRT_IO, 68); /* Error initializing libpng */ } /* Set libpng error handler */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return mkerror(PG_ERRT_IO, 71); /* Error reading PNG */ } /* Set libpng read handler */ d.data = data; d.length = datalen; png_set_read_fn(png_ptr, &d, (png_rw_ptr) &png_user_read_data); /* Read the png into memory */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING, NULL); row_pointers = png_get_rows(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &colortype, &interlace, NULL, NULL); if (colortype == PNG_COLOR_TYPE_PALETTE) { png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); } if (interlace != PNG_INTERLACE_NONE) fprintf(stderr, "png loader: OOPS... interlaced image, will b0rk\n"); /* Allocate the picogui bitmap * * Important note: normally we create bitmaps at the display's * color depth, but if we have an alpha channel * we need room for ARGB colors. */ if (colortype == PNG_COLOR_TYPE_GRAY_ALPHA || colortype == PNG_COLOR_TYPE_RGB_ALPHA || num_trans) e = vid->bitmap_new(hbmp,width,height,32); else e = vid->bitmap_new(hbmp,width,height,vid->bpp); if (iserror(e)) png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); errorcheck; #ifdef CONFIG_DITHER /* Start dithering */ e = vid->dither_start(&dither, *hbmp, 0,0,0,width,height); errorcheck; #endif /* Transcribe it into a picogui bitmap. * This method is slow, but ensures compatibility */ for (y=0;y<height;y++) { p = row_pointers[y]; for (x=0;x<width;x++) { switch (colortype) { case PNG_COLOR_TYPE_GRAY: g = *(p++); c = mkcolor(g,g,g); break; case PNG_COLOR_TYPE_GRAY_ALPHA: g = *(p++); a = *(p++); c = mkcolora(a>>1,g,g,g); break; case PNG_COLOR_TYPE_PALETTE: pp = &palette[ (*p) % num_palette ]; if (*p < num_trans) c = mkcolora(trans[*p]>>1, pp->red, pp->green, pp->blue); else if (num_trans) c = mkcolora(0x7f, pp->red, pp->green, pp->blue); else c = mkcolor(pp->red, pp->green, pp->blue); p++; break; case PNG_COLOR_TYPE_RGB: r = *(p++); g = *(p++); b = *(p++); c = mkcolor(r,g,b); break; case PNG_COLOR_TYPE_RGB_ALPHA: r = *(p++); g = *(p++); b = *(p++); a = *(p++); c = mkcolora(a>>1,r,g,b); break; } #ifdef CONFIG_DITHER vid->dither_store(dither, c, PG_LGOP_NONE); #else vid->pixel(*hbmp,x,y,VID(color_pgtohwr)(c),PG_LGOP_NONE); #endif } }
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); }