Creating GIF files for web application within FORTRAN CGIs
Below is a form starting a little CGI script that creates a GIF plot of atomic scattering factors for a selected element and a given temperature factor B. Try the application and you will get back a nice plot instead of the crude line graphs or lists I had in my first generation CGI's. So how is this done?
Why in FORTRAN ?
As scientists, we may have a useful program in FORTRAN that does a nice job and it would be desirable to make the program available on the web. The obvious benefit is that you do not have to deal with platform and implementation issues - no invalidated version proliferation, no source code mess etc - the application runs on your host computer, and the browsers take care of the platform specific implementation. All of a sudden your old F66 code has a graphical windows interface and returns great looking graphs! Just imagine how you can now create really interactive web based tutorials or applications!
The problem at hand can be split up into two essentially independent parts : First, how to get the information from the web server (which is the program that receives the web form with the requested action) into the CGI (Common Gateway Interface) program that actually executes the computation, creates the GIF and then sends the information back in the format of a valid web page to the server for display at the client's browser. The first part I describe in my CGI tutorial. If what I say here does not make sense to you, please go back go back and review basic CGI programming in FORTRAN.
The second task is to create a GIF file [gname] within the FORTRAN code, and then to display the file within the html document with a simple HTML command :
c --- pop the image to stdout WEBS0221 write(*,*)'<p><img src="'//gname//'" width="600" height="450">' WEBS0222
The new art now is to write a GIF in FORTRAN. GIF (Graphics Interchange Format) is the most commonly used compressed file format in web exchange. The GIF specification incorporates the Lempel-Zev-Welch (LZW) compression technology which is the subject of a patent awarded to Unisys. Use of this technology, and in particular creation of GIF format files, may require a license from Unisys .No license or license fees are required for non-commercial, not-for-profit GIF-based applications or for non-commercial, not-for-profit GIF-freeware, so long as the LZW capability provided is only for GIF. However, a license is required if freeware is incorporated into, or sold or distributed with a commercial or for-profit product, introduced in 1995 [or later], or enhancements of products that were introduced prior to 1995.
The PGPLOT library
Writing a compressed binary file and coding all the graphing routines would be indeed painful. Fortunately, there is quite an excellent graphics library for FORTRAN (and C). PGPLOT is not public-domain software. However, it is freely available for non-commercial use. The source code and documentation are copyrighted by the California Institute of Technology, and may not be redistributed or placed on public Web servers without permission. The installation (which I tested on NT for the DEC FORTRAN 90 compiler V5.0b) is very straightforward if you *exactly* (red, bold, asterixed) follow the provided instructions. PGPLOT can be downloaded from http://astro.caltech.edu/~tjp/pgplot/ .For the DEC NT compiler, and to obtain the necessarily 'quiet' CGI application, comparable as a Win32 console (NOT Quickwin!) application, you MUST add a few marginally modified subroutines to your project, which are available from my site. Including these subroutines explicitly in your project files overrides the PGPLOT library call resolution.
Here are the details on how to proceed for NT :
If things don't work :
Console code example
program console CONS0001 c-----------------------------------------------------------------------CONS0002 c demonstration program for quiet PGPLOT Win32 console application : CONS0003 c quietly writes a gif file in background as needed for web CGIs CONS0004 c web-tutorial example by B.RUPP Macromolecular Crystallography CONS0005 c LLNL-BBRP CONS0006 c-----------------------------------------------------------------------CONS0007 c --- needs following modified routines (add them to each console CONS0008 c project - no need to change or recompile the PGPLOT library): CONS0009 c CONS0010 c gidriv_c.f (_c means 'CONSOLE' in my lingo) CONS0011 c grdos_c.f CONS0012 c grexec_c.f CONS0013 c CONS0014 c and in case they create trouble (i.e., unwanted but in- CONS0015 c consequential warning messages), comment out the write CONS0016 c statements in : CONS0017 c CONS0018 c grmsg.f CONS0019 c grwarn.f CONS0020 c CONS0021 c I normally would leave them in - in case you have a problem CONS0022 c and need diagnostics CONS0023 c CONS0024 c --- that's all folks -- CONS0025 CONS0026 character fname*6,fext*4 CONS0027 c --- PGOPEN is an integer function of PGPLOT library CONS0028 integer PGOPEN CONS0029 CONS0030 c --- create a random file name in case 2 users concurrently use the CONS0031 c same cgi - not elegant but p=1/625 does it for me here CONS0032 fext='.gif' CONS0033 call random_name (fname,fext,2,25) CONS0034 CONS0035 c --- call PGOPEN to initiate PGPLOT and open the output device CONS0036 c with the filename as parameter and check the return code CONS0037 c from PGOPEN. CONS0038 CONS0039 if (PGOPEN(fname//'/GIF') .le. 0) stop CONS0040 CONS0041 c --- we want black linegraphs on white background CONS0042 call PGSCR(0, 1., 1., 1.) !black becomes white CONS0043 call PGSCR(1, 0., 0., 0.) !white becomes black CONS0044 CONS0045 c --- call the first PGPLOT demonstration subroutine CONS0046 call PGEX1 CONS0047 c --- no argument needed, all graphics definitions etc in CONS0048 c include files of PGPLOT library CONS0049 CONS0050 c --- clean up things and close files/device properly CONS0051 call pgclos CONS0052 c --- now you should have a gif file xy.GIF in your active directory CONS0053 end CONS0054 CONS0055 subroutine random_name (fname,fext,in,num) RAND0001 RAND0002 character fname*(*),fext*4 RAND0003 integer iran(in) RAND0004 real rand(in) RAND0005 RAND0006 call random_seed () RAND0007 call random_number (rand) RAND0008 RAND0009 do i=1,in RAND0010 iran(i)=int(rand(i)*num) RAND0011 fname(i:i)=char(iran(i)+65) RAND0012 end do RAND0013 RAND0014 fname=fname(1:in)//fext RAND0015 return RAND0016 end RAND0017
 I once received a patent for an algorithm describing the form function, including its FFT, of the common English water toilet. Sitting on the crapper may henceforth require a license. I hope we have properly covered all legal aspects.
Back to Introduction
This World Wide Web site conceived and maintained by Bernhard Rupp
Last revised January 17, 2010 14:04