⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 png.c

📁 linux下开源图片codec
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <png.h>#include "loader.h"#ifdef USE_X11# include "viewer.h"#endifstatic const char *ct[] = {    "gray",  "X1", "rgb",  "palette",    "graya", "X5", "rgba", "X7",};struct png_state {    FILE         *infile;    png_structp  png;    png_infop    info;    png_bytep    image;    png_uint_32  w,h;    int          color_type;};static void*png_init(FILE *fp, char *filename, unsigned int page,	 struct ida_image_info *i, int thumbnail){    struct png_state *h;    int bit_depth, interlace_type;    int pass, number_passes;    unsigned int y;    png_uint_32 resx, resy;    png_color_16 *file_bg, my_bg = {	.red   = 192,	.green = 192,	.blue  = 192,	.gray  = 192,    };    int unit;        h = malloc(sizeof(*h));    memset(h,0,sizeof(*h));    h->infile = fp;    h->png = png_create_read_struct(PNG_LIBPNG_VER_STRING,				    NULL, NULL, NULL);    if (NULL == h->png)	goto oops;    h->info = png_create_info_struct(h->png);    if (NULL == h->info)	goto oops;    png_init_io(h->png, h->infile);    png_read_info(h->png, h->info);    png_get_IHDR(h->png, h->info, &h->w, &h->h,		 &bit_depth,&h->color_type,&interlace_type, NULL,NULL);    png_get_pHYs(h->png, h->info, &resx, &resy, &unit);    i->width  = h->w;    i->height = h->h;    if (PNG_RESOLUTION_METER == unit)	i->dpi = res_m_to_inch(resx);    if (debug)	fprintf(stderr,"png: color_type=%s #1\n",ct[h->color_type]);    i->npages = 1;        png_set_packing(h->png);    if (bit_depth == 16)	png_set_strip_16(h->png);    if (h->color_type == PNG_COLOR_TYPE_PALETTE)	png_set_palette_to_rgb(h->png);    if (h->color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)	png_set_gray_1_2_4_to_8(h->png);    if (png_get_bKGD(h->png, h->info, &file_bg)) {	png_set_background(h->png,file_bg,PNG_BACKGROUND_GAMMA_FILE,1,1.0);    } else {	png_set_background(h->png,&my_bg,PNG_BACKGROUND_GAMMA_SCREEN,0,1.0);    }    number_passes = png_set_interlace_handling(h->png);    png_read_update_info(h->png, h->info);    h->color_type = png_get_color_type(h->png, h->info);    if (debug)	fprintf(stderr,"png: color_type=%s #2\n",ct[h->color_type]);        h->image = malloc(i->width * i->height * 4);        for (pass = 0; pass < number_passes-1; pass++) {	if (debug)	    fprintf(stderr,"png: pass #%d\n",pass);	for (y = 0; y < i->height; y++) {	    png_bytep row = h->image + y * i->width * 4;	    png_read_rows(h->png, &row, NULL, 1);	}    }    return h; oops:    if (h->image)	free(h->image);    if (h->png)	png_destroy_read_struct(&h->png, NULL, NULL);    fclose(h->infile);    free(h);    return NULL;}static voidpng_read(unsigned char *dst, unsigned int line, void *data){    struct png_state *h = data;    png_bytep row = h->image + line * h->w * 4;    switch (h->color_type) {    case PNG_COLOR_TYPE_GRAY:	png_read_rows(h->png, &row, NULL, 1);	load_gray(dst,row,h->w);	break;    case PNG_COLOR_TYPE_RGB:	png_read_rows(h->png, &row, NULL, 1);	memcpy(dst,row,3*h->w);	break;    case PNG_COLOR_TYPE_RGB_ALPHA:	png_read_rows(h->png, &row, NULL, 1);	load_rgba(dst,row,h->w);	break;    case PNG_COLOR_TYPE_GRAY_ALPHA:	png_read_rows(h->png, &row, NULL, 1);	load_graya(dst,row,h->w);	break;    default:	/* shouldn't happen */	fprintf(stderr,"Oops: %s:%d\n",__FILE__,__LINE__);	exit(1);    }}static voidpng_done(void *data){    struct png_state *h = data;    free(h->image);    png_destroy_read_struct(&h->png, &h->info, NULL);    fclose(h->infile);    free(h);}static struct ida_loader png_loader = {    magic: "\x89PNG",    moff:  0,    mlen:  4,    name:  "libpng",    init:  png_init,    read:  png_read,    done:  png_done,};static void __init init_rd(void){    load_register(&png_loader);}#ifdef USE_X11/* ---------------------------------------------------------------------- *//* save                                                                   */static intpng_write(FILE *fp, struct ida_image *img){    png_structp png_ptr = NULL;    png_infop info_ptr  = NULL;    png_bytep row;    unsigned int y;       /* Create and initialize the png_struct with the desired error handler    * functions.  If you want to use the default stderr and longjump method,    * you can supply NULL for the last three parameters.  We also check that    * the library version is compatible with the one used at compile time,    * in case we are using dynamically linked libraries.  REQUIRED.    */    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);    if (png_ptr == NULL)	goto oops;   /* Allocate/initialize the image information data.  REQUIRED */   info_ptr = png_create_info_struct(png_ptr);   if (info_ptr == NULL)       goto oops;   if (setjmp(png_jmpbuf(png_ptr)))       goto oops;   png_init_io(png_ptr, fp);   png_set_IHDR(png_ptr, info_ptr, img->i.width, img->i.height, 8,		PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,		PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);   if (img->i.dpi) {       png_set_pHYs(png_ptr, info_ptr,		    res_inch_to_m(img->i.dpi),		    res_inch_to_m(img->i.dpi),		    PNG_RESOLUTION_METER);   }   png_write_info(png_ptr, info_ptr);   png_set_packing(png_ptr);   for (y = 0; y < img->i.height; y++) {       row = img->data + y * 3 * img->i.width;       png_write_rows(png_ptr, &row, 1);   }   png_write_end(png_ptr, info_ptr);   png_destroy_write_struct(&png_ptr, &info_ptr);   return 0; oops:   fprintf(stderr,"can't save image: libpng error\n");   if (png_ptr)       png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);   return -1;}static struct ida_writer png_writer = {    label:  "PNG",    ext:    { "png", NULL},    write:  png_write,};static void __init init_wr(void){    write_register(&png_writer);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -