void ImageFormat_PNG::CopyPixels(unsigned int* destination) { if (!info_ptr_ || !png_ptr_) { return; } png_infop info_ptr=static_cast<png_infop>(info_ptr_); png_structp png_ptr=static_cast<png_structp>(png_ptr_); Assert(info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA || info_ptr->color_type==PNG_COLOR_TYPE_RGB,"Unknown PNG format"); if (info_ptr->color_type!=PNG_COLOR_TYPE_RGB_ALPHA && info_ptr->color_type!=PNG_COLOR_TYPE_RGB) { return; } if (info_ptr->color_type==PNG_COLOR_TYPE_RGB_ALPHA) { unsigned char* data=reinterpret_cast<unsigned char*>(destination); png_byte** row_pointers=png_get_rows(png_ptr, info_ptr); int rowSize=info_ptr->width*4; for (unsigned int y=0; y<info_ptr->height; y++) { for (unsigned int x=0; x<info_ptr->width; x++) { data[x*4+y*rowSize+0]=row_pointers[y][x*4+0]; data[x*4+y*rowSize+1]=row_pointers[y][x*4+1]; data[x*4+y*rowSize+2]=row_pointers[y][x*4+2]; data[x*4+y*rowSize+3]=row_pointers[y][x*4+3]; } } } else { unsigned char* data=reinterpret_cast<unsigned char*>(destination); png_byte** row_pointers=png_get_rows(png_ptr, info_ptr); int rowSize=info_ptr->width*4; for (unsigned int y=0; y<info_ptr->height; y++) { for (unsigned int x=0; x<info_ptr->width; x++) { data[x*4+y*rowSize+0]=row_pointers[y][x*3+0]; data[x*4+y*rowSize+1]=row_pointers[y][x*3+1]; data[x*4+y*rowSize+2]=row_pointers[y][x*3+2]; data[x*4+y*rowSize+3]=0xff; } } } }
void TextWindow::ScreenBackgroundImage(int link, uint32_t v) { if(SS.bgImage.fromFile) MemFree(SS.bgImage.fromFile); SS.bgImage.fromFile = NULL; if(link == 'l') { FILE *f = NULL; png_struct *png_ptr = NULL; png_info *info_ptr = NULL; char importFile[MAX_PATH] = ""; if(!GetOpenFile(importFile, PNG_EXT, PNG_PATTERN)) goto err; f = fopen(importFile, "rb"); if(!f) goto err; uint8_t header[8]; if (fread(header, 1, 8, f) != 8) goto err; if(png_sig_cmp(header, 0, 8)) goto err; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) goto err; info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) goto err; if(setjmp(png_jmpbuf(png_ptr))) goto err; png_init_io(png_ptr, f); png_set_sig_bytes(png_ptr, 8); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, NULL); int w; w = (int)png_get_image_width(png_ptr, info_ptr); int h; h = (int)png_get_image_height(png_ptr, info_ptr); uint8_t **rows; rows = png_get_rows(png_ptr, info_ptr); // Round to next-highest powers of two, since the textures require // that. And round up to 4, to guarantee 32-bit alignment. int rw; rw = max(4, RoundUpToPowerOfTwo(w)); int rh; rh = max(4, RoundUpToPowerOfTwo(h)); SS.bgImage.fromFile = (uint8_t *)MemAlloc(rw*rh*3); {for(int i = 0; i < h; i++) { memcpy(SS.bgImage.fromFile + ((h - 1) - i)*(rw*3), rows[i], w*3); }} SS.bgImage.w = w; SS.bgImage.h = h; SS.bgImage.rw = rw; SS.bgImage.rh = rh; SS.bgImage.scale = SS.GW.scale; SS.bgImage.origin = SS.GW.offset.ScaledBy(-1); err: if(png_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); if(f) fclose(f); } SS.later.showTW = true; }
/* 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 * pngfile_to_bytes(char* file_name) { printf("reading file %s\n",file_name); png_structp png_ptr; png_infop info_ptr, end_ptr; png_uint_32 width, height; int bit_depth; int color_type; int interlace_type; int i; FILE *fp = fopen(file_name, "rb"); if (!fp) { fprintf(stderr, "can't open %s\n", file_name); return 0; } /* 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"); end_ptr = png_create_info_struct(png_ptr); if (!end_ptr) abort_("[read_png_file] png_create_info_struct failed"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 0); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); Image* img = (Image*)malloc(sizeof(Image)); img->w = width; img->h = height; img->hasAlpha = (color_type == PNG_COLOR_TYPE_RGBA); int bytes_per_pixel = 3; if(img->hasAlpha) { bytes_per_pixel = 4; } unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr); img->data = (char*) malloc(row_bytes * height); png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); for (i = 0; i < height; i++) { memcpy(img->data + row_bytes*i, row_pointers[i], row_bytes); } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(fp); return img; }
// //////////////////////////////////////////////////// // // 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 Image::loadWithPng() { FILE* file = fopen(this->file.c_str(), "rb"); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_infop info_ptr = png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, file); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0); int m_width = png_get_image_width(png_ptr, info_ptr); int m_height = png_get_image_height(png_ptr, info_ptr); int color_type = png_get_color_type(png_ptr, info_ptr); int size = m_height * m_width * 4; unsigned char* rgba = (unsigned char*)malloc(size); int pos = 0; png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr); for (int i = 0; i < m_height; i++) { for (int j = 0; j < (4 * m_width); j += 4) { rgba[pos++] = row_pointers[i][j]; //R rgba[pos++] = row_pointers[i][j + 1]; //B rgba[pos++] = row_pointers[i][j + 2]; //G rgba[pos++] = row_pointers[i][j + 3]; //A } } png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(file); auto _data = rgba; this->width = m_width; this->height = m_height; this->size = size; _rect.x = m_width; _rect.y = m_height; this->_data = rgba; }
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); }
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; }
CNSL_Display Pnger_Load(const char* filename) { CNSL_Display null; null.width = 0; null.height = 0; null.pixels = NULL; FILE* pngfile = fopen(filename, "rb"); if (!pngfile) { fprintf(stderr, "unable to open %s\n", filename); return null; } png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if (!png_ptr) { fprintf(stderr, "unable to create png read struct.\n"); return null; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); fprintf(stderr, "unable to create png info struct.\n"); return null; } png_init_io(png_ptr, pngfile); unsigned int transforms = PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_EXPAND; png_read_png(png_ptr, info_ptr, transforms, NULL); uint8_t** row_pointers = png_get_rows(png_ptr, info_ptr); int width = png_get_image_width(png_ptr, info_ptr); int height = png_get_image_height(png_ptr, info_ptr); CNSL_Display pixels = CNSL_AllocDisplay(width, height); int x, y; for (y = 0; y < pixels.height; y++) { for (x = 0; x < pixels.width; x++) { uint8_t rc = row_pointers[y][3*x]; uint8_t gc = row_pointers[y][3*x+1]; uint8_t bc = row_pointers[y][3*x+2]; CNSL_SetPixel(pixels, x, y, CNSL_MakeColor(rc, gc, bc)); } } return pixels; }
void ogl::texture::load_png(const void *buf, size_t len, std::vector<GLubyte>& p) { // Initialize all PNG import data structures. png_structp rp = 0; png_infop ip = 0; png_bytep *bp = 0; if (!(rp = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) throw std::runtime_error("Failure creating PNG read structure"); if (!(ip = png_create_info_struct(rp))) throw std::runtime_error("Failure creating PNG info structure"); // Initialize the user-defined IO structure. struct png_user_io user; user.buf = (png_bytep) buf; user.len = (png_size_t) len; png_set_read_fn(rp, &user, png_user_read); // Enable the default PNG error handler. if (setjmp(png_jmpbuf(rp)) == 0) { // Read the PNG header. png_read_png(rp, ip, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_SWAP_ENDIAN, 0); // Extract image properties. w = GLsizei(png_get_image_width (rp, ip)); h = GLsizei(png_get_image_height(rp, ip)); c = GLsizei(png_get_channels (rp, ip)); p.resize(w * h * c); // Read the pixel data. if ((bp = png_get_rows(rp, ip))) for (GLsizei i = 0, j = h - 1; i < h; ++i, --j) memcpy(&p[w * c * i], bp[j], (w * c)); } // Release all resources. png_destroy_read_struct(&rp, &ip, 0); }
/** * The PNG Heightmap loader. */ static void ReadHeightmapPNGImageData(byte *map, png_structp png_ptr, png_infop info_ptr) { uint x, y; byte gray_palette[256]; png_bytep *row_pointers = nullptr; bool has_palette = png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE; uint channels = png_get_channels(png_ptr, info_ptr); /* Get palette and convert it to grayscale */ if (has_palette) { int i; int palette_size; png_color *palette; bool all_gray = true; png_get_PLTE(png_ptr, info_ptr, &palette, &palette_size); for (i = 0; i < palette_size && (palette_size != 16 || all_gray); i++) { all_gray &= palette[i].red == palette[i].green && palette[i].red == palette[i].blue; gray_palette[i] = RGBToGrayscale(palette[i].red, palette[i].green, palette[i].blue); } /** * For a non-gray palette of size 16 we assume that * the order of the palette determines the height; * the first entry is the sea (level 0), the second one * level 1, etc. */ if (palette_size == 16 && !all_gray) { for (i = 0; i < palette_size; i++) { gray_palette[i] = 256 * i / palette_size; } } } row_pointers = png_get_rows(png_ptr, info_ptr); /* Read the raw image data and convert in 8-bit grayscale */ for (x = 0; x < png_get_image_width(png_ptr, info_ptr); x++) { for (y = 0; y < png_get_image_height(png_ptr, info_ptr); y++) { byte *pixel = &map[y * png_get_image_width(png_ptr, info_ptr) + x]; uint x_offset = x * channels; if (has_palette) { *pixel = gray_palette[row_pointers[y][x_offset]]; } else if (channels == 3) { *pixel = RGBToGrayscale(row_pointers[y][x_offset + 0], row_pointers[y][x_offset + 1], row_pointers[y][x_offset + 2]); } else { *pixel = row_pointers[y][x_offset]; } } } }
bool PNGImageLoader::loadImageData(PixelOrigin origin, DataSource* data, ImageContext* context) { PNGImageContext* png = static_cast<PNGImageContext*>(context); byte red; byte green; byte blue; byte alpha; size_t width = png->getWidth(); size_t height = png->getHeight(); png_bytepp row_pointers = png_get_rows(png->d_png_ptr, png->d_info_ptr); if (png->d_bit_depth == 8) { // Read RGBA if (png->d_num_channels == 4) { for (size_t j = 0 ; j < height ; ++j) { for(size_t i = 0 ; i < width ; ++i) { size_t pixel_offset = 4 * i; red = *(row_pointers[j] + pixel_offset); green = *(row_pointers[j] + pixel_offset + 1); blue = *(row_pointers[j] + pixel_offset + 2); alpha = *(row_pointers[j] + pixel_offset + 3); png->setNextPixel(red, green, blue, alpha); } } } else if (png->d_num_channels == 3) { alpha = 0xff; for (size_t j = 0 ; j < height ; ++j) { for(size_t i = 0 ; i < width ; ++i) { size_t pixel_offset = 3 * i; red = *(row_pointers[j] + pixel_offset); green = *(row_pointers[j] + pixel_offset + 1); blue = *(row_pointers[j] + pixel_offset + 2); png->setNextPixel(red, green, blue, alpha); } } } } if (origin == PO_BOTTOM_LEFT) return png->flipVertically(); return true; }
/* * 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; }
struct image *read_png(char *s, int len) { png_structp png_ptr; png_infop info_ptr; struct read_state state; state.base = s; state.off = 0; state.len = len; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, fail, fail, fail); if (png_ptr == NULL) { fprintf(stderr, "PNG init failed\n"); exit(EXIT_FAILURE); } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fprintf(stderr, "PNG init failed\n"); exit(EXIT_FAILURE); } png_set_read_fn(png_ptr, &state, user_read_data); png_set_sig_bytes(png_ptr, 0); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL); png_uint_32 width, height; int bit_depth; int color_type, interlace_type; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); struct image *i = malloc(sizeof(struct image)); i->width = width; i->height = height; i->depth = png_get_channels(png_ptr, info_ptr); i->buf = malloc(i->width * i->height * i->depth); unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr); png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); int n; for (n = 0; n < i->height; n++) { memcpy(i->buf + row_bytes * n, row_pointers[n], row_bytes); } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return i; }
static int read_file(struct img_pixmap *img, struct img_io *io) { png_struct *png; png_info *info; unsigned char **lineptr, *dest; int i, channel_bits, color_type, ilace_type, compression, filtering, fmt; png_uint_32 xsz, ysz; if(!(png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) { return -1; } if(!(info = png_create_info_struct(png))) { png_destroy_read_struct(&png, 0, 0); return -1; } if(setjmp(png_jmpbuf(png))) { png_destroy_read_struct(&png, &info, 0); return -1; } png_set_read_fn(png, io, read_func); png_set_sig_bytes(png, 0); png_read_png(png, info, 0, 0); png_get_IHDR(png, info, &xsz, &ysz, &channel_bits, &color_type, &ilace_type, &compression, &filtering); if((fmt = png_type_to_fmt(color_type, channel_bits)) == -1) { png_destroy_read_struct(&png, &info, 0); return -1; } if(img_set_pixels(img, xsz, ysz, fmt, 0) == -1) { png_destroy_read_struct(&png, &info, 0); return -1; } lineptr = (unsigned char**)png_get_rows(png, info); dest = img->pixels; for(i=0; i<ysz; i++) { memcpy(dest, lineptr[i], xsz * img->pixelsz); dest += xsz * img->pixelsz; } png_destroy_read_struct(&png, &info, 0); 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]; }
EFI_STATUS png_init(WINDOW **w, RECT *loc, WINDOW *parent, FILE *fp, EW_BITMAP *info) { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(png_ptr == NULL) { fprintf(stderr, "efiwindow: png_init: png_create_read_struct failed\n"); return EFI_ABORTED; } png_infop info_ptr = png_create_info_struct(png_ptr); if(info_ptr == NULL) { fprintf(stderr, "efiwindow: png_init: png_create_info_struct failed\n"); return EFI_ABORTED; } png_init_io(png_ptr, fp); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_BGR, NULL); struct png_data *pd = (struct png_data *)malloc(sizeof(struct png_data)); memset(pd, 0, sizeof(struct png_data)); png_get_IHDR(png_ptr, info_ptr, &pd->width, &pd->height, &pd->bdepth, &pd->color_type, &pd->interlace_method, &pd->comp_method, &pd->filt_method); pd->row_pointers = png_get_rows(png_ptr, info_ptr); switch(pd->color_type) { case PNG_COLOR_TYPE_RGB: pd->pixel_size = (3 * pd->bdepth) / 8; break; case PNG_COLOR_TYPE_RGBA: pd->pixel_size = (4 * pd->bdepth) / 8; break; default: fprintf(stderr, "efiwindow: png_init: unsupported color type: %i\n", pd->color_type); return EFI_ABORTED; } memcpy(&pd->bmp, info, sizeof(EW_BITMAP)); return ew_create_window(w, loc, parent, png_paint, pd, sizeof(struct png_data)); }
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; }
BitmapPNG* LoadPNG(vgui::InputStream& stream) { //allocate structures for read png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return NULL; png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return NULL; } //set up our alternate read function png_set_read_fn(png_ptr,&stream,png_read_vgui_stream); //read the image png_read_png(png_ptr,info_ptr,PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16,NULL); png_bytepp rows = png_get_rows(png_ptr, info_ptr); png_read_image(png_ptr,rows); //we now have the information in row format, it needs to be converted to a single array //of 32bit pixel values specified as a uchar* so that we can create the image object uchar* data = new uchar[info_ptr->width*info_ptr->height*4]; convertToUChar(info_ptr,rows,data); //create the BitmpPNG that we are going to return BitmapPNG* returnVal = new BitmapPNG(info_ptr->width,info_ptr->height,data); //read the information after the image for completeness png_read_end(png_ptr,NULL); //free up png structures and other memory we've used delete[] data; png_destroy_read_struct(&png_ptr,&info_ptr,(png_infopp)NULL); return returnVal; }
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; }
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; }
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]); } } }
int gr3_readpngtomemory_(int *pixels, const char *pngfile, int width, int height) { FILE *png_fp; png_structp png_ptr; png_infop info_ptr = NULL; png_infop end_info = NULL; unsigned char sig[8]; png_bytep *row_pointers; int i; png_fp = fopen(pngfile,"rb"); if (!png_fp) { return 1; } i = fread(sig, 1, 8, png_fp); if (!png_check_sig(sig, 8)){ return 2; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return 3; } info_ptr = png_create_info_struct(png_ptr); end_info = png_create_info_struct(png_ptr); if (!info_ptr || !end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); return 4; } png_init_io(png_ptr, png_fp); png_set_sig_bytes(png_ptr, 8); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); row_pointers = png_get_rows(png_ptr, info_ptr); for (i = 0; i < height; i++) { memcpy(pixels+(height-1-i)*width,row_pointers[i],width*sizeof(int)); } png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(png_fp); return 0; }
bool CCImage::_initWithPngData(void * pData, int nDatalen) { bool bRet = false; png_byte header[8] = {0}; png_structp png_ptr = 0; png_infop info_ptr = 0; unsigned char * pImateData = 0; do { // png header len is 8 bytes CC_BREAK_IF(nDatalen < 8); // check the data is png or not memcpy(header, pData, 8); CC_BREAK_IF(png_sig_cmp(header, 0, 8)); // init png_struct png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); CC_BREAK_IF(! png_ptr); // init png_info info_ptr = png_create_info_struct(png_ptr); CC_BREAK_IF(!info_ptr); #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA) CC_BREAK_IF(setjmp(png_jmpbuf(png_ptr))); #endif // set the read call back function tImageSource imageSource; imageSource.data = (unsigned char*)pData; imageSource.size = nDatalen; imageSource.offset = 0; png_set_read_fn(png_ptr, &imageSource, pngReadCallback); // read png // PNG_TRANSFORM_EXPAND: perform set_expand() // PNG_TRANSFORM_PACKING: expand 1, 2 and 4-bit samples to bytes // PNG_TRANSFORM_STRIP_16: strip 16-bit samples to 8 bits // PNG_TRANSFORM_GRAY_TO_RGB: expand grayscale samples to RGB (or GA to RGBA) png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_GRAY_TO_RGB, 0); int color_type = 0; png_uint_32 nWidth = 0; png_uint_32 nHeight = 0; int nBitsPerComponent = 0; png_get_IHDR(png_ptr, info_ptr, &nWidth, &nHeight, &nBitsPerComponent, &color_type, 0, 0, 0); // init image info m_bPreMulti = true; m_bHasAlpha = ( info_ptr->color_type & PNG_COLOR_MASK_ALPHA ) ? true : false; // allocate memory and read data int bytesPerComponent = 3; if (m_bHasAlpha) { bytesPerComponent = 4; } pImateData = new unsigned char[nHeight * nWidth * bytesPerComponent]; CC_BREAK_IF(! pImateData); png_bytep * rowPointers = png_get_rows(png_ptr, info_ptr); // copy data to image info int bytesPerRow = nWidth * bytesPerComponent; if(m_bHasAlpha) { unsigned int *tmp = (unsigned int *)pImateData; for(unsigned int i = 0; i < nHeight; i++) { for(int j = 0; j < bytesPerRow; j += 4) { *tmp++ = CC_RGB_PREMULTIPLY_APLHA( rowPointers[i][j], rowPointers[i][j + 1], rowPointers[i][j + 2], rowPointers[i][j + 3] ); } } } else { for (unsigned int j = 0; j < nHeight; ++j) { memcpy(pImateData + j * bytesPerRow, rowPointers[j], bytesPerRow); } } m_nBitsPerComponent = nBitsPerComponent; m_nHeight = (short)nHeight; m_nWidth = (short)nWidth; m_pData = pImateData; pImateData = 0; bRet = true; } while (0); CC_SAFE_DELETE_ARRAY(pImateData); if (png_ptr) { png_destroy_read_struct(&png_ptr, (info_ptr) ? &info_ptr : 0, 0); } return bRet; }
int liimg_png_load ( const char* file, int* result_width, int* result_height, void** result_pixels) { #ifdef HAVE_FREEIMAGE size_t i; size_t x; size_t y; size_t w; size_t h; uint8_t* pixels; FIBITMAP* image; RGBQUAD color; /* Load the image. */ image = FreeImage_Load (FIF_PNG, file, PNG_DEFAULT); if (image == NULL) return 0; /* Allocate pixel data. */ w = FreeImage_GetWidth (image); h = FreeImage_GetHeight (image); if (w > 0 && h > 0) { pixels = lisys_calloc (w * h * 4, 1); if (pixels == NULL) { FreeImage_Unload (image); return 0; } } else pixels = NULL; /* Copy the pixel data. */ for (y = 0, i = 0 ; y < h ; y++) { for (x = 0 ; x < w ; x++, i++) { FreeImage_GetPixelColor (image, x, h - y - 1, &color); pixels[4 * i + 0] = color.rgbRed; pixels[4 * i + 1] = color.rgbGreen; pixels[4 * i + 2] = color.rgbBlue; if (FreeImage_GetBPP (image) == 32) pixels[4 * i + 3] = color.rgbReserved; else pixels[4 * i + 3] = 0xFF; } } /* Set the results. */ *result_width = w; *result_height = h; *result_pixels = pixels; FreeImage_Unload (image); return 1; #else int x; int y; int depth; int width; int height; char* dst; void* pixels; FILE* fp; png_bytepp rows; png_infop info; png_structp png; /* Initialize structures. */ png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png == NULL) { lisys_error_set (ENOMEM, NULL); return 0; } info = png_create_info_struct (png); if (info == NULL) { png_destroy_read_struct (&png, NULL, NULL); lisys_error_set (ENOMEM, NULL); return 0; } /* Open file. */ fp = fopen (file, "rb"); if (fp == NULL) { lisys_error_set (EIO, "cannot open file `%s'", file); png_destroy_read_struct (&png, &info, NULL); return 0; } /* Read data. */ if (setjmp (png_jmpbuf (png))) { lisys_error_set (EIO, "error while reading `%s'", file); png_destroy_read_struct (&png, &info, NULL); fclose (fp); return 0; } png_init_io (png, fp); png_read_png (png, info, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING, NULL); width = png_get_image_width (png, info); height = png_get_image_height (png, info); rows = png_get_rows (png, info); depth = png_get_rowbytes (png, info); depth /= width; fclose (fp); /* Allocate pixel data. */ pixels = lisys_malloc (width * height * 4); if (pixels == NULL) { png_destroy_read_struct (&png, &info, NULL); return 0; } /* Copy pixel data. */ if (depth == 3) { for (y = 0 ; y < height ; y++) { dst = pixels + 4 * width * y; for (x = 0 ; x < width ; x++) { dst[4 * x + 0] = ((char*) rows[y])[3 * x + 0]; dst[4 * x + 1] = ((char*) rows[y])[3 * x + 1]; dst[4 * x + 2] = ((char*) rows[y])[3 * x + 2]; dst[4 * x + 3] = 0xFF; } } } else { for (y = 0 ; y < height ; y++) { dst = pixels + 4 * width * y; memcpy (dst, rows[y], 4 * width); } } *result_pixels = pixels; *result_width = width; *result_height = height; png_destroy_read_struct (&png, &info, NULL); return 1; #endif }
void DisplaySplashImage() { FILE *f = FioFOpenFile(SPLASH_IMAGE_FILE); if (f == NULL) return; png_byte header[8]; fread(header, sizeof(png_byte), 8, f); if (png_sig_cmp(header, 0, 8) != 0) { fclose(f); return; } png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning); if (png_ptr == NULL) { fclose(f); return; } png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); fclose(f); return; } png_infop end_info = png_create_info_struct(png_ptr); if (end_info == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); fclose(f); return; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(f); return; } png_init_io(png_ptr, f); png_set_sig_bytes(png_ptr, 8); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); uint width = png_get_image_width(png_ptr, info_ptr); uint height = png_get_image_height(png_ptr, info_ptr); uint bit_depth = png_get_bit_depth(png_ptr, info_ptr); uint color_type = png_get_color_type(png_ptr, info_ptr); if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(f); return; } if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(f); return; } png_colorp palette; int num_palette; png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr); if (width > (uint) _screen.width) width = _screen.width; if (height > (uint) _screen.height) height = _screen.height; uint xoff = (_screen.width - width) / 2; uint yoff = (_screen.height - height) / 2; switch (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth()) { case 8: { uint8 *dst_ptr = (uint8 *)_screen.dst_ptr; /* Initialize buffer */ MemSetT(dst_ptr, 0xff, _screen.pitch * _screen.height); for (uint y = 0; y < height; y++) { uint8 *src = row_pointers[y]; uint8 *dst = dst_ptr + (yoff + y) * _screen.pitch + xoff; memcpy(dst, src, width); } for (int i = 0; i < num_palette; i++) { _cur_palette[i].a = i == 0 ? 0 : 0xff; _cur_palette[i].r = palette[i].red; _cur_palette[i].g = palette[i].green; _cur_palette[i].b = palette[i].blue; } _cur_palette[0xff].a = 0xff; _cur_palette[0xff].r = 0; _cur_palette[0xff].g = 0; _cur_palette[0xff].b = 0; _pal_first_dirty = 0; _pal_count_dirty = 256; break; } case 32: { uint32 *dst_ptr = (uint32 *)_screen.dst_ptr; /* Initialize buffer */ MemSetT(dst_ptr, 0, _screen.pitch * _screen.height); for (uint y = 0; y < height; y++) { uint8 *src = row_pointers[y]; uint32 *dst = dst_ptr + (yoff + y) * _screen.pitch + xoff; for (uint x = 0; x < width; x++) { dst[x] = palette[src[x]].blue | (palette[src[x]].green << 8) | (palette[src[x]].red << 16) | 0xff000000; } } break; } } png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(f); return; }
TypedImage LoadPng(const std::string& filename) { PANGOLIN_UNUSED(filename); #ifdef HAVE_PNG FILE *in = fopen(filename.c_str(), "rb"); if( in ) { //check the header const size_t nBytes = 8; png_byte header[nBytes]; size_t nread = fread(header, 1, nBytes, in); int nIsPNG = png_sig_cmp(header, 0, nread); if ( nIsPNG != 0 ) { throw std::runtime_error( filename + " is not a PNG file" ); } //set up initial png structs png_structp png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, &PngWarningsCallback); if (!png_ptr) { throw std::runtime_error( "PNG Init error 1" ); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); throw std::runtime_error( "PNG Init error 2" ); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); throw std::runtime_error( "PNG Init error 3" ); } png_init_io(png_ptr, in); png_set_sig_bytes(png_ptr, nBytes); //read the file png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_SWAP_ENDIAN, NULL); if( png_get_bit_depth(png_ptr, info_ptr) == 1) { //Unpack bools to bytes to ease loading. png_set_packing(png_ptr); } else if( png_get_bit_depth(png_ptr, info_ptr) < 8) { //Expand nonbool colour depths up to 8bpp png_set_expand_gray_1_2_4_to_8(png_ptr); } //Get rid of palette, by transforming it to RGB if(png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); } if( png_get_interlace_type(png_ptr,info_ptr) != PNG_INTERLACE_NONE) { throw std::runtime_error( "Interlace not yet supported" ); } const size_t w = png_get_image_width(png_ptr,info_ptr); const size_t h = png_get_image_height(png_ptr,info_ptr); const size_t pitch = png_get_rowbytes(png_ptr, info_ptr); TypedImage img(w, h, PngFormat(png_ptr, info_ptr), pitch); png_bytepp rows = png_get_rows(png_ptr, info_ptr); for( unsigned int r = 0; r < h; r++) { memcpy( img.ptr + pitch*r, rows[r], pitch ); } png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(in); return img; } throw std::runtime_error("Unable to load PNG file, '" + filename + "'"); #else throw std::runtime_error("PNG Support not enabled. Please rebuild Pangolin."); #endif }
__error__ "PNG_FLAG_FILLER_AFTER" has an unexpected value #endif #endif /* * Check if it's safe to access libpng's internal structures directly. * Some fields might have their offsets shifted due to changes in * libpng's configuration. */ static void _opng_validate_internal(png_structp png_ptr, png_infop info_ptr) { #if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_color_16p background; #endif #if defined(PNG_hIST_SUPPORTED) png_uint_16p hist; #endif #if defined(PNG_sBIT_SUPPORTED) png_color_8p sig_bit; #endif png_bytep trans_alpha; int num_trans; png_color_16p trans_color; /* Check info_ptr. */ if (png_get_rows(png_ptr, info_ptr) != info_ptr->row_pointers) goto error; #if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_get_bKGD(png_ptr, info_ptr, &background)) if (background != &info_ptr->background) goto error; #endif #if defined(PNG_hIST_SUPPORTED) if (png_get_hIST(png_ptr, info_ptr, &hist)) if (hist != info_ptr->hist) goto error; #endif #if defined(PNG_sBIT_SUPPORTED) if (png_get_sBIT(png_ptr, info_ptr, &sig_bit)) if (sig_bit != &info_ptr->sig_bit) goto error; #endif if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color)) if ((trans_alpha != NULL && (trans_alpha != info_ptr->trans_alpha || num_trans != info_ptr->num_trans)) || (trans_color != NULL && trans_color != &info_ptr->trans_color)) goto error; /* Also check png_ptr. It's not much, we're doing what we can... */ if (png_get_compression_buffer_size(png_ptr) != png_ptr->zbuf_size) goto error; /* Everything looks okay. */ return; error: png_error(png_ptr, "[internal error] Inconsistent internal structures (incorrect libpng?)"); }