PngFile.c
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:12k
源码类别:

界面编程

开发平台:

Visual C++

  1. //-------------------------------------
  2. //  PNGFILE.C -- Image File Functions
  3. //-------------------------------------
  4. // Copyright 2000, Willem van Schaik.  For conditions of distribution and
  5. // use, see the copyright/license/disclaimer notice in png.h
  6. #include <windows.h>
  7. #include <commdlg.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include "png.h"
  11. #include "pngfile.h"
  12. #include "cexcept.h"
  13. define_exception_type(const char *);
  14. extern struct exception_context the_exception_context[1];
  15. struct exception_context the_exception_context[1];
  16. png_const_charp msg;
  17. static OPENFILENAME ofn;
  18. static png_structp png_ptr = NULL;
  19. static png_infop info_ptr = NULL;
  20. // cexcept interface
  21. static void
  22. png_cexcept_error(png_structp png_ptr, png_const_charp msg)
  23. {
  24.    if(png_ptr)
  25.      ;
  26. #ifndef PNG_NO_CONSOLE_IO
  27.    fprintf(stderr, "libpng error: %sn", msg);
  28. #endif
  29.    {
  30.       Throw msg;
  31.    }
  32. }
  33. // Windows open-file functions
  34. void PngFileInitialize (HWND hwnd)
  35. {
  36.     static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)*.png")
  37.         TEXT ("All Files (*.*)*.*");
  38.     ofn.lStructSize       = sizeof (OPENFILENAME);
  39.     ofn.hwndOwner         = hwnd;
  40.     ofn.hInstance         = NULL;
  41.     ofn.lpstrFilter       = szFilter;
  42.     ofn.lpstrCustomFilter = NULL;
  43.     ofn.nMaxCustFilter    = 0;
  44.     ofn.nFilterIndex      = 0;
  45.     ofn.lpstrFile         = NULL;          // Set in Open and Close functions
  46.     ofn.nMaxFile          = MAX_PATH;
  47.     ofn.lpstrFileTitle    = NULL;          // Set in Open and Close functions
  48.     ofn.nMaxFileTitle     = MAX_PATH;
  49.     ofn.lpstrInitialDir   = NULL;
  50.     ofn.lpstrTitle        = NULL;
  51.     ofn.Flags             = 0;             // Set in Open and Close functions
  52.     ofn.nFileOffset       = 0;
  53.     ofn.nFileExtension    = 0;
  54.     ofn.lpstrDefExt       = TEXT ("png");
  55.     ofn.lCustData         = 0;
  56.     ofn.lpfnHook          = NULL;
  57.     ofn.lpTemplateName    = NULL;
  58. }
  59. BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
  60. {
  61.     ofn.hwndOwner         = hwnd;
  62.     ofn.lpstrFile         = pstrFileName;
  63.     ofn.lpstrFileTitle    = pstrTitleName;
  64.     ofn.Flags             = OFN_HIDEREADONLY;
  65.     return GetOpenFileName (&ofn);
  66. }
  67. BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
  68. {
  69.     ofn.hwndOwner         = hwnd;
  70.     ofn.lpstrFile         = pstrFileName;
  71.     ofn.lpstrFileTitle    = pstrTitleName;
  72.     ofn.Flags             = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
  73.     return GetSaveFileName (&ofn);
  74. }
  75. // PNG image handler functions
  76. BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData,
  77.                    int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor)
  78. {
  79.     static FILE        *pfFile;
  80.     png_byte            pbSig[8];
  81.     int                 iBitDepth;
  82.     int                 iColorType;
  83.     double              dGamma;
  84.     png_color_16       *pBackground;
  85.     png_uint_32         ulChannels;
  86.     png_uint_32         ulRowBytes;
  87.     png_byte           *pbImageData = *ppbImageData;
  88.     static png_byte   **ppbRowPointers = NULL;
  89.     int                 i;
  90.     // open the PNG input file
  91.     if (!pstrFileName)
  92.     {
  93.         *ppbImageData = pbImageData = NULL;
  94.         return FALSE;
  95.     }
  96.     if (!(pfFile = fopen(pstrFileName, "rb")))
  97.     {
  98.         *ppbImageData = pbImageData = NULL;
  99.         return FALSE;
  100.     }
  101.     // first check the eight byte PNG signature
  102.     fread(pbSig, 1, 8, pfFile);
  103.     if (!png_check_sig(pbSig, 8))
  104.     {
  105.         *ppbImageData = pbImageData = NULL;
  106.         return FALSE;
  107.     }
  108.     // create the two png(-info) structures
  109.     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
  110.       (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
  111.     if (!png_ptr)
  112.     {
  113.         *ppbImageData = pbImageData = NULL;
  114.         return FALSE;
  115.     }
  116.     info_ptr = png_create_info_struct(png_ptr);
  117.     if (!info_ptr)
  118.     {
  119.         png_destroy_read_struct(&png_ptr, NULL, NULL);
  120.         *ppbImageData = pbImageData = NULL;
  121.         return FALSE;
  122.     }
  123.     Try
  124.     {
  125.         
  126.         // initialize the png structure
  127.         
  128. #if !defined(PNG_NO_STDIO)
  129.         png_init_io(png_ptr, pfFile);
  130. #else
  131.         png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data);
  132. #endif
  133.         
  134.         png_set_sig_bytes(png_ptr, 8);
  135.         
  136.         // read all PNG info up to image data
  137.         
  138.         png_read_info(png_ptr, info_ptr);
  139.         
  140.         // get width, height, bit-depth and color-type
  141.         
  142.         png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,
  143.             &iColorType, NULL, NULL, NULL);
  144.         
  145.         // expand images of all color-type and bit-depth to 3x8 bit RGB images
  146.         // let the library process things like alpha, transparency, background
  147.         
  148.         if (iBitDepth == 16)
  149.             png_set_strip_16(png_ptr);
  150.         if (iColorType == PNG_COLOR_TYPE_PALETTE)
  151.             png_set_expand(png_ptr);
  152.         if (iBitDepth < 8)
  153.             png_set_expand(png_ptr);
  154.         if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
  155.             png_set_expand(png_ptr);
  156.         if (iColorType == PNG_COLOR_TYPE_GRAY ||
  157.             iColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
  158.             png_set_gray_to_rgb(png_ptr);
  159.         
  160.         // set the background color to draw transparent and alpha images over.
  161.         if (png_get_bKGD(png_ptr, info_ptr, &pBackground))
  162.         {
  163.             png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
  164.             pBkgColor->red   = (byte) pBackground->red;
  165.             pBkgColor->green = (byte) pBackground->green;
  166.             pBkgColor->blue  = (byte) pBackground->blue;
  167.         }
  168.         else
  169.         {
  170.             pBkgColor = NULL;
  171.         }
  172.         
  173.         // if required set gamma conversion
  174.         if (png_get_gAMA(png_ptr, info_ptr, &dGamma))
  175.             png_set_gamma(png_ptr, (double) 2.2, dGamma);
  176.         
  177.         // after the transformations have been registered update info_ptr data
  178.         
  179.         png_read_update_info(png_ptr, info_ptr);
  180.         
  181.         // get again width, height and the new bit-depth and color-type
  182.         
  183.         png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth,
  184.             &iColorType, NULL, NULL, NULL);
  185.         
  186.         
  187.         // row_bytes is the width x number of channels
  188.         
  189.         ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);
  190.         ulChannels = png_get_channels(png_ptr, info_ptr);
  191.         
  192.         *piChannels = ulChannels;
  193.         
  194.         // now we can allocate memory to store the image
  195.         
  196.         if (pbImageData)
  197.         {
  198.             free (pbImageData);
  199.             pbImageData = NULL;
  200.         }
  201.         if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight)
  202.                             * sizeof(png_byte))) == NULL)
  203.         {
  204.             png_error(png_ptr, "Visual PNG: out of memory");
  205.         }
  206.         *ppbImageData = pbImageData;
  207.         
  208.         // and allocate memory for an array of row-pointers
  209.         
  210.         if ((ppbRowPointers = (png_bytepp) malloc((*piHeight)
  211.                             * sizeof(png_bytep))) == NULL)
  212.         {
  213.             png_error(png_ptr, "Visual PNG: out of memory");
  214.         }
  215.         
  216.         // set the individual row-pointers to point at the correct offsets
  217.         
  218.         for (i = 0; i < (*piHeight); i++)
  219.             ppbRowPointers[i] = pbImageData + i * ulRowBytes;
  220.         
  221.         // now we can go ahead and just read the whole image
  222.         
  223.         png_read_image(png_ptr, ppbRowPointers);
  224.         
  225.         // read the additional chunks in the PNG file (not really needed)
  226.         
  227.         png_read_end(png_ptr, NULL);
  228.         
  229.         // and we're done
  230.         
  231.         free (ppbRowPointers);
  232.         ppbRowPointers = NULL;
  233.         
  234.         // yepp, done
  235.     }
  236.     Catch (msg)
  237.     {
  238.         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  239.         *ppbImageData = pbImageData = NULL;
  240.         
  241.         if(ppbRowPointers)
  242.             free (ppbRowPointers);
  243.         fclose(pfFile);
  244.         return FALSE;
  245.     }
  246.     fclose (pfFile);
  247.     return TRUE;
  248. }
  249. BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData,
  250.                    int iWidth, int iHeight, png_color bkgColor)
  251. {
  252.     const int           ciBitDepth = 8;
  253.     const int           ciChannels = 3;
  254.     static FILE        *pfFile;
  255.     png_uint_32         ulRowBytes;
  256.     static png_byte   **ppbRowPointers = NULL;
  257.     int                 i;
  258.     // open the PNG output file
  259.     if (!pstrFileName)
  260.         return FALSE;
  261.     if (!(pfFile = fopen(pstrFileName, "wb")))
  262.         return FALSE;
  263.     // prepare the standard PNG structures
  264.     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
  265.       (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
  266.     if (!png_ptr)
  267.     {
  268.         fclose(pfFile);
  269.         return FALSE;
  270.     }
  271.     info_ptr = png_create_info_struct(png_ptr);
  272.     if (!info_ptr) {
  273.         fclose(pfFile);
  274.         png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  275.         return FALSE;
  276.     }
  277.     Try
  278.     {
  279.         // initialize the png structure
  280.         
  281. #if !defined(PNG_NO_STDIO)
  282.         png_init_io(png_ptr, pfFile);
  283. #else
  284.         png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush);
  285. #endif
  286.         
  287.         // we're going to write a very simple 3x8 bit RGB image
  288.         
  289.         png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth,
  290.             PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
  291.             PNG_FILTER_TYPE_BASE);
  292.         
  293.         // write the file header information
  294.         
  295.         png_write_info(png_ptr, info_ptr);
  296.         
  297.         // swap the BGR pixels in the DiData structure to RGB
  298.         
  299.         png_set_bgr(png_ptr);
  300.         
  301.         // row_bytes is the width x number of channels
  302.         
  303.         ulRowBytes = iWidth * ciChannels;
  304.         
  305.         // we can allocate memory for an array of row-pointers
  306.         
  307.         if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL)
  308.             Throw "Visualpng: Out of memory";
  309.         
  310.         // set the individual row-pointers to point at the correct offsets
  311.         
  312.         for (i = 0; i < iHeight; i++)
  313.             ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2);
  314.         
  315.         // write out the entire image data in one call
  316.         
  317.         png_write_image (png_ptr, ppbRowPointers);
  318.         
  319.         // write the additional chunks to the PNG file (not really needed)
  320.         
  321.         png_write_end(png_ptr, info_ptr);
  322.         
  323.         // and we're done
  324.         
  325.         free (ppbRowPointers);
  326.         ppbRowPointers = NULL;
  327.         
  328.         // clean up after the write, and free any memory allocated
  329.         
  330.         png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  331.         
  332.         // yepp, done
  333.     }
  334.     Catch (msg)
  335.     {
  336.         png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  337.         if(ppbRowPointers)
  338.             free (ppbRowPointers);
  339.         fclose(pfFile);
  340.         return FALSE;
  341.     }
  342.     
  343.     fclose (pfFile);
  344.     
  345.     return TRUE;
  346. }
  347. #ifdef PNG_NO_STDIO
  348. static void
  349. png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
  350. {
  351.    png_size_t check;
  352.    /* fread() returns 0 on error, so it is OK to store this in a png_size_t
  353.     * instead of an int, which is what fread() actually returns.
  354.     */
  355.    check = (png_size_t)fread(data, (png_size_t)1, length,
  356.       (FILE *)png_ptr->io_ptr);
  357.    if (check != length)
  358.    {
  359.       png_error(png_ptr, "Read Error");
  360.    }
  361. }
  362. static void
  363. png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  364. {
  365.    png_uint_32 check;
  366.    check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
  367.    if (check != length)
  368.    {
  369.       png_error(png_ptr, "Write Error");
  370.    }
  371. }
  372. static void
  373. png_flush(png_structp png_ptr)
  374. {
  375.    FILE *io_ptr;
  376.    io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
  377.    if (io_ptr != NULL)
  378.       fflush(io_ptr);
  379. }
  380. #endif
  381. //-----------------
  382. //  end of source
  383. //-----------------