root/trunk/orca/gl/png_load.c

Revision 144, 4.6 kB (checked in by krobillard, 3 years ago)

Native arguments are now kept on the stack until after the call and the
result is now always put into a1.

Line 
1//============================================================================
2//
3// Orca PNG Loader
4//
5//============================================================================
6
7
8#include <assert.h>
9#include <png.h>
10#include "gx.h"
11#include "os.h"
12#include "ovalue.h"
13
14
15#ifndef png_jmpbuf
16#define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
17#endif
18
19
20//#define PRINT_IMAGE
21
22static void make_image( png_structp png, png_infop info )
23{
24    OBinary* bin;
25    png_uint_32 width, height;
26    int bit_depth, color_type, interlace_type, compression_type, filter_type;
27    png_bytepp row_pointers;
28
29    png_get_IHDR( png, info, &width, &height, &bit_depth, &color_type,
30                  &interlace_type, &compression_type, &filter_type );
31
32#ifdef PRINT_IMAGE
33    dprint( "\n%ldx%ld bit_depth: %d color_type: %d\n", width, height,
34            bit_depth, color_type );
35#endif
36
37    if( bit_depth == 8 )
38    {
39        int png_bpp = bit_depth / 8;
40        int format = OR_IMG_GRAY;
41
42        if( color_type == PNG_COLOR_TYPE_PALETTE )
43        {
44            orError( "png palette not supported" );
45            return;
46        }
47        else if( color_type == PNG_COLOR_TYPE_RGB )
48        {
49            png_bpp *= 3;
50            format = OR_IMG_RGB;
51        }
52        else if( color_type == PNG_COLOR_TYPE_RGB_ALPHA )
53        {
54            png_bpp *= 4;
55            format = OR_IMG_RGBA;
56        }
57
58        bin = orMakeImage( format, width, height );
59        {
60        OValue* a1 = orTOS;
61        orResult( OT_IMAGE, orBinaryN(bin) );
62        }
63
64        if( bin->byteArray )
65        {
66            png_uint_32 y;
67            int png_bpl = width * png_bpp;
68#define bpl     png_bpl
69            //int bpl = orImageBytesPerLine(img);
70            char* dest = (char*) orImagePixels(bin);
71
72            //dprint( "KR %ldx%ld depth: %d color: %d bpp: %d\n",
73            //        width, height, bit_depth, color_type, png_bpp );
74
75            row_pointers = png_get_rows( png, info );
76
77            for( y = 0; y < height; y++ )
78            {
79                memCpy( dest, row_pointers[ y ], png_bpl );
80                dest += bpl;
81#ifdef PRINT_IMAGE
82                png_bytep c, end;
83                c = row_pointers[ y ];
84                end = c + png_bpl;
85                for( ; c != end; ++c )
86                {
87                    dprint( "%02x", *c );
88                }
89                dprint( "\n" );
90#endif
91            }
92        }
93    }
94    else
95    {
96        orError( "png bit_depth %d not supported", bit_depth );
97    }
98}
99
100
101/**
102  Generic PNG read function using the high-level png_read_png().
103*/
104static int load_png( FILE *fp, unsigned int sig_read )
105{
106    png_structp png;
107    png_infop info;
108
109    png = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
110                                  /*
111                                  (png_voidp) user_error_ptr,
112                                  user_error_fn,
113                                  user_warning_fn );
114                                  */
115    if( ! png )
116        return 0;
117
118    /* Allocate/initialize the memory for image information.  REQUIRED. */
119    info = png_create_info_struct( png );
120    if( ! info )
121    {
122        png_destroy_read_struct( &png, (png_infopp)NULL, (png_infopp)NULL );
123        return 0;
124    }
125
126    if( setjmp( png_jmpbuf(png) ) )
127    {
128        /* If we get here, we had a problem reading the file */
129        png_destroy_read_struct( &png, &info, (png_infopp) NULL );
130        return 0;
131    }
132
133    png_init_io( png, fp ); /* Using standard C streams */
134    //png_set_read_fn( png, (void*) user_io_ptr, user_read_fn );
135
136    /* If we have already read some of the signature */
137    png_set_sig_bytes( png, sig_read );
138
139#if 0
140    row_pointers = png_malloc(png_ptr, height*sizeof(png_bytep));
141    for( int i=0; i<height, i++ )
142        row_pointers[i]=png_malloc(png_ptr, width*pixel_size);
143    png_set_rows(png_ptr, info_ptr, &row_pointers);
144#endif
145
146    /* hilevel read */
147    png_read_png( png, info,
148                  PNG_TRANSFORM_STRIP_16 |
149                  PNG_TRANSFORM_PACKING |
150                  PNG_TRANSFORM_EXPAND,
151                  NULL );
152
153    // At this point the image has been read (make_image calls png_get_IHDR).
154    make_image( png, info );
155
156    /* clean up after the read, and free any memory allocated - REQUIRED */
157    png_destroy_read_struct( &png, &info, (png_infopp) NULL );
158
159    return 1;
160}
161
162
163int png_loader( char* filename, uint8_t* sig, int sigLen )
164{
165    if( png_sig_cmp( sig, 0, sigLen ) == 0 )
166    {
167        FILE* fp = fopen( filename, "rb" );
168        if( fp )
169        {
170            load_png( fp, 0 );
171            fclose( fp );
172        }
173        return 1;
174    }
175    return 0;
176}
177
178
179/*EOF*/
Note: See TracBrowser for help on using the browser.