png.c
上传用户:hengzhunsh
上传日期:2013-09-07
资源大小:19k
文件大小:5k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*
  2.     fbv  --  simple image viewer for the linux framebuffer
  3.     Copyright (C) 2000, 2001, 2003  Mateusz Golicz
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.     This program is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.     GNU General Public License for more details.
  12.     You should have received a copy of the GNU General Public License
  13.     along with this program; if not, write to the Free Software
  14.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include "config.h"
  17. #ifdef FBV_SUPPORT_PNG
  18. #include <png.h>
  19. #include "fbv.h"
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include <unistd.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #define PNG_BYTES_TO_CHECK 4
  27. #ifndef min
  28. #define min(x,y) ((x) < (y) ? (x) : (y))
  29. #endif
  30. int fh_png_id(char *name)
  31. {
  32.     int fd;
  33.     char id[4];
  34.     fd=open(name,O_RDONLY); if(fd==-1) return(0);
  35.     read(fd,id,4);
  36.     close(fd);
  37.     if(id[1]=='P' && id[2]=='N' && id[3]=='G') return(1);
  38.     return(0);
  39. }
  40.     
  41. int fh_png_load(char *name,unsigned char *buffer, unsigned char ** alpha,int x,int y)
  42. {
  43.     png_structp png_ptr;
  44.     png_infop info_ptr;
  45.     png_uint_32 width, height;
  46.     int i;
  47.     int bit_depth, color_type, interlace_type;
  48.     int number_passes,pass, trans = 0;
  49.     char *rp;
  50.     png_bytep rptr[2];
  51.     char *fbptr;
  52.     FILE *fh;
  53.     if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE);
  54.     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  55.     if (png_ptr == NULL) return(FH_ERROR_FORMAT);
  56.     info_ptr = png_create_info_struct(png_ptr);
  57.     if (info_ptr == NULL)
  58.     {
  59. png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
  60.         fclose(fh); return(FH_ERROR_FORMAT);
  61.     }
  62.     rp=0;
  63.     if (setjmp(png_ptr->jmpbuf))
  64.     {
  65. png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
  66.         if(rp) free(rp);
  67. fclose(fh); return(FH_ERROR_FORMAT);
  68.     }
  69.     png_init_io(png_ptr,fh);
  70.     png_read_info(png_ptr, info_ptr);
  71.     png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL);
  72.     if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); 
  73.     if (bit_depth < 8) png_set_packing(png_ptr);
  74.     if (color_type == PNG_COLOR_TYPE_GRAY || color_type== PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr);
  75. if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
  76. {
  77. trans = 1;
  78. png_set_tRNS_to_alpha(png_ptr);
  79. }
  80.     if(bit_depth == 16) png_set_strip_16(png_ptr); 
  81.     number_passes = png_set_interlace_handling(png_ptr);
  82.     png_read_update_info(png_ptr,info_ptr);
  83. if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGB_ALPHA || trans)
  84. {
  85. unsigned char * alpha_buffer = (unsigned char*) malloc(width * height);
  86. unsigned char * aptr;
  87.      rp = (char*) malloc(width * 4);
  88.     rptr[0] = (png_bytep) rp;
  89.     
  90. *alpha = alpha_buffer;
  91.     for (pass = 0; pass < number_passes; pass++)
  92.      {
  93. fbptr = buffer;
  94. aptr = alpha_buffer;
  95. for(i=0; i<height; i++)
  96.      {
  97. int n;
  98. unsigned char *trp = rp;
  99.          png_read_rows(png_ptr, rptr, NULL, 1);
  100. for(n = 0; n < width; n++, fbptr += 3, trp += 4)
  101. {
  102. memcpy(fbptr, trp, 3);
  103. *(aptr++) = trp[3];
  104. }
  105. }
  106.      }
  107.     free(rp);
  108. }
  109. else
  110. {
  111.     for (pass = 0; pass < number_passes; pass++)
  112.      {
  113. fbptr = buffer;
  114. for(i=0; i<height; i++, fbptr += width*3)
  115.      {
  116.     rptr[0] = (png_bytep) fbptr;
  117.          png_read_rows(png_ptr, rptr, NULL, 1);
  118. }
  119.      }
  120. }
  121.     png_read_end(png_ptr, info_ptr);
  122.     png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
  123.     fclose(fh);
  124.     return(FH_ERROR_OK);
  125. }
  126. int fh_png_getsize(char *name,int *x,int *y)
  127. {
  128.     png_structp png_ptr;
  129.     png_infop info_ptr;
  130.     png_uint_32 width, height;
  131.     int bit_depth, color_type, interlace_type;
  132.     char *rp;
  133.     FILE *fh;
  134.     if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE);
  135.     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  136.     if (png_ptr == NULL) return(FH_ERROR_FORMAT);
  137.     info_ptr = png_create_info_struct(png_ptr);
  138.     if (info_ptr == NULL)
  139.     {
  140. png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
  141.         fclose(fh); return(FH_ERROR_FORMAT);
  142.     }
  143.     rp=0;
  144.     if (setjmp(png_ptr->jmpbuf))
  145.     {
  146. png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
  147.         if(rp) free(rp);
  148. fclose(fh); return(FH_ERROR_FORMAT);
  149.     }
  150.    
  151.     png_init_io(png_ptr,fh);
  152.     png_read_info(png_ptr, info_ptr);
  153.     png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL);
  154.     png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
  155.     *x=width;
  156.     *y=height;
  157.     fclose(fh);
  158.     return(FH_ERROR_OK);
  159. }
  160. #endif