Subversion Repositories pentevo

Rev

Rev 1081 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "sshot_png.h"
  6.  
  7. typedef void (PNGAPI *png_write_end_ptr) PNGARG((png_structp png_ptr,
  8.    png_infop info_ptr));
  9. typedef void (PNGAPI *png_write_image_ptr) PNGARG((png_structp png_ptr,
  10.    png_bytepp image));
  11. typedef void (PNGAPI *png_set_bgr_ptr) PNGARG((png_structp png_ptr));
  12. typedef void (PNGAPI *png_write_info_ptr) PNGARG((png_structp png_ptr,
  13.    png_infop info_ptr));
  14. typedef void (PNGAPI *png_set_IHDR_ptr) PNGARG((png_structp png_ptr,
  15.    png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
  16.    int color_type, int interlace_method, int compression_method,
  17.    int filter_method));
  18. typedef void (PNGAPI *png_set_write_fn_ptr) PNGARG((png_structp png_ptr,
  19.    png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
  20. typedef void (PNGAPI *png_destroy_write_struct_ptr)
  21.    PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
  22. typedef png_infop (PNGAPI *png_create_info_struct_ptr)
  23.    PNGARG((png_structp png_ptr));
  24. typedef void (PNGAPI *png_set_compression_level_ptr) PNGARG((png_structp png_ptr,
  25.    int level));
  26. typedef png_structp (PNGAPI *png_create_write_struct_ptr)
  27.    PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
  28.    png_error_ptr error_fn, png_error_ptr warn_fn));
  29. typedef void (PNGAPI *png_set_filter_ptr) PNGARG((png_structp png_ptr, int method,
  30.    int filters));
  31.  
  32. static png_error_ptr png_error_p = nullptr;
  33. static png_write_end_ptr png_write_end_p = nullptr;
  34. static png_write_image_ptr png_write_image_p = nullptr;
  35. static png_set_bgr_ptr png_set_bgr_p = nullptr;
  36. static png_write_info_ptr png_write_info_p = nullptr;
  37. static png_set_IHDR_ptr png_set_IHDR_p = nullptr;
  38. static png_set_write_fn_ptr png_set_write_fn_p = nullptr;
  39. static png_destroy_write_struct_ptr png_destroy_write_struct_p = nullptr;
  40. static png_create_info_struct_ptr png_create_info_struct_p = nullptr;
  41. static png_set_compression_level_ptr png_set_compression_level_p = nullptr;
  42. static png_create_write_struct_ptr png_create_write_struct_p = nullptr;
  43. static png_set_filter_ptr png_set_filter_p = nullptr;
  44.  
  45. static HMODULE PngDll = nullptr;
  46. bool PngInit()
  47. {
  48. #if defined(_WIN64) || defined(AMD64)
  49.         PngDll = LoadLibrary("libpng64.dll");
  50. #else
  51.         PngDll = LoadLibrary("libpng16.dll");
  52. #endif
  53.     if(!PngDll)
  54.         return false;
  55.     png_error_p = (png_error_ptr)GetProcAddress(PngDll, "png_error");
  56.     if(!png_error_p)
  57.         return false;
  58.     png_write_end_p = (png_write_end_ptr)GetProcAddress(PngDll, "png_write_end");
  59.     if(!png_write_end_p)
  60.         return false;
  61.     png_write_image_p = (png_write_image_ptr)GetProcAddress(PngDll, "png_write_image");
  62.     if(!png_write_image_p)
  63.         return false;
  64.     png_set_bgr_p = (png_set_bgr_ptr)GetProcAddress(PngDll, "png_set_bgr");
  65.     if(!png_set_bgr_p)
  66.         return false;
  67.     png_write_info_p = (png_write_info_ptr)GetProcAddress(PngDll, "png_write_info");
  68.     if(!png_write_info_p)
  69.         return false;
  70.     png_set_IHDR_p = (png_set_IHDR_ptr)GetProcAddress(PngDll, "png_set_IHDR");
  71.     if(!png_set_IHDR_p)
  72.         return false;
  73.     png_set_write_fn_p = (png_set_write_fn_ptr)GetProcAddress(PngDll, "png_set_write_fn");
  74.     if(!png_set_write_fn_p)
  75.         return false;
  76.     png_destroy_write_struct_p = (png_destroy_write_struct_ptr)GetProcAddress(PngDll, "png_destroy_write_struct");
  77.     if(!png_destroy_write_struct_p)
  78.         return false;
  79.     png_create_info_struct_p = (png_create_info_struct_ptr)GetProcAddress(PngDll, "png_create_info_struct");
  80.     if(!png_create_info_struct_p)
  81.         return false;
  82.     png_set_compression_level_p = (png_set_compression_level_ptr)GetProcAddress(PngDll, "png_set_compression_level");
  83.     if(!png_set_compression_level_p)
  84.         return false;
  85.     png_create_write_struct_p = (png_create_write_struct_ptr)GetProcAddress(PngDll, "png_create_write_struct");
  86.     if(!png_create_write_struct_p)
  87.         return false;
  88.     png_set_filter_p = (png_set_filter_ptr)GetProcAddress(PngDll, "png_set_filter");
  89.     if(!png_set_filter_p)
  90.         return false;
  91.     return true;
  92. }
  93.  
  94. void PngDone()
  95. {
  96.     if(PngDll)
  97.         FreeLibrary(PngDll);
  98. }
  99.  
  100. static png_structp png_ptr = nullptr;
  101. static png_infop info_ptr = nullptr;
  102. static FILE *io_ptr;
  103.  
  104. static void
  105. PNGAPI
  106. png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
  107. {
  108.    size_t check;
  109.  
  110.    check = fwrite(data, 1, length, (FILE *)(io_ptr));
  111.    if (check != length)
  112.    {
  113.       png_error_p(png_ptr, "Write Error");
  114.    }
  115. }
  116.  
  117. static void
  118. PNGAPI
  119. png_flush(png_structp png_ptr)
  120. {
  121.         /*
  122.    FILE *io_ptr;
  123.    io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
  124.    */
  125.         if (io_ptr != nullptr)
  126.       fflush(io_ptr);
  127.  
  128. }
  129.  
  130. BOOL PngSaveImage (FILE *pfFile, png_byte *pDiData,
  131.                    int iWidth, int iHeight, png_color bkgColor)
  132. {
  133.     (void)bkgColor;
  134.  
  135.     const int           ciBitDepth = 8;
  136.     const int           ciChannels = 3;
  137.  
  138.     png_uint_32         ulRowBytes;
  139.     static png_byte   **ppbRowPointers = nullptr;
  140.     int                 i;
  141.  
  142.     // prepare the standard PNG structures
  143.     png_ptr = png_create_write_struct_p(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  144.     if (!png_ptr)
  145.     {
  146.         return FALSE;
  147.     }
  148.  
  149.     png_set_filter_p(png_ptr, 0, PNG_NO_FILTERS);
  150.  
  151.     png_set_compression_level_p(png_ptr, 4/*Z_BEST_COMPRESSION*/);
  152.  
  153.     info_ptr = png_create_info_struct_p(png_ptr);
  154.     if (!info_ptr)
  155.     {
  156.         png_destroy_write_struct_p(&png_ptr, (png_infopp) nullptr);
  157.         return FALSE;
  158.     }
  159.  
  160.     // initialize the png structure
  161.         io_ptr = pfFile;
  162.     png_set_write_fn_p(png_ptr, (png_voidp)pfFile, (png_rw_ptr)png_write_data, png_flush);
  163.    
  164.     // we're going to write a very simple 3x8 bit RGB image
  165.     png_set_IHDR_p(png_ptr, info_ptr, png_uint_32(iWidth), png_uint_32(iHeight), ciBitDepth,
  166.         PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
  167.         PNG_FILTER_TYPE_BASE);
  168.    
  169.     // write the file header information
  170.     png_write_info_p(png_ptr, info_ptr);
  171.    
  172.     // swap the BGR pixels in the DiData structure to RGB
  173.     png_set_bgr_p(png_ptr);
  174.    
  175.     // row_bytes is the width x number of channels
  176.     ulRowBytes = png_uint_32(iWidth * ciChannels);
  177.    
  178.     // we can allocate memory for an array of row-pointers
  179.     ppbRowPointers = (png_bytepp) malloc(unsigned(iHeight) * sizeof(png_bytep));
  180.    
  181.     // set the individual row-pointers to point at the correct offsets
  182.     for (i = 0; i < iHeight; i++)
  183.         ppbRowPointers[i] = pDiData + unsigned(i) * (((ulRowBytes + 3) >> 2) << 2);
  184.  
  185.     // write out the entire image data in one call
  186.     png_write_image_p(png_ptr, ppbRowPointers);
  187.    
  188.     // write the additional chunks to the PNG file (not really needed)
  189.     png_write_end_p(png_ptr, info_ptr);
  190.    
  191.     // and we're done
  192.     free (ppbRowPointers);
  193.     ppbRowPointers = nullptr;
  194.  
  195.        
  196.    
  197.     // clean up after the write, and free any memory allocated
  198.     png_destroy_write_struct_p(&png_ptr, (png_infopp) nullptr);
  199.    
  200.     return TRUE;
  201. }
  202.