libpng.c
上传用户:tangyu_668
上传日期:2014-02-27
资源大小:678k
文件大小:3k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2006 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include <stdio.h>
  22. #include <malloc.h>
  23. #include "libpng.h"
  24. #include "....libpngpng.h"
  25. static void read_data_fn(png_structp png_ptr, png_bytep data, png_size_t length)
  26. {
  27. struct png_t* png = (struct png_t*)png_get_progressive_ptr(png_ptr);
  28. if(png->pos + length > png->size) png_error(png_ptr, "Read Error");
  29. memcpy(data, &png->data[png->pos], length);
  30. png->pos += length;
  31. }
  32. unsigned char* DecompressPNG(struct png_t* png, int* w, int* h)
  33. {
  34.     png_structp png_ptr;
  35. png_infop info_ptr;
  36. png_infop end_info;
  37. unsigned char* pic;
  38. unsigned char* row;
  39. unsigned int x, y, c;
  40. if(png_sig_cmp(png->data, 0, 8) != 0)  return NULL;
  41. png->pos = 8;
  42.     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  43. // (png_voidp)user_error_ptr, user_error_fn, user_warning_fn);
  44.     if(!png_ptr) 
  45. return NULL;
  46.     png_set_read_fn(png_ptr, (png_voidp)png, read_data_fn);
  47.     info_ptr = png_create_info_struct(png_ptr);     if(!info_ptr)     {         png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);         return NULL;     }
  48.     end_info = png_create_info_struct(png_ptr);     if(!end_info)     {         png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);         return NULL;     }
  49.     if(setjmp(png_jmpbuf(png_ptr)))     {         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);         return NULL;     }
  50. png_set_sig_bytes(png_ptr, 8);
  51. png_read_png(
  52. png_ptr, info_ptr, 
  53. PNG_TRANSFORM_STRIP_16 | 
  54. PNG_TRANSFORM_STRIP_ALPHA | 
  55. PNG_TRANSFORM_PACKING |
  56. PNG_TRANSFORM_EXPAND |
  57. PNG_TRANSFORM_BGR, 
  58. NULL);
  59. if(png_get_channels(png_ptr, info_ptr) != 3) 
  60. {
  61.         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); return NULL;
  62. }
  63. pic = calloc(info_ptr->width * info_ptr->height, 4);
  64. *w = info_ptr->width;
  65. *h = info_ptr->height;
  66. for(y = 0; y < info_ptr->height; y++)
  67. {
  68. row = &pic[y * info_ptr->width * 4];
  69. for(x = 0; x < info_ptr->width*3; row += 4)
  70. {
  71. for(c = 0; c < 3; c++)
  72. {
  73. row[c] = info_ptr->row_pointers[y][x++];
  74. }
  75. }
  76. }
  77.     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
  78. return pic;
  79. }