/** \brief Get color depth. * * Transform the color depth accordingly. * * On unacceptable color type, 0 is returned. * * @return Color depth dependant on actual color depth and model. */ unsigned getBpp() const { uint8_t bpp = png_get_bit_depth(m_png, m_info); if(8 != bpp) { return 0; } switch(png_get_color_type(m_png, m_info)) { case PNG_COLOR_TYPE_GRAY: return 8; case PNG_COLOR_TYPE_GRAY_ALPHA: return 16; case PNG_COLOR_TYPE_RGB: return 24; case PNG_COLOR_TYPE_RGB_ALPHA: return 32; default: return 0; } }
int main(int argc, char *argv[]) { const char *desc; const char *pngfname = argv[1]; FILE *rfp = fopen(pngfname, "rb"); png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop read_info_ptr = png_create_info_struct(read_ptr); png_infop end_info_ptr = png_create_info_struct(read_ptr); png_set_read_user_transform_fn(read_ptr, custom_transform_fn); //png_set_user_transform_info(read_ptr, NULL, 4, 4); // FIXME, limited by pngrtran.c png_init_io(read_ptr, rfp); png_read_png(read_ptr, read_info_ptr, PNG_TRANSFORM_IDENTITY, NULL); switch (png_get_color_type(read_ptr, read_info_ptr)) { ENUM2DESC(PNG_COLOR_TYPE_GRAY); ENUM2DESC(PNG_COLOR_TYPE_PALETTE); ENUM2DESC(PNG_COLOR_TYPE_RGB); ENUM2DESC(PNG_COLOR_TYPE_RGB_ALPHA); ENUM2DESC(PNG_COLOR_TYPE_GRAY_ALPHA); default: desc = "PNG_COLOR_UNKNOWN"; break; } printf("%s: COLOR_TYPE = [%s]\n", pngfname, desc); printf("%s: SIZE = %u x %u, BIT_DEPTH = %u\n", pngfname, (unsigned)png_get_image_width(read_ptr, read_info_ptr), (unsigned)png_get_image_height(read_ptr, read_info_ptr), (unsigned)png_get_bit_depth(read_ptr, read_info_ptr)); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); fclose(rfp); return 0; }
static void make_png(void) { png_bytepp row_pointers=NULL; rgb_t * row_data=NULL; int i; int nfreqs = nfft/2+1; png_structp png_ptr=NULL; png_infop info_ptr=NULL; CHECKNULL( png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,0,0,0) ); CHECKNULL( info_ptr = png_create_info_struct(png_ptr) ); png_init_io(png_ptr, fout ); png_set_IHDR(png_ptr, info_ptr ,nfreqs,nrows,8,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT ); row_data = (rgb_t*)malloc(sizeof(rgb_t) * nrows * nfreqs) ; cpx2pixels(row_data, vals, nfreqs*nrows ); row_pointers = realloc(row_pointers, nrows*sizeof(png_bytep)); for (i=0;i<nrows;++i) { row_pointers[i] = (png_bytep)(row_data + i*nfreqs); } png_set_rows(png_ptr, info_ptr, row_pointers); fprintf(stderr,"creating %dx%d png\n",nfreqs,nrows); fprintf(stderr,"bitdepth %d \n",png_get_bit_depth(png_ptr,info_ptr ) ); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY , NULL); }
void init() { char buf[PNG_BYTES_TO_CHECK]; // read in some of the signature bytes io_error_if( fread( buf, 1, PNG_BYTES_TO_CHECK, get() ) != detail::PNG_BYTES_TO_CHECK, "png_check_validity: fail to read file" ); // compare the first PNG_BYTES_TO_CHECK bytes of the signature. io_error_if( png_sig_cmp( (png_bytep)buf, (png_size_t)0, detail::PNG_BYTES_TO_CHECK ) != 0, "png_check_validity: invalid png file" ); _png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); io_error_if( _png_ptr == NULL, "png_get_file_size: fail to call png_create_write_struct()" ); // allocate/initialize the image information data _info_ptr = png_create_info_struct( _png_ptr ); if( _info_ptr == NULL ) { png_destroy_read_struct( &_png_ptr, png_infopp_NULL, png_infopp_NULL ); io_error( "png_get_file_size: fail to call png_create_info_struct()" ); } 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 ); io_error( "png_get_file_size: fail to call setjmp()" ); } png_init_io( _png_ptr, get() ); png_set_sig_bytes( _png_ptr, PNG_BYTES_TO_CHECK ); png_read_info( _png_ptr, _info_ptr ); if( little_endian() && png_get_bit_depth( _png_ptr, _info_ptr ) > 8 ) png_set_swap( _png_ptr ); }
//--------------------------------------------------------------------- inline void normalizePngInfo(png_struct* png_ptr, png_info* info_ptr) { int bit_depth, color_type; /* get some usefull information from header */ bit_depth = png_get_bit_depth (png_ptr, info_ptr); color_type = png_get_color_type (png_ptr, info_ptr); /* convert index color images to RGB images */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); } /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { png_set_expand_gray_1_2_4_to_8(png_ptr); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha (png_ptr); } /* make each canal to use exactly 8 bits */ if (bit_depth == 16) { png_set_strip_16 (png_ptr); } else if (bit_depth < 8) { png_set_packing (png_ptr); } /* update info structure to apply transformations */ png_read_update_info(png_ptr, info_ptr); }
/* Ripped from the libpng manual */ png_bytepp readpng(const char *filename, int* width, int* height) { FILE *fp = fopen(filename, "rb"); char header[8]; png_structp png_ptr; png_infop info_ptr, end_info; if (!fp) { fprintf(stderr, "%s ", filename); perror("fopen"); return NULL; } fread(header, 1, 8, fp); if(png_sig_cmp((png_byte*)header, 0, 8)) { fprintf(stderr, "%s: Not a PNG image!\n", filename); return NULL; } png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) return NULL; info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return NULL; } end_info = png_create_info_struct(png_ptr); if(!end_info) { png_destroy_read_struct(&png_ptr, NULL, NULL); return NULL; } /* Set up jump target for libpng errors */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fprintf(stderr, "libpng error!\n"); fclose(fp); return NULL; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_png(png_ptr, info_ptr, 0, NULL); /* Make sure the image is in the format we want */ *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); if(png_get_bit_depth(png_ptr, info_ptr) != 8 || png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB) fprintf(stderr, "Need an 8 bit/color RGB image!!\n"); /* Warning! We leak these data structures!!! */ return png_get_rows(png_ptr, info_ptr); }
// //////////////////////////////////////////////////// // // Image* readPNGIntoImage() // //////////////////////////////////////////////////// // Image* PNGCodec::readPNGIntoImage(png_structp &png, png_infop &pngInfo) { uint8 **buf; int y; png_uint_32 iWidth, iHeight, iRowLength; png_byte iColourType, iBitsPerChannel, iNumChannels; png_bytepp pngRows; Image* imgPNG; png_read_png(png, pngInfo, PNG_TRANSFORM_BGR | PNG_TRANSFORM_STRIP_ALPHA, png_voidp_NULL); // pixels are in info_ptr->row_pointers // where row_pointers is: // png_bytep row_pointers[height]; // and is probably not contiguous iColourType = png_get_color_type(png, pngInfo); // if (iColourType != PNG_COLOR_TYPE_RGB_ALPHA) if (iColourType != PNG_COLOR_TYPE_RGB) throw new std::runtime_error("Colour type not supported - RGB only, PNGCodec::readPNGIntoImage()"); iBitsPerChannel = png_get_bit_depth(png, pngInfo); iNumChannels = png_get_channels(png, pngInfo); iHeight = png_get_image_height(png, pngInfo); iWidth = png_get_image_width(png, pngInfo); iRowLength = iWidth * (iBitsPerChannel * iNumChannels) / 8; // Should be same as iWidth // 07-Jul-2009: Directly load the PNG into a pre-created image's // buffer. Otherwise ImageRGB24 will make a copy of the buf, which // is a waste of space (and problematic for very large PNGs!) imgPNG = new Image; imgPNG->width = iWidth; imgPNG->height = iHeight; imgPNG->data = new unsigned char*[iHeight]; for (y = 0; y < iHeight; y++) { imgPNG->data[y] = new unsigned char[iRowLength]; } buf = imgPNG->data; pngRows = png_get_rows(png, pngInfo); for (y = 0; y < iHeight; y++) { // for (x = 0; x < iWidth; x++) { // This assumes BGR order, in readiness for the ImageRGB24 constructor // It also assumes 24-bit, no alpha // Yes, this is not good... memcpy(buf[y], pngRows[y], iRowLength); //memcpy((buf + (y * iRowLength)), pngRows[y], iRowLength); } // Clean up png_destroy_read_struct(&png, &pngInfo, png_infopp_NULL); return imgPNG; }
void read_png_file(char *filename) { FILE *fp = fopen(filename, "rb"); png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png) abort(); png_infop info = png_create_info_struct(png); if(!info) abort(); if(setjmp(png_jmpbuf(png))) abort(); png_init_io(png, fp); png_read_info(png, info); width = png_get_image_width(png, info); height = png_get_image_height(png, info); color_type = png_get_color_type(png, info); bit_depth = png_get_bit_depth(png, info); // Read any color_type into 8bit depth, RGBA format. // See http://www.libpng.org/pub/png/libpng-manual.txt if(bit_depth == 16) png_set_strip_16(png); if(color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth. if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png); if(png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png); // These color_type don't have an alpha channel then fill it with 0xff. if(color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) png_set_filler(png, 0xFF, PNG_FILLER_AFTER); if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png); png_read_update_info(png, info); row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); int y ; for( y = 0; y < height; y++) { row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info)); } png_read_image(png, row_pointers); fclose(fp); }
void read_png_file(char* file_name) { unsigned char header[8]; // 8 is the maximum size that can be checked /* open file and test for it being a png */ FILE *fp = fopen(file_name, "rb"); if (!fp) abort_("[read_png_file] File %s could not be opened for reading", file_name); 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", file_name); /* 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); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); number_of_passes = png_set_interlace_handling(png_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); if (bit_depth == 16) rowbytes = width*8; else rowbytes = width*4; for (y=0; y<height; y++) row_pointers[y] = (png_byte*) malloc(rowbytes); png_read_image(png_ptr, row_pointers); fclose(fp); }
static png_bytep * read_png(png_structp png_ptr, png_infop info_ptr, at_input_opts_type * opts) { int row; png_color_16p original_bg; png_color_16 my_bg; png_read_info(png_ptr, info_ptr); png_set_strip_16(png_ptr); png_set_packing(png_ptr); if ((png_get_bit_depth(png_ptr, info_ptr) < 8) || (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) || (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) png_set_expand(png_ptr); if (png_get_bKGD(png_ptr, info_ptr, &original_bg)) { /* Fill transparent region with ... */ my_bg.index = 0; if (opts && opts->background_color) { my_bg.red = 256 * opts->background_color->r; my_bg.green = 256 * opts->background_color->g; my_bg.blue = 256 * opts->background_color->b; my_bg.gray = 256* ((opts->background_color->r + opts->background_color->g + opts->background_color->b) / 3); } else /* else, use white */ my_bg.red = my_bg.green = my_bg.blue = my_bg.gray = 0xFFFF; png_set_background(png_ptr, &my_bg, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); } else png_set_strip_alpha(png_ptr); png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); // PGC to replace commented lines png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); png_read_end(png_ptr, info_ptr); return png_get_rows(png_ptr, info_ptr); // info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, // info_ptr->height * sizeof(png_bytep)); //#ifdef PNG_FREE_ME_SUPPORTED // info_ptr->free_me |= PNG_FREE_ROWS; //#endif // for (row = 0; row < (int)info_ptr->height; row++) // info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, // png_get_rowbytes(png_ptr, info_ptr)); // // png_read_image(png_ptr, info_ptr->row_pointers); // info_ptr->valid |= PNG_INFO_IDAT; // png_read_end(png_ptr, info_ptr); // return png_get_rows(png_ptr, info_ptr); }
bool PNGImage::read_png_file() { png_byte header[8]; // 8 is the maximum size that can be checked /* open file and test for it being a png */ fp = fopen(filename.c_str(), "rb"); if (!fp) return false; fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) return false; /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return false; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) return false; if (setjmp(png_jmpbuf(png_ptr))) return false; png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); res_x = png_get_image_width(png_ptr, info_ptr); res_y = png_get_image_height(png_ptr, info_ptr); png_byte color_type = png_get_color_type(png_ptr, info_ptr); png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr); int number_of_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) return false; img_pointer = (png_bytep*) malloc(sizeof(png_bytep) * res_y); for (int y=0; y < res_y; y++) img_pointer[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); png_read_image(png_ptr, img_pointer); switch(png_get_color_type(png_ptr, info_ptr)) { case PNG_COLOR_TYPE_RGB: cout << "RGB" << endl; break; case PNG_COLOR_TYPE_RGBA: cout << "RGBA" << endl; break; } return true; }
static void read_png(struct display *dp, struct buffer *bp, const char *operation, int transforms) { png_structp pp; png_infop ip; /* This cleans out any previous read and sets operation and transforms to * empty. */ display_clean_read(dp); if (operation != NULL) /* else this is a verify and do not overwrite info */ { dp->operation = operation; dp->transforms = transforms; } dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp, display_error, display_warning); if (pp == NULL) display_log(dp, LIBPNG_ERROR, "failed to create read struct"); /* The png_read_png API requires us to make the info struct, but it does the * call to png_read_info. */ dp->read_ip = ip = png_create_info_struct(pp); if (ip == NULL) display_log(dp, LIBPNG_ERROR, "failed to create info struct"); # ifdef PNG_SET_USER_LIMITS_SUPPORTED /* Remove the user limits, if any */ png_set_user_limits(pp, 0x7fffffff, 0x7fffffff); # endif /* Set the IO handling */ buffer_start_read(bp); png_set_read_fn(pp, bp, read_function); png_read_png(pp, ip, transforms, NULL/*params*/); #if 0 /* crazy debugging */ { png_bytep pr = png_get_rows(pp, ip)[0]; size_t rb = png_get_rowbytes(pp, ip); size_t cb; char c = ' '; fprintf(stderr, "%.4x %2d (%3lu bytes):", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb); for (cb=0; cb<rb; ++cb) fputc(c, stderr), fprintf(stderr, "%.2x", pr[cb]), c='.'; fputc('\n', stderr); } #endif }
int main(int argc, char **argv) { FILE *fin, *fout; if (argc < 3) { printf("Usage: vmuicon <icon.raw> <icon.c>\n"); exit(0); } fin = fopen(argv[1], "rb"); if (!fin) abort_("File %s could not be opened for reading", argv[1]); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("Failed to create PNG read struct\n"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("Failed to create PNG info struct\n"); if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fin); abort_("Error reading PNG\n"); } png_init_io(png_ptr, fin); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_INVERT_MONO | PNG_TRANSFORM_PACKSWAP, NULL); if ((png_get_image_width(png_ptr, info_ptr) != IMAGE_WIDTH) || (png_get_image_height(png_ptr, info_ptr) != IMAGE_HEIGHT)) abort_("Image is not %ix%i pixels\n", IMAGE_WIDTH, IMAGE_HEIGHT); if ((png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_GRAY) || (png_get_bit_depth(png_ptr, info_ptr) != 1)) abort_("Image is not a grayscale image with bit depth 1\n"); rows = png_get_rows(png_ptr, info_ptr); fout = fopen(argv[2], "w+"); if (!fout) abort_("File %s could not be opened for writing", argv[2]); write_data(fout); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fin); fclose(fout); return 0; }
// Read out the image meta-data void LLPngWrapper::updateMetaData() { png_set_interlace_handling(mReadPngPtr); // <alchemy/> png_read_update_info(mReadPngPtr, mReadInfoPtr); mWidth = png_get_image_width(mReadPngPtr, mReadInfoPtr); mHeight = png_get_image_height(mReadPngPtr, mReadInfoPtr); mBitDepth = png_get_bit_depth(mReadPngPtr, mReadInfoPtr); mColorType = png_get_color_type(mReadPngPtr, mReadInfoPtr); mChannels = png_get_channels(mReadPngPtr, mReadInfoPtr); }
void pngSetHeader(PngStream* stream) { stream->info.imageWidth = png_get_image_width(stream->png_ptr, stream->info_ptr); stream->info.imageHeight = png_get_image_height(stream->png_ptr, stream->info_ptr); stream->info.numComponents = png_get_channels(stream->png_ptr, stream->info_ptr); stream->info.colorSpace = getPngDecColourType(png_get_color_type(stream->png_ptr, stream->info_ptr)); stream->info.bitDepth = png_get_bit_depth(stream->png_ptr, stream->info_ptr); stream->info.interlaceMethod = png_get_interlace_type(stream->png_ptr, stream->info_ptr); stream->info.chunkInformation = pngDecGetChunkInformation(stream); }
// Read out the image meta-data void LLPngWrapper::updateMetaData() { png_read_update_info(mReadPngPtr, mReadInfoPtr); mWidth = png_get_image_width(mReadPngPtr, mReadInfoPtr); mHeight = png_get_image_height(mReadPngPtr, mReadInfoPtr); mBitDepth = png_get_bit_depth(mReadPngPtr, mReadInfoPtr); mColorType = png_get_color_type(mReadPngPtr, mReadInfoPtr); mChannels = png_get_channels(mReadPngPtr, mReadInfoPtr); mHasBKGD = png_get_bKGD(mReadPngPtr, mReadInfoPtr, &mBackgroundColor); }
PngImage::PngImage(const ByteBuffer &compressed_bytes) { if (png_sig_cmp((png_bytep)compressed_bytes.raw(), 0, 8)) panic("not png file"); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) panic("unable to create png read struct"); png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) panic("unable to create png info struct"); // don't call any png_* functions outside of this function D: if (setjmp(png_jmpbuf(png_ptr))) panic("libpng has jumped the shark"); png_set_sig_bytes(png_ptr, 8); PngIo png_io = {8, (unsigned char *)compressed_bytes.raw(), compressed_bytes.length()}; png_set_read_fn(png_ptr, &png_io, read_png_data); png_read_info(png_ptr, info_ptr); _width = png_get_image_width(png_ptr, info_ptr); _height = png_get_image_height(png_ptr, info_ptr); if (_width <= 0 || _height <= 0) panic("spritesheet image has no pixels"); // bits per channel (not per pixel) int bits_per_channel = png_get_bit_depth(png_ptr, info_ptr); if (bits_per_channel != 8) panic("expected 8 bits per channel"); int channel_count = png_get_channels(png_ptr, info_ptr); if (channel_count != 4) panic("expected 4 channels"); int color_type = png_get_color_type(png_ptr, info_ptr); if (color_type != PNG_COLOR_TYPE_RGBA) panic("expected RGBA"); _pitch = _width * bits_per_channel * channel_count / 8; _image_data.resize(_height * _pitch); png_bytep *row_ptrs = ok_mem(allocate_zero<png_bytep>(_height)); for (int i = 0; i < _height; i++) { png_uint_32 q = (_height - i - 1) * _pitch; row_ptrs[i] = (png_bytep)_image_data.raw() + q; } png_read_image(png_ptr, row_ptrs); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); destroy(row_ptrs, _height); }
static void nspng_setup_transforms(png_structp png_ptr, png_infop info_ptr) { int bit_depth, color_type; #if 0 int intent; double gamma; #endif bit_depth = png_get_bit_depth(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); /* Set up our transformations */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); } if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8)) { png_set_expand_gray_1_2_4_to_8(png_ptr); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(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); } if (!(color_type & PNG_COLOR_MASK_ALPHA)) { png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); } #if 0 /* gamma correction - we use 2.2 as our screen gamma * this appears to be correct (at least in respect to !Browse) * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case */ if (png_get_sRGB(png_ptr, info_ptr, &intent)) { png_set_gamma(png_ptr, 2.2, 0.45455); } else { if (png_get_gAMA(png_ptr, info_ptr, &gamma)) { png_set_gamma(png_ptr, 2.2, gamma); } else { png_set_gamma(png_ptr, 2.2, 0.45455); } } #endif png_read_update_info(png_ptr, info_ptr); }
bool png_validate_file_and_query_size(size_t *img_width, size_t *img_height, const char *file_name) { bool ret = true; size_t width = -1; size_t height = -1; png_byte color_type; png_byte bit_depth; png_structp png_ptr; png_infop info_ptr; unsigned char header[8]; // 8 is the maximum size that can be checked FILE *fp = fopen(file_name, "rb"); if (!fp) abort_("[read_png_file] File %s could not be opened for reading", file_name); 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", file_name); /* 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); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); if (color_type != PNG_COLOR_TYPE_RGB || bit_depth != 8) ret = false; png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); *img_width = width; *img_height = height; return ret; }
GrfArray* grf_image_read_png(const char* filename){ png_structp png_ptr; png_infop info_ptr; unsigned char header[8]; FILE* infile = fopen(filename, "rb"); if(!infile) abort_("[read_png_file] File %s could not be opened for reading", filename); fread(header, 1, 8, infile); if(png_sig_cmp(header, 0, 8)) abort_("[read_png_file] File %s is not recognized as a PNG file", filename); 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, infile); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); uint32_t* size = malloc(sizeof(uint32_t) * 3); size[0] = png_get_image_height(png_ptr, info_ptr); size[1] = png_get_image_width(png_ptr, info_ptr); size[2] = png_get_channels(png_ptr, info_ptr); uint8_t bit_depth = png_get_bit_depth(png_ptr, info_ptr); GrfDataType type; switch (bit_depth) { case 16: type = GRF_UINT16; break; default: type = GRF_UINT8; break; } GrfArray* array = grf_array_new_with_size_type(3, size, type); png_read_update_info(png_ptr, info_ptr); // Read file if(setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image"); uint8_t**buffer = (uint8_t**)malloc(sizeof(uint8_t*) * size[0]); size_t row_stride = png_get_rowbytes(png_ptr, info_ptr); uint32_t i; for(i = 0; i < size[0]; i++) buffer[i] = array->data_uint8 + row_stride * i; png_read_image(png_ptr, buffer); fclose(infile); free(buffer); return array; }
void haveRow(unsigned int rowNum, int pass, unsigned char* data) { if (interlaced) { png_byte pngDepth = png_get_bit_depth(pngReadStruct, pngInfoStruct); Q_ASSERT(pngDepth <= depth * 8); requestScanline(rowNum, scanlineBuf); png_progressive_combine_row(pngReadStruct, scanlineBuf, data); notifyScanline(pass + 1, scanlineBuf); } else notifyScanline(pass + 1, data); }
/* * Analyze the usage of samples. * The output value usage_map[n] indicates whether the sample n * is used. The usage_map[] array must have 256 entries. * The function requires a valid bit depth between 1 and 8. */ static void opng_analyze_sample_usage(png_structp png_ptr, png_infop info_ptr, png_bytep usage_map) { png_bytep sample_ptr; int init_shift, init_mask, shift, mask; png_uint_32 i, j; png_uint_32 height = png_get_image_height(png_ptr, info_ptr); png_uint_32 width = png_get_image_width(png_ptr, info_ptr); int bit_depth = png_get_bit_depth(png_ptr, info_ptr); png_bytepp row_ptr = png_get_rows(png_ptr, info_ptr); /* Initialize the output entries with 0. */ memset(usage_map, 0, 256); /* Iterate through all sample values. */ if (bit_depth == 8) { for (i = 0; i < height; ++i, ++row_ptr) { for (j = 0, sample_ptr = *row_ptr; j < width; ++j, ++sample_ptr) usage_map[*sample_ptr] = 1; } } else { OPNG_ASSERT(bit_depth < 8); init_shift = 8 - bit_depth; init_mask = (1 << 8) - (1 << init_shift); for (i = 0; i < height; ++i, ++row_ptr) { for (j = 0, sample_ptr = *row_ptr; j < width; ++sample_ptr) { mask = init_mask; shift = init_shift; do { usage_map[(*sample_ptr & mask) >> shift] = 1; mask >>= bit_depth; shift -= bit_depth; ++j; } while (mask > 0 && j < width); } } } #ifdef PNG_bKGD_SUPPORTED png_color_16p background; /* bKGD also counts as a used sample. */ if (png_get_bKGD(png_ptr, info_ptr, &background)) usage_map[background->index] = 1; #endif }
static void loadpng(const char name[], u8 **outdata, u32 *w, u32 *h) { FILE *f = fopen(name, "r"); if (!f) die("Can't open file\n"); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (!png_ptr) die("PNG error\n"); png_infop info = png_create_info_struct(png_ptr); if (!info) die("PNG error\n"); if (setjmp(png_jmpbuf(png_ptr))) die("PNG error\n"); png_init_io(png_ptr, f); png_read_png(png_ptr, info, PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_STRIP_ALPHA, NULL); u8 **rows = png_get_rows(png_ptr, info); const u32 imgw = png_get_image_width(png_ptr, info); const u32 imgh = png_get_image_height(png_ptr, info); const u8 type = png_get_color_type(png_ptr, info); const u8 depth = png_get_bit_depth(png_ptr, info); if (imgw % 8 != 0 || imgh % 8 != 0) die("Image is not divisible by 8\n"); if (type != PNG_COLOR_TYPE_PALETTE) die("Input must be a paletted PNG, got %u\n", type); if (depth != 8) die("Depth not 8 (%u) - maybe you have old libpng?\n", depth); const u32 rowbytes = png_get_rowbytes(png_ptr, info); if (rowbytes != imgw) die("Packing failed, row was %u instead of %u\n", rowbytes, imgw); u8 * const data = calloc(imgw, imgh); u32 i; for (i = 0; i < imgh; i++) { u8 * const target = data + imgw * i; memcpy(target, &rows[i][0], imgw); } fclose(f); png_destroy_info_struct(png_ptr, &info); png_destroy_read_struct(&png_ptr, NULL, NULL); *outdata = data; *w = imgw; *h = imgh; }
void CL_PNGProvider_Generic::read_data_grayscale_alpha() { format.set_type(pixelformat_rgba); format.set_red_mask(0xff000000); format.set_green_mask(0x00ff0000); format.set_blue_mask(0x0000ff00); format.set_alpha_mask(0x000000ff); format.set_depth(32); pitch = width * 4; int bit_depth = png_get_bit_depth(png_ptr,info_ptr); int rowbytes = png_get_rowbytes(png_ptr, info_ptr); // We expand the grayscale values if necessare, so we always // get 8bits per pixel if (bit_depth < 8) png_set_expand (png_ptr); // Allocating the temporary buffer unsigned char* tmp_image = new unsigned char[height * rowbytes]; png_bytep* row_pointers = new png_bytep[height]; { for (int y = 0; y < height; y++) row_pointers[y] = tmp_image + (rowbytes * y); } png_read_image(png_ptr, row_pointers); delete[] row_pointers; // Creating the final image out of tmp_image image = new unsigned char[pitch * height]; for (int i = 0; i < rowbytes * height; i += 2) { if (!CL_Endian::is_system_big()) { image[2*i + 0] = tmp_image[i + 1]; image[2*i + 3] = tmp_image[i + 0]; } else { image[2*i + 0] = tmp_image[i + 0]; image[2*i + 3] = tmp_image[i + 1]; } image[2*i + 1] = tmp_image[i + 0]; image[2*i + 2] = tmp_image[i + 0]; } delete[] tmp_image; }
static int loadPNGDecode(unsigned char **pixels, int *width, int *height, int flags, png_structp png_ptr, png_infop info_ptr, png_infop end_info, const char *callerStr) { // get header info png_read_info(png_ptr, info_ptr); *width = png_get_image_width(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); int color_type = png_get_color_type(png_ptr, info_ptr); int bit_depth = png_get_bit_depth(png_ptr, info_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8) 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); // decode if (pixels) { if (!(flags & PNG_NO_ALLOC)) *pixels = (unsigned char*)malloc(3 * (*width) * (*height) * sizeof(unsigned char)); unsigned char **row_pointers = (unsigned char **)malloc(2 * (*height) * sizeof(unsigned char*)); if ((*pixels == NULL) || (row_pointers == NULL)) { cprintf("%s: memory allocation error\n", callerStr); if ((!(flags & PNG_NO_ALLOC)) && (*pixels)) free(*pixels); if (row_pointers) free(row_pointers); return -1; } int i; for (i = 0; i < 2 * (*height); i++) { row_pointers[i] = *pixels; } for (i = 0; i < *height; i++) { row_pointers[i] = (*pixels) + (i) * (*width) * 3; } png_read_image(png_ptr, row_pointers); free(row_pointers); png_read_end(png_ptr, end_info); } return 0; }
/* * Check if the image information is valid. * The image information is said to be valid if all the required * critical chunk data is present in the png structures. * The function returns 1 if this information is valid, and 0 otherwise. */ int PNGAPI opng_validate_image(png_structp png_ptr, png_infop info_ptr) { /* Validate IHDR. */ if (!png_get_bit_depth(png_ptr, info_ptr)) return 0; /* Validate PLTE. */ if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_PALETTE) { if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) return 0; } /* Validate IDAT. */ if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_IDAT)) return 0; return 1; }
static void readsrc(const char in[]) { FILE *f = fopen(in, "r"); if (!f) die("Can't open %s\n", in); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (!png_ptr) die("PNG error\n"); png_infop info = png_create_info_struct(png_ptr); if (!info) die("PNG error\n"); if (setjmp(png_jmpbuf(png_ptr))) die("PNG error\n"); png_init_io(png_ptr, f); png_read_png(png_ptr, info, PNG_TRANSFORM_PACKING|PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_STRIP_ALPHA, NULL); const u8 type = png_get_color_type(png_ptr, info); if (type != PNG_COLOR_TYPE_PALETTE) die("Input must be a paletted PNG, got %u\n", type); const u8 depth = png_get_bit_depth(png_ptr, info); if (depth != 8) die("Depth not 8 (%u) - maybe you have old libpng?\n", depth); png_color *ptr; int num; png_get_PLTE(png_ptr, info, &ptr, &num); printf("Source: %u colors\n", num); memset(srcpal, 0, sizeof(png_color) * 16); u8 i; const u8 max = num < 16 ? num : 16; for (i = 0; i < max; i++) { memcpy(&srcpal[i], &ptr[i], sizeof(png_color)); } fclose(f); png_destroy_info_struct(png_ptr, &info); png_destroy_read_struct(&png_ptr, NULL, NULL); }
/* Given PNG-formatted data at bd, read the data into a buffer that we allocate * and return (row_pointers, here). * * Note: caller must free the returned value. */ png_bytep* read_png_file(png_structp png_ptr, png_infop * info_ptr, struct bufdata * bd) { int y; int height; png_byte bit_depth; png_bytep * row_pointers; if (png_sig_cmp(bd->buf, 0, 8)) abort_("[read_png_file] Input is not recognized as a PNG file"); *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"); bd->pos = 0; png_set_read_fn(png_ptr, bd, read_cb); png_read_info(png_ptr, *info_ptr); height = png_get_image_height(png_ptr, *info_ptr); bit_depth = png_get_bit_depth(png_ptr, *info_ptr); if (bit_depth != 8) abort_("[read_png_file] bit depth 16 PNG files unsupported"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image"); row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * BUF_HEIGHT); for (y=0; y<height; y++) row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr, *info_ptr)); png_read_image(png_ptr, row_pointers); return row_pointers; }
/* 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); }
PixelFormat PngFormat(png_structp png_ptr, png_infop info_ptr ) { const png_byte colour = png_get_color_type(png_ptr, info_ptr); const png_byte depth = png_get_bit_depth(png_ptr, info_ptr); if( depth == 8 ) { if( colour == PNG_COLOR_MASK_COLOR ) { return PixelFormatFromString("RGB24"); } else if( colour == (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) ) { return PixelFormatFromString("RGBA32"); } else if( colour == PNG_COLOR_MASK_ALPHA ) { return PixelFormatFromString("Y400A"); } else { return PixelFormatFromString("GRAY8"); } }else if( depth == 16 ) { if( colour == 0 ) { return PixelFormatFromString("GRAY16LE"); } } throw std::runtime_error("Unsupported PNG format"); }