Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 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
 
784 DimkaM 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;
716 lvd 44
 
784 DimkaM 45
static HMODULE PngDll = nullptr;
716 lvd 46
bool PngInit()
47
{
1081 fyrex 48
#if defined(_WIN64) || defined(AMD64)
49
        PngDll = LoadLibrary("libpng64.dll");
50
#else
51
        PngDll = LoadLibrary("libpng16.dll");
52
#endif
716 lvd 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
 
784 DimkaM 100
static png_structp png_ptr = nullptr;
101
static png_infop info_ptr = nullptr;
1081 fyrex 102
static FILE *io_ptr;
716 lvd 103
 
104
static void
105
PNGAPI
106
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
107
{
784 DimkaM 108
   size_t check;
716 lvd 109
 
1081 fyrex 110
   check = fwrite(data, 1, length, (FILE *)(io_ptr));
716 lvd 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
{
1081 fyrex 121
        /*
716 lvd 122
   FILE *io_ptr;
123
   io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
1081 fyrex 124
   */
125
        if (io_ptr != nullptr)
716 lvd 126
      fflush(io_ptr);
1081 fyrex 127
 
716 lvd 128
}
129
 
130
BOOL PngSaveImage (FILE *pfFile, png_byte *pDiData,
131
                   int iWidth, int iHeight, png_color bkgColor)
132
{
784 DimkaM 133
    (void)bkgColor;
134
 
716 lvd 135
    const int           ciBitDepth = 8;
136
    const int           ciChannels = 3;
137
 
138
    png_uint_32         ulRowBytes;
784 DimkaM 139
    static png_byte   **ppbRowPointers = nullptr;
716 lvd 140
    int                 i;
141
 
142
    // prepare the standard PNG structures
784 DimkaM 143
    png_ptr = png_create_write_struct_p(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
716 lvd 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
    {
784 DimkaM 156
        png_destroy_write_struct_p(&png_ptr, (png_infopp) nullptr);
716 lvd 157
        return FALSE;
158
    }
159
 
160
    // initialize the png structure
1081 fyrex 161
        io_ptr = pfFile;
162
    png_set_write_fn_p(png_ptr, (png_voidp)pfFile, (png_rw_ptr)png_write_data, png_flush);
716 lvd 163
 
164
    // we're going to write a very simple 3x8 bit RGB image
784 DimkaM 165
    png_set_IHDR_p(png_ptr, info_ptr, png_uint_32(iWidth), png_uint_32(iHeight), ciBitDepth,
716 lvd 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
784 DimkaM 176
    ulRowBytes = png_uint_32(iWidth * ciChannels);
716 lvd 177
 
178
    // we can allocate memory for an array of row-pointers
784 DimkaM 179
    ppbRowPointers = (png_bytepp) malloc(unsigned(iHeight) * sizeof(png_bytep));
716 lvd 180
 
181
    // set the individual row-pointers to point at the correct offsets
182
    for (i = 0; i < iHeight; i++)
784 DimkaM 183
        ppbRowPointers[i] = pDiData + unsigned(i) * (((ulRowBytes + 3) >> 2) << 2);
716 lvd 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);
784 DimkaM 193
    ppbRowPointers = nullptr;
1081 fyrex 194
 
195
 
716 lvd 196
 
197
    // clean up after the write, and free any memory allocated
784 DimkaM 198
    png_destroy_write_struct_p(&png_ptr, (png_infopp) nullptr);
716 lvd 199
 
200
    return TRUE;
201
}