IMAPNG.CPP
上传用户:wep9318
上传日期:2007-01-07
资源大小:893k
文件大小:8k
源码类别:

图片显示

开发平台:

Visual C++

  1. /*
  2.  * File: imapng.cc
  3.  * Purpose: Platform Independent JPEG Image Class
  4.  * Author: Alejandro Aguilar Sierra
  5.  * Created: 1995
  6.  * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
  7.  *
  8.  *      logjmp
  9.  */
  10. // #include "stdafx.h"
  11. #include "imapng.h"
  12. #if CIMAGE_SUPPORT_PNG
  13.    
  14. extern "C" {
  15. #include "png.h"
  16. }
  17. #include "imaiter.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. void
  24. ima_png_error(png_struct *png_ptr, char *message)
  25. {
  26. //        AfxMessageBox(message);
  27. longjmp(png_ptr->jmpbuf, 1);
  28. }
  29. BOOL
  30. CImagePNG::ReadFile(const CString& imageFileName)
  31. {
  32.   int number_passes;
  33.   if (imageFileName != "")
  34.     filename = imageFileName;
  35. FILE *fp;
  36. png_struct *png_ptr;
  37.    png_info *info_ptr;
  38. CImageIterator iter(this);
  39. /* open the file */
  40. fp = fopen((const char *)filename, "rb");
  41. if (!fp)
  42. return FALSE;
  43. /* allocate the necessary structures */
  44. png_ptr = new (png_struct);
  45. if (!png_ptr)
  46. {
  47. fclose(fp);
  48. return FALSE;
  49. }
  50. info_ptr = new (png_info);
  51. if (!info_ptr)
  52. {
  53. fclose(fp);
  54. delete(png_ptr);
  55. return FALSE;
  56. }
  57. /* set error handling */
  58. if (setjmp(png_ptr->jmpbuf))
  59. {
  60. png_read_destroy(png_ptr, info_ptr, (png_info *)0);
  61. fclose(fp);
  62. delete(png_ptr);
  63. delete(info_ptr);
  64. /* If we get here, we had a problem reading the file */
  65. return FALSE;
  66. }
  67.         //png_set_error(ima_png_error, NULL);
  68. /* initialize the structures, info first for error handling */
  69. png_info_init(info_ptr);
  70. png_read_init(png_ptr);
  71. /* set up the input control */
  72. png_init_io(png_ptr, fp);
  73. /* read the file information */
  74. png_read_info(png_ptr, info_ptr);
  75. /* allocate the memory to hold the image using the fields
  76. of png_info. */
  77. png_color_16 my_background={ 0, 31, 127, 255, 0 };
  78.  /*
  79. if (info_ptr->valid & PNG_INFO_bKGD)
  80. png_set_background(png_ptr, &(info_ptr->background),
  81. PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
  82. else   */ {//puts(" back ");
  83. png_set_background(png_ptr, &my_background,
  84. PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
  85.  }
  86. /* tell libpng to strip 16 bit depth files down to 8 bits */
  87. if (info_ptr->bit_depth == 16)
  88. png_set_strip_16(png_ptr);
  89. int pixel_depth=(info_ptr->pixel_depth<24) ? info_ptr->pixel_depth: 24;
  90. Create(info_ptr->width, info_ptr->height, pixel_depth,
  91. info_ptr->color_type);
  92. if (info_ptr->num_palette>0)
  93.   SetPalette((int)info_ptr->num_palette, (rgb_color_struct*)info_ptr->palette);
  94. int row_stride = info_ptr->width * ((pixel_depth+7)>>3);
  95.  // printf("P = %d D = %d RS= %d ", info_ptr->num_palette, info_ptr->pixel_depth,row_stride);
  96. // printf("CT = %d TRS = %d BD= %d ", info_ptr->color_type, info_ptr->valid & PNG_INFO_tRNS,info_ptr->bit_depth);
  97. byte *row_pointers = new byte[row_stride];
  98. /* turn on interlace handling */
  99. if (info_ptr->interlace_type)
  100. number_passes = png_set_interlace_handling(png_ptr);
  101. else
  102. number_passes = 1;
  103. // printf("NP = %d ", number_passes);
  104. for (int pass=0; pass< number_passes; pass++) {
  105. iter.Upset();
  106. int y=0;
  107. do {
  108. //   (unsigned char *)iter.GetRow();
  109.   if (info_ptr->interlace_type)  {
  110.  if (pass>0)
  111. iter.GetRow(row_pointers, row_stride);
  112.  png_read_row(png_ptr, row_pointers, NULL);
  113.   }
  114.   else
  115.  png_read_row(png_ptr, row_pointers, NULL);
  116.   iter.SetRow(row_pointers, row_stride);
  117.   y++;
  118. } while(iter.PrevRow());
  119. // printf("Y=%d ",y);
  120. }
  121. delete[] row_pointers;
  122. /* read the rest of the file, getting any additional chunks
  123. in info_ptr */
  124. png_read_end(png_ptr, info_ptr);
  125. /* clean up after the read, and free any memory allocated */
  126. png_read_destroy(png_ptr, info_ptr, (png_info *)0);
  127. /* free the structures */
  128. delete(png_ptr);
  129. delete(info_ptr);
  130. /* close the file */
  131. fclose(fp);
  132. /* that's it */
  133. return TRUE;
  134. }
  135. /* write a png file */
  136. BOOL CImagePNG::SaveFile(const CString& imageFileName)
  137. {
  138. if (imageFileName != "")
  139. filename = imageFileName;
  140.   CImageIterator iter(this);
  141.   FILE *fp;
  142.    png_struct *png_ptr;
  143. png_info *info_ptr;
  144.    /* open the file */
  145. fp = fopen((const char *)filename, "wb");
  146. if (!fp)
  147. return FALSE;
  148. /* allocate the necessary structures */
  149. png_ptr = new (png_struct);
  150. if (!png_ptr)
  151. {
  152. fclose(fp);
  153. return FALSE;
  154. }
  155. info_ptr = new (png_info);
  156. if (!info_ptr)
  157. {
  158. fclose(fp);
  159. delete(png_ptr);
  160. return FALSE;
  161. }
  162. /* set error handling */
  163. if (setjmp(png_ptr->jmpbuf))
  164. {
  165. png_write_destroy(png_ptr);
  166. fclose(fp);
  167. delete(png_ptr);
  168. delete(info_ptr);
  169. /* If we get here, we had a problem reading the file */
  170. return FALSE;
  171. }
  172.         //png_set_error(ima_png_error, NULL);
  173. // printf("writig pg %s ", filename);
  174.    /* initialize the structures */
  175. png_info_init(info_ptr);
  176. png_write_init(png_ptr);
  177.             
  178. int row_stride = GetWidth() * ((GetDepth()+7)>>3);
  179. /* set up the output control */
  180.    png_init_io(png_ptr, fp);
  181. /* set the file information here */
  182. info_ptr->width = GetWidth();
  183. info_ptr->height = GetHeight();
  184. info_ptr->pixel_depth = GetDepth();
  185. info_ptr->channels = (GetDepth()>8) ? 3: 1;
  186. info_ptr->bit_depth = GetDepth()/info_ptr->channels;
  187. info_ptr->color_type = GetColorType();
  188. info_ptr->compression_type = info_ptr->filter_type = info_ptr->interlace_type=0;
  189. info_ptr->valid = 0;
  190. info_ptr->rowbytes = row_stride;
  191. // printf("P = %d D = %d RS= %d GD= %d CH= %d ", info_ptr->pixel_depth, info_ptr->bit_depth, row_stride, GetDepth(), info_ptr->channels);
  192. /* set the palette if there is one */
  193. if ((GetColorType() & COLORTYPE_PALETTE) && GetPalette())
  194. {
  195.   printf("writig paleta[%d %d %x]",GetColorType() ,COLORTYPE_PALETTE, GetPalette());
  196.   info_ptr->valid |= PNG_INFO_PLTE;
  197.   info_ptr->palette = new png_color[256];
  198.   info_ptr->num_palette = 256;
  199.   for (int i=0; i<256; i++)
  200.  GetPalette()->GetRGB(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
  201. }  
  202. //   printf("Paleta [%d %d %x]",GetColorType() ,COLORTYPE_PALETTE, GetPalette());
  203.    /* optional significant bit chunk */
  204. //   info_ptr->valid |= PNG_INFO_sBIT;
  205. //   info_ptr->sig_bit = true_bit_depth;
  206. /* optional gamma chunk */
  207. //   info_ptr->valid |= PNG_INFO_gAMA;
  208. //   info_ptr->gamma = gamma;
  209. /* other optional chunks */
  210.    /* write the file information */
  211.    png_write_info(png_ptr, info_ptr);
  212.    /* set up the transformations you want.  Note that these are
  213.       all optional.  Only call them if you want them */
  214. /* shift the pixels up to a legal bit depth and fill in
  215.       as appropriate to correctly scale the image */
  216. //   png_set_shift(png_ptr, &(info_ptr->sig_bit));
  217. /* pack pixels into bytes */
  218. //   png_set_packing(png_ptr);
  219. /* flip bgr pixels to rgb */
  220. //   png_set_bgr(png_ptr);
  221.    /* swap bytes of 16 bit files to most significant bit first */
  222. //   png_set_swap(png_ptr);
  223.    /* get rid of filler bytes, pack rgb into 3 bytes */
  224. //   png_set_rgbx(png_ptr);
  225. /* If you are only writing one row at a time, this works */
  226. byte *row_pointers = new byte[row_stride];
  227.    iter.Upset();
  228. do {
  229. //   (unsigned char *)iter.GetRow();
  230.   iter.GetRow(row_pointers, row_stride);
  231.   png_write_row(png_ptr, row_pointers);
  232. } while(iter.PrevRow());
  233.         
  234.         delete[] row_pointers;
  235. /* write the rest of the file */
  236.    png_write_end(png_ptr, info_ptr);
  237. /* clean up after the write, and free any memory allocated */
  238.    png_write_destroy(png_ptr);
  239.    /* if you malloced the palette, free it here */
  240.    if (info_ptr->palette)
  241. delete[] (info_ptr->palette);
  242. /* free the structures */
  243. delete(png_ptr);
  244. delete(info_ptr);
  245. /* close the file */
  246. fclose(fp);
  247. /* that's it */
  248. return TRUE;
  249. }
  250. #endif // CIMAGE_SUPPORT_PNG