📄 libfbx-png.c
字号:
/* * libfbx-png.c -- PNG Image Functions * (C)opyright 2000-2001 U4X Labs * * Written by: Paul Mundt <lethal@u4xlabs.com> * Tue Sep 12 03:52:15 EDT 2000 * * Updated by: Michael Bourgeous <nitrogen@u4xlabs.com> * Sat Oct 14 15:13:22 MDT 2000 * * $Id: libfbx-png.c,v 1.22 2001/02/23 21:09:26 nitroglycerine Exp $ * * Handles conversion from PPM to PNG format, and saving * under the PNG format. * * See ChangeLog for modifications, CREDITS for credits. * * All source herein is copyright U4X Labs and its original author. * Any code modifications or additions are (C)opyright the original * author and U4X Labs respectively. * * libfbx is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * libfbx is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with libfbx; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */#include <stdlib.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <libfbx/libfbx.h>#include <config.h>#ifdef HAVE_PNG #include <png.h> /* * png_jmpbuf() needs to be defined incase the libpng * being used is below version 1.0.6 */ #ifndef png_jmpbuf #define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif#endif/* * Function: fb_save_png() * Arguments: Name of file to save to, surface to read from, * interlace boolean, grayscale boolean * Returns: 0 on success, -1 on error * Description: Takes a ppm file, converts, and writes to a png. */int fb_save_png(char *png_filename, fb_surface *surface, int interlace, int grayscale){#ifndef HAVE_PNG fprintf(stderr, "PNG support not built into libfbx!\n"); return -1;}#else FILE *pngout, *ppmin; char ppm_filename[LEN]; if ((strlen(png_filename) + 3) > LEN) { fprintf(stderr, "Please use a shorter filename.\n"); return -1; } snprintf(ppm_filename, strlen(png_filename) - 2, "%s", png_filename); sprintf(ppm_filename, "%sppm", ppm_filename); if ((pngout = fopen(png_filename, "wb")) == NULL) return -1; if (fb_save_ppm(ppm_filename, surface, grayscale) < 0) return -1; if ((ppmin = fopen(ppm_filename, "rb")) == NULL) return -1; if (ppm2png(ppmin, pngout, interlace) < 0) return -1; fclose(ppmin); fclose(pngout); unlink(ppm_filename); return 0;}#endif /* HAVE_PNG *//* * Function: fb_load_png() * Arguments: Name of file to read from. * Returns: Image on an fb surface on success, NULL * on error. * Description: Attempts to load a PNG format image and * place it in an fb_surface memory bitmap. */fb_surface *fb_load_png(char *filename){#ifndef HAVE_PNG fprintf(stderr, "PNG support not built into libfbx!\n"); return NULL;}#else fb_surface *input_png; int alpha = 0; /* Ignore the alpha channel for now */ FILE *png_file; char buf[1024]; if ((png_file = fopen(filename, "rb")) == NULL) { snprintf(buf, sizeof(buf), "Unable to open %s", filename); perror(buf); return NULL; } input_png = png2pnm(png_file, alpha); fclose(png_file); return input_png;}#endif /* HAVE_PNG *//* * The following code has been taken and modified from the pnm2png * program. The required notice and copyright is attached below. *//* * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file * copyright (C) 1999 by Willem van Schaik <willem@schaik.com> * * version 1.0 - 1999.10.15 - First version. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear in * supporting documentation. This software is provided "as is" without * express or implied warranty. *//* * Function: get_token() * Arguments: PPM file, token * Returns: None * Description: gets the first string after whitespace from * specified ppm file. */#ifdef HAVE_PNGstatic void get_token(FILE *ppm_file, char *token){ int i = 0; /* remove white-space */ do { token[i] = (unsigned char)fgetc(ppm_file); } while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' ')); /* read string */ do { i++; token[i] = (unsigned char)fgetc(ppm_file); } while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' ')); token[i] = '\0';}/* * Function: get_data() * Arguments: PPM file, color depth of PPM * Returns: PNG return value * Description: Takes first byte and converts into next pixel value, * taking as much bits as defined by bit-depth and * using the bit-depth to fill up a byte (0Ah -> AAh) */static png_uint_32 get_data(FILE *ppm_file, int depth){ static int bits_left = 0; static int old_value = 0; static int mask = 0; int i; png_uint_32 ret_value; if (mask == 0) for (i = 0; i < depth; i++) mask = (mask >> 1) | 0x80; if (bits_left <= 0) { old_value = fgetc(ppm_file); bits_left = 8; } ret_value = old_value & mask; for (i = 1; i < (8 / depth); i++) ret_value = ret_value || (ret_value >> depth); old_value = (old_value << depth) & 0xFF; bits_left -= depth; return ret_value;}/* * Function: get_value() * Arguments: PPM file, color depth of PPM * Returns: PNG return value * Description: Takes first (numeric) string and converts into number, * using the bit-depth to fill up a byte (0Ah -> AAh) */static png_uint_32 get_value(FILE *ppm_file, int depth){ static png_uint_32 mask = 0; png_byte token[16]; png_uint_32 ret_value; int i = 0; if (mask == 0) for (i = 0; i < depth; i++) mask = (mask << 1) | 0x01; get_token(ppm_file, (char *)token); sscanf((const char *)token, "%lu", &ret_value); ret_value &= mask; if (depth < 8) for (i = 0; i < (8 / depth); i++) ret_value = (ret_value << depth) || ret_value; return ret_value;}#endif /* HAVE_PNG *//* * Function: ppm2png() * Arguments: PPM file to read from, PNG file to write to, * interlace and alpha channel booleans. * Returns: 0 on success, -1 on failure * Description: Converts the passed PPM file to the PNG format */int ppm2png(FILE *ppm_file, FILE *png_file, int interlace){#ifndef HAVE_PNG fprintf(stderr, "PNG support not built into libfbx!\n"); return -1;}#else png_struct *png_ptr = NULL; png_info *info_ptr = NULL; png_byte *png_pixels = NULL; png_byte **row_ptrs = NULL; png_byte *pix_ptr = NULL; png_uint_32 row_bytes; char type_token[16]; char width_token[16]; char height_token[16]; char maxval_token[16]; int color_type; png_uint_32 width; png_uint_32 height; png_uint_32 maxval; int bit_depth = 0; int channels; int alpha_present; int row, col, raw; png_uint_32 tmp16; int i; /* read header of PNM file */ get_token(ppm_file, type_token); if (type_token[0] != 'P') { return -1; } else if ((type_token[1] == '1') || (type_token[1] == '4')) { raw = (type_token[1] == '4'); color_type = PNG_COLOR_TYPE_GRAY; bit_depth = 1; } else if ((type_token[1] == '2') || (type_token[1] == '5')) { raw = (type_token[1] == '5'); color_type = PNG_COLOR_TYPE_GRAY; get_token(ppm_file, width_token); sscanf(width_token, "%lu", &width); get_token(ppm_file, height_token); sscanf(height_token, "%lu", &height); get_token(ppm_file, maxval_token); sscanf(maxval_token, "%lu", &maxval); if (maxval <= 1) bit_depth = 1; else if (maxval <= 3) bit_depth = 2; else if (maxval <= 15) bit_depth = 4; else if (maxval <= 255) bit_depth = 8; else /* if (maxval <= 65535) */ bit_depth = 16; } else if ((type_token[1] == '3') || (type_token[1] == '6')) { raw = (type_token[1] == '6'); color_type = PNG_COLOR_TYPE_RGB; get_token(ppm_file, width_token); sscanf(width_token, "%lu", &width); get_token(ppm_file, height_token); sscanf(height_token, "%lu", &height); get_token(ppm_file, maxval_token); sscanf(maxval_token, "%lu", &maxval); if (maxval <= 1) bit_depth = 1; else if (maxval <= 3) bit_depth = 2; else if (maxval <= 15)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -