bool Image::loadPNG(const char *fileName){
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
FILE *file;
png_byte pbSig[8];
int iBitDepth, iColorType;
png_byte **ppbRowPointers;
// open the PNG input file
if ((file = fopen(fileName, "rb")) == NULL) return false;
// first check the eight byte PNG signature
fread(pbSig, 1, 8, file);
if (!png_check_sig(pbSig, 8)){
fclose(file);
return false;
}
// create the two png(-info) structures
if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr) NULL, (png_error_ptr) NULL)) == NULL){
fclose(file);
return false;
}
if ((info_ptr = png_create_info_struct(png_ptr)) == NULL){
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(file);
return false;
}
// initialize the png structure
png_init_io(png_ptr, file);
png_set_sig_bytes(png_ptr, 8);
// read all PNG info up to image data
png_read_info(png_ptr, info_ptr);
// get width, height, bit-depth and color-type
png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) &width, (png_uint_32 *) &height, &iBitDepth, &iColorType, NULL, NULL, NULL);
depth = 1;
nMipMaps = 1;
int nChannels = png_get_channels(png_ptr, info_ptr);
switch (nChannels){
case 1:
format = FORMAT_I8;
break;
case 3:
format = FORMAT_RGB8;
break;
case 4:
format = FORMAT_RGBA8;
break;
}
int rowSize = width * nChannels * iBitDepth / 8;
// now we can allocate memory to store the image
pixels = new unsigned char[rowSize * height];
// set the individual row-pointers to point at the correct offsets
ppbRowPointers = new png_bytep[height];
for (int i = 0; i < height; i++)
ppbRowPointers[i] = pixels + i * rowSize;
// now we can go ahead and just read the whole image
png_read_image(png_ptr, ppbRowPointers);
// read the additional chunks in the PNG file (not really needed)
png_read_end(png_ptr, NULL);
delete ppbRowPointers;
if (iColorType == PNG_COLOR_TYPE_PALETTE){
png_colorp palette;
int num_palette;
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
unsigned char *newPixels = new unsigned char[width * height * 3];
if (iBitDepth == 4){
for (int i = 0; i < rowSize * height; i++){
unsigned int i0 = pixels[i] >> 4;
unsigned int i1 = pixels[i] & 0xF;
newPixels[6 * i ] = palette[i0].red;
newPixels[6 * i + 1] = palette[i0].green;
newPixels[6 * i + 2] = palette[i0].blue;
newPixels[6 * i + 3] = palette[i1].red;
newPixels[6 * i + 4] = palette[i1].green;
newPixels[6 * i + 5] = palette[i1].blue;
}
} else {
for (int i = 0; i < rowSize * height; i++){
newPixels[3 * i ] = palette[pixels[i]].red;
newPixels[3 * i + 1] = palette[pixels[i]].green;
newPixels[3 * i + 2] = palette[pixels[i]].blue;
}
}
format = FORMAT_RGB8;
delete pixels;
pixels = newPixels;
}
// and we're done
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(file);
return true;
}
Är du inte intresserad av stöd för paletterade png eller gråskala osv så går det att kapa ner lite.