int image_png_read_header(MediaScanImage *i, MediaScanResult *r) { int x; PNGData *p = malloc(sizeof(PNGData)); i->_png = (void *)p; LOG_MEM("new PNGData @ %p\n", i->_png); p->buf = (Buffer *)r->_buf; p->fp = r->_fp; p->path = r->path; p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) p, image_png_error, image_png_warning); if (!p->png_ptr) FATAL("Could not initialize libpng\n"); p->info_ptr = png_create_info_struct(p->png_ptr); if (!p->info_ptr) { png_destroy_read_struct(&p->png_ptr, (png_infopp) NULL, (png_infopp) NULL); FATAL("Could not initialize libpng\n"); } if (setjmp(png_jmpbuf(p->png_ptr))) { image_png_destroy(i); return 0; } png_set_read_fn(p->png_ptr, p, image_png_read_buf); png_read_info(p->png_ptr, p->info_ptr); i->width = png_get_image_width(p->png_ptr, p->info_ptr); i->height = png_get_image_height(p->png_ptr, p->info_ptr); i->channels = png_get_channels(p->png_ptr, p->info_ptr); i->has_alpha = 1; r->mime_type = MIME_IMAGE_PNG; // Match with DLNA profile // DLNA does not support interlaced images if (png_get_interlace_type(p->png_ptr, p->info_ptr) == PNG_INTERLACE_NONE) { for (x = 0; png_profiles_mapping[x].profile; x++) { if (i->width <= png_profiles_mapping[x].max_width && i->height <= png_profiles_mapping[x].max_height) { r->dlna_profile = png_profiles_mapping[x].profile->id; break; } } } return 1; }
int PngSize( FILE * fd, long *width, long *height) { png_structp png_read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, /* we would need to point to error handlers here to do it properly */ (png_error_ptr) NULL, (png_error_ptr) NULL); png_infop info_ptr = png_create_info_struct(png_read_ptr); (*width) = 0; (*height) = 0; /* this is to make compile on aix work since they seem to define jmpbuf to be _jmpbuf which breaks compilation */ #ifndef png_jmpbuf #ifdef PNG_SETJMP_SUPPORTED # define png_jmpbuf(png_ptr) ((png_ptr)->PNG_jmpbuf) #else #ifdef jmpbuf #undef jmpbuf #endif # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif #endif if (setjmp(png_jmpbuf(png_read_ptr))) { png_destroy_read_struct(&png_read_ptr, &info_ptr, (png_infopp) NULL); return 0; } png_init_io(png_read_ptr, fd); png_read_info(png_read_ptr, info_ptr); (*width) = png_get_image_width(png_read_ptr, info_ptr); (*height) = png_get_image_height(png_read_ptr, info_ptr); png_destroy_read_struct(&png_read_ptr, &info_ptr, NULL); if (*width > 0 && *height > 0) return 1; else return 0; }
int oil_libpng_init(struct oil_libpng *ol, png_structp rpng, png_infop rinfo, int out_width, int out_height) { int ret, in_width, in_height, buf_len; enum oil_colorspace cs; ol->rpng = rpng; ol->rinfo = rinfo; ol->in_vpos = 0; ol->inbuf = NULL; ol->inimage = NULL; cs = png_cs_to_oil(png_get_color_type(rpng, rinfo)); if (cs == OIL_CS_UNKNOWN) { return -1; } in_width = png_get_image_width(rpng, rinfo); in_height = png_get_image_height(rpng, rinfo); ret = oil_scale_init(&ol->os, in_height, out_height, in_width, out_width, cs); if (ret!=0) { free(ol->inbuf); return ret; } buf_len = png_get_rowbytes(rpng, rinfo); switch (png_get_interlace_type(rpng, rinfo)) { case PNG_INTERLACE_NONE: ol->inbuf = malloc(buf_len); if (!ol->inbuf) { oil_scale_free(&ol->os); return -2; } break; case PNG_INTERLACE_ADAM7: ol->inimage = alloc_full_image_buf(in_height, buf_len); if (!ol->inimage) { oil_scale_free(&ol->os); return -2; } png_read_image(rpng, ol->inimage); break; } return 0; }
static void readPng(gambatte::uint_least32_t *const out, const char *const filename) { const struct PngContext { png_structp png; png_infop info; png_infop endinfo; PngContext() : png(png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0)), info(png ? png_create_info_struct(png) : 0), endinfo(png ? png_create_info_struct(png) : 0) { assert(png); assert(info); assert(endinfo); } ~PngContext() { png_destroy_read_struct(&png, &info, &endinfo); } } pngCtx; const struct FileCtx { std::FILE *f; FileCtx(const char *filename) : f(std::fopen(filename, "rb")) { assert(f); } ~FileCtx() { std::fclose(f); } } fileCtx(filename); if (setjmp(png_jmpbuf(pngCtx.png))) std::abort(); png_init_io(pngCtx.png, fileCtx.f); png_read_png(pngCtx.png, pngCtx.info, 0, 0); assert(png_get_image_height(pngCtx.png, pngCtx.info) == 144); assert(png_get_rowbytes(pngCtx.png, pngCtx.info) == 160 * 4); png_bytep *const rows = png_get_rows(pngCtx.png, pngCtx.info); for (std::size_t y = 0; y < 144; ++y) for (std::size_t x = 0; x < 160; ++x) out[y * 160 + x] = rows[y][x * 4] << 16 | rows[y][x * 4 + 1] << 8 | rows[y][x * 4 + 2]; }
Texture* TextureReader::read() { verifySignature(reader); initialisePNGReader(reader); const unsigned char* data = readImageData(); const unsigned int width = png_get_image_width(_png, _pngInfo); const unsigned int height = png_get_image_height(_png, _pngInfo); _data = (GLubyte*)data; Texture* texture = new Texture(_data, width, height, 0); texture->setData(data); delete[] data; png_destroy_read_struct(&_png, &_pngInfo, NULL); return texture; }
int png_load_hdr(img I) { unsigned char sig[PNG_SIG_LEN]; png_structp png_ptr; png_infop info_ptr; rewind(I->fp); if (fread(sig, sizeof(sig[0]), PNG_SIG_LEN, I->fp) != PNG_SIG_LEN) { return(0); } /* Check the PNG signature of the file */ if (png_sig_cmp(sig, (png_size_t)0, PNG_SIG_LEN)) { I->err = IE_HDRFORMAT; return 0; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { I->err = IE_HDRFORMAT; return 0; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); I->err = IE_HDRFORMAT; return 0; } rewind(I->fp); png_init_io(png_ptr, I->fp); png_read_info(png_ptr, info_ptr); I->width = png_get_image_width(png_ptr, info_ptr); I->height = png_get_image_height(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return(1); }
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; }
int svlImageCodecPNG::ReadDimensions(std::istream &stream, unsigned int &width, unsigned int &height) { // check file for signature png_byte pngsig[PNG_SIG_SIZE]; if (stream.read(reinterpret_cast<char*>(pngsig), PNG_SIG_SIZE).fail() || png_sig_cmp(pngsig, 0, PNG_SIG_SIZE) != 0) { return SVL_FAIL; } // create read structure png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (png_ptr == 0) return SVL_FAIL; // create info structure png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == 0) { png_destroy_read_struct(&png_ptr, reinterpret_cast<png_infopp>(0), reinterpret_cast<png_infopp>(0)); return SVL_FAIL; } width = 0; height = 0; // setup error handling if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, reinterpret_cast<png_infopp>(0)); return SVL_OK; } PNG_source_stream source; source.stream = &stream; source.error = false; png_set_read_fn(png_ptr, &source, PNG_read_data_stream); png_set_sig_bytes(png_ptr, PNG_SIG_SIZE); png_read_info(png_ptr, info_ptr); // check file header width = static_cast<unsigned int>(png_get_image_width(png_ptr, info_ptr)); height = static_cast<unsigned int>(png_get_image_height(png_ptr, info_ptr)); // clean up png_destroy_read_struct(&png_ptr, &info_ptr,reinterpret_cast<png_infopp>(0)); return SVL_OK; }
/* read the png image to fill row_pointers */ int read_png(FILE *fp, png_bytep **row_pointers, png_uint_32 *width, png_uint_32 *height) { png_structp png_ptr; png_infop info_ptr; png_uint_32 color_type; unsigned char header[PNG_HEADER_SIZE]; /* check if it's a png file */ size_t bytes_read = fread(header, sizeof(unsigned char), PNG_HEADER_SIZE, fp); if (ferror(fp) || (bytes_read != PNG_HEADER_SIZE)) { return 0; } if (png_sig_cmp(header, 0, PNG_HEADER_SIZE) != 0) { return 0; } /* initialize libpng stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, PNG_HEADER_SIZE); // because of the check above png_read_info(png_ptr, info_ptr); *height = png_get_image_height(png_ptr, info_ptr); *width = png_get_image_width(png_ptr, info_ptr); *row_pointers = png_malloc(png_ptr, *height*sizeof(png_bytep)); for (int i=0; i<*height; i++) { (*row_pointers)[i] = png_malloc(png_ptr, *width*PIXEL_SIZE); } png_set_rows(png_ptr, info_ptr, *row_pointers); color_type = png_get_color_type(png_ptr, info_ptr); /* we don't need alpha channel */ if (color_type & PNG_COLOR_MASK_ALPHA) { png_set_strip_alpha(png_ptr); } png_read_update_info(png_ptr, info_ptr); /* and ... finally read the image */ png_read_image(png_ptr, *row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 1; }
int png_get_bbox (FILE *png_file, uint32_t *width, uint32_t *height, double *xdensity, double *ydensity) { png_structp png_ptr; png_infop png_info_ptr; rewind (png_file); png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, warn); if (png_ptr == NULL || (png_info_ptr = png_create_info_struct (png_ptr)) == NULL) { WARN("%s: Creating Libpng read/info struct failed.", PNG_DEBUG_STR); if (png_ptr) png_destroy_read_struct(&png_ptr, NULL, NULL); return -1; } /* Inititializing file IO. */ png_init_io (png_ptr, png_file); /* Read PNG info-header and get some info. */ png_read_info(png_ptr, png_info_ptr); *width = png_get_image_width (png_ptr, png_info_ptr); *height = png_get_image_height(png_ptr, png_info_ptr); if (compat_mode) *xdensity = *ydensity = 72.0 / 100.0; else { png_uint_32 xppm = png_get_x_pixels_per_meter(png_ptr, png_info_ptr); png_uint_32 yppm = png_get_y_pixels_per_meter(png_ptr, png_info_ptr); *xdensity = xppm ? 72.0 / 0.0254 / xppm : 1.0; *ydensity = yppm ? 72.0 / 0.0254 / yppm : 1.0; } /* Cleanup */ if (png_info_ptr) png_destroy_info_struct(png_ptr, &png_info_ptr); if (png_ptr) png_destroy_read_struct(&png_ptr, NULL, NULL); return 0; }
int svlImageCodecPNG::ReadDimensions(const unsigned char *buffer, const size_t buffersize, unsigned int &width, unsigned int &height) { if (!buffer || buffersize < static_cast<unsigned int>(PNG_SIG_SIZE)) return SVL_FAIL; // check file for signature if (png_sig_cmp(const_cast<unsigned char*>(buffer), 0, PNG_SIG_SIZE) != 0) return SVL_FAIL; // create read structure png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (png_ptr == 0) return SVL_FAIL; // create info structure png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == 0) { png_destroy_read_struct(&png_ptr, reinterpret_cast<png_infopp>(0), reinterpret_cast<png_infopp>(0)); return SVL_FAIL; } width = 0; height = 0; // setup error handling if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, reinterpret_cast<png_infopp>(0)); return SVL_OK; } _PNG_source_memory source; source.buffer = const_cast<unsigned char*>(buffer + PNG_SIG_SIZE); source.buffersize = static_cast<unsigned int>(buffersize - PNG_SIG_SIZE); source.error = false; png_set_read_fn(png_ptr, &source, PNG_read_data_memory); png_set_sig_bytes(png_ptr, PNG_SIG_SIZE); png_read_info(png_ptr, info_ptr); // check file header width = static_cast<unsigned int>(png_get_image_width(png_ptr, info_ptr)); height = static_cast<unsigned int>(png_get_image_height(png_ptr, info_ptr)); // clean up png_destroy_read_struct(&png_ptr, &info_ptr,reinterpret_cast<png_infopp>(0)); return SVL_OK; }
static int getSizePng(const char *file, unsigned int *width, unsigned int *height) { FILE *fp = fopen(file, "rb"); if(!fp){ printf("Couldn't open file: %s\n", file); return false; } unsigned char header[8]; fread(header, 1, sizeof(header), fp); if(png_sig_cmp(header, 0, sizeof(header))){ printf("File supplied is not a valid PNG: %s\n", file); return false; } png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png){ return false; } png_infop info = png_create_info_struct(png); if(!info){ png_destroy_read_struct(&png, NULL, NULL); fclose(fp); return false; } if(setjmp(png_jmpbuf(png))){ png_destroy_read_struct(&png, &info, NULL); fclose(fp); return false; } png_init_io(png, fp); png_set_sig_bytes(png, sizeof(header)); png_read_info(png, info); *width = png_get_image_width(png, info); *height = png_get_image_height(png, info); return true; }
unsigned char* TextureReader::readImageData() { const int transforms = PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16; png_read_png(_png, _pngInfo, transforms, NULL); const unsigned int height = png_get_image_height(_png, _pngInfo); const unsigned int rowSize = png_get_rowbytes(_png, _pngInfo); unsigned char* data = new unsigned char[height * rowSize]; unsigned char* row = data; unsigned char** rows = png_get_rows(_png, _pngInfo); for(unsigned int i = height - 1u; i != UINT32_MAX; --i) { std::copy(rows[i], rows[i] + rowSize, row); row += rowSize; } return data; }
static HPDF_STATUS ReadPngData_Interlaced (HPDF_Dict image, png_structp png_ptr, png_infop info_ptr) { png_uint_32 len = png_get_rowbytes(png_ptr, info_ptr); png_uint_32 height = png_get_image_height(png_ptr, info_ptr); png_bytep* row_pointers = HPDF_GetMem (image->mmgr, height * sizeof (png_bytep)); if (row_pointers) { HPDF_UINT i; HPDF_MemSet (row_pointers, 0, height * sizeof (png_bytep)); for (i = 0; i < (HPDF_UINT)height; i++) { row_pointers[i] = HPDF_GetMem (image->mmgr, len); if (image->error->error_no != HPDF_OK) break; } if (image->error->error_no == HPDF_OK) { png_read_image(png_ptr, row_pointers); if (image->error->error_no == HPDF_OK) { /* add this line */ for (i = 0; i < (HPDF_UINT)height; i++) { if (HPDF_Stream_Write (image->stream, row_pointers[i], len) != HPDF_OK) break; } } } /* clean up */ for (i = 0; i < (HPDF_UINT)height; i++) { HPDF_FreeMem (image->mmgr, row_pointers[i]); } HPDF_FreeMem (image->mmgr, row_pointers); } return image->error->error_no; }
struct image *png_open(FILE *f){ struct png_t *p; rewind(f); if(!ispng(f)) return NULL; p = malloc(sizeof(struct png_t)); if((p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL){ free(p); return NULL; } if((p->info_ptr = png_create_info_struct(p->png_ptr)) == NULL){ png_destroy_read_struct(&p->png_ptr, (png_infopp)NULL, (png_infopp)NULL); free(p); return NULL; } if((p->end_info = png_create_info_struct(p->png_ptr)) == NULL){ png_destroy_read_struct(&p->png_ptr, &p->info_ptr, (png_infopp)NULL); free(p); return NULL; } if(setjmp(png_jmpbuf(p->png_ptr))){ png_destroy_read_struct(&p->png_ptr, &p->info_ptr, &p->end_info); free(p); return NULL; } p->f = f; rewind(f); png_init_io(p->png_ptr, f); png_read_info(p->png_ptr, p->info_ptr); p->img.bufwidth = png_get_image_width(p->png_ptr, p->info_ptr); p->img.bufheight = png_get_image_height(p->png_ptr, p->info_ptr); p->img.fmt = &libpng; return (struct image *)p; }
void GL::Image::load(const unsigned char *buf, size_t bufSize) { GLBufferReader reader((const uint8_t*)buf, bufSize); png_byte sig[8]; if (reader.read(sig, sizeof(sig)) == sizeof(sig)) { if (png_sig_cmp(sig, 0, sizeof(sig)) == 0) { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png_ptr); png_infop end_info = png_create_info_struct(png_ptr); if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } png_set_sig_bytes(png_ptr, sizeof(sig)); png_set_read_fn(png_ptr, &reader, pngReader); png_read_info(png_ptr, info_ptr); // color type should be PNG_COLOR_TYPE_PALETTE width_ = png_get_image_width(png_ptr, info_ptr); height_ = png_get_image_height(png_ptr, info_ptr); png_set_expand(png_ptr); png_set_bgr(png_ptr); // for BGR for OpenGL texture png_read_update_info(png_ptr, info_ptr); png_byte color_type = png_get_color_type(png_ptr, info_ptr); png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); png_byte *image_data = new png_byte[rowbytes * height_]; png_bytep row_pointers[height_]; for (int y = 0; y < height_; ++y) { row_pointers[y] = image_data + (y * rowbytes); } png_read_image(png_ptr, row_pointers); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); loadTextureData_(image_data, color_type == PNG_COLOR_TYPE_RGB_ALPHA); delete[] image_data; } } }
static VALUE write_png2(VALUE *args) { struct io_write *data; png_structp png_ptr = (png_structp)args[0]; png_infop info_ptr = (png_infop)args[1]; VALUE scanline, image_in = args[2]; size_t i; write_configure(image_in, png_ptr, info_ptr); png_write_info(png_ptr, info_ptr); for (i = 0; i < png_get_image_height(png_ptr, info_ptr); i++) { scanline = rb_funcall(image_in, id_gets, 0); write_scanline(scanline, png_ptr, info_ptr); } png_write_end(png_ptr, info_ptr); data = (struct io_write *)png_get_io_ptr(png_ptr); return INT2FIX(data->total); }
png_bytep delete_alpha(png_structp* png_ptr, png_infop* info_ptr, png_bytep pixeldata) { png_bytep dataBlock; png_uint_32 height, width; height = png_get_image_height(*png_ptr, *info_ptr); width = png_get_image_width(*png_ptr, *info_ptr); dataBlock = (png_bytep)malloc(sizeof(png_bytep)*width*height*3); for(png_uint_32 i = 0; i<height; i++) { for(png_uint_32 j = 0; j<width; j++) { *(dataBlock + i*width*3 + j*3) = *(pixeldata + i*width*4 + j*4); *(dataBlock + i*width*3 + j*3 + 1) = *(pixeldata + i*width*4 + j*4 + 1); *(dataBlock + i*width*3 + j*3 + 2) = *(pixeldata + i*width*4 + j*4 + 2); } } return dataBlock; }
QVariant QPngHandler::option(ImageOption option) const { if (d->state == QPngHandlerPrivate::Error) return QVariant(); if (d->state == QPngHandlerPrivate::Ready && !d->readPngHeader()) return QVariant(); if (option == Gamma) return d->gamma == 0.0 ? d->fileGamma : d->gamma; else if (option == Quality) return d->quality; else if (option == Description) return d->description; else if (option == Size) return QSize(png_get_image_width(d->png_ptr, d->info_ptr), png_get_image_height(d->png_ptr, d->info_ptr)); else if (option == ScaledSize) return d->scaledSize; else if (option == ImageFormat) return d->readImageFormat(); return QVariant(); }
/* 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); }
void CL_PNGProvider_Generic::read_data() { // initial fileinfo png_read_info(png_ptr, info_ptr); // reduce 16bit/channel to 8Bit/channel png_set_strip_16(png_ptr); // reread infostruct to reflect the made settings 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); color_type = png_get_color_type(png_ptr,info_ptr); switch (color_type) { case PNG_COLOR_TYPE_GRAY: read_data_grayscale (); break; case PNG_COLOR_TYPE_GRAY_ALPHA: read_data_grayscale_alpha (); break; case PNG_COLOR_TYPE_PALETTE: read_data_palette (); break; case PNG_COLOR_TYPE_RGB: read_data_rgb (); break; case PNG_COLOR_TYPE_RGB_ALPHA: read_data_rgba (); break; default: throw CL_Error ("CL_PNGProvider_Generic: Unsupported PNG format!"); break; } }
/* 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; }
int Graph_GetPNGSize( const char *filepath, int *width, int *height ) { #ifdef USE_LIBPNG int ret; png_infop info_ptr; png_structp png_ptr; char buf[PNG_BYTES_TO_CHECK]; FILE *fp = fopen( filepath, "rb" ); if( !fp ) { return FILE_ERROR_OPEN_ERROR; } 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 ) ); ret = fread( buf, 1, PNG_BYTES_TO_CHECK, fp ); if( ret < PNG_BYTES_TO_CHECK ) { fclose( fp ); png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); return FILE_ERROR_UNKNOWN_FORMAT; } ret = png_sig_cmp( (png_bytep)buf, (png_size_t)0, PNG_BYTES_TO_CHECK ); if( ret != 0 ) { fclose( fp ); png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); return FILE_ERROR_UNKNOWN_FORMAT; } rewind( fp ); png_init_io( png_ptr, fp ); png_read_png( png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0 ); *width = png_get_image_width( png_ptr, info_ptr ); *height = png_get_image_height( png_ptr, info_ptr ); fclose( fp ); png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); #else _DEBUG_MSG( "warning: not PNG support!" ); #endif return ret; }
static void pngToPixels(png_structp png, png_infop info, Pixel** pixels, int* width, int* height) { const int w = png_get_image_width(png, info); const int h = png_get_image_height(png, info); const int channels = png_get_channels(png, info); Pixel* const px = malloc(w * h * sizeof(Pixel)); png_bytepp rows = png_get_rows(png, info); for(int i = 0; i < h; i++) { for(int j = 0; j < w; j++) { *(px + i * w + j) = a_pixel_make( rows[i][j * channels + 0], rows[i][j * channels + 1], rows[i][j * channels + 2] ); } } *width = w; *height = h; *pixels = px; }
void print_image(png_structp png_ptr, png_infop info_ptr) { long int width, height; png_bytepp row_pointers; int x,y; /* Get information about image. */ width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); printf("%ld x %ld \n", width, height); /* Retrieves the image data. */ row_pointers = png_get_rows(png_ptr, info_ptr); for (y=0; y<height; y++) { png_byte* row = row_pointers[y]; for (x=0; x<width; x++) { png_byte* ptr = &(row[x*4]); printf("Pixel at position [ %d - %d ] has RGBA values: %d - %d - %d - %d\n", x, y, ptr[0], ptr[1], ptr[2], ptr[3]); } } }
static void pngToPixels(png_structp Png, png_infop Info, APixel** Pixels, int* Width, int* Height) { const int w = png_get_image_width(Png, Info); const int h = png_get_image_height(Png, Info); const int channels = png_get_channels(Png, Info); APixel* const px = a_mem_malloc(w * h * sizeof(APixel)); png_bytepp rows = png_get_rows(Png, Info); for(int i = 0; i < h; i++) { for(int j = 0; j < w; j++) { *(px + i * w + j) = a_pixel_make( rows[i][j * channels + 0], rows[i][j * channels + 1], rows[i][j * channels + 2] ); } } *Width = w; *Height = h; *Pixels = px; }
bool PNGReadPixels(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride) { if (setjmp(png_jmpbuf(png))) { return false; } uint8_t* pixelData = pixels; unsigned pngHeight = png_get_image_height(png, info); if (height < pngHeight) { pngHeight = height; } unsigned pngWidth = png_get_image_width(png, info); if (width < pngWidth) { pngWidth = width; } unsigned i; png_bytep row = malloc(png_get_rowbytes(png, info)); for (i = 0; i < pngHeight; ++i) { png_read_row(png, row, 0); unsigned x; for (x = 0; x < pngWidth; ++x) { #if defined(__POWERPC__) || defined(__PPC__) pixelData[stride * i * 4 + x * 4 + 3] = row[x * 3]; pixelData[stride * i * 4 + x * 4 + 2] = row[x * 3 + 1]; pixelData[stride * i * 4 + x * 4 + 1] = row[x * 3 + 2]; #else pixelData[stride * i * 4 + x * 4] = row[x * 3]; pixelData[stride * i * 4 + x * 4 + 1] = row[x * 3 + 1]; pixelData[stride * i * 4 + x * 4 + 2] = row[x * 3 + 2]; #endif } } free(row); return true; }
/** * info_callback -- PNG header has been completely received, prepare to process * image data */ static void info_callback(png_structp png_s, png_infop info) { int interlace; png_uint_32 width, height; nspng_content *png_c = png_get_progressive_ptr(png_s); width = png_get_image_width(png_s, info); height = png_get_image_height(png_s, info); interlace = png_get_interlace_type(png_s, info); png_c->base.width = width; png_c->base.height = height; png_c->base.size += width * height * 4; /* see if progressive-conversion should continue */ if (image_cache_speculate((struct content *)png_c) == false) { longjmp(png_jmpbuf(png_s), CBERR_NOPRE); } /* Claim the required memory for the converted PNG */ png_c->bitmap = bitmap_create(width, height, BITMAP_NEW); if (png_c->bitmap == NULL) { /* Failed to create bitmap skip pre-conversion */ longjmp(png_jmpbuf(png_s), CBERR_NOPRE); } png_c->rowstride = bitmap_get_rowstride(png_c->bitmap); png_c->bpp = bitmap_get_bpp(png_c->bitmap); nspng_setup_transforms(png_s, info); png_c->rowbytes = png_get_rowbytes(png_s, info); png_c->interlace = (interlace == PNG_INTERLACE_ADAM7); LOG(("size %li * %li, rowbytes %zu", (unsigned long)width, (unsigned long)height, png_c->rowbytes)); }
int begin(char* base_file_name, unsigned char *png_buf, long long png_length) { MY_PNG_READ_OFFSET = 0; PNG_LENGTH = png_length; ENTIRE_PNG_BUF = png_buf; if (png_sig_cmp(ENTIRE_PNG_BUF, 0, 8) != 0) { error(-1, "png_sig_cmp", E_INVALID); return -1; } DEBUG_PRINT(("Initial png size is %lld bytes\n", PNG_LENGTH)); my_png_meta *pm = calloc(1, sizeof(my_png_meta)); my_init_libpng(pm); //If libpng errors, we end up here if (setjmp(png_jmpbuf(pm->read_ptr))) { DEBUG_PRINT(("libpng called setjmp!\n")); my_deinit_libpng(pm); free(ENTIRE_PNG_BUF); error(-1, "libpng", "libpng encountered an error\n"); return -1; } //Normally a file, but instead make it our buffer void *read_io_ptr = png_get_io_ptr(pm->read_ptr); png_set_read_fn(pm->read_ptr, read_io_ptr, my_png_read_fn); //Transform all PNG image types to RGB int transforms = PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_EXPAND; png_read_png(pm->read_ptr, pm->info_ptr, transforms, NULL); //Now that it was read and transformed, its size will differ PNG_LENGTH = 0; //Lets collect our metadata struct ihdr_infos_s ihdr_infos; ihdr_infos.bit_depth = png_get_bit_depth(pm->read_ptr, pm->info_ptr); ihdr_infos.color_type = png_get_color_type(pm->read_ptr, pm->info_ptr); ihdr_infos.filter_method = png_get_filter_type(pm->read_ptr, pm->info_ptr); ihdr_infos.compression_type = png_get_compression_type(pm->read_ptr, pm->info_ptr); ihdr_infos.interlace_type = png_get_interlace_type(pm->read_ptr, pm->info_ptr); ihdr_infos.height = png_get_image_height(pm->read_ptr, pm->info_ptr); ihdr_infos.width = png_get_image_width(pm->read_ptr, pm->info_ptr); if (ihdr_infos.color_type != 2) { DEBUG_PRINT((E_INVALID)); free(ENTIRE_PNG_BUF); my_deinit_libpng(pm); DEBUG_PRINT(("Looks like libpng could not correctly convert to RGB\n")); return -1; } //Just in case we want to enable alpha, etc switch(ihdr_infos.color_type) { case 0: //greyscale case 3: //indexed ihdr_infos.bytes_per_pixel = 1; break; case 4: ihdr_infos.bytes_per_pixel = 2; break; //greyscale w/ alpha case 2: ihdr_infos.bytes_per_pixel = 3; break; //Truecolour (RGB) case 6: ihdr_infos.bytes_per_pixel = 4; break; //Truecolour w/ alpha default: error_fatal(1, "ihdr_infos", "Unknown image type"); //should never happen } ihdr_infos.scanline_len = (ihdr_infos.bytes_per_pixel * ihdr_infos.width) + 1; DEBUG_PRINT(("HEIGHT: %u\n", ihdr_infos.height)); DEBUG_PRINT(("WIDTH: %u\n", ihdr_infos.width)); DEBUG_PRINT(("BIT_DEPTH: %u\n", ihdr_infos.bit_depth)); // Don't compress, since we are merely copying it to memory, // we will be decompressing it again anyway png_set_compression_level(pm->write_ptr, Z_NO_COMPRESSION); void *write_io_ptr = png_get_io_ptr(pm->write_ptr); png_set_write_fn(pm->write_ptr, write_io_ptr, my_png_write_fn, my_png_dummy_flush); //Make sure we use all filters png_set_filter(pm->write_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH); //Set our comment struct png_text_struct comment_struct; comment_struct.compression = -1; comment_struct.key = " Glitched by pnglitch.xyz "; comment_struct.text = NULL; comment_struct.text_length = 0; png_set_text(pm->write_ptr, pm->info_ptr, &comment_struct, 1); //Buffer is Written using callback my_png_write_fn to buffer //ENTIRE_PNG_BUF. PNG_LENGTH will be updated automatically by it png_write_png(pm->write_ptr, pm->info_ptr, PNG_TRANSFORM_IDENTITY, NULL); my_deinit_libpng(pm); DEBUG_PRINT(("libpng output buf is %lld bytes\n", PNG_LENGTH)); //Now that libpng has converted the image //and we have it in a buffer, we process it by hand with zlib struct z_stream_s inflate_stream; my_init_zlib(&inflate_stream); inflateInit(&inflate_stream); //Pointer to keep track of where we are unsigned char *pngp = ENTIRE_PNG_BUF; //Skip PNG Signature pngp += 8; //Get Header unsigned char ihdr_bytes_buf[4+4+13+4]; // size + label + content + crc buf_read(ihdr_bytes_buf, &pngp, 4+4+13+4); //When we run into non-idat chunks, we will want to preserve them. //The spec says there's no chunk that needs to go after IDAT, //so we can simply concatenate all of these chunks into a buffer //then write them all at once after the IHDR //ancillary chunks, eg comments unsigned char *ancil_chunks_buf = calloc(1,1); long long ancil_chunks_len = 0; unsigned char *unzip_idats_buf = calloc(1, 1); long unzip_buf_len = 1; long unzip_buf_offset = 0; long long zipped_idats_len = 0; //Length of all idats as we read them unsigned long accum_png_len = 8 + (4+4+13+4); int chunk_count = 0; printf("Uncompressing image data...\n"); while (1) { unsigned char chunk_label[4]; unsigned char chunk_len_buf[4]; buf_read(chunk_len_buf, &pngp, 4); //first 4 bytes are the length of data section long chunk_len = four_bytes_to_int(chunk_len_buf); accum_png_len += chunk_len + 4 + 4 + 4; // plus len, crc, label DEBUG_PRINT(("at %lu --> %lld\n", accum_png_len, PNG_LENGTH)); //leave at end of buffer if (accum_png_len >= PNG_LENGTH) break; //read the chunk label (name of this header) buf_read(chunk_label, &pngp, 4); DEBUG_PRINT(("Reading chunk %d with label '%c%c%c%c', size %ld\n", chunk_count, chunk_label[0], chunk_label[1], chunk_label[2], chunk_label[3], chunk_len)); chunk_count += 1; if (memcmp(chunk_label, "IDAT", 4) == 0) { zipped_idats_len += chunk_len; //read the chunk's data section unsigned char *raw_chunk_buf = calloc(chunk_len, 1); buf_read(raw_chunk_buf, &pngp, chunk_len); //Tell inflate to uncompress it inflate_stream.next_in = raw_chunk_buf; inflate_stream.avail_in = chunk_len; //Now uncompress it (resizes buffer automatically) unsigned char *check_uncompress = uncompress_buffer(&inflate_stream, unzip_idats_buf, &unzip_buf_len, &unzip_buf_offset); //Stop if error if (check_uncompress == NULL) { DEBUG_PRINT((E_GLITCH)); free(ancil_chunks_buf); free(raw_chunk_buf); free(unzip_idats_buf); free(ENTIRE_PNG_BUF); return -1; } //Moving on unzip_idats_buf = check_uncompress; free(raw_chunk_buf); pngp += 4; // skip CRC } else { //This is not an idat ancil_chunks_buf = realloc(ancil_chunks_buf, ancil_chunks_len + 4 + 4 + chunk_len + 4); //make room for new data //append length and label bytes append_bytes(ancil_chunks_buf, chunk_len_buf, &ancil_chunks_len, 4); append_bytes(ancil_chunks_buf, chunk_label, &ancil_chunks_len, 4); //append chunk data unsigned char *raw_chunk_buf = calloc(chunk_len, 1); buf_read(raw_chunk_buf, &pngp, chunk_len); append_bytes(ancil_chunks_buf, raw_chunk_buf, &ancil_chunks_len, chunk_len ); //append chunk crc unsigned char chunk_crc_buf[4]; buf_read(chunk_crc_buf, &pngp, 4); append_bytes(ancil_chunks_buf, chunk_crc_buf, &ancil_chunks_len, 4); free(raw_chunk_buf); DEBUG_PRINT(("ancillary chunks length: %lld\n", ancil_chunks_len)); } } //buf contains all idats uncompressed, concatenated unsigned long unzipped_idats_len = inflate_stream.total_out; unzip_idats_buf = realloc(unzip_idats_buf, unzipped_idats_len); //we already have ancillary chunks and idats, don't need the original free(ENTIRE_PNG_BUF); inflateEnd(&inflate_stream); printf("Uncompressed %lld bytes to %ld bytes\n", zipped_idats_len, unzipped_idats_len); printf("Glitching image data...\n"); for (int g=0;g<NUM_OUTPUT_FILES;g++) { //do glitches switch(g) { case 5: glitch_random(unzip_idats_buf, unzipped_idats_len, ihdr_infos.scanline_len, 0.0005); break; case 6: glitch_random_filter(unzip_idats_buf, unzipped_idats_len, ihdr_infos.scanline_len); break; default: glitch_filter(unzip_idats_buf, unzipped_idats_len, ihdr_infos.scanline_len, g); } //recompress so we can write them to file long long glitched_idats_len = 0; unsigned char *glitched_idats = zip_idats(unzip_idats_buf, unzipped_idats_len, &glitched_idats_len); if (glitched_idats == NULL) { DEBUG_PRINT((E_GLITCH)); free (unzip_idats_buf); free (ancil_chunks_buf); return -1; } char path[MAX_PATH_LENGTH]; bzero(path, MAX_PATH_LENGTH); snprintf(path, MAX_PATH_LENGTH, "%s%s%s-%d.png", OUTPUT_DIRECTORY, DIR_SEP, base_file_name, g); DEBUG_PRINT(("Output file name is %s\n", path)); FILE *outfp = fopen(path, "wb"); write_glitched_image(glitched_idats, glitched_idats_len, ihdr_bytes_buf, ancil_chunks_buf, ancil_chunks_len, outfp); printf("%s\n", path); fflush(stdout); fclose(outfp); free(glitched_idats); } free(ancil_chunks_buf); free(unzip_idats_buf); return 0; }
void PNGImageDecoder::headerAvailable() { png_structp png = m_reader->pngPtr(); png_infop info = m_reader->infoPtr(); png_uint_32 width = png_get_image_width(png, info); png_uint_32 height = png_get_image_height(png, info); // Protect against large PNGs. See http://bugzil.la/251381 for more details. const unsigned long maxPNGSize = 1000000UL; if (width > maxPNGSize || height > maxPNGSize) { longjmp(JMPBUF(png), 1); return; } // Set the image size now that the image header is available. if (!setSize(width, height)) { longjmp(JMPBUF(png), 1); return; } int bitDepth, colorType, interlaceType, compressionType, filterType, channels; png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, &interlaceType, &compressionType, &filterType); // The options we set here match what Mozilla does. // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA. if (colorType == PNG_COLOR_TYPE_PALETTE || (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)) png_set_expand(png); png_bytep trns = 0; int trnsCount = 0; if (png_get_valid(png, info, PNG_INFO_tRNS)) { png_get_tRNS(png, info, &trns, &trnsCount, 0); png_set_expand(png); } if (bitDepth == 16) png_set_strip_16(png); if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png); #if USE(QCMSLIB) if ((colorType & PNG_COLOR_MASK_COLOR) && !m_ignoreGammaAndColorProfile) { // We only support color profiles for color PALETTE and RGB[A] PNG. Supporting // color profiles for gray-scale images is slightly tricky, at least using the // CoreGraphics ICC library, because we expand gray-scale images to RGB but we // do not similarly transform the color profile. We'd either need to transform // the color profile or we'd need to decode into a gray-scale image buffer and // hand that to CoreGraphics. bool sRGB = false; ColorProfile colorProfile; getColorProfile(png, info, colorProfile, sRGB); bool imageHasAlpha = (colorType & PNG_COLOR_MASK_ALPHA) || trnsCount; m_reader->createColorTransform(colorProfile, imageHasAlpha, sRGB); m_hasColorProfile = !!m_reader->colorTransform(); } #endif if (!m_hasColorProfile) { // Deal with gamma and keep it under our control. const double inverseGamma = 0.45455; const double defaultGamma = 2.2; double gamma; if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) { const double maxGamma = 21474.83; if ((gamma <= 0.0) || (gamma > maxGamma)) { gamma = inverseGamma; png_set_gAMA(png, info, gamma); } png_set_gamma(png, defaultGamma, gamma); } else { png_set_gamma(png, defaultGamma, inverseGamma); } } // Tell libpng to send us rows for interlaced pngs. if (interlaceType == PNG_INTERLACE_ADAM7) png_set_interlace_handling(png); // Update our info now. png_read_update_info(png, info); channels = png_get_channels(png, info); ASSERT(channels == 3 || channels == 4); m_reader->setHasAlpha(channels == 4); if (m_reader->decodingSizeOnly()) { // If we only needed the size, halt the reader. #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 5) // '0' argument to png_process_data_pause means: Do not cache unprocessed data. m_reader->setReadOffset(m_reader->currentBufferSize() - png_process_data_pause(png, 0)); #else m_reader->setReadOffset(m_reader->currentBufferSize() - png->buffer_size); png->buffer_size = 0; #endif } }