~scarneiro/ubuntu/oneiric/stereograph/fix-for-755934

« back to all changes in this revision

Viewing changes to gfxio.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Palfrader
  • Date: 2001-11-17 17:40:57 UTC
  • Revision ID: james.westby@ubuntu.com-20011117174057-tf6kt9uc3jymr2ru
Tags: upstream-0.30a
ImportĀ upstreamĀ versionĀ 0.30a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Stereograph 0.30a, 26/12/2000;
 
2
 * Graphics I/O functions;
 
3
 * Copyright (c) 2000 by Fabian Januszewski <fabian.linux@januszewski.de>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <ctype.h>
 
24
#include <math.h>
 
25
#include <time.h>
 
26
#include <png.h>
 
27
 
 
28
/* uncomment the following line to compile for big endian machines */
 
29
//#define BIG_ENDIAN
 
30
 
 
31
#include "renderer.h"
 
32
#include "gfxio.h"
 
33
#include "globals.h"
 
34
 
 
35
 
 
36
#define frand1() ((float)rand() / (float)RAND_MAX)
 
37
#define PI 3.14159265358979
 
38
 
 
39
/* add a pair of triangles to a stereogram */
 
40
int Add_Triangles(int x, int size, int width, struct GFX_DATA *gfx) {
 
41
        int z, y;
 
42
        for(y = 0; (y < size) && (y < gfx->Height); y++)
 
43
                for(z = 0; (z < size - 2*y); z++)
 
44
                        if(((y + x - width/2 + z) >= 0) && ((y + x + width/2 + z) < gfx->Width))
 
45
                                gfx->Data[y * gfx->Width + y + x - width/2 + z] = gfx->Data[y * gfx->Width + y + x + width/2 + z] = 0;
 
46
        return 0;
 
47
}
 
48
 
 
49
 
 
50
/* generates a random texture */
 
51
int Generate_Random_Texture(struct GFX_DATA *gfx, int width, int height, int type) {
 
52
        int a = 0, z;
 
53
        gfx->Data = (int*) malloc(width*height*sizeof(int));
 
54
        if(gfx->Data) {
 
55
                srand((unsigned int)time(NULL));
 
56
                gfx->Width = width;
 
57
                gfx->Height = height;
 
58
                switch(type) {
 
59
                        case TEX_BW:
 
60
                                for(z = 0; z < (height*width); z++)
 
61
                                        gfx->Data[z] = (rand()&1) * 65793 * 255;
 
62
                                break;
 
63
                        case TEX_GRAYSCALE:
 
64
                                for(z = 0; z < (height*width); z++)
 
65
                                        gfx->Data[z] = (rand()&255) * 65793;
 
66
                                break;
 
67
                        case TEX_COLORED:
 
68
                                for(z = 0; z < (height*width); z++)
 
69
                                        gfx->Data[z] = (rand()&(65793 * 255));
 
70
                                break;
 
71
                        case TEX_SINLINE:
 
72
                                a = Generate_Sinline_Texture(gfx);
 
73
                                break;
 
74
                        default:
 
75
                                free(gfx->Data);
 
76
                                gfx->Data = NULL;
 
77
                                if (verbose) printf("FAILED\n");
 
78
                                fprintf(stderr, "unsupported random texture type;\n");
 
79
                                a = -1;
 
80
                }
 
81
        } else {
 
82
                if (verbose) printf("FAILED\n");
 
83
                fprintf(stderr, "could not allocate memory for random texture;\n");
 
84
                a = -3;
 
85
        }
 
86
        if(verbose && !a) printf("done;\n");
 
87
        return a;
 
88
}
 
89
 
 
90
 
 
91
/* resizes a texture to the width of width pixels */
 
92
int Resize_GFX(struct GFX_DATA *gfx, int width) {
 
93
        int y;
 
94
        int *temp_gfx;
 
95
 
 
96
        if(verbose) printf("resizing texture...");
 
97
        temp_gfx = (int*) malloc(gfx->Height * width * sizeof(int));
 
98
        if(!temp_gfx) {
 
99
                if(verbose) printf("FAILED;\n");
 
100
                fprintf(stderr, "error allocating memory for texture!\n");
 
101
                return -3;
 
102
        } else
 
103
                for(y = 0; (y < gfx->Height); y++)
 
104
                        memcpy(temp_gfx + y * width, gfx->Data + gfx->Width * y, width*sizeof(int));
 
105
        free(gfx->Data);
 
106
        gfx->Data = temp_gfx;
 
107
        gfx->Width = width;
 
108
        if(verbose) printf("done;\n");
 
109
        return 0;
 
110
}
 
111
 
 
112
 
 
113
/* inverts a base image */
 
114
int Invert_GFX(struct GFX_DATA *gfx) {
 
115
        int z, r = 0, g = 0, b = 0;
 
116
 
 
117
        if(verbose) printf("inverting base...");
 
118
        for(z = 0; z < (gfx->Width * gfx->Height); z++) {
 
119
                r = 255 -  (gfx->Data[z]          & 255);
 
120
                g = 255 - ((gfx->Data[z] /   256) & 255);
 
121
                b = 255 - ((gfx->Data[z] / 65536) & 255);
 
122
                gfx->Data[z] = r + (b * 256) + (g * 65536);
 
123
        }
 
124
        if(verbose) printf("done;\n");
 
125
        return 0;
 
126
}
 
127
 
 
128
 
 
129
/* adjusts the base levels for transparent rendering */
 
130
int T_adjust_level(struct GFX_DATA **T_gfx, int T_layers, int T_level) {
 
131
        int t, z, r_t = 0, g_t = 0, b_t = 0, r = 0, g = 0, b = 0;
 
132
 
 
133
        if(verbose) printf("ajdusting levels...");
 
134
        for(t = 1; t < T_layers; t++)
 
135
                for(z = 0; z < (T_gfx[0]->Width * T_gfx[0]->Height); z++) {
 
136
                        r =  T_gfx[t - 1]->Data[z]          & 255;
 
137
                        g = (T_gfx[t - 1]->Data[z] /   256) & 255;
 
138
                        b = (T_gfx[t - 1]->Data[z] / 65536) & 255;
 
139
                        r_t =  T_gfx[t]->Data[z]          & 255;
 
140
                        g_t = (T_gfx[t]->Data[z] /   256) & 255;
 
141
                        b_t = (T_gfx[t]->Data[z] / 65536) & 255;
 
142
                        switch (T_level) {
 
143
                                case T_NO_LEVEL:
 
144
                                        break;
 
145
                                case T_BACK_LEVEL:
 
146
                                        if(!r_t && !g_t && !r_t) {
 
147
                                                r_t = r;
 
148
                                                g_t = g;
 
149
                                                b_t = b;
 
150
                                        }
 
151
                                        break;
 
152
                                case T_TOP_LEVEL:
 
153
                                        if((r_t + g_t + r_t) < (r + g + b)) {
 
154
                                                r_t = r;
 
155
                                                g_t = g;
 
156
                                                b_t = b;
 
157
                                        }
 
158
                                        break;
 
159
                                default :
 
160
                                        if(verbose) printf("FAILED\n");
 
161
                                        fprintf(stderr, "Unimplemented transparency level;\n");
 
162
                                        return -1;
 
163
                        }
 
164
                        T_gfx[t]->Data[z] = r_t + (b_t * 256) + (g_t * 65536);
 
165
                }
 
166
        if(verbose) printf("done;\n");
 
167
        return 0;
 
168
}
 
169
 
 
170
 
 
171
/* reads a png or targa file */
 
172
int Read_Gfx_File (char *file_name, struct GFX_DATA *gfx)
 
173
{
 
174
        int a;
 
175
        FILE *ifile = NULL;
 
176
        unsigned char check_header[8];
 
177
 
 
178
        ifile = fopen(file_name, "r");
 
179
 
 
180
        if(ifile == NULL) {
 
181
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "loading gfx data...FAILED;\n");
 
182
                fprintf(stderr, "cannot open file '%s'!\n", file_name);
 
183
                return -1;
 
184
        } else {
 
185
                a = identify_GFX_file(ifile, check_header);
 
186
                switch (a) {
 
187
                        case GFX_PNG :
 
188
                                a = Read_PNG(ifile, check_header, gfx);
 
189
                                break;
 
190
                        case GFX_TARGA :
 
191
                                a = Read_TARGA(ifile, check_header, gfx);
 
192
                                break;
 
193
                        case GFX_PPM :
 
194
                                a = Read_PPM(ifile, check_header, gfx);
 
195
                                break;
 
196
                }
 
197
        }
 
198
 
 
199
        fclose(ifile);
 
200
        ifile = NULL;
 
201
        if(!a && verbose) printf("gfx data read (%i*%i);\n", gfx->Width, gfx->Height);
 
202
        return a;
 
203
}
 
204
 
 
205
 
 
206
/* writes a png, ppm or targa file */
 
207
int Write_Gfx_File (char *file_name, int output_format, struct GFX_DATA *gfx)
 
208
{
 
209
        int a;
 
210
        FILE *ofile = NULL;
 
211
 
 
212
 
 
213
        if(verbose) printf("saving '%s' (%i*%i)...", file_name, gfx->Width, gfx->Height);
 
214
 
 
215
        if(!file_name)
 
216
                ofile = stdout;
 
217
        else
 
218
                ofile = fopen(file_name, "w+");
 
219
 
 
220
        if(ofile == NULL) {
 
221
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
 
222
                fprintf(stderr, "cannot create file %s!\n", file_name);
 
223
                return -1;
 
224
        } else
 
225
 
 
226
        switch (output_format) {
 
227
                case GFX_TARGA :
 
228
                        a = Write_TARGA(ofile, gfx);
 
229
                        break;
 
230
                case GFX_PNG :
 
231
                        a = Write_PNG(ofile, gfx);
 
232
                        break;
 
233
                case GFX_PPM :
 
234
                        a = Write_PPM(ofile, gfx);
 
235
                        break;
 
236
                default :
 
237
                        if(strlen(file_name) >= 4) {
 
238
                                if(!strcmp(file_name + strlen(file_name) - 4, ".tga"))
 
239
                                        a = Write_TARGA(ofile, gfx);
 
240
                                else if(!strcmp(file_name + strlen(file_name) - 4, ".png"))
 
241
                                        a = Write_PNG(ofile, gfx);
 
242
                                else if(!strcmp(file_name + strlen(file_name) - 4, ".ppm"))
 
243
                                        a = Write_PPM(ofile, gfx);
 
244
                                else {
 
245
                                        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
 
246
                                        fprintf(stderr, "unsupported output format!\n");
 
247
                                        a = -2;
 
248
                                }
 
249
                        } else {
 
250
                                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
 
251
                                fprintf(stderr, "unsupported output format!\n");
 
252
                                a = -2;
 
253
                        }               
 
254
        }
 
255
 
 
256
        fclose(ofile);
 
257
        ofile = NULL;
 
258
        return a;
 
259
}
 
260
 
 
261
 
 
262
 
 
263
 
 
264
/*** gfxio internals ***/
 
265
int identify_GFX_file(FILE *ifile, unsigned char *check_header) {
 
266
 
 
267
        if(fread(check_header, sizeof(char), 2, ifile) != 2) {
 
268
                if(verbose) printf("FAILED!\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
269
                fprintf(stderr, "cannot read header! (file corrupt?)\n");
 
270
                return -2;
 
271
        } else if((check_header[0] == 'P') && ((check_header[1] == '3') || (check_header[1] == '6')))
 
272
                return GFX_PPM;
 
273
        else {
 
274
                if(fread(check_header + 2, sizeof(char), 6, ifile) != 6) {
 
275
                        if(verbose) printf("FAILED!\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
276
                        fprintf(stderr, "cannot read header! (file corrupt?)\n");
 
277
                        return -2;
 
278
                } else {
 
279
                        if(!png_sig_cmp(check_header, 0, 8))
 
280
                                return GFX_PNG;
 
281
                        else
 
282
                                return GFX_TARGA;
 
283
                }
 
284
        }
 
285
        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
 
286
        fprintf(stderr, "cannot identify gfx file, unsupported format!\n");
 
287
        return -1;
 
288
}
 
289
 
 
290
int skip_space_n_comments(FILE *ifile) {
 
291
        int a;
 
292
        while(isspace(a = fgetc(ifile)) || (a == '#'))
 
293
                if(a == '#')
 
294
                        while(fgetc(ifile) != 10);
 
295
        ungetc(a, ifile);
 
296
        return 0;
 
297
}
 
298
 
 
299
int get_dec(FILE *ifile) {
 
300
        static int a, c;
 
301
        c = 0;
 
302
        
 
303
        while(isdigit(a = fgetc(ifile)))
 
304
                c = c*10 + (a - '0');
 
305
        ungetc(a, ifile);
 
306
 
 
307
        return c;
 
308
}
 
309
 
 
310
int Read_PPM (FILE *ifile, unsigned char *check_header, struct GFX_DATA *gfx)
 
311
{
 
312
        int a, z, c_max;
 
313
 
 
314
        skip_space_n_comments(ifile);
 
315
        gfx->Width = get_dec(ifile);
 
316
        skip_space_n_comments(ifile);
 
317
        gfx->Height = get_dec(ifile);
 
318
 
 
319
        gfx->Data = (int*)malloc(gfx->Width*gfx->Height*sizeof(int));
 
320
        if(!gfx->Data) {
 
321
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
322
                fprintf(stderr, "error allocating memory for image dimensions of %i * %i pixels in 32 bit\n", gfx->Width, gfx->Height);
 
323
                return -3;
 
324
        }
 
325
 
 
326
        skip_space_n_comments(ifile);
 
327
        c_max = 255 / get_dec(ifile);
 
328
 
 
329
        if(check_header[1] == '3')
 
330
                for(z = 0; z < (gfx->Width * gfx->Height); z++) {
 
331
                        while(isspace(a = fgetc(ifile))); ungetc(a, ifile);
 
332
                        gfx->Data[z] = get_dec(ifile) * c_max;
 
333
                        while(isspace(a = fgetc(ifile))); ungetc(a, ifile);
 
334
                        gfx->Data[z] += (get_dec(ifile) * c_max) * 256;
 
335
                        while(isspace(a = fgetc(ifile))); ungetc(a, ifile);
 
336
                        gfx->Data[z] += (get_dec(ifile) * c_max) * 65536;
 
337
                }
 
338
        else if (check_header[1] == '6') {
 
339
                while(isspace(a = fgetc(ifile))); ungetc(a, ifile);
 
340
                for(z = 0; z < (gfx->Width * gfx->Height); z++) {
 
341
                        gfx->Data[z] = fgetc(ifile) * c_max;
 
342
                        gfx->Data[z] += (fgetc(ifile) * c_max) * 256;
 
343
                        gfx->Data[z] += (fgetc(ifile) * c_max) * 65536;
 
344
                }
 
345
        } else {
 
346
                if (verbose) printf("FAILED\n");
 
347
                fprintf(stderr, "unknown PPM magic!\n");
 
348
        }
 
349
 
 
350
        return 0;
 
351
}
 
352
 
 
353
 
 
354
int Read_PNG (FILE *ifile, unsigned char *check_header, struct GFX_DATA *gfx)
 
355
{
 
356
        png_voidp user_error_ptr = NULL;
 
357
        png_structp png_ptr;
 
358
        png_infop info_ptr;
 
359
        png_infop end_info;
 
360
 
 
361
        int bit_depth, color_type, interlace_type, interlace_passes;
 
362
 
 
363
        //unsigned char header_check[8];
 
364
        int z;
 
365
 
 
366
        /* checking png header */
 
367
        //fread(header_check, sizeof(char), 8, ifile);
 
368
        //} else {
 
369
 
 
370
                /* initializing */
 
371
                png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, user_error_ptr, NULL, NULL);
 
372
                if (!png_ptr) {
 
373
                        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
 
374
                        fprintf(stderr, "cannot create png read struct!\n");
 
375
                        return -1;
 
376
                }
 
377
                info_ptr = png_create_info_struct(png_ptr);
 
378
                if (!info_ptr) {
 
379
                        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
 
380
                        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
 
381
                        fprintf(stderr, "cannot create png info struct!\n");
 
382
                        return -1;
 
383
                }
 
384
                end_info = png_create_info_struct(png_ptr);
 
385
                if (!end_info) {
 
386
                        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
 
387
                        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
 
388
                        fprintf(stderr, "cannot create png (end) info struct!\n");
 
389
                        return -1;
 
390
                }
 
391
                
 
392
                /* libpng error handling */
 
393
                if (setjmp(png_ptr->jmpbuf)) {
 
394
                        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
 
395
                        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
 
396
                        fprintf(stderr, "libpng reported an error!\n");
 
397
                        return -1;
 
398
                }
 
399
                
 
400
 
 
401
                /* setting up file pointer */
 
402
                png_init_io(png_ptr, ifile);
 
403
                /* the offset created by the png check */
 
404
                png_set_sig_bytes(png_ptr, 8);
 
405
                
 
406
                /* setting up alpha channel for non-transparency */
 
407
                /* png_set_invert_alpha(png_ptr); */
 
408
                
 
409
                /* okay, let's get the full header now */
 
410
                png_read_info(png_ptr, info_ptr);
 
411
 
 
412
                png_get_IHDR(png_ptr, info_ptr, NULL, NULL, &bit_depth, &color_type, &interlace_type, NULL, NULL);
 
413
 
 
414
                /* general format conversions */
 
415
 
 
416
                /* handle lower bit rates */
 
417
                /*if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8)
 
418
                        png_set_expand(png_ptr);
 
419
                if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth <= 8)
 
420
                        png_set_expand(png_ptr);
 
421
                if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))*/
 
422
                        png_set_expand(png_ptr);
 
423
                
 
424
                /* reduce from 16 bits/channel to 8 bits */
 
425
                        /* correct use of little endian */
 
426
                /*if (bit_depth == 16) {*/
 
427
                #ifndef BIG_ENDIAN
 
428
                        png_set_swap(png_ptr);  // swap byte pairs to little endian
 
429
                #endif
 
430
                png_set_strip_16(png_ptr);
 
431
                /*}*/
 
432
 
 
433
 
 
434
                /* if it's a gray scale, convert it to RGB */
 
435
                /* if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) */
 
436
                        png_set_gray_to_rgb(png_ptr);
 
437
 
 
438
                /* convert indexed to full 32 bit RGBA */
 
439
                /* if (color_type == PNG_COLOR_TYPE_RGB) */
 
440
                png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
 
441
 
 
442
                /* activate libpng interlace handling */
 
443
                interlace_passes = png_set_interlace_handling(png_ptr);
 
444
 
 
445
                /* okay, final info set up */
 
446
                png_read_update_info(png_ptr, info_ptr);
 
447
 
 
448
                gfx->Width = png_get_image_width(png_ptr, info_ptr);
 
449
                gfx->Height = png_get_image_height(png_ptr, info_ptr);
 
450
 
 
451
                gfx->Data = (int*)malloc(gfx->Width*gfx->Height*sizeof(int));
 
452
                if(!gfx->Data) {
 
453
                        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
 
454
                        if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
455
                        fprintf(stderr, "error allocating memory for image dimensions of %i * %i pixels in 32 bit\n", gfx->Width, gfx->Height);
 
456
                        return -3;
 
457
                }
 
458
 
 
459
                /* alternatively read it row by row, interlacing as expected */
 
460
                for(z = 0; z < (gfx->Height * interlace_passes); z++)
 
461
                        png_read_row(png_ptr, (void *) (gfx->Data + ((z % gfx->Height) * gfx->Width)), NULL);
 
462
 
 
463
                png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
 
464
                /* that's it */         
 
465
        //}
 
466
        return 0;
 
467
}
 
468
 
 
469
int Write_PNG (FILE *ofile, struct GFX_DATA *gfx)
 
470
{
 
471
        png_voidp user_error_ptr = NULL;
 
472
        png_structp png_ptr;
 
473
        png_infop info_ptr;
 
474
 
 
475
        int z;
 
476
 
 
477
        /* initializing */
 
478
        png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, user_error_ptr, NULL, NULL);
 
479
        if (!png_ptr) {
 
480
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED\n");
 
481
                fprintf(stderr, "cannot create png write struct!\n");
 
482
                return -1;
 
483
        }
 
484
        info_ptr = png_create_info_struct(png_ptr);
 
485
        if (!info_ptr) {
 
486
                png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
 
487
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED\n");
 
488
                fprintf(stderr, "cannot create png info struct!\n");
 
489
                return -1;
 
490
        }
 
491
                
 
492
        /* libpng error handling */
 
493
        if (setjmp(png_ptr->jmpbuf)) {
 
494
                png_destroy_write_struct(&png_ptr, &info_ptr);
 
495
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED\n");
 
496
                fprintf(stderr, "libpng reported an error!\n");
 
497
                return -1;
 
498
        }
 
499
                
 
500
        /* setting up file pointer */
 
501
        png_init_io(png_ptr, ofile);
 
502
 
 
503
        /* setting up png info header */
 
504
        png_set_IHDR(png_ptr, info_ptr, gfx->Width, gfx->Height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 
505
 
 
506
        png_set_invert_alpha(png_ptr);
 
507
                
 
508
        /* let's flush the header down */
 
509
        png_write_info(png_ptr, info_ptr);
 
510
 
 
511
        /*
 
512
        #ifndef BIG_ENDIAN
 
513
                png_set_swap(png_ptr);  // swap bytes to big endian, for little endian machines and only useful when writing 16 bits/channel;
 
514
        #endif
 
515
        */
 
516
 
 
517
        for(z = 0; z < gfx->Height; z++)
 
518
                png_write_row(png_ptr, (void *) (gfx->Data + z*gfx->Width));
 
519
 
 
520
        png_write_end(png_ptr, NULL);
 
521
 
 
522
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
523
        /* that's it */         
 
524
 
 
525
        return 0;
 
526
}
 
527
 
 
528
int Read_TARGA (FILE *ifile, unsigned char *check_header, struct GFX_DATA *gfx)
 
529
{
 
530
        /* TARGA uses the Intel format for integer coding (low byte first) */
 
531
 
 
532
        unsigned char header[20];
 
533
        int x, y, *palette, c, l, s, z;
 
534
 
 
535
        /* copy the preread check header to the real header */
 
536
        memcpy(header, check_header, sizeof(char)*8);
 
537
 
 
538
        /* reading all header information */
 
539
        if(fread(header + 8, sizeof(char), 10, ifile) != 10) {
 
540
                if(verbose) printf("FAILED!\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
541
                fprintf(stderr, "cannot read header! (file corrupt?)\n");
 
542
                return -2;
 
543
        }
 
544
 
 
545
        /* general measurements */
 
546
        gfx->Width = (int)header[12] + (int)header[13]*256;
 
547
        gfx->Height = (int)header[14] + (int)header[15]*256;
 
548
        gfx->Data = (int*)malloc(gfx->Width*gfx->Height*sizeof(int));
 
549
        if(!gfx->Data) {
 
550
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
551
                fprintf(stderr, "error allocating memory for image dimensions of %i * %i pixels in 32 bit\n", gfx->Width, gfx->Height);
 
552
                fprintf(stderr, "debug header follows:\n");
 
553
                for(x = 0; x < 20; x += 4)
 
554
                        fprintf(stderr, " %i, %i, %i, %i;\n", (int)header[x], (int)header[x + 1], (int)header[x + 2], (int)header[x + 3]);
 
555
                return -3;
 
556
        }
 
557
 
 
558
        /* reading image identification field */
 
559
        for(x = 0; x < header[0]; x++)
 
560
                getc(ifile);
 
561
 
 
562
        /* reading palette data */
 
563
        if((header[1] != 0) && ((header[5] + header[6]*256) > 0) && (((header[3] + header[4]*256) + (header[5] + header[6]*256)) <= 256)) {
 
564
                palette = (int*)malloc(((header[3] + header[4]*256) + (header[5] + header[6]*256)) * sizeof(int));
 
565
                for(x = header[3] + header[4]*256; (x < (header[5] + header[6]*256)); x++)
 
566
                        Read_TARGA_RGB(ifile, (int)header[7], NULL, palette + x);
 
567
        } else
 
568
                palette = NULL;
 
569
 
 
570
        if(((header[2] == 2) && (header[16] >= 16)) || (((header[2] == 1) || header[2] == 3) && (header[16] == 8))) {
 
571
        /* type 1: 8 bit/palette, uncompressed; type 2: 16 bit++, uncompressed; type 3: 8 bit monocrome, uncompressed; */
 
572
                if(header[17] & 32) {
 
573
                        for(y = 0; y < gfx->Height; y++) {
 
574
                                if(header[17] & 16)
 
575
                                        for(x = gfx->Width - 1; x >= 0; x--)
 
576
                                                Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
 
577
                                else
 
578
                                        for(x = 0; x < gfx->Width; x++)
 
579
                                                Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
 
580
                        }
 
581
                } else {
 
582
                        for(y = gfx->Height - 1; y >= 0; y--) {
 
583
                                if(header[17] & 16)
 
584
                                        for(x = gfx->Width - 1; x >= 0; x--)
 
585
                                                Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
 
586
                                else
 
587
                                        for(x = 0; x < gfx->Width; x++)
 
588
                                                Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
 
589
                        }
 
590
                }
 
591
                /*if(verbose) printf("gfx data read (%i*%i);\n", gfx->Width, gfx->Height);*/
 
592
                free(palette);
 
593
                return 0;
 
594
        } else if(((header[2] == 10) && (header[16] >= 16)) || (((header[2] == 9) || header[2] == 11) && (header[16] == 8))) {
 
595
        /* type 9: 8 bit/palette RLE; type 10: 16 bit++, RLE; type 11: 8 bit monocrome, RLE; */
 
596
                for(z = 0; ((l = getc(ifile)) != EOF) && (z < (gfx->Height * gfx->Width)); ) {
 
597
                        if(l & 128) { /* compressed data follows */
 
598
                                l &= 127; /* extracting length */
 
599
                                Read_TARGA_RGB(ifile, (int)header[16], palette, &c);
 
600
                                for(s = 0; (s <= l); s++) {
 
601
                                        x = z % gfx->Width;
 
602
                                        y = (z - x) / gfx->Width;
 
603
                                        if(header[17] & 16)
 
604
                                                x = gfx->Width - 1 - x;
 
605
                                        if(!(header[17] & 32))
 
606
                                                y = gfx->Height - 1 - y;
 
607
                                        if((x < gfx->Width) && (y < gfx->Height) && (x >= 0) && (y >= 0))
 
608
                                                gfx->Data[(y * gfx->Width) + x] = c;
 
609
                                        else
 
610
                                                fprintf(stderr, "(%i, %i) => error\n", x, y);
 
611
                                        z++;
 
612
                                }
 
613
                        } else { /* uncompressed data follows */
 
614
                                for(s = 0; (s <= l); s++) {
 
615
                                        x = z % gfx->Width;
 
616
                                        y = (z - x) / gfx->Width;
 
617
                                        if(header[17] & 16)
 
618
                                                x = gfx->Width - 1 - x;
 
619
                                        if(!(header[17] & 32))
 
620
                                                y = gfx->Height - 1 - y;
 
621
                                        if((x < gfx->Width) && (y < gfx->Height) && (x >= 0) && (y >= 0))
 
622
                                                Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
 
623
                                        else
 
624
                                                fprintf(stderr, "(%i, %i) => error\n", x, y);
 
625
                                        z++;
 
626
                                }
 
627
                        }
 
628
                }
 
629
                /*if(verbose) printf("gfx data read (%i*%i);\n", gfx->Width, gfx->Height);*/
 
630
                free(palette);
 
631
                return 0;
 
632
        } else {
 
633
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED;\n");
 
634
                fprintf(stderr, "Unsupported Targa Data Format %i@%i;\nOnly TARGA types 1, 2, 3 (uncompressed) and 9, 10, 11 (RLE) are supported;\n", header[2], header[16]);
 
635
                free(palette);
 
636
                return -1;
 
637
        }
 
638
}
 
639
 
 
640
 
 
641
int Read_TARGA_RGB(FILE *ifile, int bits, int *palette, int *c) {
 
642
        static int a, r, g, b, z1, z2;
 
643
        a = 0;
 
644
        if(bits == 8) {
 
645
                if(palette)
 
646
                        (*c) = palette[(int)getc(ifile)];
 
647
                else
 
648
                        (*c) = (int)getc(ifile) * 65793;  /* 65793 = (1+256+65536) */
 
649
        } else if(bits == 16) {
 
650
                        z1 = getc(ifile);
 
651
                        z2 = getc(ifile);
 
652
                        r = (int)((255.0/31.0) * (float)((z1 & 124) / 4) );  /* 124 = 64 + 32 + 16 + 8 + 4 */
 
653
                        g = (int)((255.0/31.0) * (float)(((z1 & 3) * 8) | ((z2 & 224) / 32)) );  /* 224 = 128 + 64 + 32 */
 
654
                        b = (int)((255.0/31.0) * (float)(z2 & 31) );
 
655
                        (*c) = r + (g * 256) + (b * 65536);
 
656
                        a = z1 & 128;
 
657
                } else {
 
658
                        r = getc(ifile);
 
659
                        g = getc(ifile);
 
660
                        b = getc(ifile);
 
661
                        (*c) = r + (g * 256) + (b * 65536);
 
662
                        if(bits == 32)
 
663
                                a = getc(ifile);
 
664
                }
 
665
        return a; /* attribute (alpha/transparency information, 32 bit only) */
 
666
}
 
667
 
 
668
/* writes all gfx data to stdout, preceded by the resolution of gfx data - everything 32 bit wide */
 
669
int Write_PPM (FILE *ofile, struct GFX_DATA *gfx)
 
670
{
 
671
        int a, x, y;
 
672
 
 
673
        fprintf(ofile, "P6\n");
 
674
        fprintf(ofile, "%i %i\n", gfx->Width, gfx->Height);
 
675
        fprintf(ofile, "255\n");
 
676
        a = 0;
 
677
        for(y = 0; (y < gfx->Height) && (a != EOF); y++)
 
678
                for(x = 0; (x < gfx->Width) && (a != EOF); x++) {
 
679
                        putc(gfx->Data[y * gfx->Width + x] & 255, ofile);
 
680
                        putc((gfx->Data[y * gfx->Width + x] / 256) & 255, ofile);
 
681
                        a = putc((gfx->Data[y * gfx->Width + x] / 65536) & 255, ofile);
 
682
                }
 
683
        if(a != EOF) {
 
684
                return 0;
 
685
        } else {
 
686
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
 
687
                        fprintf(stderr, "cannot write to file! (disk full?)\n");
 
688
                return -1;
 
689
        }
 
690
}
 
691
 
 
692
int Write_TARGA (FILE *ofile, struct GFX_DATA *gfx)
 
693
{
 
694
        int a, x, y;
 
695
        /* standard TARGA header consists of 18 bytes */
 
696
        /* id tag length */
 
697
        putc(strlen("created by stereograph"), ofile);
 
698
        /* color pallette, yes/no */
 
699
        putc(0, ofile);
 
700
        /* TARGA type 2: RGB 24 bit, no pallette */
 
701
        putc(2, ofile);
 
702
        /* 5 following bytes contain only pallette information */
 
703
        putc(0, ofile);
 
704
        putc(0, ofile);
 
705
        putc(0, ofile);
 
706
        putc(0, ofile);
 
707
        putc(0, ofile);
 
708
        /* x offset */
 
709
        putc(0, ofile);
 
710
        putc(0, ofile);
 
711
        /* y offset */
 
712
        putc(0, ofile);
 
713
        putc(0, ofile);
 
714
        /* width, low byte first */
 
715
        putc(gfx->Width & 255, ofile);
 
716
        putc((gfx->Width / 256) & 255, ofile);
 
717
        /* height */
 
718
        putc(gfx->Height & 255, ofile);
 
719
        putc((gfx->Height / 256) & 255, ofile);
 
720
        /* bits per pixel */
 
721
        putc(32-8, ofile);
 
722
        /* Image Descriptor Flags */
 
723
        putc(0, ofile);
 
724
        fwrite("created by stereograph", sizeof(char), strlen("created by stereograph"), ofile);
 
725
        /* data follows */
 
726
        a = 0;
 
727
        for(y = gfx->Height - 1; (y >= 0) && (a != EOF); y--)
 
728
                for(x = 0; (x < gfx->Width) && (a != EOF); x++) {
 
729
                        putc(gfx->Data[y * gfx->Width + x] & 255, ofile);
 
730
                        putc((gfx->Data[y * gfx->Width + x] / 256) & 255, ofile);
 
731
                        a = putc((gfx->Data[y * gfx->Width + x] / 65536) & 255, ofile);
 
732
                }
 
733
        if(a != EOF) {
 
734
                return 0;
 
735
        } else {
 
736
                if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
 
737
                        fprintf(stderr, "cannot write to file! (disk full?)\n");
 
738
                return -1;
 
739
        }
 
740
}
 
741
 
 
742
 
 
743
int fdata_to_GFX(float *datafield[3], struct GFX_DATA *gfx) {
 
744
        int z;
 
745
        float a, b;
 
746
        a = frand1();
 
747
        b = sqrt(a * frand1());
 
748
        for(z = 0; z < (gfx->Width*gfx->Height); z++) {
 
749
                if(datafield[3][z] > a) {
 
750
                        gfx->Data[z] = (int)(datafield[2][z] * (rand()&255));
 
751
                        gfx->Data[z] += (int)(datafield[0][z] * (rand()&255))*256;
 
752
                        gfx->Data[z] += (int)(datafield[1][z] * (rand()&255))*65536;
 
753
                } else if (datafield[3][z] > b) {
 
754
                        gfx->Data[z] = (int)(datafield[0][z] * 255.0);
 
755
                        gfx->Data[z] += (int)(datafield[1][z] * 255.0)*256;
 
756
                        gfx->Data[z] += (int)(datafield[2][z] * 255.0)*65536;
 
757
                } else {
 
758
                        gfx->Data[z] = (int)(datafield[0][z] * datafield[4][z] * 255.0);
 
759
                        gfx->Data[z] += (int)(datafield[1][z] * datafield[4][z] * 255.0)*256;
 
760
                        gfx->Data[z] += (int)(datafield[2][z]  * datafield[4][z] * 255.0)*65536;
 
761
                        gfx->Data[z] += (int)(datafield[1][z] * (1.0 - datafield[4][z]) * 255.0);
 
762
                        gfx->Data[z] += (int)(datafield[2][z] * (1.0 - datafield[4][z]) * 255.0)*256;
 
763
                        gfx->Data[z] += (int)(datafield[0][z]  * (1.0 - datafield[4][z]) * 255.0)*65536;
 
764
                }
 
765
        }
 
766
        return 0;
 
767
}
 
768
 
 
769
 
 
770
float c_sin(int a, float b) {
 
771
        static float *sincache = NULL;
 
772
        static float cb = 0.0, maxb = 0.0;
 
773
 
 
774
        if((int)b <= 0) {
 
775
                free(sincache);
 
776
                sincache = NULL;
 
777
                cb = 0.0;
 
778
                maxb = 0.0;
 
779
        } else {
 
780
                if(cb != b) {
 
781
                        if (maxb < b) {
 
782
                                sincache = (float*)realloc(sincache, (int)b * sizeof(float));
 
783
                                maxb = b;
 
784
                        }
 
785
                        for(cb = 0.0; cb < b; cb += 1.0)
 
786
                                sincache[(int)cb] = sin(PI * (1.5 + (cb / b)));
 
787
                        cb = b;
 
788
                }
 
789
                return sincache[a];
 
790
        }
 
791
        return 0.0;
 
792
}
 
793
 
 
794
 
 
795
void Sinline_Fill_H(float *dataline, int x1, int x2, int width) {
 
796
        static int z;
 
797
        static float a;
 
798
 
 
799
        a = 0.5 * (dataline[x1] - dataline[x2 % width]);
 
800
        for(z = x1 + 1; z < x2; z++)
 
801
                //dataline[z % width] = dataline[x1] - (a * (sin(PI * (1.5 + ((float)(z - x1) / (float)(x2 - x1)))) + 1.0));
 
802
                dataline[z % width] = dataline[x1] - (a * (c_sin(z - x1, (float)(x2 - x1)) + 1.0));
 
803
}
 
804
 
 
805
 
 
806
void Sinline_Fill_H_flat(float *dataline, int x1, int x2, int width) {
 
807
        static int z;
 
808
        static float a;
 
809
 
 
810
        a = 0.5 * (dataline[x1] - dataline[x2 % width]);
 
811
        for(z = x1 + 1; z < x2; z++)
 
812
                dataline[z % width] = dataline[x1] - a;
 
813
}
 
814
 
 
815
 
 
816
void Sinline_Fill_datafield_H(float* datafield, int width, int height) {
 
817
        int tx, x, y;
 
818
        int lines, line_offset;
 
819
        float phase;
 
820
        float period;
 
821
        //float a;
 
822
 
 
823
        lines = 1 + (5*width/height) + rand() % 4;
 
824
        line_offset = (int)((float)width * frand1()) / lines;
 
825
        for(tx = 0; tx < lines; tx++) {
 
826
                //period = PI / (float)height / (((a = frand1()) == 0) ? 1.0 : a);    // to avoid division by zero
 
827
                period = (PI / (float)height) / (frand1()*0.5 + 0.1);
 
828
                phase = frand1() * 2.0 * PI;
 
829
                x = line_offset + ((width / lines) * tx);
 
830
                for(y = 0; y < height; y++) {
 
831
                        datafield[(y * width) + x] = 0.5 + (0.5 * sin(phase + period * (float)y));
 
832
                        if(tx > 0)
 
833
                                Sinline_Fill_H(datafield + (y * width), x - (width/lines), x, width);
 
834
                }
 
835
        }
 
836
        for(y = 0; y < height; y++)
 
837
                Sinline_Fill_H(datafield + (y * width), line_offset + ((width / lines) * (lines - 1)), line_offset + width, width);
 
838
}
 
839
 
 
840
 
 
841
void Sinline_Fill_V(float *dataline, int y1, int y2, int height, int width) {
 
842
        static int z;
 
843
        static float a;
 
844
 
 
845
        a = 0.5 * (dataline[y1 * width] - dataline[(y2 % height) * width]);
 
846
        for(z = y1 + 1; z < y2; z++)
 
847
                //dataline[(z % height) * width] = dataline[y1*width] - (a * (sin(PI * (1.5 + ((float)(z - y1) / (float)(y2 - y1)))) + 1.0));
 
848
                dataline[(z % height) * width] = dataline[y1*width] - (a * (c_sin(z - y1, (float)(y2 - y1)) + 1.0));
 
849
}
 
850
 
 
851
 
 
852
void Sinline_Fill_V_flat(float *dataline, int y1, int y2, int height, int width) {
 
853
        static int z;
 
854
        static float a;
 
855
 
 
856
        a = 0.5 * (dataline[y1 * width] - dataline[(y2 % height) * width]);
 
857
        for(z = y1 + 1; z < y2; z++)
 
858
                dataline[(z % height) * width] = dataline[y1*width] - a;
 
859
}
 
860
 
 
861
 
 
862
void Sinline_Fill_datafield_V(float* datafield, int width, int height) {
 
863
        int ty, x, y;
 
864
        int lines, line_offset;
 
865
        float phase;
 
866
        float period;
 
867
 
 
868
        lines = 1 + (3*height/width) + rand() % 4;
 
869
        line_offset = (int)((float)height * frand1()) / lines;
 
870
        for(ty = 0; ty < lines; ty++) {
 
871
                period = 2.0*(PI / (float)width) * (rand()%4 + 1);    // to avoid division by zero
 
872
                phase = frand1() * 2.0 * PI;
 
873
                y = line_offset + ((height / lines) * ty);
 
874
                for(x = 0; x < width; x++) {
 
875
                        datafield[(y * width) + x] = 0.5 + (0.5 * sin(phase + period * (float)x));
 
876
                        if(ty > 0)
 
877
                                Sinline_Fill_V(datafield + x, y - (height/lines), y, height, width);
 
878
                }
 
879
        }
 
880
        for(x = 0; x < width; x++)
 
881
                Sinline_Fill_V(datafield + x, line_offset + ((height / lines) * (lines - 1)), line_offset + height, height, width);
 
882
}
 
883
 
 
884
 
 
885
void Sinline_merge_datafields_add(float *datafield, float *datafield1, float *datafield2, int c) {
 
886
        int z;
 
887
        for(z = 0; z < c; z++)
 
888
                datafield[z] = 0.5 * (datafield1[z] + datafield2[z]);
 
889
}
 
890
 
 
891
 
 
892
void Sinline_merge_datafields_mul(float *datafield, float *datafield1, float *datafield2, int c) {
 
893
        int z;
 
894
        for(z = 0; z < c; z++)
 
895
                datafield[z] = sqrt(datafield1[z] * datafield2[z]);
 
896
}
 
897
 
 
898
 
 
899
int Generate_Sinline_Texture(struct GFX_DATA *gfx)
 
900
{
 
901
        int z;
 
902
        float *a, *datafield[5];
 
903
 
 
904
        for(z = 0; (z < 5) && (a || !z); z++)
 
905
                a = datafield[z] = (float*) malloc(gfx->Width * gfx->Height * sizeof(float));
 
906
        if(a) {
 
907
 
 
908
                        Sinline_Fill_datafield_H(datafield[0], gfx->Width, gfx->Height);
 
909
                        Sinline_Fill_datafield_V(datafield[1], gfx->Width, gfx->Height);
 
910
                        Sinline_merge_datafields_add(datafield[2], datafield[0], datafield[1], gfx->Width*gfx->Height);
 
911
                        Sinline_Fill_datafield_H(datafield[0], gfx->Width, gfx->Height);
 
912
                        Sinline_Fill_datafield_V(datafield[1], gfx->Width, gfx->Height);
 
913
                        Sinline_merge_datafields_mul(datafield[2], datafield[2], datafield[1], gfx->Width*gfx->Height);
 
914
                        Sinline_merge_datafields_add(datafield[2], datafield[2], datafield[0], gfx->Width*gfx->Height);
 
915
 
 
916
                        Sinline_Fill_datafield_H(datafield[0], gfx->Width, gfx->Height);
 
917
                        Sinline_Fill_datafield_V(datafield[1], gfx->Width, gfx->Height);
 
918
                        Sinline_merge_datafields_mul(datafield[3], datafield[0], datafield[1], gfx->Width*gfx->Height);
 
919
                        Sinline_Fill_datafield_H(datafield[0], gfx->Width, gfx->Height);
 
920
                        Sinline_Fill_datafield_V(datafield[1], gfx->Width, gfx->Height);
 
921
                        Sinline_merge_datafields_add(datafield[3], datafield[3], datafield[0], gfx->Width*gfx->Height);
 
922
                        Sinline_merge_datafields_add(datafield[3], datafield[3], datafield[1], gfx->Width*gfx->Height);
 
923
 
 
924
                        Sinline_Fill_datafield_H(datafield[0], gfx->Width, gfx->Height);
 
925
                        Sinline_Fill_datafield_V(datafield[1], gfx->Width, gfx->Height);
 
926
                        Sinline_merge_datafields_mul(datafield[1], datafield[0], datafield[1], gfx->Width*gfx->Height);
 
927
                        Sinline_Fill_datafield_H(datafield[0], gfx->Width, gfx->Height);
 
928
                        Sinline_merge_datafields_add(datafield[1], datafield[0], datafield[1], gfx->Width*gfx->Height);
 
929
                        Sinline_Fill_datafield_V(datafield[0], gfx->Width, gfx->Height);
 
930
                        Sinline_merge_datafields_add(datafield[1], datafield[0], datafield[1], gfx->Width*gfx->Height);
 
931
 
 
932
                        Sinline_Fill_datafield_H(datafield[4], gfx->Width, gfx->Height);
 
933
                        Sinline_Fill_datafield_V(datafield[1], gfx->Width, gfx->Height);
 
934
                        Sinline_merge_datafields_mul(datafield[1], datafield[4], datafield[1], gfx->Width*gfx->Height);
 
935
                        Sinline_Fill_datafield_H(datafield[4], gfx->Width, gfx->Height);
 
936
                        Sinline_merge_datafields_add(datafield[1], datafield[4], datafield[1], gfx->Width*gfx->Height);
 
937
                        Sinline_Fill_datafield_V(datafield[4], gfx->Width, gfx->Height);
 
938
                        Sinline_merge_datafields_add(datafield[1], datafield[4], datafield[1], gfx->Width*gfx->Height);
 
939
 
 
940
                        for(z = 0; z < 4; z++) {
 
941
                                Sinline_Fill_datafield_H(datafield[4], gfx->Width, gfx->Height);
 
942
                                Sinline_merge_datafields_add(datafield[z], datafield[4], datafield[z], gfx->Width*gfx->Height);
 
943
                                Sinline_Fill_datafield_V(datafield[4], gfx->Width, gfx->Height);
 
944
                                Sinline_merge_datafields_add(datafield[z], datafield[4], datafield[z], gfx->Width*gfx->Height);
 
945
                        }
 
946
                        Sinline_Fill_datafield_V(datafield[4], gfx->Width, gfx->Height);
 
947
 
 
948
                c_sin(0, 0);
 
949
                fdata_to_GFX(datafield, gfx);
 
950
                for(z = 0; z < 5; z++)
 
951
                        free(datafield[z]);
 
952
        } else {
 
953
                for(z = 0; (z < 5) && datafield[z]; z++)
 
954
                        free(datafield[z]);
 
955
                free(gfx->Data);
 
956
                gfx->Data = NULL;
 
957
                if (verbose) printf("FAILED\n");
 
958
                fprintf(stderr, "could not allocate memory;\n");
 
959
                return -1;
 
960
        }
 
961
        return 0;
 
962
}