📄 libfbx-png.c
字号:
bit_depth = 4; else if (maxval <= 255) bit_depth = 8; else /* if (maxval <= 65535) */ bit_depth = 16; } else { return -1; } /* calculate the number of channels and store alpha-presence */ if (color_type == PNG_COLOR_TYPE_GRAY) channels = 1; else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) channels = 2; else if (color_type == PNG_COLOR_TYPE_RGB) channels = 3; else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) channels = 4; else channels = 0; /* should not happen */ alpha_present = (channels - 1) % 2; /* row_bytes is the width x number of channels x (bit-depth / 8) */ row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); if ((png_pixels = (png_byte *)malloc(row_bytes * height * sizeof(png_byte))) == NULL) return -1; /* read data from PNM file */ pix_ptr = png_pixels; for (row = 0; row < height; row++) { for (col = 0; col < width; col++) { for (i = 0; i < (channels - alpha_present); i++) { if (raw) *pix_ptr++ = get_data(ppm_file, bit_depth); else if (bit_depth <= 8) *pix_ptr++ = get_value(ppm_file, bit_depth); else { tmp16 = get_value(ppm_file, bit_depth); *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF); pix_ptr++; *pix_ptr = (png_byte) (tmp16 & 0xFF); pix_ptr++; } } } } /* prepare the standard PNG structures */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return -1; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); return -1; } /* * setjmp() must be called in every function that calls a * PNG-reading libpng function */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); return -1; } /* initialize the png structure */ png_init_io(png_ptr, png_file); /* we're going to write more or less the same PNG as the input file */ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* write the file header information */ png_write_info(png_ptr, info_ptr); /* if needed we will allocate memory for an new array of row-pointers */ if (row_ptrs == (unsigned char **)NULL) { if ((row_ptrs = (png_byte **) malloc(height * sizeof(png_bytep))) == NULL) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); return -1; } } /* set the individual row_ptrs to point at the correct offsets */ for (i = 0; i < (height); i++) row_ptrs[i] = png_pixels + i * row_bytes; /* write out the entire image data in one call */ png_write_image(png_ptr, row_ptrs); /* write the additional chuncks to the PNG file (not really needed) */ png_write_end(png_ptr, info_ptr); /* clean up after the write, and free any memory allocated */ png_destroy_write_struct(&png_ptr, (png_infopp) NULL); if (row_ptrs != (unsigned char **)NULL) free(row_ptrs); if (png_pixels != (unsigned char *)NULL) free(png_pixels); return 0;}#endif /* HAVE_PNG *//* FIXME: Should probably rename this to something more sensible. *//* * Function: png2pnm() * Arguments: File pointer to read from, alpha boolean. * Returns: Image on an fb surface on success, NULL * on error. * Description: Converts a PNG to a PPM. */fb_surface *png2pnm(FILE *png_file, int alpha){#ifndef HAVE_PNG fprintf(stderr, "PNG support not built into libfbx!\n"); return NULL;}#else fb_surface *input_png; png_struct *png_ptr = NULL; png_info *info_ptr = NULL; png_byte buf[8]; png_byte *png_pixels = NULL; png_byte **row_pointers = NULL; png_byte *pix_ptr = NULL; png_uint_32 row_bytes; png_uint_32 width; png_uint_32 height; unsigned char r, g, b, a = '\0'; int bit_depth; int channels; int color_type; int alpha_present; int row, col; int ret; int i; /* read and check signature in PNG file */ ret = fread(buf, 1, 8, png_file); if (ret != 8) return NULL; ret = png_check_sig(buf, 8); if (!ret) return NULL; /* create png and info structures */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return NULL; /* out of memory */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return NULL; /* out of memory */ } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } /* set up the input control for C streams */ png_init_io(png_ptr, png_file); png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ /* read the file information */ png_read_info(png_ptr, info_ptr); /* get size and bit-depth of the PNG-image */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); /* * set-up the transformations */ /* transform paletted images into full-color rgb */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); /* expand images to bit-depth 8 (only applicable for grayscale images) */ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); /* transform transparency maps into full alpha-channel */ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);#ifdef NJET /* downgrade 16-bit images to 8 bit */ if (bit_depth == 16) png_set_strip_16(png_ptr); /* transform grayscale images into full-color */ if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); /* only if file has a file gamma, we do a correction */ if (png_get_gAMA(png_ptr, info_ptr, &file_gamma)) png_set_gamma(png_ptr, (double) 2.2, file_gamma);#endif /* all transformations have been registered; now update info_ptr data, * get rowbytes and channels, and allocate image memory */ png_read_update_info(png_ptr, info_ptr); /* get the new color-type and bit-depth (after expansion/stripping) */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); /* calculate new number of channels and store alpha-presence */ if (color_type == PNG_COLOR_TYPE_GRAY) channels = 1; else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) channels = 2; else if (color_type == PNG_COLOR_TYPE_RGB) channels = 3; else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) channels = 4; else channels = 0; /* should never happen */ alpha_present = (channels - 1) % 2; /* check if alpha is expected to be present in file */ if (alpha && !alpha_present) return NULL; /* row_bytes is the width x number of channels x (bit-depth / 8) */ row_bytes = png_get_rowbytes(png_ptr, info_ptr); if ((png_pixels = (png_byte *)malloc(row_bytes * height * sizeof(png_byte))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } if ((row_pointers = (png_byte **)malloc(height * sizeof(png_bytep))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(png_pixels); png_pixels = NULL; return NULL; } /* set the individual row_pointers to point at the correct offsets */ for (i = 0; i < (height); i++) row_pointers[i] = png_pixels + i * row_bytes; /* now we can go ahead and just read the whole image */ png_read_image(png_ptr, row_pointers); /* read rest of file and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); /* write data to PNM file */ pix_ptr = png_pixels; input_png = fb_create_surface(width, height); for (row = 0; row < height; row++) { for (col = 0; col < width; col++) { if (bit_depth == 16) { r = (((unsigned char)*pix_ptr++ << 8) + (unsigned char)*pix_ptr++); g = (((unsigned char)*pix_ptr++ << 8) + (unsigned char)*pix_ptr++); b = (((unsigned char)*pix_ptr++ << 8) + (unsigned char)*pix_ptr++); if (alpha) a = (((unsigned char)*pix_ptr++ << 8) + (unsigned char)*pix_ptr++); } else { r = (unsigned char)*pix_ptr++; g = (unsigned char)*pix_ptr++; b = (unsigned char)*pix_ptr++; if (alpha) a = (unsigned char)*pix_ptr++; } alpha ? fb_putpixel_alpha(a, col, row, r, g, b, input_png) : fb_putpixel(col, row, r, g, b, input_png); } } if (row_pointers != (unsigned char **)NULL) free(row_pointers); if (png_pixels != (unsigned char *)NULL) free(png_pixels); return input_png;}#endif /* HAVE_PNG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -