static int read_png ( FILE *fp ) { png_structp png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING,0,0,0 ); png_infop info_ptr = NULL; png_bytep row = NULL, display = NULL; if ( png_ptr == NULL ) return 0; if ( setjmp ( png_jmpbuf ( png_ptr ) ) ) { png_destroy_read_struct ( &png_ptr, &info_ptr, NULL ); if ( row != NULL ) free ( row ); if ( display != NULL ) free ( display ); return 0; } png_init_io ( png_ptr, fp ); info_ptr = png_create_info_struct ( png_ptr ); if ( info_ptr == NULL ) png_error ( png_ptr, "OOM allocating info structure" ); png_read_info ( png_ptr, info_ptr ); { png_size_t rowbytes = png_get_rowbytes ( png_ptr, info_ptr ); row = malloc ( rowbytes ); display = malloc ( rowbytes ); if ( row == NULL || display == NULL ) png_error ( png_ptr, "OOM allocating row buffers" ); { png_uint_32 height = png_get_image_height ( png_ptr, info_ptr ); int passes = png_set_interlace_handling ( png_ptr ); int pass; png_start_read_image ( png_ptr ); for ( pass = 0; pass < passes; ++pass ) { png_uint_32 y = height; /* NOTE: this trashes the row each time; interlace handling won't * work, but this avoids memory thrashing for speed testing. */ while ( y-- > 0 ) png_read_row ( png_ptr, row, display ); } } } /* Make sure to read to the end of the file: */ png_read_end ( png_ptr, info_ptr ); png_destroy_read_struct ( &png_ptr, &info_ptr, NULL ); free ( row ); free ( display ); return 1; }
/* This function is called (as set by png_set_progressive_read_fn() above) when enough data has been supplied so all of the header has been read. */ void info_callback(png_structp png_ptr, png_infop info) { file_end=0; width = png_get_image_width(png_ptr,info); height = png_get_image_height(png_ptr,info); pixel_depth = png_get_bit_depth(png_ptr,info); channels = png_get_channels(png_ptr,info); color_type = png_get_color_type(png_ptr,info); if(color_type == PNG_COLOR_TYPE_GRAY) {} if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA){} if(color_type == PNG_COLOR_TYPE_RGB) {} if(color_type == PNG_COLOR_TYPE_RGB_ALPHA) {} if(color_type == PNG_COLOR_TYPE_PALETTE ) { int r = png_get_PLTE(png_ptr,info,&palette,&num_palette); if(r == 0) { } png_uint_16p histogram = NULL; png_get_hIST(png_ptr, info, &histogram); png_set_expand(png_ptr); png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info); pixel_depth = 8; } int row_bytes = png_get_rowbytes(png_ptr,info); row_pointers = malloc(sizeof(png_bytep *) * height); for(size_t n=0;n<height;n++) { row_pointers[n] = malloc(row_bytes); } png_start_read_image(png_ptr); }
static int read_png(FILE *fp) { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0); png_infop info_ptr = NULL; png_bytep row = NULL, display = NULL; if (png_ptr == NULL) return 0; if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if (row != NULL) free(row); if (display != NULL) free(display); return 0; } png_init_io(png_ptr, fp); info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) png_error(png_ptr, "OOM allocating info structure"); png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, NULL, 0); png_read_info(png_ptr, info_ptr); { png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); /* Failure to initialize these is harmless */ row = malloc(rowbytes); display = malloc(rowbytes); if (row == NULL || display == NULL) png_error(png_ptr, "OOM allocating row buffers"); { png_uint_32 height = png_get_image_height(png_ptr, info_ptr); # ifdef PNG_READ_INTERLACING_SUPPORTED int passes = png_set_interlace_handling(png_ptr); # else /* !READ_INTERLACING */ int passes = png_get_interlace_type(png_ptr, info_ptr) == PNG_INTERLACE_ADAM7 ? PNG_INTERLACE_ADAM7_PASSES : 1; # endif /* !READ_INTERLACING */ int pass; png_start_read_image(png_ptr); for (pass = 0; pass < passes; ++pass) { png_uint_32 y = height; # ifndef PNG_READ_INTERLACING_SUPPORTED if (passes == PNG_INTERLACE_ADAM7_PASSES) y = PNG_PASS_ROWS(y, pass); # endif /* READ_INTERLACING */ /* NOTE: this trashes the row each time; interlace handling won't * work, but this avoids memory thrashing for speed testing. */ while (y-- > 0) png_read_row(png_ptr, row, display); } } } /* Make sure to read to the end of the file: */ png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(row); free(display); return 1; }
static void read_png(unsigned char** block, unsigned* width, unsigned* height, FILE* file, const int base_img_size) { png_structp png_ptr; png_infop info_ptr; png_bytep* row_pointers; unsigned row, x, y; int rowbytes; char* dst; //png_uint_32 is 64 bit on some architectures! png_uint_32 widthpu32,heightpu32; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (png_ptr == NULL) { printf("read_png: Could not create read struct.\n"); exit(1); } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { printf("read_png: Could not create info struct.\n"); png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); exit(1); } if (setjmp(png_ptr->jmpbuf)) { printf("read_png: fatal error.\n"); png_destroy_read_struct(&png_ptr, &info_ptr, (png_info**)0); /* free pointers before returning, if necessary */ free(png_ptr); free(info_ptr); exit(1); } /* Set up the input control if you are using standard C streams */ png_init_io(png_ptr, file); /* 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, &widthpu32, &heightpu32, &bit_depth, &color_type, &interlace_type, NULL, NULL ); *width = widthpu32; *height = heightpu32; if (*height % base_img_size != 0 || *width % base_img_size != 0) { printf("read_png: Invalid image size.\n"); exit(1); } // printf("read_png: width=%d, height=%d, bit_depth=%d\n", width, height, bit_depth); // printf("read_png: color_type=%d, interlace_type=%d\n", color_type, interlace_type); /* tell libpng to strip 16 bit/color files down to 8 bits/color */ png_set_strip_16(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); /* Expand paletted colors into true RGB triplets */ png_set_expand(png_ptr); png_start_read_image(png_ptr); /* The easiest way to read the image: */ rowbytes = png_get_rowbytes(png_ptr, info_ptr) * 3; row_pointers = malloc(*height * sizeof(*row_pointers)); row_pointers[0] = malloc(rowbytes * *height * 2); for (row = 1; row < *height; row++) { row_pointers[row] = row_pointers[row - 1] + rowbytes * 2; } /* Read the entire image in one go */ png_read_image(png_ptr, row_pointers); // we use fixed height here because block is of limited, fixed size // not fixed any more *block = realloc(*block, *height * *width * 6); // *block = malloc(*height * *width * 6); dst = *block; for (y = 0; y < *height; y++) { for (x = 0; x < *width * 3; x++) { *dst++ = row_pointers[y][x]; // *dst++ = 0; } } free(row_pointers[0]); free(row_pointers); /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); /* At this point you have read the entire image */ /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); }