1
/* Stereograph 0.30a, 26/12/2000;
2
* Graphics I/O functions;
3
* Copyright (c) 2000 by Fabian Januszewski <fabian.linux@januszewski.de>
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.
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.
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.
28
/* uncomment the following line to compile for big endian machines */
36
#define frand1() ((float)rand() / (float)RAND_MAX)
37
#define PI 3.14159265358979
39
/* add a pair of triangles to a stereogram */
40
int Add_Triangles(int x, int size, int width, struct GFX_DATA *gfx) {
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;
50
/* generates a random texture */
51
int Generate_Random_Texture(struct GFX_DATA *gfx, int width, int height, int type) {
53
gfx->Data = (int*) malloc(width*height*sizeof(int));
55
srand((unsigned int)time(NULL));
60
for(z = 0; z < (height*width); z++)
61
gfx->Data[z] = (rand()&1) * 65793 * 255;
64
for(z = 0; z < (height*width); z++)
65
gfx->Data[z] = (rand()&255) * 65793;
68
for(z = 0; z < (height*width); z++)
69
gfx->Data[z] = (rand()&(65793 * 255));
72
a = Generate_Sinline_Texture(gfx);
77
if (verbose) printf("FAILED\n");
78
fprintf(stderr, "unsupported random texture type;\n");
82
if (verbose) printf("FAILED\n");
83
fprintf(stderr, "could not allocate memory for random texture;\n");
86
if(verbose && !a) printf("done;\n");
91
/* resizes a texture to the width of width pixels */
92
int Resize_GFX(struct GFX_DATA *gfx, int width) {
96
if(verbose) printf("resizing texture...");
97
temp_gfx = (int*) malloc(gfx->Height * width * sizeof(int));
99
if(verbose) printf("FAILED;\n");
100
fprintf(stderr, "error allocating memory for texture!\n");
103
for(y = 0; (y < gfx->Height); y++)
104
memcpy(temp_gfx + y * width, gfx->Data + gfx->Width * y, width*sizeof(int));
106
gfx->Data = temp_gfx;
108
if(verbose) printf("done;\n");
113
/* inverts a base image */
114
int Invert_GFX(struct GFX_DATA *gfx) {
115
int z, r = 0, g = 0, b = 0;
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);
124
if(verbose) printf("done;\n");
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;
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;
146
if(!r_t && !g_t && !r_t) {
153
if((r_t + g_t + r_t) < (r + g + b)) {
160
if(verbose) printf("FAILED\n");
161
fprintf(stderr, "Unimplemented transparency level;\n");
164
T_gfx[t]->Data[z] = r_t + (b_t * 256) + (g_t * 65536);
166
if(verbose) printf("done;\n");
171
/* reads a png or targa file */
172
int Read_Gfx_File (char *file_name, struct GFX_DATA *gfx)
176
unsigned char check_header[8];
178
ifile = fopen(file_name, "r");
181
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "loading gfx data...FAILED;\n");
182
fprintf(stderr, "cannot open file '%s'!\n", file_name);
185
a = identify_GFX_file(ifile, check_header);
188
a = Read_PNG(ifile, check_header, gfx);
191
a = Read_TARGA(ifile, check_header, gfx);
194
a = Read_PPM(ifile, check_header, gfx);
201
if(!a && verbose) printf("gfx data read (%i*%i);\n", gfx->Width, gfx->Height);
206
/* writes a png, ppm or targa file */
207
int Write_Gfx_File (char *file_name, int output_format, struct GFX_DATA *gfx)
213
if(verbose) printf("saving '%s' (%i*%i)...", file_name, gfx->Width, gfx->Height);
218
ofile = fopen(file_name, "w+");
221
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
222
fprintf(stderr, "cannot create file %s!\n", file_name);
226
switch (output_format) {
228
a = Write_TARGA(ofile, gfx);
231
a = Write_PNG(ofile, gfx);
234
a = Write_PPM(ofile, gfx);
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);
245
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
246
fprintf(stderr, "unsupported output format!\n");
250
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
251
fprintf(stderr, "unsupported output format!\n");
264
/*** gfxio internals ***/
265
int identify_GFX_file(FILE *ifile, unsigned char *check_header) {
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");
271
} else if((check_header[0] == 'P') && ((check_header[1] == '3') || (check_header[1] == '6')))
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");
279
if(!png_sig_cmp(check_header, 0, 8))
285
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
286
fprintf(stderr, "cannot identify gfx file, unsupported format!\n");
290
int skip_space_n_comments(FILE *ifile) {
292
while(isspace(a = fgetc(ifile)) || (a == '#'))
294
while(fgetc(ifile) != 10);
299
int get_dec(FILE *ifile) {
303
while(isdigit(a = fgetc(ifile)))
304
c = c*10 + (a - '0');
310
int Read_PPM (FILE *ifile, unsigned char *check_header, struct GFX_DATA *gfx)
314
skip_space_n_comments(ifile);
315
gfx->Width = get_dec(ifile);
316
skip_space_n_comments(ifile);
317
gfx->Height = get_dec(ifile);
319
gfx->Data = (int*)malloc(gfx->Width*gfx->Height*sizeof(int));
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);
326
skip_space_n_comments(ifile);
327
c_max = 255 / get_dec(ifile);
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;
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;
346
if (verbose) printf("FAILED\n");
347
fprintf(stderr, "unknown PPM magic!\n");
354
int Read_PNG (FILE *ifile, unsigned char *check_header, struct GFX_DATA *gfx)
356
png_voidp user_error_ptr = NULL;
361
int bit_depth, color_type, interlace_type, interlace_passes;
363
//unsigned char header_check[8];
366
/* checking png header */
367
//fread(header_check, sizeof(char), 8, ifile);
371
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, user_error_ptr, NULL, NULL);
373
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "reading gfx data...FAILED\n");
374
fprintf(stderr, "cannot create png read struct!\n");
377
info_ptr = png_create_info_struct(png_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");
384
end_info = png_create_info_struct(png_ptr);
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");
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");
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);
406
/* setting up alpha channel for non-transparency */
407
/* png_set_invert_alpha(png_ptr); */
409
/* okay, let's get the full header now */
410
png_read_info(png_ptr, info_ptr);
412
png_get_IHDR(png_ptr, info_ptr, NULL, NULL, &bit_depth, &color_type, &interlace_type, NULL, NULL);
414
/* general format conversions */
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);
424
/* reduce from 16 bits/channel to 8 bits */
425
/* correct use of little endian */
426
/*if (bit_depth == 16) {*/
428
png_set_swap(png_ptr); // swap byte pairs to little endian
430
png_set_strip_16(png_ptr);
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);
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);
442
/* activate libpng interlace handling */
443
interlace_passes = png_set_interlace_handling(png_ptr);
445
/* okay, final info set up */
446
png_read_update_info(png_ptr, info_ptr);
448
gfx->Width = png_get_image_width(png_ptr, info_ptr);
449
gfx->Height = png_get_image_height(png_ptr, info_ptr);
451
gfx->Data = (int*)malloc(gfx->Width*gfx->Height*sizeof(int));
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);
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);
463
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
469
int Write_PNG (FILE *ofile, struct GFX_DATA *gfx)
471
png_voidp user_error_ptr = NULL;
478
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, user_error_ptr, NULL, NULL);
480
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED\n");
481
fprintf(stderr, "cannot create png write struct!\n");
484
info_ptr = png_create_info_struct(png_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");
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");
500
/* setting up file pointer */
501
png_init_io(png_ptr, ofile);
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);
506
png_set_invert_alpha(png_ptr);
508
/* let's flush the header down */
509
png_write_info(png_ptr, info_ptr);
513
png_set_swap(png_ptr); // swap bytes to big endian, for little endian machines and only useful when writing 16 bits/channel;
517
for(z = 0; z < gfx->Height; z++)
518
png_write_row(png_ptr, (void *) (gfx->Data + z*gfx->Width));
520
png_write_end(png_ptr, NULL);
522
png_destroy_write_struct(&png_ptr, &info_ptr);
528
int Read_TARGA (FILE *ifile, unsigned char *check_header, struct GFX_DATA *gfx)
530
/* TARGA uses the Intel format for integer coding (low byte first) */
532
unsigned char header[20];
533
int x, y, *palette, c, l, s, z;
535
/* copy the preread check header to the real header */
536
memcpy(header, check_header, sizeof(char)*8);
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");
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));
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]);
558
/* reading image identification field */
559
for(x = 0; x < header[0]; x++)
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);
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++) {
575
for(x = gfx->Width - 1; x >= 0; x--)
576
Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
578
for(x = 0; x < gfx->Width; x++)
579
Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
582
for(y = gfx->Height - 1; y >= 0; y--) {
584
for(x = gfx->Width - 1; x >= 0; x--)
585
Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
587
for(x = 0; x < gfx->Width; x++)
588
Read_TARGA_RGB(ifile, (int)header[16], palette, gfx->Data + (y * gfx->Width) + x);
591
/*if(verbose) printf("gfx data read (%i*%i);\n", gfx->Width, gfx->Height);*/
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++) {
602
y = (z - x) / gfx->Width;
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;
610
fprintf(stderr, "(%i, %i) => error\n", x, y);
613
} else { /* uncompressed data follows */
614
for(s = 0; (s <= l); s++) {
616
y = (z - x) / gfx->Width;
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);
624
fprintf(stderr, "(%i, %i) => error\n", x, y);
629
/*if(verbose) printf("gfx data read (%i*%i);\n", gfx->Width, gfx->Height);*/
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]);
641
int Read_TARGA_RGB(FILE *ifile, int bits, int *palette, int *c) {
642
static int a, r, g, b, z1, z2;
646
(*c) = palette[(int)getc(ifile)];
648
(*c) = (int)getc(ifile) * 65793; /* 65793 = (1+256+65536) */
649
} else if(bits == 16) {
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);
661
(*c) = r + (g * 256) + (b * 65536);
665
return a; /* attribute (alpha/transparency information, 32 bit only) */
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)
673
fprintf(ofile, "P6\n");
674
fprintf(ofile, "%i %i\n", gfx->Width, gfx->Height);
675
fprintf(ofile, "255\n");
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);
686
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
687
fprintf(stderr, "cannot write to file! (disk full?)\n");
692
int Write_TARGA (FILE *ofile, struct GFX_DATA *gfx)
695
/* standard TARGA header consists of 18 bytes */
697
putc(strlen("created by stereograph"), ofile);
698
/* color pallette, yes/no */
700
/* TARGA type 2: RGB 24 bit, no pallette */
702
/* 5 following bytes contain only pallette information */
714
/* width, low byte first */
715
putc(gfx->Width & 255, ofile);
716
putc((gfx->Width / 256) & 255, ofile);
718
putc(gfx->Height & 255, ofile);
719
putc((gfx->Height / 256) & 255, ofile);
722
/* Image Descriptor Flags */
724
fwrite("created by stereograph", sizeof(char), strlen("created by stereograph"), ofile);
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);
736
if(verbose) printf("FAILED;\n"); else fprintf(stderr, "writing gfx data...FAILED;\n");
737
fprintf(stderr, "cannot write to file! (disk full?)\n");
743
int fdata_to_GFX(float *datafield[3], struct GFX_DATA *gfx) {
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;
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;
770
float c_sin(int a, float b) {
771
static float *sincache = NULL;
772
static float cb = 0.0, maxb = 0.0;
782
sincache = (float*)realloc(sincache, (int)b * sizeof(float));
785
for(cb = 0.0; cb < b; cb += 1.0)
786
sincache[(int)cb] = sin(PI * (1.5 + (cb / b)));
795
void Sinline_Fill_H(float *dataline, int x1, int x2, int width) {
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));
806
void Sinline_Fill_H_flat(float *dataline, int x1, int x2, int width) {
810
a = 0.5 * (dataline[x1] - dataline[x2 % width]);
811
for(z = x1 + 1; z < x2; z++)
812
dataline[z % width] = dataline[x1] - a;
816
void Sinline_Fill_datafield_H(float* datafield, int width, int height) {
818
int lines, line_offset;
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));
833
Sinline_Fill_H(datafield + (y * width), x - (width/lines), x, width);
836
for(y = 0; y < height; y++)
837
Sinline_Fill_H(datafield + (y * width), line_offset + ((width / lines) * (lines - 1)), line_offset + width, width);
841
void Sinline_Fill_V(float *dataline, int y1, int y2, int height, int width) {
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));
852
void Sinline_Fill_V_flat(float *dataline, int y1, int y2, int height, int width) {
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;
862
void Sinline_Fill_datafield_V(float* datafield, int width, int height) {
864
int lines, line_offset;
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));
877
Sinline_Fill_V(datafield + x, y - (height/lines), y, height, width);
880
for(x = 0; x < width; x++)
881
Sinline_Fill_V(datafield + x, line_offset + ((height / lines) * (lines - 1)), line_offset + height, height, width);
885
void Sinline_merge_datafields_add(float *datafield, float *datafield1, float *datafield2, int c) {
887
for(z = 0; z < c; z++)
888
datafield[z] = 0.5 * (datafield1[z] + datafield2[z]);
892
void Sinline_merge_datafields_mul(float *datafield, float *datafield1, float *datafield2, int c) {
894
for(z = 0; z < c; z++)
895
datafield[z] = sqrt(datafield1[z] * datafield2[z]);
899
int Generate_Sinline_Texture(struct GFX_DATA *gfx)
902
float *a, *datafield[5];
904
for(z = 0; (z < 5) && (a || !z); z++)
905
a = datafield[z] = (float*) malloc(gfx->Width * gfx->Height * sizeof(float));
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);
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);
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);
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);
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);
946
Sinline_Fill_datafield_V(datafield[4], gfx->Width, gfx->Height);
949
fdata_to_GFX(datafield, gfx);
950
for(z = 0; z < 5; z++)
953
for(z = 0; (z < 5) && datafield[z]; z++)
957
if (verbose) printf("FAILED\n");
958
fprintf(stderr, "could not allocate memory;\n");