~hikiko/nux/arb-srgba-shader

« back to all changes in this revision

Viewing changes to NuxImage/NPng.cpp

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-02 03:28:11 UTC
  • Revision ID: neil.patel@canonical.com-20100902032811-i2m18tfb6pkasnvt
Remove Win EOL chars

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
 
23
 
#include <fstream>
24
 
 
25
 
#include "NuxCore/NKernel.h"
26
 
 
27
 
#include "png.h"
28
 
#include "NPng.h"
29
 
#include "BitmapFormats.h"
30
 
 
31
 
 
32
 
#include <stdio.h>
33
 
#if defined(_WIN32)
34
 
    #include <windows.h>
35
 
#endif
36
 
 
37
 
NAMESPACE_BEGIN
38
 
 
39
 
#define FAILMSGANDRETURN \
40
 
{\
41
 
    nuxAssertMsg(0, TEXT("[PNG Read Error] Cannot open %s for read."), FileNameAnsi); \
42
 
    return 0;\
43
 
}
44
 
#if defined(_WIN32)
45
 
 
46
 
#define PNG_FREERESOURCE if(hglobal) FreeResource(hglobal);
47
 
#define PNG_DECLARE_RESVAR \
48
 
    DWORD       ressz;\
49
 
    HRSRC       HRes    = NULL;\
50
 
    HGLOBAL hglobal = NULL;\
51
 
    void*       resptr;
52
 
#define PNG_SETREADFN \
53
 
    if(!fp) png_set_read_fn(png_ptr, (void *)resptr, png_read_resource_fn);      else
54
 
#define PNG_READHEADER \
55
 
    if(!fp)\
56
 
    {\
57
 
    memcpy(sig, resptr, 8);\
58
 
    resptr = (void*)((char*)resptr + 8);\
59
 
    } else
60
 
 
61
 
#else
62
 
 
63
 
#define PNG_FREERESOURCE 
64
 
#define PNG_DECLARE_RESVAR 
65
 
#define PNG_SETREADFN 
66
 
#define PNG_READHEADER
67
 
 
68
 
#endif
69
 
 
70
 
 
71
 
 
72
 
namespace 
73
 
{
74
 
#if defined(_WIN32)
75
 
    struct png_resource_access
76
 
    {
77
 
        png_resource_access() : hModule(NULL), res_type_id(0) {}
78
 
        HMODULE hModule;
79
 
        std::string res_type_name;
80
 
        unsigned long res_type_id;
81
 
    };
82
 
    png_resource_access png_resource;
83
 
#endif
84
 
}
85
 
 
86
 
void png_read_resource_fn(png_structp png_ptr, png_bytep data, png_size_t leng);
87
 
 
88
 
#if defined(_WIN32)
89
 
void set_png_module_handle(unsigned long hM) 
90
 
91
 
    png_resource.hModule = (HMODULE)hM; 
92
 
}
93
 
void set_png_module_restypename(const char * restypename) 
94
 
{
95
 
    if(HIWORD(restypename))
96
 
    {
97
 
        png_resource.res_type_name = restypename;
98
 
        png_resource.res_type_id = 0;
99
 
    }
100
 
    else
101
 
    {
102
 
        //resource.res_type_name.clear(); should exist (cf STL Doc)
103
 
        png_resource.res_type_id = (unsigned long)restypename;
104
 
    }
105
 
}
106
 
#endif
107
 
 
108
 
 
109
 
#if defined(_WIN32)
110
 
HRSRC get_resource(const char * filename)
111
 
{
112
 
    HRSRC HRes;
113
 
#ifdef _UNICODE
114
 
    unsigned int count = strlen(filename);
115
 
    wchar_t *wfilename = new wchar_t[count];
116
 
    mbstowcs(wfilename, filename, count);
117
 
 
118
 
    count = png_resource.res_type_name.size();
119
 
    wchar_t *wres_type_name = new wchar_t[count];
120
 
    mbstowcs(wres_type_name, png_resource.res_type_name.c_str(), count);
121
 
 
122
 
    HRes = FindResource(png_resource.hModule, wfilename, 
123
 
        png_resource.res_type_id ? (LPCWSTR)png_resource.res_type_id : wres_type_name);
124
 
 
125
 
    delete [] wfilename;
126
 
    delete [] wres_type_name;
127
 
#else
128
 
    HRes = FindResource(png_resource.hModule, filename, 
129
 
        png_resource.res_type_id ? (LPCSTR)png_resource.res_type_id : png_resource.res_type_name.c_str());
130
 
#endif
131
 
    return HRes;
132
 
}
133
 
#endif
134
 
 
135
 
NBitmapData* read_png_rgba(const TCHAR* filename)
136
 
{
137
 
    //--------- Resource stuff
138
 
    PNG_DECLARE_RESVAR
139
 
    //---------
140
 
    FILE * fp = NULL;
141
 
    png_byte sig[8];
142
 
    int bit_depth, color_type;
143
 
    double              gamma;
144
 
    png_uint_32 channels, row_bytes;
145
 
    png_structp png_ptr = 0;
146
 
    png_infop info_ptr = 0;
147
 
 
148
 
    ANSICHAR* FileNameAnsi = (ANSICHAR*) TCHAR_TO_ANSI(filename);
149
 
    if(!FileNameAnsi) 
150
 
    {
151
 
        nuxAssertMsg(0, TEXT("[read_png_rgba] Incorrect file name: %s."), filename);
152
 
        return 0;
153
 
    }
154
 
 
155
 
 
156
 
#if defined(_WIN32)
157
 
    struct _stat file_info;
158
 
#else
159
 
    struct stat file_info;
160
 
#endif
161
 
 
162
 
 
163
 
    // System call: check if the file exist
164
 
#if defined(_WIN32)
165
 
    if(_stat(FileNameAnsi, &file_info) != 0)
166
 
#else
167
 
    if(stat(FileNameAnsi, &file_info) != 0)
168
 
#endif
169
 
    {
170
 
        nuxAssert(TEXT("[read_png_rgba] File not found: %s."));
171
 
        return 0;
172
 
    }
173
 
 
174
 
#if (defined INL_VISUAL_STUDIO_2005) || (defined INL_VISUAL_STUDIO_2008)
175
 
    fopen_s(&fp, FileNameAnsi, "rb");
176
 
#else
177
 
    fp = fopen(FileNameAnsi, "rb");
178
 
#endif
179
 
 
180
 
    if(!fp)
181
 
#if defined(_WIN32)
182
 
    {
183
 
        // Try resource access
184
 
        HRes = get_resource(FileNameAnsi);
185
 
 
186
 
        if(!HRes)
187
 
            FAILMSGANDRETURN
188
 
            hglobal     =       LoadResource(png_resource.hModule, HRes);
189
 
        if(!hglobal) 
190
 
            FAILMSGANDRETURN
191
 
            ressz = SizeofResource(png_resource.hModule, HRes);
192
 
        resptr =        (char*)LockResource(hglobal);
193
 
        if(!resptr) 
194
 
            FAILMSGANDRETURN
195
 
    }
196
 
#else
197
 
        FAILMSGANDRETURN
198
 
#endif
199
 
 
200
 
    // first check the eight byte PNG signature
201
 
    PNG_READHEADER fread(sig, 1, 8, fp);
202
 
    if (!png_check_sig(sig, 8))
203
 
    { 
204
 
        if(fp) fclose(fp); 
205
 
        PNG_FREERESOURCE
206
 
            return 0; 
207
 
    }
208
 
 
209
 
 
210
 
    // start back here!!!!
211
 
 
212
 
    // create the two png(-info) structures
213
 
 
214
 
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
215
 
    if (!png_ptr)
216
 
    { 
217
 
        if(fp) fclose(fp); 
218
 
        PNG_FREERESOURCE
219
 
            return 0; 
220
 
    }
221
 
 
222
 
    info_ptr = png_create_info_struct(png_ptr);
223
 
    if (!info_ptr)
224
 
    {
225
 
        png_destroy_read_struct(&png_ptr, 0, 0);
226
 
        if(fp) fclose(fp);
227
 
        PNG_FREERESOURCE
228
 
    }
229
 
 
230
 
    // initialize the png structure
231
 
    PNG_SETREADFN png_init_io(png_ptr, fp);     
232
 
 
233
 
    png_set_sig_bytes(png_ptr, 8);
234
 
 
235
 
    // read all PNG info up to image data
236
 
    png_read_info(png_ptr, info_ptr);
237
 
 
238
 
    // get width, height, bit-depth and color-type      
239
 
    unsigned long width, height;
240
 
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
241
 
 
242
 
    // expand images of all color-type and bit-depth to 3x8 bit RGB images
243
 
    // let the library process things like alpha, transparency, background
244
 
 
245
 
    if (bit_depth == 16) png_set_strip_16(png_ptr);
246
 
    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
247
 
    if (bit_depth < 8) png_set_expand(png_ptr);
248
 
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
249
 
    if (color_type == PNG_COLOR_TYPE_GRAY ||
250
 
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
251
 
        png_set_gray_to_rgb(png_ptr);
252
 
 
253
 
    // if required set gamma conversion
254
 
    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, (double) 2.2, gamma);
255
 
 
256
 
    // after the transformations have been registered update info_ptr data
257
 
    png_read_update_info(png_ptr, info_ptr);
258
 
 
259
 
    // get again width, height and the new bit-depth and color-type
260
 
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
261
 
 
262
 
 
263
 
    // row_bytes is the width x number of channels
264
 
    row_bytes = png_get_rowbytes(png_ptr, info_ptr);
265
 
    channels = png_get_channels(png_ptr, info_ptr);
266
 
 
267
 
    if ( channels == 3 )
268
 
    {
269
 
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Unable to open image of type RGB %s using read_png_rgba()."), filename);
270
 
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Try using read_png_rgb() instead!"));
271
 
        if(fp) fclose(fp); 
272
 
        return 0;
273
 
    }
274
 
 
275
 
    // now we can allocate memory to store the image
276
 
    png_byte * img = new png_byte[row_bytes * height];
277
 
    // and allocate memory for an array of row-pointers
278
 
    png_byte ** row = new png_byte * [height];
279
 
 
280
 
 
281
 
    // set the individual row-pointers to point at the correct offsets
282
 
    for (unsigned int i = 0; i < height; i++)
283
 
        row[i] = img + i * row_bytes;
284
 
 
285
 
    // now we can go ahead and just read the whole image
286
 
    png_read_image(png_ptr, row);
287
 
 
288
 
    // read the additional chunks in the PNG file (not really needed)
289
 
    png_read_end(png_ptr, NULL);
290
 
 
291
 
    //image = array2<vec4ub>(w, h);
292
 
    NTextureData* TextureObjectData = new NTextureData(BITFMT_R8G8B8A8, width, height, 1);
293
 
    {
294
 
        for(unsigned int i=0; i < width; i++)
295
 
            for(unsigned int j=0; j < height; j++)
296
 
            {
297
 
                BYTE* png_data_pointer = img + ((height-j-1)*row_bytes + i * 4);
298
 
                UINT value = 
299
 
                    (*(png_data_pointer + 3) << 24) |   // a
300
 
                    (*(png_data_pointer + 2) << 16) |   // b
301
 
                    (*(png_data_pointer + 1) << 8)  |   // g
302
 
                    *(png_data_pointer + 0);            // r
303
 
 
304
 
                TextureObjectData->GetSurface(0).Write32b(i, j, value); // = vec4ub(img + ((h-j-1)*row_bytes + i * 4));
305
 
            }
306
 
    }
307
 
 
308
 
    delete [] row;
309
 
    delete [] img;
310
 
 
311
 
    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
312
 
 
313
 
    if(TextureObjectData)
314
 
        TextureObjectData->GetSurface(0).FlipVertical();
315
 
 
316
 
    if(fp) fclose (fp);
317
 
    PNG_FREERESOURCE
318
 
 
319
 
    return TextureObjectData;
320
 
}
321
 
 
322
 
NBitmapData* read_png_rgb(const TCHAR* filename)
323
 
{
324
 
    //--------- Resource stuff
325
 
    PNG_DECLARE_RESVAR
326
 
    //----------
327
 
    FILE * fp;
328
 
    png_byte sig[8];
329
 
    int bit_depth, color_type;
330
 
    double              gamma;
331
 
    png_uint_32 channels, row_bytes;
332
 
    png_structp png_ptr = 0;
333
 
    png_infop info_ptr = 0;
334
 
 
335
 
    // open the PNG input file
336
 
    ANSICHAR* FileNameAnsi = (ANSICHAR*) TCHAR_TO_ANSI(filename);
337
 
    if(!FileNameAnsi) 
338
 
    {
339
 
        nuxAssertMsg(0, TEXT("[read_png_rgb] Incorrect file name: %s."), filename);
340
 
        return 0;
341
 
    }
342
 
 
343
 
#if defined(_WIN32)
344
 
    struct _stat file_info;
345
 
#else
346
 
    struct stat file_info;
347
 
#endif
348
 
 
349
 
 
350
 
    // System call: check if the file exist
351
 
#if defined(_WIN32)
352
 
    if(_stat(FileNameAnsi, &file_info) != 0)
353
 
#else
354
 
    if(stat(FileNameAnsi, &file_info) != 0)
355
 
#endif
356
 
    {
357
 
        nuxAssert(TEXT("[read_png_rgb] File not found: %s."));
358
 
        return 0;
359
 
    }
360
 
 
361
 
#if (defined INL_VISUAL_STUDIO_2005) || (defined INL_VISUAL_STUDIO_2008)
362
 
    fopen_s(&fp, FileNameAnsi, "rb");
363
 
#else
364
 
    fp = fopen(FileNameAnsi, "rb");
365
 
#endif
366
 
 
367
 
    if(!fp)
368
 
#if defined(_WIN32)
369
 
    {
370
 
        // Try resource access
371
 
        HRes = get_resource(FileNameAnsi);
372
 
 
373
 
        if(!HRes)
374
 
            FAILMSGANDRETURN
375
 
            hglobal     =       LoadResource(png_resource.hModule, HRes);
376
 
        if(!hglobal) 
377
 
            FAILMSGANDRETURN
378
 
            ressz = SizeofResource(png_resource.hModule, HRes);
379
 
        resptr =        (char*)LockResource(hglobal);
380
 
        if(!resptr) 
381
 
            FAILMSGANDRETURN
382
 
    }
383
 
#else
384
 
        FAILMSGANDRETURN
385
 
#endif
386
 
 
387
 
    // first check the eight byte PNG signature
388
 
    PNG_READHEADER fread(sig, 1, 8, fp);
389
 
    if (!png_check_sig(sig, 8))
390
 
    { 
391
 
        if(fp) fclose(fp); 
392
 
        PNG_FREERESOURCE;
393
 
        return 0; 
394
 
    }
395
 
 
396
 
    // start back here!!!!
397
 
 
398
 
    // create the two png(-info) structures
399
 
 
400
 
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
401
 
    if (!png_ptr) { 
402
 
        if(fp) fclose(fp); 
403
 
        PNG_FREERESOURCE;
404
 
        return 0; 
405
 
    }
406
 
 
407
 
    info_ptr = png_create_info_struct(png_ptr);
408
 
    if (!info_ptr)
409
 
    {
410
 
        png_destroy_read_struct(&png_ptr, 0, 0);
411
 
        if(fp) fclose(fp); 
412
 
        PNG_FREERESOURCE
413
 
    }
414
 
 
415
 
    // initialize the png structure
416
 
    PNG_SETREADFN png_init_io(png_ptr, fp);     
417
 
 
418
 
    png_set_sig_bytes(png_ptr, 8);
419
 
 
420
 
    // read all PNG info up to image data
421
 
    png_read_info(png_ptr, info_ptr);
422
 
 
423
 
    // get width, height, bit-depth and color-type      
424
 
    unsigned long w, h;
425
 
    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
426
 
 
427
 
    // expand images of all color-type and bit-depth to 3x8 bit RGB images
428
 
    // let the library process things like alpha, transparency, background
429
 
 
430
 
    if (bit_depth == 16) png_set_strip_16(png_ptr);
431
 
    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
432
 
    if (bit_depth < 8) png_set_expand(png_ptr);
433
 
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
434
 
    if (color_type == PNG_COLOR_TYPE_GRAY ||
435
 
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
436
 
        png_set_gray_to_rgb(png_ptr);
437
 
    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
438
 
        png_set_strip_alpha(png_ptr);
439
 
 
440
 
    // if required set gamma conversion
441
 
    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, (double) 2.2, gamma);
442
 
 
443
 
    // after the transformations have been registered update info_ptr data
444
 
    png_read_update_info(png_ptr, info_ptr);
445
 
 
446
 
    // get again width, height and the new bit-depth and color-type
447
 
    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
448
 
 
449
 
 
450
 
    // row_bytes is the width x number of channels
451
 
    row_bytes = png_get_rowbytes(png_ptr, info_ptr);
452
 
    channels = png_get_channels(png_ptr, info_ptr);
453
 
 
454
 
    if ( channels == 4 )
455
 
    {
456
 
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Unable to open image of type RGBA %s using read_png_rgb()."), filename);
457
 
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Try using read_png_rgba() instead!"));
458
 
        if(fp) fclose(fp); 
459
 
        return 0;
460
 
    }
461
 
 
462
 
    // now we can allocate memory to store the image
463
 
 
464
 
    png_byte * img = new png_byte[row_bytes * h];
465
 
 
466
 
    // and allocate memory for an array of row-pointers
467
 
 
468
 
    png_byte ** row = new png_byte * [h];
469
 
 
470
 
 
471
 
    // set the individual row-pointers to point at the correct offsets
472
 
 
473
 
    for (unsigned int i = 0; i < h; i++)
474
 
        row[i] = img + i * row_bytes;
475
 
 
476
 
    // now we can go ahead and just read the whole image
477
 
 
478
 
    png_read_image(png_ptr, row);
479
 
 
480
 
    // read the additional chunks in the PNG file (not really needed)
481
 
 
482
 
    png_read_end(png_ptr, NULL);
483
 
 
484
 
    //image = array2<vec3ub>(w, h);
485
 
    NTextureData* TextureObjectData = new NTextureData(BITFMT_R8G8B8, w, h, 1);
486
 
    {
487
 
        for(unsigned int i=0; i < w; i++)
488
 
            for(unsigned int j=0; j < h; j++)
489
 
            {
490
 
                BYTE* png_data_pointer = img + ((h-j-1)*row_bytes + i * 3);
491
 
 
492
 
                UINT value = 
493
 
                    (*(png_data_pointer + 2) << 16) |   //r
494
 
                    (*(png_data_pointer + 1) << 8)  |   //g
495
 
                    *(png_data_pointer + 0);            //b
496
 
 
497
 
                TextureObjectData->GetSurface(0).Write24b(i, j, value);    // vec3ub(img + ((h-j-1)*row_bytes + i * 3));
498
 
            }
499
 
    }
500
 
 
501
 
 
502
 
    delete [] row;
503
 
    delete [] img;
504
 
 
505
 
    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
506
 
 
507
 
    if(TextureObjectData)
508
 
        TextureObjectData->GetSurface(0).FlipVertical();
509
 
 
510
 
    if(fp) fclose (fp);
511
 
    PNG_FREERESOURCE
512
 
    return TextureObjectData;
513
 
}
514
 
 
515
 
 
516
 
////FIXME: LIBPNG expands to RGB and only R is fetched...
517
 
//bool read_png_grey(const char * filename, glh::array2<unsigned char> & image)
518
 
//{
519
 
//    //--------- Resource stuff
520
 
//    PNG_DECLARE_RESVAR
521
 
//        //---------
522
 
//        FILE * fp;
523
 
//    png_byte sig[8];
524
 
//    int bit_depth, color_type;
525
 
//    double              gamma;
526
 
//    png_uint_32 channels, row_bytes;
527
 
//    png_structp png_ptr = 0;
528
 
//    png_infop info_ptr = 0;
529
 
//
530
 
//
531
 
//    // This is the SDK default path...
532
 
//    if(path.path.size() < 1)
533
 
//    {
534
 
//        path.path.push_back(""); // added by Ashu, for case where fully qualified path is given
535
 
//        path.path.push_back(".");
536
 
//        path.path.push_back("../../../MEDIA/textures/1D");
537
 
//        path.path.push_back("../../../../MEDIA/textures/1D");
538
 
//        path.path.push_back("../../../../../../../MEDIA/textures/1D");
539
 
//        path.path.push_back("../../../MEDIA/textures/2D");
540
 
//        path.path.push_back("../../../../MEDIA/textures/2D");
541
 
//        path.path.push_back("../../../../../../../MEDIA/textures/2D");
542
 
//        path.path.push_back("../../../MEDIA/textures/rectangles");
543
 
//        path.path.push_back("../../../../MEDIA/textures/rectangles");
544
 
//        path.path.push_back("../../../../../../../MEDIA/textures/rectangles");
545
 
//        path.path.push_back("../../../MEDIA/textures/cubemaps");
546
 
//        path.path.push_back("../../../../MEDIA/textures/cubemaps");
547
 
//        path.path.push_back("../../../../../../../MEDIA/textures/cubemaps");
548
 
//        path.path.push_back("../../../MEDIA/textures/3D");
549
 
//        path.path.push_back("../../../../MEDIA/textures/3D");
550
 
//        path.path.push_back("../../../../../../../MEDIA/textures/3D");
551
 
//    }
552
 
//
553
 
//    // open the PNG input file
554
 
//    if (!filename) return false;
555
 
//
556
 
//    if (!(fp = path.fopen(filename)))
557
 
//#if defined(_WIN32)
558
 
//    {
559
 
//        // Try resource access
560
 
//        HRes = get_resource(filename);
561
 
//
562
 
//        if(!HRes)
563
 
//            FAILMSGANDRETURN
564
 
//            hglobal   =       LoadResource(png_resource.hModule, HRes);
565
 
//        if(!hglobal) 
566
 
//            FAILMSGANDRETURN
567
 
//            ressz = SizeofResource(png_resource.hModule, HRes);
568
 
//        resptr =      (char*)LockResource(hglobal);
569
 
//        if(!resptr) 
570
 
//            FAILMSGANDRETURN
571
 
//    }
572
 
//#else
573
 
//        FAILMSGANDRETURN
574
 
//#endif
575
 
//
576
 
//        // first check the eight byte PNG signature
577
 
//        PNG_READHEADER fread(sig, 1, 8, fp);
578
 
//    if (!png_check_sig(sig, 8)) { 
579
 
//        if(fp) fclose(fp); 
580
 
//        PNG_FREERESOURCE
581
 
//            return false; 
582
 
//    }
583
 
//
584
 
//
585
 
//    // start back here!!!!
586
 
//
587
 
//    // create the two png(-info) structures
588
 
//
589
 
//    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
590
 
//    if (!png_ptr) { 
591
 
//        if(fp) fclose(fp); 
592
 
//        PNG_FREERESOURCE
593
 
//            return false; 
594
 
//    }
595
 
//
596
 
//    info_ptr = png_create_info_struct(png_ptr);
597
 
//    if (!info_ptr)
598
 
//    {
599
 
//        png_destroy_read_struct(&png_ptr, 0, 0);
600
 
//        if(fp) fclose(fp); 
601
 
//        PNG_FREERESOURCE
602
 
//    }
603
 
//
604
 
//    // initialize the png structure
605
 
//    PNG_SETREADFN png_init_io(png_ptr, fp);   
606
 
//
607
 
//    png_set_sig_bytes(png_ptr, 8);
608
 
//
609
 
//    // read all PNG info up to image data
610
 
//    png_read_info(png_ptr, info_ptr);
611
 
//
612
 
//    // get width, height, bit-depth and color-type    
613
 
//    unsigned long w, h;
614
 
//    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
615
 
//
616
 
//    // expand images of all color-type and bit-depth to 3x8 bit RGB images
617
 
//    // let the library process things like alpha, transparency, background
618
 
//
619
 
//    if (bit_depth == 16) png_set_strip_16(png_ptr);
620
 
//    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
621
 
//    if (bit_depth < 8) png_set_expand(png_ptr);
622
 
//    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
623
 
//    if (color_type == PNG_COLOR_TYPE_GRAY ||
624
 
//        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
625
 
//        png_set_gray_to_rgb(png_ptr);
626
 
//
627
 
//    // if required set gamma conversion
628
 
//    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, (double) 2.2, gamma);
629
 
//
630
 
//    // after the transformations have been registered update info_ptr data
631
 
//    png_read_update_info(png_ptr, info_ptr);
632
 
//
633
 
//    // get again width, height and the new bit-depth and color-type
634
 
//    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
635
 
//
636
 
//
637
 
//    // row_bytes is the width x number of channels
638
 
//    row_bytes = png_get_rowbytes(png_ptr, info_ptr);
639
 
//    channels = png_get_channels(png_ptr, info_ptr);
640
 
//
641
 
//    // now we can allocate memory to store the image
642
 
//
643
 
//    png_byte * img = new png_byte[row_bytes * h];
644
 
//
645
 
//    // and allocate memory for an array of row-pointers
646
 
//
647
 
//    png_byte ** row = new png_byte * [h];
648
 
//
649
 
//
650
 
//    // set the individual row-pointers to point at the correct offsets
651
 
//
652
 
//    for (unsigned int i = 0; i < h; i++)
653
 
//        row[i] = img + i * row_bytes;
654
 
//
655
 
//    // now we can go ahead and just read the whole image
656
 
//
657
 
//    png_read_image(png_ptr, row);
658
 
//
659
 
//    // read the additional chunks in the PNG file (not really needed)
660
 
//
661
 
//    png_read_end(png_ptr, NULL);
662
 
//
663
 
//    image = array2<unsigned char>(w, h);
664
 
//
665
 
//    {
666
 
//        for(unsigned int i=0; i < w; i++)
667
 
//            for(unsigned int j=0; j < h; j++)
668
 
//            { image(i,j) = *(img + ((h-j-1)*row_bytes + i * 3)); }
669
 
//    }
670
 
//
671
 
//    delete [] row;
672
 
//    delete [] img;
673
 
//
674
 
//    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
675
 
//
676
 
//    if(fp) fclose (fp);
677
 
//    PNG_FREERESOURCE
678
 
//
679
 
//        return true;
680
 
//}
681
 
 
682
 
void png_read_resource_fn(png_structp png_ptr, png_bytep data, png_size_t leng)
683
 
{
684
 
    png_bytep src = (png_bytep)png_ptr->io_ptr;
685
 
 
686
 
    for(unsigned int i=0; i<leng; i++)
687
 
        data[i] = *src++;
688
 
    png_ptr->io_ptr = (void*)src;
689
 
}
690
 
 
691
 
NAMESPACE_END
 
23
#include <fstream>
 
24
 
 
25
#include "NuxCore/NKernel.h"
 
26
 
 
27
#include "png.h"
 
28
#include "NPng.h"
 
29
#include "BitmapFormats.h"
 
30
 
 
31
 
 
32
#include <stdio.h>
 
33
#if defined(_WIN32)
 
34
    #include <windows.h>
 
35
#endif
 
36
 
 
37
NAMESPACE_BEGIN
 
38
 
 
39
#define FAILMSGANDRETURN \
 
40
{\
 
41
    nuxAssertMsg(0, TEXT("[PNG Read Error] Cannot open %s for read."), FileNameAnsi); \
 
42
    return 0;\
 
43
}
 
44
#if defined(_WIN32)
 
45
 
 
46
#define PNG_FREERESOURCE if(hglobal) FreeResource(hglobal);
 
47
#define PNG_DECLARE_RESVAR \
 
48
    DWORD       ressz;\
 
49
    HRSRC       HRes    = NULL;\
 
50
    HGLOBAL hglobal = NULL;\
 
51
    void*       resptr;
 
52
#define PNG_SETREADFN \
 
53
    if(!fp) png_set_read_fn(png_ptr, (void *)resptr, png_read_resource_fn);      else
 
54
#define PNG_READHEADER \
 
55
    if(!fp)\
 
56
    {\
 
57
    memcpy(sig, resptr, 8);\
 
58
    resptr = (void*)((char*)resptr + 8);\
 
59
    } else
 
60
 
 
61
#else
 
62
 
 
63
#define PNG_FREERESOURCE 
 
64
#define PNG_DECLARE_RESVAR 
 
65
#define PNG_SETREADFN 
 
66
#define PNG_READHEADER
 
67
 
 
68
#endif
 
69
 
 
70
 
 
71
 
 
72
namespace 
 
73
{
 
74
#if defined(_WIN32)
 
75
    struct png_resource_access
 
76
    {
 
77
        png_resource_access() : hModule(NULL), res_type_id(0) {}
 
78
        HMODULE hModule;
 
79
        std::string res_type_name;
 
80
        unsigned long res_type_id;
 
81
    };
 
82
    png_resource_access png_resource;
 
83
#endif
 
84
}
 
85
 
 
86
void png_read_resource_fn(png_structp png_ptr, png_bytep data, png_size_t leng);
 
87
 
 
88
#if defined(_WIN32)
 
89
void set_png_module_handle(unsigned long hM) 
 
90
 
91
    png_resource.hModule = (HMODULE)hM; 
 
92
}
 
93
void set_png_module_restypename(const char * restypename) 
 
94
{
 
95
    if(HIWORD(restypename))
 
96
    {
 
97
        png_resource.res_type_name = restypename;
 
98
        png_resource.res_type_id = 0;
 
99
    }
 
100
    else
 
101
    {
 
102
        //resource.res_type_name.clear(); should exist (cf STL Doc)
 
103
        png_resource.res_type_id = (unsigned long)restypename;
 
104
    }
 
105
}
 
106
#endif
 
107
 
 
108
 
 
109
#if defined(_WIN32)
 
110
HRSRC get_resource(const char * filename)
 
111
{
 
112
    HRSRC HRes;
 
113
#ifdef _UNICODE
 
114
    unsigned int count = strlen(filename);
 
115
    wchar_t *wfilename = new wchar_t[count];
 
116
    mbstowcs(wfilename, filename, count);
 
117
 
 
118
    count = png_resource.res_type_name.size();
 
119
    wchar_t *wres_type_name = new wchar_t[count];
 
120
    mbstowcs(wres_type_name, png_resource.res_type_name.c_str(), count);
 
121
 
 
122
    HRes = FindResource(png_resource.hModule, wfilename, 
 
123
        png_resource.res_type_id ? (LPCWSTR)png_resource.res_type_id : wres_type_name);
 
124
 
 
125
    delete [] wfilename;
 
126
    delete [] wres_type_name;
 
127
#else
 
128
    HRes = FindResource(png_resource.hModule, filename, 
 
129
        png_resource.res_type_id ? (LPCSTR)png_resource.res_type_id : png_resource.res_type_name.c_str());
 
130
#endif
 
131
    return HRes;
 
132
}
 
133
#endif
 
134
 
 
135
NBitmapData* read_png_rgba(const TCHAR* filename)
 
136
{
 
137
    //--------- Resource stuff
 
138
    PNG_DECLARE_RESVAR
 
139
    //---------
 
140
    FILE * fp = NULL;
 
141
    png_byte sig[8];
 
142
    int bit_depth, color_type;
 
143
    double              gamma;
 
144
    png_uint_32 channels, row_bytes;
 
145
    png_structp png_ptr = 0;
 
146
    png_infop info_ptr = 0;
 
147
 
 
148
    ANSICHAR* FileNameAnsi = (ANSICHAR*) TCHAR_TO_ANSI(filename);
 
149
    if(!FileNameAnsi) 
 
150
    {
 
151
        nuxAssertMsg(0, TEXT("[read_png_rgba] Incorrect file name: %s."), filename);
 
152
        return 0;
 
153
    }
 
154
 
 
155
 
 
156
#if defined(_WIN32)
 
157
    struct _stat file_info;
 
158
#else
 
159
    struct stat file_info;
 
160
#endif
 
161
 
 
162
 
 
163
    // System call: check if the file exist
 
164
#if defined(_WIN32)
 
165
    if(_stat(FileNameAnsi, &file_info) != 0)
 
166
#else
 
167
    if(stat(FileNameAnsi, &file_info) != 0)
 
168
#endif
 
169
    {
 
170
        nuxAssert(TEXT("[read_png_rgba] File not found: %s."));
 
171
        return 0;
 
172
    }
 
173
 
 
174
#if (defined INL_VISUAL_STUDIO_2005) || (defined INL_VISUAL_STUDIO_2008)
 
175
    fopen_s(&fp, FileNameAnsi, "rb");
 
176
#else
 
177
    fp = fopen(FileNameAnsi, "rb");
 
178
#endif
 
179
 
 
180
    if(!fp)
 
181
#if defined(_WIN32)
 
182
    {
 
183
        // Try resource access
 
184
        HRes = get_resource(FileNameAnsi);
 
185
 
 
186
        if(!HRes)
 
187
            FAILMSGANDRETURN
 
188
            hglobal     =       LoadResource(png_resource.hModule, HRes);
 
189
        if(!hglobal) 
 
190
            FAILMSGANDRETURN
 
191
            ressz = SizeofResource(png_resource.hModule, HRes);
 
192
        resptr =        (char*)LockResource(hglobal);
 
193
        if(!resptr) 
 
194
            FAILMSGANDRETURN
 
195
    }
 
196
#else
 
197
        FAILMSGANDRETURN
 
198
#endif
 
199
 
 
200
    // first check the eight byte PNG signature
 
201
    PNG_READHEADER fread(sig, 1, 8, fp);
 
202
    if (!png_check_sig(sig, 8))
 
203
    { 
 
204
        if(fp) fclose(fp); 
 
205
        PNG_FREERESOURCE
 
206
            return 0; 
 
207
    }
 
208
 
 
209
 
 
210
    // start back here!!!!
 
211
 
 
212
    // create the two png(-info) structures
 
213
 
 
214
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
 
215
    if (!png_ptr)
 
216
    { 
 
217
        if(fp) fclose(fp); 
 
218
        PNG_FREERESOURCE
 
219
            return 0; 
 
220
    }
 
221
 
 
222
    info_ptr = png_create_info_struct(png_ptr);
 
223
    if (!info_ptr)
 
224
    {
 
225
        png_destroy_read_struct(&png_ptr, 0, 0);
 
226
        if(fp) fclose(fp);
 
227
        PNG_FREERESOURCE
 
228
    }
 
229
 
 
230
    // initialize the png structure
 
231
    PNG_SETREADFN png_init_io(png_ptr, fp);     
 
232
 
 
233
    png_set_sig_bytes(png_ptr, 8);
 
234
 
 
235
    // read all PNG info up to image data
 
236
    png_read_info(png_ptr, info_ptr);
 
237
 
 
238
    // get width, height, bit-depth and color-type      
 
239
    unsigned long width, height;
 
240
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
 
241
 
 
242
    // expand images of all color-type and bit-depth to 3x8 bit RGB images
 
243
    // let the library process things like alpha, transparency, background
 
244
 
 
245
    if (bit_depth == 16) png_set_strip_16(png_ptr);
 
246
    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
 
247
    if (bit_depth < 8) png_set_expand(png_ptr);
 
248
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
 
249
    if (color_type == PNG_COLOR_TYPE_GRAY ||
 
250
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
251
        png_set_gray_to_rgb(png_ptr);
 
252
 
 
253
    // if required set gamma conversion
 
254
    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, (double) 2.2, gamma);
 
255
 
 
256
    // after the transformations have been registered update info_ptr data
 
257
    png_read_update_info(png_ptr, info_ptr);
 
258
 
 
259
    // get again width, height and the new bit-depth and color-type
 
260
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
 
261
 
 
262
 
 
263
    // row_bytes is the width x number of channels
 
264
    row_bytes = png_get_rowbytes(png_ptr, info_ptr);
 
265
    channels = png_get_channels(png_ptr, info_ptr);
 
266
 
 
267
    if ( channels == 3 )
 
268
    {
 
269
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Unable to open image of type RGB %s using read_png_rgba()."), filename);
 
270
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Try using read_png_rgb() instead!"));
 
271
        if(fp) fclose(fp); 
 
272
        return 0;
 
273
    }
 
274
 
 
275
    // now we can allocate memory to store the image
 
276
    png_byte * img = new png_byte[row_bytes * height];
 
277
    // and allocate memory for an array of row-pointers
 
278
    png_byte ** row = new png_byte * [height];
 
279
 
 
280
 
 
281
    // set the individual row-pointers to point at the correct offsets
 
282
    for (unsigned int i = 0; i < height; i++)
 
283
        row[i] = img + i * row_bytes;
 
284
 
 
285
    // now we can go ahead and just read the whole image
 
286
    png_read_image(png_ptr, row);
 
287
 
 
288
    // read the additional chunks in the PNG file (not really needed)
 
289
    png_read_end(png_ptr, NULL);
 
290
 
 
291
    //image = array2<vec4ub>(w, h);
 
292
    NTextureData* TextureObjectData = new NTextureData(BITFMT_R8G8B8A8, width, height, 1);
 
293
    {
 
294
        for(unsigned int i=0; i < width; i++)
 
295
            for(unsigned int j=0; j < height; j++)
 
296
            {
 
297
                BYTE* png_data_pointer = img + ((height-j-1)*row_bytes + i * 4);
 
298
                UINT value = 
 
299
                    (*(png_data_pointer + 3) << 24) |   // a
 
300
                    (*(png_data_pointer + 2) << 16) |   // b
 
301
                    (*(png_data_pointer + 1) << 8)  |   // g
 
302
                    *(png_data_pointer + 0);            // r
 
303
 
 
304
                TextureObjectData->GetSurface(0).Write32b(i, j, value); // = vec4ub(img + ((h-j-1)*row_bytes + i * 4));
 
305
            }
 
306
    }
 
307
 
 
308
    delete [] row;
 
309
    delete [] img;
 
310
 
 
311
    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
 
312
 
 
313
    if(TextureObjectData)
 
314
        TextureObjectData->GetSurface(0).FlipVertical();
 
315
 
 
316
    if(fp) fclose (fp);
 
317
    PNG_FREERESOURCE
 
318
 
 
319
    return TextureObjectData;
 
320
}
 
321
 
 
322
NBitmapData* read_png_rgb(const TCHAR* filename)
 
323
{
 
324
    //--------- Resource stuff
 
325
    PNG_DECLARE_RESVAR
 
326
    //----------
 
327
    FILE * fp;
 
328
    png_byte sig[8];
 
329
    int bit_depth, color_type;
 
330
    double              gamma;
 
331
    png_uint_32 channels, row_bytes;
 
332
    png_structp png_ptr = 0;
 
333
    png_infop info_ptr = 0;
 
334
 
 
335
    // open the PNG input file
 
336
    ANSICHAR* FileNameAnsi = (ANSICHAR*) TCHAR_TO_ANSI(filename);
 
337
    if(!FileNameAnsi) 
 
338
    {
 
339
        nuxAssertMsg(0, TEXT("[read_png_rgb] Incorrect file name: %s."), filename);
 
340
        return 0;
 
341
    }
 
342
 
 
343
#if defined(_WIN32)
 
344
    struct _stat file_info;
 
345
#else
 
346
    struct stat file_info;
 
347
#endif
 
348
 
 
349
 
 
350
    // System call: check if the file exist
 
351
#if defined(_WIN32)
 
352
    if(_stat(FileNameAnsi, &file_info) != 0)
 
353
#else
 
354
    if(stat(FileNameAnsi, &file_info) != 0)
 
355
#endif
 
356
    {
 
357
        nuxAssert(TEXT("[read_png_rgb] File not found: %s."));
 
358
        return 0;
 
359
    }
 
360
 
 
361
#if (defined INL_VISUAL_STUDIO_2005) || (defined INL_VISUAL_STUDIO_2008)
 
362
    fopen_s(&fp, FileNameAnsi, "rb");
 
363
#else
 
364
    fp = fopen(FileNameAnsi, "rb");
 
365
#endif
 
366
 
 
367
    if(!fp)
 
368
#if defined(_WIN32)
 
369
    {
 
370
        // Try resource access
 
371
        HRes = get_resource(FileNameAnsi);
 
372
 
 
373
        if(!HRes)
 
374
            FAILMSGANDRETURN
 
375
            hglobal     =       LoadResource(png_resource.hModule, HRes);
 
376
        if(!hglobal) 
 
377
            FAILMSGANDRETURN
 
378
            ressz = SizeofResource(png_resource.hModule, HRes);
 
379
        resptr =        (char*)LockResource(hglobal);
 
380
        if(!resptr) 
 
381
            FAILMSGANDRETURN
 
382
    }
 
383
#else
 
384
        FAILMSGANDRETURN
 
385
#endif
 
386
 
 
387
    // first check the eight byte PNG signature
 
388
    PNG_READHEADER fread(sig, 1, 8, fp);
 
389
    if (!png_check_sig(sig, 8))
 
390
    { 
 
391
        if(fp) fclose(fp); 
 
392
        PNG_FREERESOURCE;
 
393
        return 0; 
 
394
    }
 
395
 
 
396
    // start back here!!!!
 
397
 
 
398
    // create the two png(-info) structures
 
399
 
 
400
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
 
401
    if (!png_ptr) { 
 
402
        if(fp) fclose(fp); 
 
403
        PNG_FREERESOURCE;
 
404
        return 0; 
 
405
    }
 
406
 
 
407
    info_ptr = png_create_info_struct(png_ptr);
 
408
    if (!info_ptr)
 
409
    {
 
410
        png_destroy_read_struct(&png_ptr, 0, 0);
 
411
        if(fp) fclose(fp); 
 
412
        PNG_FREERESOURCE
 
413
    }
 
414
 
 
415
    // initialize the png structure
 
416
    PNG_SETREADFN png_init_io(png_ptr, fp);     
 
417
 
 
418
    png_set_sig_bytes(png_ptr, 8);
 
419
 
 
420
    // read all PNG info up to image data
 
421
    png_read_info(png_ptr, info_ptr);
 
422
 
 
423
    // get width, height, bit-depth and color-type      
 
424
    unsigned long w, h;
 
425
    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
 
426
 
 
427
    // expand images of all color-type and bit-depth to 3x8 bit RGB images
 
428
    // let the library process things like alpha, transparency, background
 
429
 
 
430
    if (bit_depth == 16) png_set_strip_16(png_ptr);
 
431
    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
 
432
    if (bit_depth < 8) png_set_expand(png_ptr);
 
433
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
 
434
    if (color_type == PNG_COLOR_TYPE_GRAY ||
 
435
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
436
        png_set_gray_to_rgb(png_ptr);
 
437
    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
438
        png_set_strip_alpha(png_ptr);
 
439
 
 
440
    // if required set gamma conversion
 
441
    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, (double) 2.2, gamma);
 
442
 
 
443
    // after the transformations have been registered update info_ptr data
 
444
    png_read_update_info(png_ptr, info_ptr);
 
445
 
 
446
    // get again width, height and the new bit-depth and color-type
 
447
    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
 
448
 
 
449
 
 
450
    // row_bytes is the width x number of channels
 
451
    row_bytes = png_get_rowbytes(png_ptr, info_ptr);
 
452
    channels = png_get_channels(png_ptr, info_ptr);
 
453
 
 
454
    if ( channels == 4 )
 
455
    {
 
456
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Unable to open image of type RGBA %s using read_png_rgb()."), filename);
 
457
        //nuxAssertMsg(0, TEXT("[read_png_rgba] Try using read_png_rgba() instead!"));
 
458
        if(fp) fclose(fp); 
 
459
        return 0;
 
460
    }
 
461
 
 
462
    // now we can allocate memory to store the image
 
463
 
 
464
    png_byte * img = new png_byte[row_bytes * h];
 
465
 
 
466
    // and allocate memory for an array of row-pointers
 
467
 
 
468
    png_byte ** row = new png_byte * [h];
 
469
 
 
470
 
 
471
    // set the individual row-pointers to point at the correct offsets
 
472
 
 
473
    for (unsigned int i = 0; i < h; i++)
 
474
        row[i] = img + i * row_bytes;
 
475
 
 
476
    // now we can go ahead and just read the whole image
 
477
 
 
478
    png_read_image(png_ptr, row);
 
479
 
 
480
    // read the additional chunks in the PNG file (not really needed)
 
481
 
 
482
    png_read_end(png_ptr, NULL);
 
483
 
 
484
    //image = array2<vec3ub>(w, h);
 
485
    NTextureData* TextureObjectData = new NTextureData(BITFMT_R8G8B8, w, h, 1);
 
486
    {
 
487
        for(unsigned int i=0; i < w; i++)
 
488
            for(unsigned int j=0; j < h; j++)
 
489
            {
 
490
                BYTE* png_data_pointer = img + ((h-j-1)*row_bytes + i * 3);
 
491
 
 
492
                UINT value = 
 
493
                    (*(png_data_pointer + 2) << 16) |   //r
 
494
                    (*(png_data_pointer + 1) << 8)  |   //g
 
495
                    *(png_data_pointer + 0);            //b
 
496
 
 
497
                TextureObjectData->GetSurface(0).Write24b(i, j, value);    // vec3ub(img + ((h-j-1)*row_bytes + i * 3));
 
498
            }
 
499
    }
 
500
 
 
501
 
 
502
    delete [] row;
 
503
    delete [] img;
 
504
 
 
505
    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
 
506
 
 
507
    if(TextureObjectData)
 
508
        TextureObjectData->GetSurface(0).FlipVertical();
 
509
 
 
510
    if(fp) fclose (fp);
 
511
    PNG_FREERESOURCE
 
512
    return TextureObjectData;
 
513
}
 
514
 
 
515
 
 
516
////FIXME: LIBPNG expands to RGB and only R is fetched...
 
517
//bool read_png_grey(const char * filename, glh::array2<unsigned char> & image)
 
518
//{
 
519
//    //--------- Resource stuff
 
520
//    PNG_DECLARE_RESVAR
 
521
//        //---------
 
522
//        FILE * fp;
 
523
//    png_byte sig[8];
 
524
//    int bit_depth, color_type;
 
525
//    double              gamma;
 
526
//    png_uint_32 channels, row_bytes;
 
527
//    png_structp png_ptr = 0;
 
528
//    png_infop info_ptr = 0;
 
529
//
 
530
//
 
531
//    // This is the SDK default path...
 
532
//    if(path.path.size() < 1)
 
533
//    {
 
534
//        path.path.push_back(""); // added by Ashu, for case where fully qualified path is given
 
535
//        path.path.push_back(".");
 
536
//        path.path.push_back("../../../MEDIA/textures/1D");
 
537
//        path.path.push_back("../../../../MEDIA/textures/1D");
 
538
//        path.path.push_back("../../../../../../../MEDIA/textures/1D");
 
539
//        path.path.push_back("../../../MEDIA/textures/2D");
 
540
//        path.path.push_back("../../../../MEDIA/textures/2D");
 
541
//        path.path.push_back("../../../../../../../MEDIA/textures/2D");
 
542
//        path.path.push_back("../../../MEDIA/textures/rectangles");
 
543
//        path.path.push_back("../../../../MEDIA/textures/rectangles");
 
544
//        path.path.push_back("../../../../../../../MEDIA/textures/rectangles");
 
545
//        path.path.push_back("../../../MEDIA/textures/cubemaps");
 
546
//        path.path.push_back("../../../../MEDIA/textures/cubemaps");
 
547
//        path.path.push_back("../../../../../../../MEDIA/textures/cubemaps");
 
548
//        path.path.push_back("../../../MEDIA/textures/3D");
 
549
//        path.path.push_back("../../../../MEDIA/textures/3D");
 
550
//        path.path.push_back("../../../../../../../MEDIA/textures/3D");
 
551
//    }
 
552
//
 
553
//    // open the PNG input file
 
554
//    if (!filename) return false;
 
555
//
 
556
//    if (!(fp = path.fopen(filename)))
 
557
//#if defined(_WIN32)
 
558
//    {
 
559
//        // Try resource access
 
560
//        HRes = get_resource(filename);
 
561
//
 
562
//        if(!HRes)
 
563
//            FAILMSGANDRETURN
 
564
//            hglobal   =       LoadResource(png_resource.hModule, HRes);
 
565
//        if(!hglobal) 
 
566
//            FAILMSGANDRETURN
 
567
//            ressz = SizeofResource(png_resource.hModule, HRes);
 
568
//        resptr =      (char*)LockResource(hglobal);
 
569
//        if(!resptr) 
 
570
//            FAILMSGANDRETURN
 
571
//    }
 
572
//#else
 
573
//        FAILMSGANDRETURN
 
574
//#endif
 
575
//
 
576
//        // first check the eight byte PNG signature
 
577
//        PNG_READHEADER fread(sig, 1, 8, fp);
 
578
//    if (!png_check_sig(sig, 8)) { 
 
579
//        if(fp) fclose(fp); 
 
580
//        PNG_FREERESOURCE
 
581
//            return false; 
 
582
//    }
 
583
//
 
584
//
 
585
//    // start back here!!!!
 
586
//
 
587
//    // create the two png(-info) structures
 
588
//
 
589
//    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
 
590
//    if (!png_ptr) { 
 
591
//        if(fp) fclose(fp); 
 
592
//        PNG_FREERESOURCE
 
593
//            return false; 
 
594
//    }
 
595
//
 
596
//    info_ptr = png_create_info_struct(png_ptr);
 
597
//    if (!info_ptr)
 
598
//    {
 
599
//        png_destroy_read_struct(&png_ptr, 0, 0);
 
600
//        if(fp) fclose(fp); 
 
601
//        PNG_FREERESOURCE
 
602
//    }
 
603
//
 
604
//    // initialize the png structure
 
605
//    PNG_SETREADFN png_init_io(png_ptr, fp);   
 
606
//
 
607
//    png_set_sig_bytes(png_ptr, 8);
 
608
//
 
609
//    // read all PNG info up to image data
 
610
//    png_read_info(png_ptr, info_ptr);
 
611
//
 
612
//    // get width, height, bit-depth and color-type    
 
613
//    unsigned long w, h;
 
614
//    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
 
615
//
 
616
//    // expand images of all color-type and bit-depth to 3x8 bit RGB images
 
617
//    // let the library process things like alpha, transparency, background
 
618
//
 
619
//    if (bit_depth == 16) png_set_strip_16(png_ptr);
 
620
//    if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
 
621
//    if (bit_depth < 8) png_set_expand(png_ptr);
 
622
//    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
 
623
//    if (color_type == PNG_COLOR_TYPE_GRAY ||
 
624
//        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
625
//        png_set_gray_to_rgb(png_ptr);
 
626
//
 
627
//    // if required set gamma conversion
 
628
//    if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, (double) 2.2, gamma);
 
629
//
 
630
//    // after the transformations have been registered update info_ptr data
 
631
//    png_read_update_info(png_ptr, info_ptr);
 
632
//
 
633
//    // get again width, height and the new bit-depth and color-type
 
634
//    png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 0, 0, 0);
 
635
//
 
636
//
 
637
//    // row_bytes is the width x number of channels
 
638
//    row_bytes = png_get_rowbytes(png_ptr, info_ptr);
 
639
//    channels = png_get_channels(png_ptr, info_ptr);
 
640
//
 
641
//    // now we can allocate memory to store the image
 
642
//
 
643
//    png_byte * img = new png_byte[row_bytes * h];
 
644
//
 
645
//    // and allocate memory for an array of row-pointers
 
646
//
 
647
//    png_byte ** row = new png_byte * [h];
 
648
//
 
649
//
 
650
//    // set the individual row-pointers to point at the correct offsets
 
651
//
 
652
//    for (unsigned int i = 0; i < h; i++)
 
653
//        row[i] = img + i * row_bytes;
 
654
//
 
655
//    // now we can go ahead and just read the whole image
 
656
//
 
657
//    png_read_image(png_ptr, row);
 
658
//
 
659
//    // read the additional chunks in the PNG file (not really needed)
 
660
//
 
661
//    png_read_end(png_ptr, NULL);
 
662
//
 
663
//    image = array2<unsigned char>(w, h);
 
664
//
 
665
//    {
 
666
//        for(unsigned int i=0; i < w; i++)
 
667
//            for(unsigned int j=0; j < h; j++)
 
668
//            { image(i,j) = *(img + ((h-j-1)*row_bytes + i * 3)); }
 
669
//    }
 
670
//
 
671
//    delete [] row;
 
672
//    delete [] img;
 
673
//
 
674
//    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
 
675
//
 
676
//    if(fp) fclose (fp);
 
677
//    PNG_FREERESOURCE
 
678
//
 
679
//        return true;
 
680
//}
 
681
 
 
682
void png_read_resource_fn(png_structp png_ptr, png_bytep data, png_size_t leng)
 
683
{
 
684
    png_bytep src = (png_bytep)png_ptr->io_ptr;
 
685
 
 
686
    for(unsigned int i=0; i<leng; i++)
 
687
        data[i] = *src++;
 
688
    png_ptr->io_ptr = (void*)src;
 
689
}
 
690
 
 
691
NAMESPACE_END