OK, I'm a little boggled here. Lee Skinner sent me the following bug report: "But I have run into some problems. Starting with the par file 640test.par, I ran 2 tests at 640x480, passes=g1. These generated the 2 images testb1.gif and testm1.gif, which have slightly but quite noticeable wrong center-mag co-ordinates. I also generated the same 2 pars in DOS Fractint (images DOSTSTB1.GIF and DOSTSTM1.GIF) which are generated with the correct co-ordinates. Then I generated the file New.par in Fractint for Windows by using the <b> command for all 4 images. Note the new center-mag co-ordinated for the DOS images which include #INF and #IO. Finally I generated the file NEWDOS.par in DOS Fractint by using the <b> command for all 4 images. Note the new center-mag co-ordinated for the Windows images which include #QNAN and #IND. Also DOS isn't able to access the calculation time for the Windows generated images." Now this has all the hallmarks of one program interpreting ints as 16-bits and another program interpreting ints as 32-bits. However, everything in the structure is defined in terms of datatypes that would seem to have the same size on 16-bit and 32-bit compilers: struct fractal_info /* for saving data in GIF file */ { char info_id[8]; /* Unique identifier for info block */ short iterationsold; /* Pre version 18.24 */ short fractal_type; /* 0=Mandelbrot 1=Julia 2= ... */ double xmin; double xmax; double ymin; double ymax; double creal; double cimag; short videomodeax; short videomodebx; short videomodecx; short videomodedx; short dotmode; short xdots; short ydots; short colors; short version; /* used to be 'future[0]' */ float parm3; float parm4; float potential[3]; short rseed; short rflag; short biomorph; short inside; short logmapold; float invert[3]; short decomp[2]; short symmetry; /* version 2 stuff */ short init3d[16]; short previewfactor; short xtrans; short ytrans; short red_crop_left; short red_crop_right; short blue_crop_left; short blue_crop_right; short red_bright; short blue_bright; short xadjust; short eyeseparation; short glassestype; /* version 3 stuff, release 13 */ short outside; /* version 4 stuff, release 14 */ double x3rd; /* 3rd corner */ double y3rd; char stdcalcmode; /* 1/2/g/b */ char useinitorbit; /* init Mandelbrot orbit flag */ short calc_status; /* resumable, finished, etc */ long tot_extend_len; /* total length of extension blocks in .gif file */ short distestold; short floatflag; short bailoutold; long calctime; BYTE trigndx[4]; /* which trig functions selected */ short finattract; double initorbit[2]; /* init Mandelbrot orbit values */ short periodicity; /* periodicity checking */ /* version 5 stuff, release 15 */ short pot16bit; /* save 16 bit continuous potential info */ float faspectratio; /* finalaspectratio, y/x */ short system; /* 0 for dos, 1 for windows */ short release; /* release number, with 2 decimals implied */ short flag3d; /* stored only for now, for future use */ short transparent[2]; short ambient; short haze; short randomize; /* version 6 stuff, release 15.x */ short rotate_lo; short rotate_hi; short distestwidth; /* version 7 stuff, release 16 */ double dparm3; double dparm4; /* version 8 stuff, release 17 */ short fillcolor; /* version 9 stuff, release 18 */ double mxmaxfp; double mxminfp; double mymaxfp; double myminfp; short zdots; float originfp; float depthfp; float heightfp; float widthfp; float distfp; float eyesfp; short orbittype; short juli3Dmode; short maxfn; short inversejulia; double dparm5; double dparm6; double dparm7; double dparm8; double dparm9; double dparm10; /* version 10 stuff, release 19 */ long bailout; short bailoutest; long iterations; short bf_math; short bflength; short yadjust; /* yikes! we left this out ages ago! */ short old_demm_colors; long logmap; long distest; double dinvert[3]; short logcalc; short stoppass; short quick_calc; double closeprox; short nobof; long orbit_interval; short orbit_delay; double math_tol[2]; short future[7]; /* for stuff we haven't thought of yet */ }; So this is really confusing me. I can see when the header is read in find_fractal_info, that its already wrong: + info_id 0x0012fa5c "Fractal" iterationsold 1800 fractal_type 73 OK to here, but then... xmin -1.2154154409869020e+098 xmax 1.3410738056630158e-018 ymin 1.3376211045644711e-123 ymax -2.2249705443687879e-256 creal 5.302851936981e-315#DEN cimag 0.00000000000000000 Those look wrong. videomodeax 0 videomodebx 0 videomodecx 27 videomodedx 640 dotmode 480 xdots 256 ydots 17 ... These are definitely wrong... I think the ax,bx,cx,dx should all be zero, dotmode should be 27 and xdots/ydots 640/480. Any ideas? -- "The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download <http://www.xmission.com/~legalize/book/download/index.html> Legalize Adulthood! <http://blogs.xmission.com/legalize/>
Alright, I think I figured this out... its the structure alignment used by the compiler. In article <E1HEIcX-0000EF-00@xmission.xmission.com>, Richard <legalize@xmission.com> writes:
struct fractal_info /* for saving data in GIF file */ {
offset 0
char info_id[8]; /* Unique identifier for info block */
offset 8
short iterationsold; /* Pre version 18.24 */
offset 10
short fractal_type; /* 0=Mandelbrot 1=Julia 2= ... */
offset 12
double xmin;
VS.NET doesn't like to put a double at an address that's not a multiple of 16, so it inserted 4 pad bytes so that xmin began at offset 16 from the beginning of the structure. That misaligned the structure with the file data and all the bytes were shifted as a result. I will fix this with a #pragma packing directive for _WIN32... -- "The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download <http://www.xmission.com/~legalize/book/download/index.html> Legalize Adulthood! <http://blogs.xmission.com/legalize/>
In article <E1HEIs0-0001dO-00@xmission.xmission.com>, Richard <legalize@xmission.com> writes:
I will fix this with a #pragma packing directive for _WIN32...
This will probably also break on other architectures like MIPS where a mis-aligned double isn't just a minor performance penalty it throws an exception. The more portable way to handle it would be to let the compiler do whatever padding in the structure it thinks is good in order to satisfy the alignment constraints of the processor and then do fread() on the individual members one at a time from the file instead of doing fread() on the entire structure, but we can worry about that later. I'll add a TODO: comment in the code there so we don't have to rediscover this again later the hard way. -- "The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download <http://www.xmission.com/~legalize/book/download/index.html> Legalize Adulthood! <http://blogs.xmission.com/legalize/>
Rich,
The more portable way to handle it would be to let the compiler do whatever padding in the structure it thinks is good in order to satisfy the alignment constraints of the processor and then do fread() on the individual members one at a time from the file instead of doing fread() on the entire structure, but we can worry about that later. I'll add a TODO: comment in the code there so we don't have to rediscover this again later the hard way.
Take a look at the decode_fractal_info() routine in the general.c file used by xfractint. Jonathan
In article <1170769280.3895.2.camel@linux.site>, Jonathan Osuch <osuchj@avalon.net> writes:
Take a look at the decode_fractal_info() routine in the general.c file used by xfractint.
Yeah, I saw that and meant to look at it but I didn't yet. I looked at it just now and it seems to go through great contortions to read floats and doubles -- but aren't they just IEEE floats and doubles? On any architecture that supports IEEE you can just use fread, or am I missing something? This binary IO business might be an argument for making the fractal info in PNG just a par/XML text string. -- "The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download <http://www.xmission.com/~legalize/book/download/index.html> Legalize Adulthood! <http://blogs.xmission.com/legalize/>
participants (2)
-
Jonathan Osuch -
Richard