InputStream vs void pointer

Hi All,
In my C program I have one void pointer. I want to send this void pointer to my Java program as InputStream. Is it possible?
Thanks,
javadevlson

In my C program I have one void pointer. I want to send this void pointer to my
Java program as InputStream. Is it possible?Sure it is. You need a bit of JNI stuff to pass that void* back to Java as a byte[];
given that array just use a ByteArrayInputStream.
kind regards,
Jos

Similar Messages

  • Import CVI Instrument driver with void pointer

    Hi,
    I would like to use a CVI instrument driver that contains void pointers as parameters in LabVIEW. There are additional parameters which declare the kind of data where the void pointer points to.
    If I try to import this driver to LabVIEW I get warnings that the void pointer paarameters are converted to I32 since LabVIEW do not have the void pointer.
    Does anybody know if it is possible to import a CVI function with void pointers that will work properly in LabVIEW? How do I have to handle this converted void pointer?
    Thnaks,
    erik.

    Erik,
    you may have a look at this discussion forum thread.
    Best regards,
    Jochen Klier
    National Instruments Germany

  • How do I pass a void *pointer to a dll in LabView

    I did read previous posts on the matter and tried just about everything, inlcuding defining the pointer as a U32 int.
    What I am trying to do is program FLASH using WindRiver VisionPROBE EST...
    I do have some sucesses... )
    I can open a connection to the EST, initialize it, start & stop the target. No problem here..
    Here are some additional details:
    I can't read memory, write to the target register or program the FLASH, yet. Any advice on how to get further with this? Typically, when doing this using WR's visionClick sw, we need to use a register file which sets up the target. I have not seen any reference to this in their API.
    I can convert to CVI if necessary. I am using the dll's from WindRi
    ver. I'd prefer keeping everything in LV, but LW-CVI is fine.
    My problem is that I am not sure if I am passing void pointers back & forth correctly. For instance, I need to call a function which returns a status, as follows:
    status = EST_WriteTargetRegister (long handle, Unsign int register, void * value)
    How do I pass the "void * value" to the input of a Call Library FUnction Node. I did try "Adapt to type" which does give a "void * value", and I tried both "Handles by Value" & "Pointers to Handles".
    When I change the input value to anything other than "Adpapt To Type", I get a violation error. >(
    Has anyone successfully automated WindRiver's EST?
    - Thanks -
    JLV"

    Hi,
    Have you tried passing a I32, but selecting "Pointer To Value"?
    Is there any description about the "void *pointer"? Could it be a callback
    function?
    Regards,
    Wiebe.
    "JoeLabView" wrote in message
    news:[email protected]..
    > I did read previous posts on the matter and tried just about
    > everything, inlcuding defining the pointer as a U32 int.
    >
    > What I am trying to do is program FLASH using WindRiver VisionPROBE
    > EST...
    >
    > I do have some sucesses... )
    > I can open a connection to the EST, initialize it, start & stop the
    > target. No problem here..
    >
    > Here are some additional details:
    >
    >
    >
    >
    > I can't read memory, write to the target register or program the
    > FLASH, yet. Any advice on how to get f
    urther with this? Typically,
    > when doing this using WR's visionClick sw, we need to use a register
    > file which sets up the target. I have not seen any reference to this
    > in their API.
    >
    > I can convert to CVI if necessary. I am using the dll's from
    > WindRiver. I'd prefer keeping everything in LV, but LW-CVI is fine.
    >
    > My problem is that I am not sure if I am passing void pointers back &
    > forth correctly. For instance, I need to call a function which
    > returns a status, as follows:
    >
    >
    > status = EST_WriteTargetRegister (long handle, Unsign int register,
    > void * value)
    >
    >
    > How do I pass the "void * value" to the input of a Call Library
    > FUnction Node. I did try "Adapt to type" which does give a "void *
    > value", and I tried both "Handles by Value" & "Pointers to Handles".
    >
    > When I change the input value to anything other than "Adpapt To Type",
    > I get a violation error. >(
    >
    > Has anyone successfully automated WindRiver's EST?
    >
    > - Thanks -
    >
    > JLV"

  • Calling C function that has Void* pointer

    Hi
    I am trying to use some c functions in java using the JNI. This C function has 3 inputs, 2 integers and a void* pointer. I can import the 2 integers from java but dont know how to deal with the void* pointer.
    I would be greatful if someone could help me with this problem.
    Thanks
    Derek

    Hi,
    i guess the void * points to some C thingy. If you got
    the void * from C (via JNI), treat it as a long and cast it back in JNI
    as andyba suggested. If it is more than this (e.g. a C++ object)
    there is no general solution, but there are numerous special ones.
    If you tell a little more concrete what your void * points to,
    there might be more concrete suggestions.
    To get an idea, study e.g. swig's java module. But be warned,
    this is no simple topic.
    http://swig.sourceforge.net
    Have fun,
    Klaus

  • JNI equivalent of a void * pointer

    Hi I am writing a java wrapper for a method which returns a void * pointer. This void * pointer is then taken as input to all the other native methods I call subsequently. How should i be casting this void * pointer in Java , should it be an Object[]. Will the pointer get mangled or something while doing this cast ?

    Cast it to a long.
    Pass it to the other methods as a long and cast it back to a void*.
    Since this is probably a allocated resource you should do the following
    1. Provide a cleanup method. Call it Destroy or Close. It calls the appropriate JNI method that cleans it by calling another C/C++ method.
    2. Create a finalizer which calls the cleanup method if the value has not yet been cleaned.

  • Pointer to void != pointer to function

    Hello C experts,
    this is a simple question about SunStudio's understanding of function pointers (it might have been asked before):
    Why is the following C code giving me a warning on all Sun compilers:
    # cat funcptr.c
    int main() {
        void (*func)() = (void*)0;
        return 0;
    # cc -c funcptr.c
    "funcptr.c", line 2: warning: assignment type mismatch:
         pointer to function() returning void "=" pointer to voidIs the warning emitted by Sun compiler a bug (over-cautions). Other compiler's don't warn here.
    Of course, I could use 0 or NULL as rvalue but I'm just wondering...
    Jochen

    Thanks everybody for your opinions.
    @Stephen:
    I wasn't aware that data pointers and function pointers may differ in any aspect. In fact, I only know data models that talk about 'pointer' width in general, like LP64 (64-bit wide long- and pointertypes), ILP32 (32-bit wide int-, long- and pointer-types), .. I'm especially surprised to hear that casting between data/function pointers will result in undefined behavior.
    Anyway, to properly 'fix' the code above, I must cast the zero to a function pointer (with matching signature) instead of a void pointer. This compiles w/o a warning:
        void (*func)() = (void (*)())0;Thanks for clarification.
    Jochen

  • Malloc() function in C -- returns void or character pointer?

    I've been learning about the free store and heap memory and what not, and I've got two books telling me two different things. One is telling me that the malloc() function returns a void pointer (note: this book has been wrong before) and the other is telling me that it always returns a character pointer. Which is correct? Thanks!

    Tron55555 wrote:
    when you say "if it's declared as returning a char pointer", are you referring to a theoretical scenario with a different compiler that has declared malloc as returning a char pointer instead of a void pointer? Do I have your meaning right?
    Yes. I think void* is standard, but I recall seeing it declared otherwise. The runtime library is written by programmers and a little time spent in this forum should convince you that programmers don't always agree on what's correct.
    This seems to be the case with Xcode, right?
    Yes. That's why I referred you to the manual page from the Darwin layer. The manual installed there should reflect the current version of gcc, which is the C compiler under Xcode. From the occasional unfortunate experience, we also know that "should" doesn't always equate to "is". But just use that manual and you'll do fine.
    Until I read about this in my other book, I never used casts with the malloc function and it always worked fine. Do you think it would be good programming practice for me to get used to writing the function with a cast in case I ever come across a compiler that requires it? I mean it couldn't hurt to write it that way right, even if I am using a compiler that declares malloc as returning a void pointer and doesn't require a cast?
    This is more a question of programming style. Type casts turn off the compiler's type checking. So in most cases, type casts are to be avoided. In the case of malloc, everyone knows the game, so an optional type cast depends on what you consider good style. The goal of all the style rules, from indenting to commenting, is to make it easy for someone else to read your code and understand it well enough to make a required change. So we ask ourselves, "What would I like to see 10 years from now when I won't even believe I wrote this stupid code?".
    \- Ray
    p.s.: Et's excellent point about byte alignment is a wonderful example of how a type cast can get you on the fast track to trouble. Casting a pointer returned from malloc is fine. But casting a pointer after it's been used could cause a problem. Byte alignment in this case means that an int can't start on an odd numbered memory location (I think it might need to be an address divisible by 4 on a 32-bit machine, but that's an Et question--especially as he's responsible for adding the subject of byte alignment to your thread). - R

  • Creating Type void

    cpsSend( const void* Message, Const int
    BCount)
    I have created the VI for the above function. I am having problem finding the right pallate that will make "Const Void* Message" when i am in the
    -Build Application or shared library
    - Define VI Prototype(function Prototype)
    I have tried to use the variant function in my VI but i am not getting "const void". Also is there a way to have a parameter of type int instead of a long, short or etc. I change the properties to the controls/indicators to u32, I32 and etc. If you can direct me to a tutorial or the instruction on how to implement this i would really appreciate. Thanks for your time.

    The const keyword is only a hint to a C compiler that the function is not modifying the buffer past in in any way. This allows a C compiler to do some optimizations in certain circumstances when calling such a function and when compiling the function any well behaved compiler should complain if you modify this pointer inside the function or pass it to a function which is not itself declared to treat this pointer as const. For LabVIEWs Call Library Node you can fully ignore this keyword.
    The void* pointer is a C syntax for a pointer which can potentially point to any datatype. In LabVIEW you will have to find out what the datatype is, this pointer should point at. It could be a byte, short, integer, long, or floating point value or an array of them or maybe also a string and configure the Call Library Node accordingly. LabVIEW is a strict datatype language and does not really allow for ambigues datatypes such as void* do present. This is no problem as the function in question will expect some specific datatype anyhow, possibly depending on a second parameter which defines what datatype the void* parameter should be treated as in this case.
    Rolf Kalbermatter
    Rolf Kalbermatter
    CIT Engineering Netherlands
    a division of Test & Measurement Solutions

  • [SOLVED]C pointer question

    I'm having a terrible time tracking down what exactly the issue is here in my code.  To me, at first it seemed like a simple missed assignment, but after tinkering in gdb I realize there is something deeper going on here that I don't understand. 
    Here is the local function in which the problem occurs.
    static void
    CountryStorageinsert(void *self, void *data){
    if (self = 0)
    return;
    CountryStorage *rs = (CountryStorage *) self;
    Record *r = (Record *) data;
    rs->countries[r->id] = r;
    if (r->id > rs->maxid)
    rs->maxid = r->id;
    rs->nrecords++;
    The issue is that no matter what the value the void *self is passed in with, the assignment to *rs is ALWAYS zero.  Additionally in my project there are three such functions, CountryStorageinit, CountryStorageinsert, CountryStoragebackup which all have similar constructs all have the same problem.  I can not seem to pass in a void pointer and cast it to a compound structure pointer.
    What is even more puzzling is I can manually, in gdb, get the behaviour I originally expected this code to have.  That is I can "(gdb) set rs = (CountryStorage *) self" and then examine rs, and vioala it has the address that self contained in the function parameters.
    I would really appreciate it if someone could tell me if my thoughts on how pointer coercion works are wrong.
    Thanks.
    Last edited by ickabob (2011-10-23 17:55:11)

    Classic C mistake;
    if (self = 0)
    as opposed to
    if (self == 0)

  • Error 1030723 Unable to get UTF-8 locale when using Essbase API 11.1.1

    Now I got a question about how to connect to an Essbase Server by using essbase client API (11.1.1). I encountered an error “Unable to get UTF-8 locale” when I tried to EssInit((pInitStruct, phInstance) API.
    However, I had no problem to call the API if I uses essbase previous client APIs (7.1 or 9.3).
    I passed the “ESS_API_UTF8” to usApiType field in the ESS_INIT_T struct. When I openned the “essapi.h” header file, I found these are some new fields (highlighted in red color below) added in the essbase client API (11.1.1)
    ESS_TSA_API_typedef_struct(ess_init_t)
    ESS_TSA_ELEMENT(ESS_ULONG_T, Version); /* This should be set to ESS_API_VERSION */
    ESS_TSA_ELEMENT(ESS_PVOID_T, UserContext); /* void pointer to user's message context */
    ESS_TSA_ELEMENT(ESS_USHORT_T, MaxHandles); /* max number of context handles required */
    ESS_TSA_ELEMENT(ESS_SIZE_T, MaxBuffer); /* max size of buffer that can be allocated */
    ESS_TSA_ELEMENT(ESS_STR_T, LocalPath); /* local path to use for file operations */
    ESS_TSA_ELEMENT(ESS_STR_T, MessageFile); /* full path name of message database file */
    ESS_TSA_ELEMENT(ESS_PFUNC_T, AllocFunc); /* user-defined memory allocation function */
    ESS_TSA_ELEMENT(ESS_PFUNC_T, ReallocFunc); /* user-defined memory reallocation function */
    ESS_TSA_ELEMENT(ESS_PFUNC_T, FreeFunc); /* user-defined memory free function */
    ESS_TSA_ELEMENT(ESS_PFUNC_T, MessageFunc); /* user-defined message callback function */
    ESS_TSA_ELEMENT(ESS_STR_T, HelpFile); /* user-defined help file path */
    ESS_TSA_ELEMENT(ESS_PVOID_T, Ess_System); /* reserved for internal use */
    ESS_TSA_ELEMENT(ESS_USHORT_T, usApiType);
    ESS_TSA_ELEMENT(ESS_PCATCHFUNC_T, CatchFunc); /* user-defined kill-own-request signal callback function */
    ESS_TSA_ELEMENT(ESS_PCATCH_INIT_FUNC_T, CatchInitFunc); /* user-defined kill-own-request signal initialization callback function */
    ESS_TSA_ELEMENT(ESS_PCATCH_TERM_FUNC_T, CatchTermFunc); /* user-defined kill-own-request signal termination callback function */
    ESS_TSA_ELEMENT(ESS_PCOOKIE_CREATE_FUNC_T, CookieCreateFunc); /* user-defined cookie creation function */
    ESS_TSA_ELEMENT(ESS_PCOOKIE_DELETE_FUNC_T, CookieDeleteFunc); /* user-defined cookie creation function */
    } ESS_TSA_END(ESS_INIT_T);
    I could not find any document to introduce the API (11.1.1. And what does the error “Unable to get UTF-8 locale” mean? How can work around it. Any environment parameters or paths need to be set?
    Please advise.

    Hi,
    The API documentation for V11 is available from :- http://download.oracle.com/docs/cd/E12825_01/epm.111/esb_apiref/frameset.htm?launch.htm
    Hopefully it might point you in the right direction.
    Cheers
    John
    http://john-goodwin.blogspot.com/

  • Bus error - Help!

    Hi,
    I've been asked to see if I can fix a C program so that it will run on a mac. It currently compiles and runs perfectly on a linux machine, but as soon as you run it on a mac, it will compile, but quit with a bus error very early on. The full code is here:
    // Program for the construction of cartograms (density-equalizing map
    // projections) using the Gastner-Newman technique. The program needs polygon
    // coordinates and a count of cases in each region as input, calculates the new
    // coordinates, and writes these to a file. Postscript images of the original
    // map and the cartogram are created.
    // WRITTEN BY MICHAEL GASTNER, September 20, 2004.
    // If you use output created by this program please acknowledge the use of this
    // code and its first publication in:
    // "Generating population density-equalizing maps", Michael T. Gastner and
    // M. E. J. Newman, Proceedings of the National Academy of Sciences of the
    // United States of America, vol. 101, pp. 7499-7504, 2004.
    // The input coordinates in MAPGENFILE must be in ArcInfo "generate" format of
    // the type:
    // 1
    // 0.3248690E+06 0.8558454E+06
    // 0.3248376E+06 0.8557575E+06
    // 0.3248171E+06 0.8556783E+06
    // 0.3247582E+06 0.8556348E+06
    // 0.3246944E+06 0.8555792E+06
    // 0.3246167E+06 0.8555253E+06
    // 0.3250221E+06 0.8557324E+06
    // 0.3249436E+06 0.8557322E+06
    // 0.3248690E+06 0.8558454E+06
    // END
    // 1
    // 0.3248690E+06 0.8558454E+06
    // 0.3249651E+06 0.8558901E+06
    // 0.3250519E+06 0.8559769E+06
    // 0.3250691E+06 0.8561246E+06
    // 0.3249678E+06 0.8560541E+06
    // 0.3249003E+06 0.8560088E+06
    // 0.3076424E+06 0.8477603E+06
    // 0.3075691E+06 0.8477461E+06
    // 0.3075595E+06 0.8476719E+06
    // END
    // 2
    // 0.6233591E+06 0.6056502E+06
    // 0.6235193E+06 0.6056467E+06
    // 0.6235054E+06 0.6055372E+06
    // 0.7384296E+06 0.2334260E+06
    // 0.7383532E+06 0.2345770E+06
    // END
    // END
    // The number of cases in CENSUSFILE must be given in the form
    // region #cases (optional comment), e. g:
    // 43 0.9 Alabama
    // 51 0.3 Alaska
    // 37 0.8 Arizona
    // 47 0.6 Arkansas
    // 25 5.4 California
    // 32 0.8 Colorado
    // 19 0.8 Connecticut
    // 29 0.3 Delaware
    // 28 0.3 District of Columbia
    // 49 2.5 Florida
    // 45 1.3 Georgia
    // 1 0.4 Hawaii
    // The output coordinates are written to CARTGENFILE in ArcInfo "generate"
    // format. A postscript image of the original input is prepared as MAP2PS,
    // an image of the cartogram as CART2PS.
    // Modified on Oct 29, 2004. The number of divisions in each dimension lx, ly
    // will now be determined from the input map. Also fixed array bound
    // violations in intpol and newt2, and centered the ps-files.
    // Modified on Dec 3, 2004. Introduced pointers bbmaxx,bbmaxy,bbminx,bbminy -
    // the bounding box coordinates for each polygon - to reduce calculations in
    // crnmbr. Thanks to Chris Brunsdon for the suggestion.
    // Program now terminates with error message if there is no density specified
    // in CENSUSFILE for a region on the map.
    // "Donut" polygons are now handled properly. Polygons oriented clockwise will
    // be considered exterior boundaries. If they are oriented anti-clockwise they
    // are holes inside an enclosing polygon. (Unconventional for mathematicians,
    // but this is ArcGIS standard.) The identifier is either that of the enclosing
    // polygon, or -99999 in which case it is a hole in the preceding polygon.
    // The population can now be a floating-point number.
    // If a region contains exactly zero population, it will be replaced by
    // MINPOPFAC times the smallest positive population in any region.
    // Obviously, MINPOPFAC should be <1, I will set it to 0.1 by default. This
    // should reduce the value of sigma necessary for the integrator to finish
    // properly.
    // Modified on March 31, 2005. Initialized maxchange in nonlinvoltra() as
    // INFTY. Replaced crnmbr() by a similar, but faster routine interior().
    // Many thanks to Stuart Anderson for pointing out this shortcut.
    // TO DO LIST:
    // - Do Gaussian blur within nonlinvoltra as a simple call to calcv and
    // eliminate gaussianblur().
    // - Modify the NR code for the FFTs to deal more naturally with the fencepost
    // issue. No more copying of arrays in sinft and cosft.
    // - Write truly two-dimensional versions of coscosft, cossinft, and sincosft.
    // See Chan and Ho: A new two-dimensional fast cosine transform algorithm,
    // IEEE Transactions on Signal Processing, 39, 481ff. (1991).
    // - Read polygon data directly from shapefile instead of generate file.
    // - Reorganize data structures. It is currently quite a mess to read.
    // Inclusions
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    // Definitions
    #define CART2PS "./cart.ps","w" // Cartogram image.
    #define CARTGENFILE "./cartogram.gen" // Cartogram generate file.
    #define CENSUSFILE "./census.dat","r" // Input.
    #define CONVERGENCE 1e-100 // Convergence criterion for integrator.
    // #define DISPLFILE "./displ.dat","w"
    #define FALSE 0
    #define HINITIAL 1e-4 // Initial time step size in nonlinvoltra.
    #define IMAX 50 // Maximum number of iterations in Newton-Raphson routine.
    #define INFTY 1e100
    #define LINELENGTH 1000
    #define MAP2PS "map.ps","w" // Map image.
    #define MAPGENFILE "./map.gen","r" // Input coordinates.
    #define MAX(a,b) ((b>a)?(b):(a))
    #define MAXINTSTEPS 3000 // Maximum number of time steps in nonlinvoltra.
    #define MAXNSQLOG 18 // The number of sample points for rho_0 is <~2^MAXNSQLOG.
    #define MIN(a,b) ((b<a)?(b):(a))
    #define MINH 1e-5 // Smallest permitted time step in the integrator.
    #define MINPOPFAC 0.1 // Replace 0 population by a fraction of the minimum.
    #define NR_END 1
    #define NSUBDIV 1 // Number of linear subdivisions for digitizing the density.
    #define PADDING 1.5 // Determines space between map and boundary.
    #define PI 3.141592653589793
    #define SIGMA 0.1 // Initial width of Gaussian blur.
    #define SIGMAFAC 1.2 // Increase sigma by this factor. Must be > 1.
    #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr;
    #define TIMELIMIT 1e8 // Maximum time allowed in integrator.
    #define TOLF 1e-3 // Sensitivity w. r. t. function value in newt2.
    #define TOLINT 1e-3 // Sensitivity of the integrator.
    #define TOLX 1e-3 // Sensitivity w. r. t. independent variables in newt2.
    #define TRUE !FALSE
    // Types
    typedef int BOOLEAN;
    typedef struct
    float x;
    float y;
    } POINT;
    // Globals
    float bbmaxx,*bbmaxy,*bbminx,*bbminy,**gridvx,*gridvy,maxx,maxy,minpop,
    minx,miny,polymaxx,polymaxy,polyminx,polyminy,*rho,**rho_0,**vx,**vy,*x,
    *xappr,xstepsize,**y,*yappr,ystepsize;
    int lx,ly,maxid,nblurs=0,npoly,npolycorn,*npolyinreg,nregcorn,nregion,
    polygonid,**polyinreg,*regionid,*regionidinv,*within;
    POINT *polycorn,*regcorn;
    // Function prototypes
    int readline(char line[],FILE *infile);
    void countpoly(FILE *infile);
    void countcorn(FILE *infile);
    void readcorn(FILE *infile);
    void makeregion(void);
    void pspicture(FILE *outfile);
    void bboxes(void);
    void interior(void);
    double regionarea(int ncrns,POINT *polygon);
    void digdens(void);
    void four1(float data[],unsigned long nn,int isign);
    void realft(float data[],unsigned long n,int isign);
    void cosft(float z[],unsigned long n,int isign);
    void sinft(float z[],unsigned long n,int isign);
    void coscosft(float **y,int isign1,int isign2);
    void cossinft(float **y,int isign1,int isign2);
    void sincosft(float **y,int isign1,int isign2);
    float **dmatrix(long nrl,long nrh,long ncl,long nch);
    float *d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh);
    void free_matrix(float **m,long nrl,long nrh,long ncl,long nch);
    void free_f3tensor(float *t,long nrl,long nrh,long ncl,long nch,long ndl,
    long ndh);
    void fourn(float data[],unsigned long nn[],int ndim,int isign);
    void rlft3(float *data,float **speq,unsigned long nn1,unsigned long nn2,
    unsigned long nn3,int isign);
    void gaussianblur(void);
    void initcond(void);
    void calcv(float t);
    float intpol(float **arr,float x,float y);
    BOOLEAN newt2(float h,float *xappr,float xguess,float *yappr,float yguess,
    int j,int k);
    BOOLEAN nonlinvoltra(void);
    POINT transf(POINT p);
    void cartogram(void);
    // Function to read one line.
    int readline(char line[],FILE *infile)
    if (fgets(line,LINELENGTH,infile)==NULL) return 1;
    return 0;
    // Function to count the number of polygons.
    void countpoly(FILE *infile)
    char line[LINELENGTH];
    npoly = 0;
    while (!readline(line,infile)) if (line[0] == 'E') npoly++;
    npoly--; // The .gen file ends with two consecutive "END"s.
    // Function to count polygon corners. Also determines minimum/maximum x-/y-
    // coordinate.
    void countcorn(FILE *infile)
    BOOLEAN bnd_ok = FALSE;
    char line[LINELENGTH];
    float x,y;
    int polyctr=0,ratiolog;
    npolycorn = (int*)calloc(npoly,sizeof(int));
    polycorn = (POINT*)malloc(npoly*sizeof(POINT));
    readline(line,infile); // Skip first line.
    readline(line,infile);
    sscanf(line,"%f %f",&x,&y);
    polyminx = x; polymaxx = x; polyminy = y; polymaxy = y;
    npolycorn[0] = 1;
    while (!readline(line,infile))
    if (line[0] != 'E')
    sscanf(line,"%f %f",&x,&y);
    if (x < polyminx) polyminx = x;
    if (x > polymaxx) polymaxx = x;
    if (y < polyminy) polyminy = y;
    if (y > polymaxy) polymaxy = y;
    npolycorn[polyctr]++;
    else
    readline(line,infile);
    polycorn[polyctr] = (POINT)malloc(npolycorn[polyctr]sizeof(POINT));
    polyctr++;
    if (ceil(log((polymaxx-polyminx)/(polymaxy-polyminy))/log(2))+
    floor(log((polymaxx-polyminx)/(polymaxy-polyminy))/log(2))>
    2*log((polymaxx-polyminx)/(polymaxy-polyminy))/log(2))
    ratiolog = (int)floor(log((polymaxx-polyminx)/(polymaxy-polyminy))/log(2));
    else
    ratiolog = (int)ceil(log((polymaxx-polyminx)/(polymaxy-polyminy))/log(2));
    lx = (int)pow(2,(int)(0.5*(ratiolog+MAXNSQLOG)));
    ly = (int)pow(2,(int)(0.5*(MAXNSQLOG-ratiolog)));
    if ((polymaxx-polyminx)/lx > (polymaxy-polyminy)/ly)
    maxx = 0.5((1PADDING)*polymaxx(1-PADDING)polyminx);
    minx = 0.5((1-PADDING)*polymaxx(1PADDING)polyminx);
    maxy = 0.5(polymaxypolyminy(maxx-minx)ly/lx);
    miny = 0.5(polymaxy+polyminy-(maxx-minx)ly/lx);
    else
    maxy = 0.5((1PADDING)*polymaxy(1-PADDING)polyminy);
    miny = 0.5((1-PADDING)*polymaxy(1PADDING)polyminy);
    maxx = 0.5(polymaxxpolyminx(maxy-miny)lx/ly);
    minx = 0.5(polymaxx+polyminx-(maxy-miny)lx/ly);
    // Uncomment the next lines for interactive choice of boundary conditions.
    /* printf("For the %i polygon(s) under consideration:\n",npoly);
    printf("minimum x = %f\tmaximum x = %f\n",polyminx,polymaxx);
    printf("minimum y = %f\tmaximum y = %f\n",polyminy,polymaxy);
    while (!bnd_ok)
    printf("Type in your choice of boundaries.\nminx = ");
    scanf("%f",&minx);
    printf("maxx = ");
    scanf("%f",&maxx);
    printf("miny = ");
    scanf("%f",&miny);
    printf("maxy = ");
    scanf("%f",&maxy);
    if (minx>polyminx || maxx<polymaxx || miny>polyminy || maxy<polymaxy)
    printf("Invalid choice, does not enclose the polygon(s).\n");
    else bnd_ok = TRUE;
    // Function to read polygon corners. The first and last vertex of each polygon
    // must be identical.
    void readcorn(FILE *infile)
    char line[LINELENGTH];
    float xcoord,ycoord;
    int i,id,polyctr=0;
    polygonid = (int)malloc(npolysizeof(int));
    xstepsize = (maxx-minx)/lx;
    ystepsize = (maxy-miny)/ly;
    if (fabs((xstepsize/ystepsize)-1)>1e-3)
    fprintf(stderr,"WARNING: Area elements are not square: %f : %f\n",
    xstepsize,ystepsize);
    readline(line,infile);
    sscanf(line,"%i",&id);
    polygonid[polyctr] = id;
    i = 0;
    while (!readline(line,infile))
    if (line[0] != 'E')
    sscanf(line,"%f %f",&xcoord,&ycoord);
    polycorn[polyctr].x = (xcoord-minx)/xstepsize;
    polycorn[polyctr][i++].y = (ycoord-miny)/ystepsize;
    else
    // Is first and last vertex the same?
    if (fabs(polycorn[polyctr][0].x-
    polycorn[polyctr][npolycorn[polyctr]-1].x)+
    fabs(polycorn[polyctr][0].y-
    polycorn[polyctr][npolycorn[polyctr]-1].y)>1e-12)
    fprintf(stderr,
    "ERROR: %i-th polygon does not close upon itself.\n",
    polyctr+1);
    fprintf(stderr,"Identifier %i, first point %f %f.\n",
    polygonid[polyctr],polycorn[polyctr][0].x*xstepsize+minx,
    polycorn[polyctr][0].y*ystepsize+miny);
    exit(1);
    readline(line,infile);
    sscanf(line,"%i",&id);
    i = 0;
    polyctr++;
    if (polyctr<npoly) polygonid[polyctr] = id;
    polyminx = (polyminx-minx)/xstepsize;
    polyminy = (polyminy-miny)/ystepsize;
    polymaxx = (polymaxx-minx)/xstepsize;
    polymaxy = (polymaxy-miny)/ystepsize;
    // Function to make regions from polygons.
    void makeregion(void)
    BOOLEAN repeat;
    int i,lastid,minid,polyctr,ptctr,regctr;
    // Count the number of regions.
    nregion = 0;
    maxid = minid = polygonid[0];
    for (polyctr=0; polyctr<npoly; polyctr++)
    if (polygonid[polyctr] == -99999) continue;
    if (polygonid[polyctr]>maxid || polygonid[polyctr]<minid) nregion++;
    else
    repeat = FALSE;
    for (i=0; i<polyctr; i++)
    if (polygonid[polyctr]==polygonid)
    repeat = TRUE;
    break;
    if (!repeat) nregion++;
    if (polygonid[polyctr]>maxid) maxid = polygonid[polyctr];
    if (polygonid[polyctr]<minid) minid = polygonid[polyctr];
    if (minid < 0)
    fprintf(stderr,
    "ERROR: Negative region identifier %i.\n",minid);
    exit(1);
    // Match region identifiers.
    regionid = (int)malloc(nregionsizeof(int));
    nregion = 0;
    maxid = minid = polygonid[0];
    for (polyctr=0; polyctr<npoly; polyctr++)
    if (polygonid[polyctr] == -99999) continue;
    if (polygonid[polyctr]>maxid || polygonid[polyctr]<minid)
    regionid[nregion++] = polygonid[polyctr];
    else
    repeat = FALSE;
    for (i=0; i<polyctr; i++)
    if (polygonid[polyctr]==polygonid)
    repeat = TRUE;
    break;
    if (!repeat) regionid[nregion++] = polygonid[polyctr];
    if (polygonid[polyctr]>maxid) maxid = polygonid[polyctr];
    if (polygonid[polyctr]<minid) minid = polygonid[polyctr];
    regionidinv = (int)malloc((maxid+1)sizeof(int));
    // Negative number for unused identifiers.
    for (i=0; i<=maxid; i++) regionidinv = -1;
    for (regctr=0; regctr<nregion; regctr++)
    regionidinv[regionid[regctr]] = regctr;
    // Which polygons contribute to which regions?
    npolyinreg = (int*)calloc(nregion,sizeof(int));
    polyinreg = (int*)malloc(nregion*sizeof(int));
    lastid = polygonid[0];
    for (polyctr=0; polyctr<npoly; polyctr++)
    if (polygonid[polyctr] != -99999)
    npolyinreg[regionidinv[polygonid[polyctr]]]++;
    lastid = polygonid[polyctr];
    else npolyinreg[regionidinv[lastid]]++;
    for (regctr=0; regctr<nregion; regctr++)
    polyinreg[regctr] = (int)malloc(npolyinreg[regctr]sizeof(int));
    for (regctr=0; regctr<nregion; regctr++) npolyinreg[regctr] = 0;
    lastid = polygonid[0];
    for (polyctr=0; polyctr<npoly; polyctr++)
    if (polygonid[polyctr] != -99999)
    polyinreg[regionidinv[polygonid[polyctr]]]
    [npolyinreg[regionidinv[polygonid[polyctr]]]++] = polyctr;
    lastid = polygonid[polyctr];
    else polyinreg[regionidinv[lastid]][npolyinreg[regionidinv[lastid]]++]
    = polyctr;
    // Make regions from polygons. Start and end each polygon at (0,0).
    nregcorn = (int*)calloc(nregion,sizeof(int));
    regcorn = (POINT*)malloc(nregion*sizeof(POINT));
    for (regctr=0; regctr<nregion; regctr++)
    for (i=0; i<npolyinreg[regctr]; i++)
    nregcorn[regctr] += npolycorn[polyinreg[regctr]]+1;
    nregcorn[regctr]++;
    for (regctr=0; regctr<nregion; regctr++)
    regcorn[regctr] = (POINT)malloc(nregcorn[regctr]sizeof(POINT));
    ptctr = 0;
    regcorn[regctr][ptctr].x = regcorn[regctr][ptctr++].y = 0.0;
    for (polyctr=0; polyctr<npolyinreg[regctr]; polyctr++)
    for (i=0; i<npolycorn[polyinreg[regctr][polyctr]]; i++)
    regcorn[regctr][ptctr++] = polycorn[polyinreg[regctr][polyctr]];
    regcorn[regctr][ptctr].x = regcorn[regctr][ptctr++].y = 0.0;
    // Function to prepare a map in postscript standard letter format.
    void pspicture(FILE *outfile)
    char line[LINELENGTH];
    float addx,addy,b,conv,g,r;
    int ptctr,regctr;
    if (11*lx > 8.5*ly)
    conv = (float)8.5*72/lx;
    addx = 0;
    addy = 1136-8.5*36ly/lx;
    else
    conv = (float)11*72/ly;
    addx = 8.536-11*36lx/ly;
    addy = 0;
    fprintf(outfile,"0.5 setlinewidth\n");
    for (regctr=0; regctr<nregion; regctr++)
    fprintf(outfile,"newpath\n");
    fprintf(outfile,"%f %f moveto\n",
    regcorn[regctr][1].x*conv+addx,
    regcorn[regctr][1].y*conv+addy);
    for (ptctr=2; ptctr<nregcorn[regctr]; ptctr++)
    if (fabs(regcorn[regctr][ptctr].x)+
    fabs(regcorn[regctr][ptctr].y)>1e-12)
    fprintf(outfile,"%f %f lineto\n",
    regcorn[regctr][ptctr].x*conv+addx,
    regcorn[regctr][ptctr].y*conv+addy);
    else
    fprintf(outfile,"closepath\n");
    if (ptctr<nregcorn[regctr]-1)
    ptctr++;
    fprintf(outfile,"%f %f moveto\n",
    regcorn[regctr][ptctr].x*conv+addx,
    regcorn[regctr][ptctr].y*conv+addy);
    // Determine colors for map (without better knowledge I will do it
    // arbitrarily).
    if (regctr%3 == 0)
    r = (float)regctr/nregion;
    g = 1-(float)regctr/nregion;
    b = fabs(1-2*(float)regctr/nregion);
    else if (regctr%3 == 1)
    b = (float)regctr/nregion;
    r = 1-(float)regctr/nregion;
    g = fabs(1-2*(float)regctr/nregion);
    else
    g = (float)regctr/nregion;
    b = 1-(float)regctr/nregion;
    r = fabs(1-2*(float)regctr/nregion);
    fprintf(outfile,"%f %f %f setrgbcolor\ngsave\nfill\n",r,g,b);
    fprintf(outfile,"grestore\n0 setgray stroke\n");
    fprintf(outfile,"showpage\n");
    // Function to find the bounding box for each polygon.
    void bboxes(void)
    int i,j;
    float maxx, minx, maxy, miny;
    bbmaxx = (float)malloc(npolysizeof(float));
    bbmaxy = (float)malloc(npolysizeof(float));
    bbminx = (float)malloc(npolysizeof(float));
    bbminy = (float)malloc(npolysizeof(float));
    for (i = 0; i < npoly; i++)
    maxx = polycorn[0].x;
    maxy = polycorn[0].y;
    minx = maxx;
    miny = maxy;
    for (j = 0; j < npolycorn; j++)
    if (polycorn[j].x > maxx) maxx = polycorn[j].x;
    if (polycorn[j].x < minx) minx = polycorn[j].x;
    if (polycorn[j].y < miny) miny = polycorn[j].y;
    if (polycorn[j].y > maxy) maxy = polycorn[j].y;
    bbmaxx=maxx;
    bbmaxy=maxy;
    bbminx=minx;
    bbminy=miny;
    void interior(void)
    int i,inhowmanyregions,inregion[2],j,k,l,m,n,regctr;
    // Initialize within[][]. -1 means outside all regions.
    for (i=0; i<=lx; i++) for (j=0; j<=ly; j++) within[j] = -1;
    // Fill within[][].
    for (i=0; i<nregion; i++) for (j=0; j<npolyinreg; j++)
    for (k=0, n=npolycorn[polyinreg[j]]-1;
    k<npolycorn[polyinreg[j]]; n=k++)
    for (l=(int)ceil(MIN(polycorn[polyinreg[j]][k-1].y,
    polycorn[polyinreg[j]][k].y));
    l<MAX(polycorn[polyinreg[j]][k-1].y,
    polycorn[polyinreg[j]][k].y); l++)
    for (m=(int)floor(bbminx[polyinreg[j]]);
    m<(polycorn[polyinreg[j]][n].x-
    polycorn[polyinreg[j]][k].x)*
    (l-polycorn[polyinreg[j]][k].y)/
    (polycorn[polyinreg[j]][n].y-
    polycorn[polyinreg[j]][k].y)+
    polycorn[polyinreg[j]][k].x;
    m++)
    within[m][l] = i-within[m][l]-1;
    // Function to determine polygon area. This is needed to determine the average
    // population.
    // The problem in short is to find the area of a polygon whose vertices are
    // given. Recall Stokes' theorem in 3d for a vector field v:
    // integral[around closed curve dA]v(x,y,z).ds =
    // integral[over area A]curl(v).dA.
    // Now let v(x,y,z) = (0,Q(x,y),0) and dA = (0,0,dx*dy). Then
    // integral[around closed curve dA]Q(x,y)dy = integral[over area A]dQ/dxdxdy.
    // If Q = x:
    // A = integral[over area A]dx*dy = integral[around closed curve dA]x dy.
    // For every edge from (x,y) to (x[i1],y[i1]) there is a
    // parametrization
    // (x(t),y(t)) = ((1-t)xtx[i+1],(1-t)y+ty[i1]), 0<t<1
    // so that the path integral along this edge is
    // int[from 0 to 1]{(1-t)xt*x[i+1]}(y[i1]-y)dt =
    // 0.5(y[i1]-y)(x+x[i1]).
    // Summing over all edges yields:
    // Area = 0.5*[(x[0]+x[1])(y[1]-y[0]) + (x[1]+x[2])(y[2]-y[1]) + ...
    // ...(x[n-1]+x[n])(y[n]-y[n-1])+(x[n]x[0])(y[0]-y[n])]
    // ArcGIS treats a clockwise direction as positive, so there is a minus sign.
    double regionarea(int ncrns,POINT *polygon)
    double area=0;
    int i;
    for (i=0; i<ncrns-1; i++)
    area -=
    0.5(polygon.xpolygon[i+1].x)(polygon[i1].y-polygon.y);
    return area -= 0.5(polygon[ncrns-1].x+polygon[0].x)
    (polygon[0].y-polygon[ncrns-1].y);
    // Function to digitize density.
    void digdens(void)
    char line[LINELENGTH];
    double area,avgdens,*cases,dens,minpop=INFTY,ncases,totarea=0.0,totpop=0.0;
    FILE* infile;
    int i,id,ii,inhowmanyregions,inregion[2],j,jj,regctr;
    if ((infile=fopen(CENSUSFILE))==NULL)
    fprintf(stderr,"ERROR: Cannot find CENSUSFILE.\n");
    exit(1);
    // Find the minimum positive number of cases.
    while (!readline(line,infile))
    sscanf(line,"%i %lf",&id,&ncases);
    if (ncases<minpop && ncases>1e-12) minpop = ncases;
    fclose(infile);
    // Store the number of cases in an array.
    cases = (double)malloc(nregionsizeof(double));
    for (i=0; i<nregion; i++) cases = -1.0;
    infile = fopen(CENSUSFILE);
    while (!readline(line,infile))
    sscanf(line,"%i %lf",&id,&ncases);
    if (id>maxid || regionidinv[id]<0)
    fprintf(stderr,"ERROR: Identifier %i in CENSUSFILE does not\n",id);
    fprintf(stderr,"match any identifier in generate file.\n");
    exit(1);
    if (ncases>1e-12) totpop += (cases[regionidinv[id]] = ncases);
    else totpop += (cases[regionidinv[id]] = MINPOPFAC*minpop);
    for (regctr=0; regctr<nregion; regctr++) if (cases[regctr] < 0.0)
    fprintf(stderr,"ERROR: No density for region %i?\n",regionid[regctr]);
    fprintf(stderr,"cases = %f\n",cases[regctr]);
    exit(1);
    fclose(infile);
    // Calculate regions' areas, total area to be mapped, regional and average
    // densities.
    area = (double)malloc(nregionsizeof(double));
    for (regctr=0; regctr<nregion; regctr++)
    totarea += (area[regctr] = regionarea(nregcorn[regctr],regcorn[regctr]));
    dens = (double)malloc(nregionsizeof(double));
    for (regctr=0; regctr<nregion; regctr++)
    dens[regctr] = cases[regctr]/area[regctr];
    avgdens = totpop/totarea;
    // Digitize density.
    for (i=0; i<=lx; i++) for (j=0; j<=ly; j++) rho_0[j] = 0; // Initialize.
    printf("digitizing density ...\n");
    for (i=0; i<lx; i++) for (j=0; j<ly; j++)
    if (within[j]==-1) rho_0[j] = avgdens;
    else rho_0[j] = dens[within[j]];
    // Fill the edges correctly.
    rho_0[0][0] += rho_0[0][ly] + rho_0[lx][0] + rho_0[lx][ly];
    for (i=1; i<lx; i++) rho_0[0] += rho_0[ly];
    for (j=1; j<ly; j++) rho_0[0][j] += rho_0[lx][j];
    for (i=0; i<lx; i++) rho_0[ly] = rho_0[0];
    for (j=0; j<=ly; j++) rho_0[lx][j] = rho_0[0][j];
    // Replace rho_0 by Fourier transform
    coscosft(rho_0,1,1);
    free(area);
    free(cases);
    for (i=0; i<npoly; i++) free(polycorn);
    free(polycorn);
    for (i=0; i<nregion; i++) free(regcorn);
    free(regcorn);
    free(dens);
    free(npolycorn);
    free(nregcorn);
    free(polygonid);
    free(regionid);
    free(regionidinv);
    free(bbmaxx);
    free(bbmaxy);
    free(bbminx);
    free(bbminy);
    for (i=0; i<nregion; i++) free(polyinreg);
    free(polyinreg);
    free(npolyinreg);
    // Function to replace data[1...2*nn] by its discrete Fourier transform, if
    // isign is input as 1; or replaces data[1...2*nn] by nn times its inverse
    // discrete Fourier transform, if isign is input as -1. data is a complex array
    // of length nn or, equivalently, a real array of length 2*nn. nn MUST be an
    // integer power of 2 (this is not checked for!).
    // From "Numerical Recipes in C".
    void four1(float data[],unsigned long nn,int isign)
    double theta,wi,wpi,wpr,wr,wtemp;
    float tempi,tempr;
    unsigned long i,istep,j,m,mmax,n;
    n=nn<<1;
    j=1;
    for (i=1; i<n; i+=2)
    if (j>i)
    // This is the bit-reversal section of the routine.
    SWAP(data[j],data);
    SWAP(data[j1],data[i1]); // Exchange the two complex numbers.
    m=n>>1;
    while (m>=2 && j>m)
    j -= m;
    m>>=1;
    j += m;
    // Here begins the Danielson-Lanczos section of the routine.
    mmax=2;
    while (n>mmax) // Outer loop executed log_2 nn times.
    istep = mmax<<1;
    // Initialize the trigonometric recurrence.
    theta = isign*(6.28318530717959/mmax);
    wtemp = sin(0.5*theta);
    wpr = -2.0wtempwtemp;
    wpi = sin(theta);
    wr = 1.0;
    wi = 0.0;
    for (m=1; m<mmax; m+=2) // Here are the two nested inner loops.
    for (i=m; i<=n; i+=istep)
    j=i+mmax; // This is the Danielson-Lanczos formula
    tempr=wrdata[j]-widata[j+1];
    tempi=wrdata[j1]widata[j];
    data[j]=data-tempr;
    data[j1]=data[i1]-tempi;
    data += tempr;
    data[i+1] += tempi;
    wr = (wtemp=wr)wpr-wiwpi+wr; // Trigonometric recurrence.
    wi = wiwprwtempwpiwi;
    mmax=istep;
    // Function to calculate the Fourier Transform of a set of n real-valued data
    // points. It replaces this data (which is stored in array data[1...n]) by the
    // positive frequency half of its complex Fourier Transform. The real-valued
    // first and last components of the complex transform are returned as elements
    // data[1] and data[2] respectively. n must be a power of 2. This routine also
    // calculates the inverse transform of a complex data array if it is the
    // transform of real data. (Result in this case must be multiplied by 2/n).
    // From "Numerical Recipes in C".
    void realft(float data[],unsigned long n,int isign)
    double theta,wi,wpi,wpr,wr,wtemp;
    float c1=0.5,c2,h1i,h1r,h2i,h2r;
    unsigned long i,i1,i2,i3,i4,np3;
    theta = 3.141592653589793/(double) (n>>1); // Initialize the recurrence
    if (isign == 1)
    c2 = -0.5;
    four1(data,n>>1,1); // The forward transform is here.
    else // Otherwise set up for an inverse transform.
    c2 = 0.5;
    theta = -theta;
    wtemp = sin(0.5*theta);
    wpr = -2.0wtempwtemp;
    wpi = sin(theta);
    wr = 1.0+wpr;
    wi = wpi;
    np3 = n+3;
    for (i=2; i<=(n>>2); i++) // Case i=1 done separately below.
    i4 = 1(i3=np3-(i2=1+(i1=ii-1)));
    // The two separate transforms are separated out of data.
    h1r = c1*(data[i1]+data[i3]);
    h1i = c1*(data[i2]-data[i4]);
    h2r = -c2*(data[i2]+data[i4]);
    h2i = c2*(data[i1]-data[i3]);
    // Here they are recombined to form the true transform of the original
    // data.
    data[i1] = h1r+wrh2r-wih2i;
    data[i2] = h1iwrh2iwih2r;
    data[i3] = h1r-wrh2r+wih2i;
    data[i4] = -h1iwrh2iwih2r;
    wr = (wtemp=wr)wpr-wiwpi+wr; // The recurrence.
    wi = wiwprwtempwpiwi;
    if (isign == 1)
    data[1] = (h1r=data[1])+data[2]; // Squeeze the first and last data
    // together to get them all within the original array.
    data[2] = h1r-data[2];
    else
    data[1] = c1*((h1r=data[1])+data[2]);
    data[2] = c1*(h1r-data[2]);
    // This is the inverse transform for the case isign = -1.
    four1(data,n>>1,-1);
    // Function to calculate the cosine transform of a set z[0...n] of real-valued
    // data points. The transformed data replace the original data in array z. n
    // must be a power of 2. For forward transform set isign=1, for back transform
    // isign = -1. (Note: The factor 2/n has been taken care of.)
    // From "Numerical Recipes in C".
    void cosft(float z[],unsigned long n,int isign)
    double theta,wi=0.0,wpi,wpr,wr=1.0,wtemp;
    float *a,sum,y1,y2;
    int j,n2;
    // Numerical Recipes starts counting at 1 which is rather confusing. I will
    // count from 0.
    a = (float)malloc((n+2)sizeof(float));
    for (j=1; j<=n+1; j++) a[j] = z[j-1];
    // Here is the Numerical Recipes code.
    theta=PI/n; //Initialize the recurrence.
    wtemp = sin(0.5*theta);
    wpr = -2.0wtempwtemp;
    wpi = sin(theta);
    sum = 0.5*(a[1]-a[n+1]);
    a[1] = 0.5*(a[1]a[n1]);
    n2 = n+2;
    for (j=2; j<=(n>>1); j++)
    wr = (wtemp=wr)wpr-wiwpi+wr;
    wi = wiwprwtempwpiwi;
    y1 = 0.5*(a[j]+a[n2-j]);
    y2 = (a[j]-a[n2-j]);
    a[j] = y1-wi*y2;
    a[n2-j] = y1+wi*y2;
    sum += wr*y2;
    realft(a,n,1);
    a[n+1] = a[2];
    a[2] = sum;
    for (j=4; j<=n; j+=2)
    sum += a[j];
    a[j] = sum;
    // Finally I revert to my counting method.
    if (isign == 1) for (j=1; j<=n+1; j++) z[j-1] = a[j];
    else if (isign == -1) for (j=1; j<=n+1; j++) z[j-1] = 2.0*a[j]/n;
    free(a);
    // Function to calculate the sine transform of a set of n real-valued data
    // points stored in array z[0..n]. The number n must be a power of 2. On exit
    // z is replaced by its transform. For forward transform set isign=1, for back
    // transform isign = -1.
    void sinft(float z[],unsigned long n,int isign)
    double theta,wi=0.0,wpi,wpr,wr=1.0,wtemp;
    float *a,sum,y1,y2;
    int j;
    unsigned long n2=n+2;
    // See my comment about Numerical Recipe's counting above. Note that the last
    // component plays a completely passive role and does not need to be stored.
    a = (float*) malloc((n+1)*sizeof(float));
    for (j=1; j<=n; j++) a[j] = z[j-1];
    // Here is the Numerical Recipes code.
    theta = PI/(double)n; // Initialize the recurrence.
    wtemp = sin(0.5*theta);
    wpr = -2.0wtempwtemp;
    wpi = sin(theta);
    a[1] = 0.0;
    for (j=2; j<=(n>>1)+1; j++)
    // Calculate the sine for the auxiliary array.
    wr = (wtemp=wr)wpr-wiwpi+wr;
    // The cosine is needed to continue the recurrence.
    wi = wiwprwtempwpiwi;
    // Construct the auxiliary array.
    y1 = wi*(a[j]+a[n2-j]);
    y2 = 0.5*(a[j]-a[n2-j]);
    // Terms j and N-j are related.
    a[j] = y1+y2;
    a[n2-j] = y1-y2;
    // Transform the auxiliary array.
    realft(a,n,1);
    // Initialize the sum used for odd terms below.
    a[1] *= 0.5;
    sum = a[2] = 0.0;
    // Even terms determined directly. Odd terms determined by running sum.
    for (j=1; j<=n-1; j+=2)
    sum += a[j];
    a[j] = a[j+1];
    a[j+1] = sum;
    // Change the indices.
    if (isign == 1) for (j=1; j<=n; j++) z[j-1] = a[j];
    else if (isign == -1) for (j=1; j<=n; j++) z[j-1] = 2.0*a[j]/n;
    z[n] = 0.0;
    free(a);
    // Function to calculate a two-dimensional cosine Fourier transform. Forward/
    // backward transform in x: isign1 = +/-1, in y: isign2 = +/-1.
    void coscosft(float **y,int isign1,int isign2)
    float temp[lx+1];
    unsigned long i,j;
    for (i=0; i<=lx; i++)
    cosft(y,ly,isign2);
    for (j=0; j<=ly; j++)
    for (i=0; i<=lx; i++) temp=y[j];
    cosft(temp,lx,isign1);
    for (i=0; i<=lx; i++) y[j]=temp;
    // Function to calculate a cosine Fourier transform in x and a sine transform
    // in y. Forward/backward transform in x: isign1 = +/-1, in y: isign2 = +/-1.
    void cossinft(float **y,int isign1,int isign2)
    float temp[lx+1];
    unsigned long i,j;
    for (i=0; i<=lx; i++)
    sinft(y,ly,isign2);
    for (j=0; j<=ly; j++)
    for (i=0; i<=lx; i++) temp=y[j];
    cosft(temp,lx,isign1);
    for (i=0; i<=lx; i++) y[j]=temp;
    // Function to calculate a sine Fourier transform in x and a cosine transform
    // in y. Forward/backward transform in x: isign1 = +/-1, in y: isign2 = +/-1.
    void sincosft(float **y,int isign1,int isign2)
    float temp[lx+1];
    unsigned long i,j;
    for (i=0; i<=lx; i++)
    cosft(y,ly,isign2);
    for (j=0; j<=ly; j++)
    for (i=0; i<=lx; i++) temp=y[j];
    sinft(temp,lx,isign1);
    for (i=0; i<=lx; i++) y[j]=temp;
    // Function to allocate a float matrix with subscript range
    // m[nrl..nrh][ncl..nch]. From "Numerical Recipes in C".
    float **dmatrix(long nrl,long nrh,long ncl,long nch)
    long i, nrow=nrh-nrl1,ncol=nch-ncl1;
    float **m;
    /* allocate pointers to rows */
    m=(float **) malloc((unsigned int)((nrow+NR_END)sizeof(float)));
    if (!m)
    fprintf(stderr,"allocation failure 1 in matrix()\n");
    exit(1);
    m += NR_END;
    m -= nrl;
    /* allocate rows and set pointers to them */
    m[nrl]=(float *) malloc((unsigned int)((nrowncol+NR_END)sizeof(float)));
    if (!m[nrl])
    fprintf(stderr,"allocation failure 2 in matrix()\n");
    exit(1);
    m[nrl] += NR_END;
    m[nrl] -= ncl;
    for(i=nrl1;i<=nrh;i+) m=m[i-1]+ncol;
    /* return pointer to array of pointers to rows */
    return m;
    // Function to allocate a float 3tensor with range
    // t[nrl..nrh][ncl..nch][ndl..ndh]. From "Numerical Recipes in C".
    float *d3tensor(long nrl, long nrh, long ncl, long nch, long ndl, long ndh)
    long i,j,nrow=nrh-nrl1,ncol=nch-ncl+1,ndep=ndh-ndl1;
    float *t;
    /* allocate pointers to pointers to rows */
    t=(float *) malloc((sizet)((nrow+NREND)sizeof(float*)));
    if (!t)
    fprintf(stderr,"allocation failure 1 in f3tensor()\n");
    exit(1);
    t += NR_END;
    t -= nrl;
    /* allocate pointers to rows and set pointers to them */
    t[nrl]=(float **) malloc((sizet)((nrowncol+NREND)*sizeof(float)));
    if (!t[nrl])
    fprintf(stderr,"allocation failure 2 in f3tensor()\n");
    exit(1);
    t[nrl] += NR_END;
    t[nrl] -= ncl;
    /* allocate rows and set pointers to them */
    t[nrl][ncl]=(float *) malloc((sizet)((nrowncol*ndep+NREND)sizeof(float)));
    if (!t[nrl][ncl])
    fprintf(stderr,"allocation failure 3 in f3tensor()\n");
    exit(1);
    t[nrl][ncl] += NR_END;
    t[nrl][ncl] -= ndl;
    for(j=ncl1;j<=nch;j+) t[nrl][j]=t[nrl][j-1]+ndep;
    for(i=nrl1;i<=nrh;i+) {
    t=t[i-1]+ncol;
    t[ncl]=t[i-1][ncl]+ncol*ndep;
    for(j=ncl1;j<=nch;j+) t[j]=t[j-1]+ndep;
    /* return pointer to array of pointers to rows */
    return t;
    void free_matrix(float **m,long nrl,long nrh,long ncl,long nch)
    free((char*) (m[nrl]+ncl-1));
    free((char*) (m+nrl-1));
    void free_f3tensor(float *t,long nrl,long nrh,long ncl,long nch,long ndl,
    long ndh)
    free((char*) (t[nrl][ncl]+ndl-1));
    free((char*) (t[nrl]+ncl-1));
    free((char*) (t+nrl-1));
    // Function to replace data by its ndim-dimensional discrete Fourier transform,
    // if isign is input as 1. nn[1..ndim] is an integer array containing the
    // lengths of each dimension (number of complex values), which MUST be all
    // powers of 2. data is a real array of length twice the product of these
    // lengths, in which the data are stored as in a multidimensional complex
    // array: real and imaginary parts of each element are in consecutive
    // locations, and the rightmost index of the array increases most rapidly as
    // one proceeds along data. For a two-dimensional array, this is equivalent to
    // storing the arrays by rows. If isign is input as -1, data is replaced by its
    // inverse transform times the product of the lengths of all dimensions.
    void fourn(float data[],unsigned long nn[],int ndim,int isign)
    int idim;
    unsigned long i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2;
    unsigned long ibit,k1,k2,n,nprev,nrem,ntot;
    double tempi,tempr;
    float theta,wi,wpi,wpr,wr,wtemp;
    for (ntot=1, idim=1; idim<=ndim; idim++)
    ntot *= nn[idim];
    nprev = 1;
    for (idim=ndim; idim>=1; idim--)
    n = nn[idim];
    nrem = ntot/(n*nprev);
    ip1=nprev << 1;
    ip2 = ip1*n;
    ip3 = ip2*nrem;
    i2rev = 1;
    for (i2=1; i2<=ip2; i2+=ip1)
    if (i2 < i2rev)
    for (i1=i2; i1<=i2+ip1-2; i1+=2)
    for (i3=i1; i3<=ip3; i3+=ip2)
    i3rev = i2rev+i3-i2;
    SWAP(data[i3],data[i3rev]);
    SWAP(data[i31],data[i3rev1]);
    ibit = ip2>>1;
    while (ibit>=ip1 && i2rev>ibit)
    i2rev -= ibit;
    ibit >>= 1;
    i2rev += ibit;
    ifp1 = ip1;
    while (ifp1 < ip2)
    ifp2 = ifp1 << 1;
    theta = 2isignPI/(ifp2/ip1);
    wtemp = sin(0.5*theta);
    wpr = -2.0wtempwtemp;
    wpi = sin(theta);
    wr = 1.0;
    wi = 0.0;
    for (i3=1; i3<=ifp1; i3+=ip1)
    for (i1=i3; i1<=i3+ip1-2; i1+=2)
    for (i2=i1; i2<=ip3; i2+=ifp2)
    k1 = i2;
    k2 = k1+ifp1;
    tempr = (float)wrdata[k2]-(float)widata[k2+1];
    tempi = (float)wrdata[k21](float)widata[k2];
    data[k2] = data[k1]-tempr;
    data[k2+1] = data[k1+1]-tempi;
    data[k1] += tempr;
    data[k1+1] += tempi;
    wr = (wtemp=wr)wpr-wiwpi+wr;
    wi = wiwprwtempwpiwi;
    ifp1 = ifp2;
    nprev *= n;
    // Function to calculate a three-dimensional Fourier transform of
    // data[1..nn1][1..nn2][1..nn3] (where nn1=1 for the case of a logically two-
    // dimensional array). This routine returns (for isign=1) the complex fast
    // Fourier transform as two complex arrays: On output, data contains the zero
    // and positive frequency values of the third frequency component, while
    // speq[1..nn1][1..2*nn2] contains the Nyquist critical frequency values of the
    // third frequency component. First (and second) frequency components are
    // stored for zero, positive, and negative frequencies, in standard wrap-around
    // order. See Numerical Recipes for description of how complex values are
    // arranged. For isign=-1, the inverse transform (times nn1nn2nn3/2 as a
    // constant multiplicative factor) is performed, with output data (viewed as
    // real array) deriving from input data (viewed as complex) and speq. For
    // inverse transforms on data not generated first by a forward transform, make
    // sure the complex input data array satisfies property 12.5.2 from NR. The
    // dimensions nn1, nn2, nn3 must always be integer powers of 2.
    void rlft3(float *data,float **speq,unsigned long nn1,unsigned long nn2,
    unsigned long nn3,int isign)
    double theta,wi,wpi,wpr,wr,wtemp;
    float c1,c2,h1r,h1i,h2r,h2i;
    unsigned long i1,i2,i3,j1,j2,j3,nn[4],ii3;
    if (1+&data[nn1][nn2][nn3]-&data[1][1][1] != nn1nn2nn3)
    fprintf(stderr,
    "rlft3: problem with dimensions or contiguity of data array\n");
    exit(1);
    c1 = 0.5;
    c2 = -0.5*isign;
    theta = 2isign(PI/nn3);
    wtemp = sin(0.5*theta);
    wpr = -2.0wtempwtemp;
    wpi = sin(theta);
    nn[1] = nn1;
    nn[2] = nn2;
    nn[3] = nn3 >> 1;
    // Case of forward transform. Here is where most all of the compute time is
    // spent. Extend data periodically into speq.
    if (isign == 1)
    fourn(&data[1][1][1]-1,nn,3,isign);
    for (i1=1; i1<=nn1; i1++)
    for (i2=1, j2=0; i2<=nn2; i2++)
    speq[i1][++j2] = data[i1][i2][1];
    speq[i1][++j2] = data[i1][i2][2];
    for (i1=1; i1<=nn1; i1++)
    // Zero frequency is its own reflection; otherwise locate corresponding
    // negative frequency in wrap-around order.
    j1 = (i1 != 1 ? nn1-i1+2 : 1);
    // Initialize trigonometric recurrence.
    wr = 1.0;
    wi = 0.0;
    for (ii3=1, i3=1; i3<=(nn3>>2)+1; i3+,ii3=2)
    for (i2=1; i2<=nn2; i2++)
    if (i3 == 1)
    j2 = (i2 != 1 ? ((nn2-i2)<<1)+3 : 1);
    h1r = c1*(data[i1][i2][1]+speq[j1][j2]);
    h1i = c1*(data[i1][i2][2]-speq[j1][j2+1]);
    h2i = c2*(data[i1][i2][1]-speq[j1][j2]);
    h2r = -c2*(data[i1][i2][2]speq[j1][j21]);
    data[i1][i2][1] = h1r+h2r;
    data[i1][i2][2] = h1i+h2i;
    speq[j1][j2] = h1r-h2r;
    speq[j1][j2+1] = h2i-h1i;
    else
    j2 = (i2 != 1 ? nn2-i2+2 : 1);
    j3 = nn3+3-(i3<<1);
    h1r = c1*(data[i1][i2][ii3]+data[j1][j2][j3]);
    h1i = c1*(data[i1][i2][ii31]-data[j1][j2][j31]);
    h2i = c2*(data[i1][i2][ii3]-data[j1][j2][j3]);
    h2r = -c2*(data[i1][i2][ii31]+data[j1][j2][j31]);
    data[i1][i2][ii3] = h1r+wrh2r-wih2i;
    data[i1][i2][ii3+1] = h1iwrh2iwih2r;
    data[j1][j2][j3] = h1r-wrh2r+wih2i;
    data[j1][j2][j3+1] = -h1iwrh2iwih2r;
    // Do the recurrence.
    wr = (wtemp=wr)wpr-wiwpi+wr;
    wi = wiwprwtempwpiwi;
    // Case of reverse transform.
    if (isign == -1)
    fourn(&data[1][1][1]-1,nn,3,isign);
    // Function to perform Gaussian blur.
    void gaussianblur(void)
    float **blur,***conv,***pop,**speqblur,**speqconv,*speqpop;
    int i,j,p,q;
    blur = d3tensor(1,1,1,lx,1,ly);
    conv = d3tensor(1,1,1,lx,1,ly);
    pop = d3tensor(1,1,1,lx,1,ly);
    speqblur = dmatrix(1,1,1,2*lx);
    speqconv = dmatrix(1,1,1,2*lx);
    speqpop = dmatrix(1,1,1,2*lx);
    // Fill population and convolution matrix.
    for (i=1; i<=lx; i++) for (j=1; j<=ly; j++)
    if (i > lx/2) p = i-1-lx;
    else p = i-1;
    if (j > ly/2) q = j-1-ly;
    else q = j-1;
    pop[1][j] = rho_0[i-1][j-1];
    conv[1][j] = 0.5*
    (erf((p+0.5)/(sqrt(2.0)(SIGMApow(SIGMAFAC,nblurs))))-
    erf((p-0.5)/(sqrt(2.0)(SIGMA*pow(SIGMAFAC,nblurs)))))
    (erf((q+0.5)/(sqrt(2.0)(SIGMApow(SIGMAFAC,nblurs))))-
    erf((q-0.5)/(sqrt(2.0)(SIGMA*pow(SIGMAFAC,nblurs)))))/(lxly);
    // Fourier transform.
    rlft3(pop,speqpop,1,lx,ly,1);
    rlft3(conv,speqconv,1,lx,ly,1);
    // Multiply pointwise.
    for (i=1; i<=lx; i++)
    for (j=1; j<=ly/2; j++)
    blur[1][2*j-1] =
    pop[1][2j-1]*conv[1][2j-1]-
    pop[1][2j]*conv[1][2j];
    blur[1][2*j] =
    pop[1][2j]*conv[1][2j-1]+
    pop[1][2j-1]*conv[1][2j];
    for (i=1; i<=lx; i++)
    speqblur[1][2*i-1] =
    speqpop[1][2i-1]*speqconv[1][2i-1]-
    speqpop[1][2i]*speqconv[1][2i];
    speqblur[1][2*i] =
    speqpop[1][2i]*speqconv[1][2i-1]+
    speqpop[1][2i-1]*speqconv[1][2i];
    // Backtransform.
    rlft3(blur,speqblur,1,lx,ly,-1);
    // Write to rho_0.
    for (i=1; i<=lx; i++) for (j=1; j<=ly; j++) rho_0[i-1][j-1] = blur[1][j];
    free_f3tensor(blur,1,1,1,lx,1,ly);
    free_f3tensor(conv,1,1,1,lx,1,ly);
    free_f3tensor(pop,1,1,1,lx,1,ly);
    free_matrix(speqblur,1,1,1,2*lx);
    free_matrix(speqconv,1,1,1,2*lx);
    free_matrix(speqpop,1,1,1,2*lx);
    // Function to initialize rho_0. The original density is blurred with width
    // SIGMA*pow(SIGMAFAC,nblurs).
    void initcond(void)
    float maxpop;
    int i,j;
    // Reconstruct population density.
    coscosft(rho_0,-1,-1);
    // There must not be negative densities.
    for (i=0; i<lx; i++) for (j=0; j<ly; j++) if (rho_0[j]<-1e10)
    fprintf(stderr,"ERROR: Negative density in DENSITYFILE.\n");
    exit(1);
    // Perform Gaussian blur.
    printf("Gaussian blur ...\n");
    gaussianblur();
    // Find the mimimum density. If it is very small suggest an increase in
    // SIGMA.
    minpop = rho_0[0][0];
    maxpop = rho_0[0][0];
    for (i=0; i<lx; i++) for (j=0; j<ly; j++) if (rho_0[j]<minpop)
    minpop = rho_0[j];
    for (i=0; i<lx; i++) for (j=0; j<ly; j++) if (rho_0[j]>maxpop)
    maxpop = rho_0[j];
    if (0<minpop && minpop<1e-8*maxpop)
    fprintf(stderr,"Minimimum population very small (%f). Integrator\n",
    minpop);
    fprintf(stderr,
    "will probably converge very slowly. You can speed up the\n");
    fprintf(stderr,"process by increasing SIGMA to a value > %f.\n",
    SIGMA*pow(SIGMAFAC,nblurs));
    // Replace rho_0 by cosine Fourier transform in both variables.
    coscosft(rho_0,1,1);
    // Function to calculate the velocity field
    void calcv(float t)
    int j,k;
    // Fill rho with Fourier coefficients.
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    rho[j][k] = exp(-((PIj/lx)*(PI*j/lx)+(PI*k/ly)*(PI*k/ly))*t)rho_0[j][k];
    // Calculate the Fourier coefficients for the partial derivative of rho.
    // Store temporary results in arrays gridvx, gridvy.
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    gridvx[j][k] = -(PIj/lx)rho[j][k];
    gridvy[j][k] = -(PIk/ly)rho[j][k];
    // Replace rho by cosine Fourier backtransform in both variables.
    coscosft(rho,-1,-1);
    // Replace vx by sine Fourier backtransform in the first and cosine Fourier
    // backtransform in the second variable.
    sincosft(gridvx,-1,-1);
    // Replace vy by cosine Fourier backtransform in the first and sine Fourier
    // backtransform in the second variable.
    cossinft(gridvy,-1,-1);
    // Calculate the velocity field.
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    gridvx[j][k] = -gridvx[j][k]/rho[j][k];
    gridvy[j][k] = -gridvy[j][k]/rho[j][k];
    // Function to bilinearly interpolate a two-dimensional array. For higher
    // accuracy one could consider higher order interpolation schemes.
    float intpol(float **arr,float x,float y)
    int gaussx,gaussy;
    float deltax,deltay;
    // Decompose x and y into an integer part and a decimal.
    gaussx = (int)x;
    gaussy = (int)y;
    deltax = x-gaussx;
    deltay = y-gaussy;
    // Interpolate.
    if (gaussx==lx && gaussy==ly)
    return arr[gaussx][gaussy];
    if (gaussx==lx)
    return (1-deltay)arr[gaussx][gaussy]deltayarr[gaussx][gaussy1];
    if (gaussy==ly)
    return (1-deltax)arr[gaussx][gaussy]deltaxarr[gaussx1][gaussy];
    return (1-deltax)(1-deltay)arr[gaussx][gaussy]+
    (1-deltax)deltayarr[gaussx][gaussy1]
    deltax(1-deltay)arr[gaussx1][gaussy]
    deltaxdeltayarr[gaussx1][gaussy1];
    // Function to find the root of the system of equations
    // xappr-0.5h*v_x(t+h,xappr,yappr)-x[j][k]-0.5*hvx[j][k]=0,
    // yappr-0.5h*v_y(t+h,xappr,yappr)-y[j][k]-0.5*hvy[j][k]=0
    // with Newton-Raphson. Returns TRUE after sufficient convergence.
    BOOLEAN newt2(float h,float *xappr,float xguess,float *yappr,float yguess,
    int j,int k)
    float deltax,deltay,dfxdx,dfxdy,dfydx,dfydy,fx,fy;
    int gaussx,gaussxplus,gaussy,gaussyplus,i;
    // Initial guess.
    *xappr = xguess;
    *yappr = yguess;
    for (i=1; i<=IMAX; i++)
    // fx, fy are the left-hand sides of the two equations. Find
    // v_x(t+h,xappr,yappr), v_y(t+h,xappr,yappr) by interpolation.
    fx = xappr-0.5*h*intpol(gridvx,*xappr,*yappr)-x[j][k]-0.5*hvx[j][k];
    fy = yappr-0.5*h*intpol(gridvy,*xappr,*yappr)-y[j][k]-0.5*hvy[j][k];
    // Linearly approximate the partial derivatives of fx, fy with a finite
    // difference method. More elaborate techniques are possible, but this
    // quick and dirty method appears to work reasonably for our purpose.
    gaussx = (int)(*xappr);
    gaussy = (int)(*yappr);
    if (gaussx == lx) gaussxplus = 0;
    else gaussxplus = gaussx+1;
    if (gaussy == ly) gaussyplus = 0;
    else gaussyplus = gaussy+1;
    deltax = x[j][k] - gaussx;
    deltay = y[j][k] - gaussy;
    dfxdx = 1 - 0.5h
    ((1-deltay)*(gridvx[gaussxplus][gaussy]-gridvx[gaussx][gaussy])+
    deltay*(gridvx[gaussxplus][gaussyplus]-gridvx[gaussx][gaussyplus]));
    dfxdy = -0.5h
    ((1-deltax)*(gridvx[gaussx][gaussyplus]-gridvx[gaussx][gaussy])+
    deltax*(gridvx[gaussxplus][gaussyplus]-gridvx[gaussxplus][gaussy]));
    dfydx = -0.5h
    ((1-deltay)*(gridvy[gaussxplus][gaussy]-gridvy[gaussx][gaussy])+
    deltay*(gridvy[gaussxplus][gaussyplus]-gridvy[gaussx][gaussyplus]));
    dfydy = 1 - 0.5h
    ((1-deltax)*(gridvy[gaussx][gaussyplus]-gridvy[gaussx][gaussy])+
    deltax*(gridvy[gaussxplus][gaussyplus]-gridvy[gaussxplus][gaussy]));
    // If the current approximation is (xappr,yappr) for the zero of
    // (fx(x,y),fy(x,y)) and J is the Jacobian, then we can approximate (in
    // vector notation) for |delta|<<1:
    // f((xappr,yappr)+delta) = f(xappr,yappr)+J*delta.
    // Setting f((xappr,yappr)+delta)=0 we obtain a set of linear equations
    // for the correction delta which moves f closer to zero, namely
    // J*delta = -f.
    // The improved approximation is then x = xappr+delta.
    // The process will be iterated until convergence is reached.
    if ((fx*fx + fy*fy) < TOLF) return TRUE;
    deltax = (fy*dfxdy - fxdfydy)/(dfxdxdfydy - dfxdy*dfydx);
    deltay = (fx*dfydx - fydfxdx)/(dfxdxdfydy - dfxdy*dfydx);
    if ((deltax*deltax + deltay*deltay) < TOLX) return TRUE;
    *xappr += deltax;
    *yappr += deltay;
    //printf("deltax %f, deltay %f\n",deltax,deltay);
    fprintf(stderr,"newt2 failed, increasing sigma to %f.\n",
    SIGMA*pow(SIGMAFAC,nblurs));
    return FALSE;
    // Function to integrate the nonlinear Volterra equation. Returns TRUE after
    // the displacement field converged, after MAXINTSTEPS integration steps, or
    // if the time exceeds TIMELIMIT.
    BOOLEAN nonlinvoltra(void)
    BOOLEAN stepsize_ok;
    #ifdef DISPLFILE
    FILE *displfile = fopen(DISPLFILE);
    #endif
    float h,maxchange=INFTY,t,vxplus,vyplus,xguess,yguess;
    int i,j,k;
    do
    initcond();
    nblurs++;
    if (minpop<0.0)
    fprintf(stderr,
    "Minimum population negative, will increase sigma to %f\n",
    SIGMA*pow(SIGMAFAC,nblurs));
    while (minpop<0.0);
    h = HINITIAL;
    t = 0; // Start at time t=0.
    // (x[j][k],y[j][k]) is the position for the element that was at position
    // (j,k) at time t=0.
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    x[j][k] = j;
    y[j][k] = k;
    calcv(0.0);
    // (gridvx[j][k],gridvy[j][k]) is the velocity at position (j,k).
    // (vx[j][k],vy[j][k]) is the velocity at position (x[j][k],y[j][k]).
    // At t=0 they are of course identical.
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    vx[j][k] = gridvx[j][k];
    vy[j][k] = gridvy[j][k];
    i = 1; // i counts the integration steps.
    // Here is the integrator.
    do
    stepsize_ok = TRUE;
    calcv(t+h);
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    // First take a naive integration step. The velocity at time t+h for
    // the element [j][k] is approximately
    // v(th,x[j][k]+hvx[j][k],y[j][k]hvy[j][k]).
    // The components, call them vxplus and vyplus, are interpolated from
    // gridvx and gridvy.
    vxplus = intpol(gridvx,x[j][k]hvx[j][k],y[j][k]hvy[j][k]);
    vyplus = intpol(gridvy,x[j][k]hvx[j][k],y[j][k]hvy[j][k]);
    // Based on (vx[j][k],vy[j][k]) and (vxplus,vyplus) we expect the
    // new position at time t+h to be:
    xguess = x[j][k] + 0.5h(vx[j][k]+vxplus);
    yguess = y[j][k] + 0.5h(vy[j][k]+vyplus);
    // Then we make a better approximation by solving the two nonlinear
    // equations:
    // xappr[j][k]-0.5hv_x(t+h,xappr[j][k],yappr[j][k])-
    // x[j][k]-0.5hvx[j][k]=0,
    // yappr[j][k]-0.5hv_y(t+h,xappr[j][k],yappr[j][k])-
    // y[j][k]-0.5hvy[j][k]=0
    // with Newton-Raphson and (xguess,yguess) as initial guess.
    // If newt2 fails to converge, exit nonlinvoltra.
    if (!newt2(h,&xappr[j][k],xguess,&yappr[j][k],yguess,j,k))
    return FALSE;
    // If the integration step was too large reduce the step size.
    if ((xguess-xappr[j][k])*(xguess-xappr[j][k])+
    (yguess-yappr[j][k])*(yguess-yappr[j][k]) > TOLINT)
    if (h<MINH)
    fprintf(stderr,
    "Time step below %f, increasing SIGMA to %f\n",
    h,SIGMA*pow(SIGMAFAC,nblurs));
    nblurs++;
    return FALSE;
    h /= 10;
    stepsize_ok = FALSE;
    break;
    if (!stepsize_ok) continue;
    else
    t += h;
    maxchange = 0.0; // Monitor the maximum change in positions.
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    if ((x[j][k]-xappr[j][k])*(x[j][k]-xappr[j][k])+
    (y[j][k]-yappr[j][k])*(y[j][k]-yappr[j][k]) > maxchange)
    maxchange =
    (x[j][k]-xappr[j][k])*(x[j][k]-xappr[j][k])+
    (y[j][k]-yappr[j][k])*(y[j][k]-yappr[j][k]);
    x[j][k] = xappr[j][k];
    y[j][k] = yappr[j][k];
    vx[j][k] = intpol(gridvx,xappr[j][k],yappr[j][k]);
    vy[j][k] = intpol(gridvy,xappr[j][k],yappr[j][k]);
    h *= 1.2; // Make the next integration step larger.
    if (i%10==0) printf("time %f\n",t);
    i++;
    } while (i<MAXINTSTEPS && t<TIMELIMIT && maxchange>CONVERGENCE);
    if (maxchange>CONVERGENCE)
    fprintf(stderr,
    "WARNING: Insufficient convergence within %i steps, time %f.\n",
    MAXINTSTEPS,TIMELIMIT);
    #ifdef DISPLFILE
    // Write displacement field to file.
    fprintf(displfile,"time %f\nminx %f\nmaxx %f\nminy %f\nmaxy %f\n",
    t,minx,maxx,miny,maxy);
    fprintf(displfile,"sigma %f\n",SIGMA*pow(SIGMAFAC,nblurs-1));
    fprintf(displfile,"background %f\nlx\nly\n\n",0,lx,ly);
    for (j=0; j<=lx; j++) for (k=0; k<=ly; k++)
    fprintf(displfile,"j %i, k %i, x %f, y %f\n",j,k,x[j][k],y[j][k]);
    fclose(displfile);
    #endif
    return TRUE;
    // Function to transform points according to displacement field.
    POINT transf(POINT p)
    float deltax,deltay,den,t,u;
    int gaussx,gaussy;
    POINT a,b,c,d,ptr;
    p.x = (p.x-minx)*lx/(maxx-minx);
    p.y = (p.y-miny)*ly/(maxy-miny);
    gaussx = (int)p.x;
    gaussy = (int)p.y;
    if (gaussx<0 || gaussx>lx || gaussy<0 || gaussy>ly)
    fprintf(stderr,"ERROR: Coordinate limits exceeded in transf.\n");
    exit(1);
    deltax = p.x - gaussx;
    deltay = p.y - gaussy;
    // The transformed point is the intersection of the lines:
    // (I) connecting
    // (1-deltax)(x,y[gaussx][gaussy])deltax(x,y[gaussx1][gaussy])
    // and
    // (1-deltax)(x,y[gaussx][gaussy1])+deltax(x,y[gaussx+1][gaussy1])
    // (II) connecting
    // (1-deltay)(x,y[gaussx][gaussy])deltay(x,y[gaussx][gaussy1])
    // and
    // (1-deltay)(x,y[gaussx1][gaussy])+deltay(x,y[gaussx+1][gaussy1]).
    // Call these four points a, b, c and d.
    a.x = (1-deltax)*x[gaussx][gaussy] + deltax*x[gaussx+1][gaussy];
    a.y = (1-deltax)*y[gaussx][gaussy] + deltax*y[gaussx+1][gaussy];
    b.x = (1-deltax)*x[gaussx][gaussy+1] + deltax*x[gaussx1][gaussy1];
    b.y = (1-deltax)*y[gaussx][gaussy+1] + deltax*y[gaussx1][gaussy1];
    c.x = (1-deltay)*x[gaussx][gaussy] + deltay*x[gaussx][gaussy+1];
    c.y = (1-deltay)*y[gaussx][gaussy] + deltay*y[gaussx][gaussy+1];
    d.x = (1-deltay)*x[gaussx+1][gaussy] + deltay*x[gaussx1][gaussy1];
    d.y = (1-deltay)*y[gaussx+1][gaussy] + deltay*y[gaussx1][gaussy1];
    // Solve the vector equation a+t(b-a) = c+u(d-c) for the scalars t, u.
    if (fabs(den=(b.x-a.x)(c.y-d.y)+(a.y-b.y)(c.x-d.x))<1e-12)
    fprintf(stderr,"ERROR: Transformed area element has parallel edges.\n");
    exit(1);
    t = ((c.x-a.x)(c.y-d.y)+(a.y-c.y)(c.x-d.x))/den;
    u = ((b.x-a.x)(c.y-a.y)+(a.y-b.y)(c.x-a.x))/den;
    if (t<-1e-3|| t>1+1e-3 || u<-1e-3 || u>1+1e-3)
    fprintf(stderr,"WARNING: Transformed area element non-convex.\n");
    ptr.x = (1-(a.x+t(b.x-a.x))/lx)minx + ((a.x+t(b.x-a.x))/lx)maxx;
    ptr.y = (1-(a.y+t(b.y-a.y))/ly)miny + ((a.y+t(b.y-a.y))/ly)maxy;
    return ptr;
    // Function to read spatial features from user-specified file and map to
    // cartogram.
    void cartogram(void)
    char id[LINELENGTH],line[LINELENGTH];
    FILE infile,outfile;
    float xcoord,ycoord;
    POINT p;
    infile = fopen(MAPGENFILE);
    outfile = fopen(CARTGENFILE,"w");
    while (!readline(line,infile))
    if (sscanf(line,"%s %f %f",&id,&xcoord,&ycoord)==3)
    p.x = xcoord;
    p.y = ycoord;
    p = transf(p);
    fprintf(outfile,"%s %f %f\n",id,p.x,p.y);
    else if (sscanf(line,"%f %f",&xcoord,&ycoord)==2)
    p.x = xcoord;
    p.y = ycoord;
    p = transf(p);
    fprintf(outfile,"%f %f\n",p.x,p.y);
    else
    sscanf(line,"%s",&id);
    fprintf(outfile,"%s\n",id);
    fclose(infile);
    fclose(outfile);
    main(void)
    BOOLEAN n;
    char c;
    FILE genfile,psfile = fopen(MAP2PS);
    float oldlx,oldly,oldmaxx,oldmaxy,oldminx,oldminy,totarea;
    int i,polyctr,regctr;
    // Read the polygon coordinates.
    if ((genfile = fopen(MAPGENFILE)) == NULL)
    fprintf(stderr,"ERROR: Cannot find MAPGENFILE\n");
    exit(1);
    countpoly(genfile);
    fclose(genfile);
    genfile = fopen(MAPGENFILE);
    countcorn(genfile);
    fclose(genfile);
    genfile = fopen(MAPGENFILE);
    readcorn(genfile);
    fclose(genfile);
    makeregion();
    printf("%i polygon(s), %i region(s)\n",npoly,nregion);
    printf("lx=%i, ly=%i\n",lx,ly);
    // Calculate total area.
    //totarea = 0.0;
    //for (regctr=0; regctr<nregion; regctr++)
    // printf("region %i has area %f, contains %i polygons\n",regionid[regctr],
    // regionarea(nregcorn[regctr],regcorn[regctr]),npolyinreg[regctr]);
    // totarea += regionarea(nregcorn[regctr],regcorn[regctr]);
    //printf("totarea = %f\n",totarea);
    // Make map.
    pspicture(psfile);
    fclose(psfile);
    // Allocate memory for arrays.
    gridvx = (float*)malloc((lx+1)*sizeof(float));
    gridvy = (float*)malloc((lx+1)*sizeof(float));
    rho = (float*)malloc((lx+1)*sizeof(float));
    rho_0 = (float*)malloc((lx+1)*sizeof(float));
    vx = (float*)malloc((lx+1)*sizeof(float));
    vy = (float*)malloc((lx+1)*sizeof(float));
    x = (float*)malloc((lx+1)*sizeof(float));
    xappr = (float*)malloc((lx+1)*sizeof(float));
    y = (float*)malloc((lx+1)*sizeof(float));
    yappr = (float*)malloc((lx+1)*sizeof(float));
    within = (int*)malloc((lx+1)*sizeof(int));
    for (i=0; i<=lx; i++)
    gridvx = (float)malloc((ly+1)sizeof(float));
    gridvy = (float)malloc((ly+1)sizeof(float));
    rho = (float)malloc((ly+1)sizeof(float));
    rho_0 = (float)malloc((ly+1)sizeof(float));
    vx = (float)malloc((ly+1)sizeof(float));
    vy = (float)malloc((ly+1)sizeof(float));
    x = (float)malloc((ly+1)sizeof(float));
    xappr = (float)malloc((ly+1)sizeof(float));
    y = (float)malloc((ly+1)sizeof(float));
    yappr = (float)malloc((ly+1)sizeof(float));
    within = (int)malloc((ly+1)sizeof(int));
    // Digitize the density.
    bboxes();
    interior();
    digdens();
    // Solve the diffusion equation.
    do n = nonlinvoltra(); while (!n);
    // Print cartogram generate file.
    cartogram();
    // Read the transformed polygon coordinates.
    oldlx = lx;
    oldly = ly;
    oldmaxx = maxx;
    oldmaxy = maxy;
    oldminx = minx;
    oldminy = miny;
    genfile = fopen(CARTGENFILE,"r");
    countpoly(genfile);
    fclose(genfile);
    genfile = fopen(CARTGENFILE,"r");
    countcorn(genfile);
    fclose(genfile);
    lx = oldlx;
    ly = oldly;
    maxx = oldmaxx;
    maxy = oldmaxy;
    minx = oldminx;
    miny = oldminy;
    genfile = fopen(CARTGENFILE,"r");
    readcorn(genfile);
    fclose(genfile);
    makeregion();
    // Make cartogram
    psfile = fopen(CART2PS);
    pspicture(psfile);
    fclose(psfile);
    The part of the code where the bus error occurs is this:
    void interior(void)
    int i,inhowmanyregions,inregion[2],j,k,l,m,n,regctr;
    // Initialize within[][]. -1 means outside all regions.
    for (i=0; i<=lx; i++) for (j=0; j<=ly; j++) within[j] = -1;
    // Fill within[][].
    for (i=0; i<nregion; i++) for (j=0; j<npolyinreg; j++)
    for (k=0, n=npolycorn[polyinreg[j]]-1;
    k<npolycorn[polyinreg[j]]; n=k++)
    for (l=(int)ceil(MIN(polycorn[polyinreg[j]][k-1].y,
    polycorn[polyinreg[j]][k].y));
    l<MAX(polycorn[polyinreg[j]][k-1].y,
    polycorn[polyinreg[j]][k].y); l++)
    for (m=(int)floor(bbminx[polyinreg[j]]);
    m<(polycorn[polyinreg[j]][n].x-
    polycorn[polyinreg[j]][k].x)*
    (l-polycorn[polyinreg[j]][k].y)/
    (polycorn[polyinreg[j]][n].y-
    polycorn[polyinreg[j]][k].y)+
    polycorn[polyinreg[j]][k].x;
    m++)
    within[m][l] = i-within[m][l]-1;
    I really have no idea what is going on. Can anyone help?
    Thanks,
    mooseguy

    orangekay wrote:
    That is absolutely unreadable.
    I agree completely. How about also providing a link to a set of input files so that we could actually run the code ourselves? Otherwise, there is no chance to debug the source code, it is just a mess.
    You might have better luck with an older version of the file. To quote the comments:
    // Modified on March 31, 2005. Initialized maxchange in nonlinvoltra() as
    // INFTY. Replaced crnmbr() by a similar, but faster routine interior().
    // Many thanks to Stuart Anderson for pointing out this shortcut.
    I suspect that the "interior" function is just plain incorrect. It doesn't matter if it runs on some other OS. Something about it is wrong and the code is so cryptic that it can't be deciphered.

  • CTD bug in simple video streaming applet.

    I'm trying to write a simple applet to use JMF to allow an end-user to view a video stream that's being served up by VLC. It doesn't have to look immensely pretty (in fact, streamlined is what I want most). I swiped some code from the jicyshout project (http://jicyshout.sourceforge.net) which handles streaming MP3s, and borrowed a framework for an applet from one of Sun's example applets for the JMF.
    Here's my code so far:
    ** begin file SimpleVideoDataSource.java **
    import java.lang.String;
    import java.net.*;
    import java.io.*;
    import java.util.Properties;
    import javax.media.*;
    import javax.media.protocol.*;
    /* The SeekableStream and DataSource tweaks are based on the code from
    * jicyshout (jicyshout.sourcefourge.net), which was written by Chris Adamson.
    * The code was simplified (no need for mp3 metadata here), cleaned up, then
    * extended for our puposes.
    * This is a DataSource using a SeekableStream suitable for
    * streaming video using the default parser supplied by JMF.
    public class SimpleVideoDataSource extends PullDataSource {
    protected MediaLocator myML;
    protected SeekableInputStream[] seekStreams;
    protected URLConnection urlConnection;
    // Constructor (trivial).
    public SimpleVideoDataSource (MediaLocator ml) throws MalformedURLException {
    super ();
    myML = ml;
    URL url = ml.getURL();
    public void connect () throws IOException {
    try {
    URL url = myML.getURL();
    urlConnection = url.openConnection();
    // Make the stream seekable, so that the JMF parser can try to parse it (instead
    // of throwing up).
    InputStream videoStream = urlConnection.getInputStream();
    seekStreams = new SeekableInputStream[1];
    seekStreams[0] = new SeekableInputStream(videoStream);
    } catch (MalformedURLException murle) {
    throw new IOException ("Malformed URL: " + murle.getMessage());
    } catch (ArrayIndexOutOfBoundsException aioobe) {
    fatalError("Array Index OOB: " + aioobe);
    // Closes up InputStream.
    public void disconnect () {
    try {
    seekStreams[0].close();
    } catch (IOException ioe) {
    System.out.println ("Can't close stream. Ew?");
    ioe.printStackTrace();
    // Returns just what it says.
    public String getContentType () {
    return "video.mpeg";
    // Does nothing, since this is a stream pulled from PullSourceStream.
    public void start () {
    // Ditto.
    public void stop () {
    // Returns a one-member array with the SeekableInputStream.
    public PullSourceStream[] getStreams () {
    try {
    // **** This seems to be the problem. ****
    if (seekStreams != null) {
    return seekStreams;
    } else {
    fatalError("sourceStreams was null! Bad kitty!");
    return seekStreams;
    } catch (Exception e) {
    fatalError("Error in getStreams(): " + e);
    return seekStreams;
    // Duration abstract stuff. Since this is a theoretically endless stream...
    public Time getDuration () {
    return DataSource.DURATION_UNBOUNDED;
    // Controls abstract stuff. No controls supported here!
    public Object getControl (String controlName) {
    return null;
    public Object[] getControls () {
    return null;
    void fatalError (String deathKnell) {
    System.err.println(":[ Fatal Error ]: - " + deathKnell);
    throw new Error(deathKnell);
    ** end file SimpleVideoDataSource.java **
    ** begin file SeekableInputStream.java **
    import java.lang.String;
    import java.net.*;
    import java.io.*;
    import java.util.Properties;
    import javax.media.*;
    import javax.media.protocol.*;
    /* The SeekableStream and DataSource tweaks are based on the code from
    * jicyshout (jicyshout.sourcefourge.net), which was written by Chris Adamson.
    * The code was simplified (no need for mp3 metadata here), cleaned up, then
    * extended for our puposes.
    /* This is an implementation of a SeekableStream which extends a
    * BufferedInputStream to basically fake JMF into thinking that
    * the stream is seekable, when in fact it's not. Basically, this
    * will keep JMF from puking over something it expects but can't
    * actually get.
    public class SeekableInputStream extends BufferedInputStream implements PullSourceStream, Seekable {
    protected int tellPoint;
    public final static int MAX_MARK = 131072; // Give JMF 128k of data to "play" with.
    protected ContentDescriptor unknownCD;
    // Constructor. Effectively trivial.
    public SeekableInputStream (InputStream in) {
    super (in, MAX_MARK);
    tellPoint = 0;
    mark (MAX_MARK);
    unknownCD = new ContentDescriptor ("unknown");
    // Specified size constructor.
    public SeekableInputStream (InputStream in, int size) {
    super (in, Math.max(size, MAX_MARK));
    tellPoint = 0;
    mark(Math.max(size, MAX_MARK));
    unknownCD = new ContentDescriptor ("unknown");
    // Reads a byte and increments tellPoint.
    public int read () throws IOException {
    int readByte = super.read();
    tellPoint++;
    return readByte;
    // Reads bytes (specified by PullSourceStream).
    public int read (byte[] buf, int off, int len) throws IOException {
    int bytesRead = super.read (buf, off, len);
    tellPoint += bytesRead;
    return bytesRead;
    public int read (byte[] buf) throws IOException {
    int bytesRead = super.read (buf);
    tellPoint += bytesRead;
    return bytesRead;
    // Returns true if in.available() <= 0 (that is, if there are no bytes to
    // read without blocking or end-of-stream).
    public boolean willReadBlock () {
    try {
    return (in.available() <= 0);
    } catch (IOException ioe) {
    // Stick a fork in it...
    return true;
    // Resets the tellPoint to 0 (meaningless after you've read one buffer length).
    public void reset () throws IOException {
    super.reset();
    tellPoint = 0;
    // Skips bytes as expected.
    public long skip (long n) throws IOException {
    long skipped = super.skip(n);
    tellPoint += skipped;
    return skipped;
    // Trivial.
    public void mark (int readLimit) {
    super.mark (readLimit);
    // Returns the "unknown" ContentDescriptor.
    public ContentDescriptor getContentDescriptor () {
    return unknownCD;
    // Lengths? We don't need no stinkin' lengths!
    public long getContentLength () {
    return SourceStream.LENGTH_UNKNOWN;
    // Theoretically, this is always false.
    public boolean endOfStream () {
    return false;
    // We don't provide any controls, either.
    public Object getControl (String controlName) {
    return null;
    public Object[] getControls () {
    return null;
    // Not really... but...
    public boolean isRandomAccess () {
    return true;
    // This only works for the first bits of the stream, while JMF is attempting
    // to figure out what the stream is. If it tries to seek after that, bad
    // things are going to happen (invalid-mark exception).
    public long seek (long where) {
    try {
    reset();
    mark(MAX_MARK);
    skip(where);
    } catch (IOException ioe) {
    ioe.printStackTrace();
    return tell();
    // Tells where in the stream we are, adjusted for seeks, resets, skips, etc.
    public long tell () {
    return tellPoint;
    void fatalError (String deathKnell) {
    System.err.println(":[ Fatal Error ]: - " + deathKnell);
    throw new Error(deathKnell);
    ** end file SeekableInputStream.java **
    ** begin file StreamingViewerApplet.java **
    * This Java Applet will take a streaming video passed to it via the applet
    * command in the embedded object and attempt to play it. No fuss, no muss.
    * Based on the SimplePlayerApplet from Sun, and uses a modified version of
    * jicyshout's (jicyshout.sourceforge.net) tweaks to get JMF to play streams.
    * Use it like this:
    * <!-- Sample HTML
    * <APPLET CODE="StreamingViewerApplet.class" WIDTH="320" HEIGHT="240">
    * <PARAM NAME="code" VALUE="StreamingViewerApplet.class">
    * <PARAM NAME="type" VALUE="application/x-java-applet;version=1.1">
    * <PARAM NAME="streamwidth" VALUE="width (defaults to 320, but will resize as per video size)">
    * <PARAM NAME="streamheight" VALUE="height (defaults to 240, but will resize as per video size)">
    * <PARAM NAME="stream" VALUE="insert://your.stream.address.and:port/here/">
    * </APPLET>
    * -->
    import java.applet.Applet;
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.String;
    import java.lang.ArrayIndexOutOfBoundsException;
    import java.net.URL;
    import java.net.MalformedURLException;
    import java.net.*;
    import java.io.*;
    import java.io.IOException;
    import java.util.Properties;
    import javax.media.*;
    import javax.media.protocol.*;
    public class StreamingViewerApplet extends Applet implements ControllerListener {
    Player player = null;
    Component visualComponent = null;
    SimpleVideoDataSource dataSource;
    URL url;
    MediaLocator ml;
    Panel panel = null;
    int width = 0;
    static int DEFAULT_VIDEO_WIDTH = 320;
    int height = 0;
    static int DEFAULT_VIDEO_HEIGHT = 240;
    String readParameter = null;
    // Initialize applet, read parameters, create media player.
    public void init () {
    try {
    setLayout(null);
    setBackground(Color.white);
    panel = new Panel();
    panel.setLayout(null);
    add(panel);
    // Attempt to read width from applet parameters. If not given, use default.
    if ((readParameter = getParameter("streamwidth")) == null) {
    width = DEFAULT_VIDEO_WIDTH;
    } else {
    width = Integer.parseInt(readParameter);
    // Ditto for height.
    if ((readParameter = getParameter("streamheight")) == null) {
    height = DEFAULT_VIDEO_HEIGHT;
    } else {
    height = Integer.parseInt(readParameter);
    panel.setBounds(0, 0, width, height);
    // Unfortunately, this we can't default.
    if ((readParameter = getParameter("stream")) == null) {
    fatalError("You must provide a stream parameter!");
    try {
    url = new URL(readParameter);
    ml = new MediaLocator(url);
    dataSource = new SimpleVideoDataSource(ml);
    } catch (MalformedURLException murle) {
    fatalError("Malformed URL Exception: " + murle);
    try {
    dataSource.connect();
    player = Manager.createPlayer(dataSource);
    } catch (IOException ioe) {
    fatalError("IO Exception: " + ioe);
    } catch (NoPlayerException npe) {
    fatalError("No Player Exception: " + npe);
    if (player != null) {
    player.addControllerListener(this);
    } else {
    fatalError("Failed to init() player!");
    } catch (Exception e) {
    fatalError("Error opening player. Details: " + e);
    // Start stream playback. This function is called the
    // first time that the applet runs, and every time the user
    // re-enters the page.
    public void start () {
    try {
    if (player != null) {
    player.realize();
    while (player.getState() != Controller.Realized) {
    Thread.sleep(100);
    // Crashes... here?
    player.start();
    } catch (Exception e) {
    fatalError("Exception thrown: " + e);
    public void stop () {
    if (player != null) {
    player.stop();
    player.deallocate();
    } else {
    fatalError("stop() called on a null player!");
    public void destroy () {
    // player.close();
    // This controllerUpdate function is defined to implement a ControllerListener
    // interface. It will be called whenever there is a media event.
    public synchronized void controllerUpdate(ControllerEvent event) {
    // If the player is dead, just leave.
    if (player == null)
    return;
    // When the player is Realized, get the visual component and add it to the Applet.
    if (event instanceof RealizeCompleteEvent) {
    if (visualComponent == null) {
    if ((visualComponent = player.getVisualComponent()) != null) {
    panel.add(visualComponent);
    Dimension videoSize = visualComponent.getPreferredSize();
    width = videoSize.width;
    height = videoSize.height;
    visualComponent.setBounds(0, 0, width, height);
    } else if (event instanceof CachingControlEvent) {
    // With streaming, this doesn't really matter much, does it?
    // Without, a progress bar of some sort would be appropriate.
    } else if (event instanceof EndOfMediaEvent) {
    // We should never see this... but...
    player.stop();
    fatalError("EndOfMediaEvent reached for streaming media. ewe ewe tea eff?");
    } else if (event instanceof ControllerErrorEvent) {
    player = null;
    fatalError(((ControllerErrorEvent)event).getMessage());
    } else if (event instanceof ControllerClosedEvent) {
    panel.removeAll();
    void fatalError (String deathKnell) {
    System.err.println(":[ Fatal Error ]: - " + deathKnell);
    throw new Error(deathKnell);
    ** end file StreamingViewerApplet.java **
    Now, I'm still new to the JMF, so this might be obvious to some of you... but it's exploding on me, and crashing to desktop (both in IE and Firefox) with some very fun errors:
    # An unexpected error has been detected by HotSpot Virtual Machine:
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x21217921, pid=3200, tid=3160
    # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode, sharing)
    # Problematic frame:
    # C 0x21217921
    --------------- T H R E A D ---------------
    Current thread (0x058f7280): JavaThread "JMF thread: com.sun.media.amovie.AMController@506411[ com.sun.media.amovie.AMController@506411 ] ( realizeThread)" [_thread_in_native, id=3160]
    siginfo: ExceptionCode=0xc0000005, writing address 0x034e6360
    (plenty more here, I can post the rest if necessary)
    The problem seems to be coming from the "return seekStreams" statement in the first file; when I have execution aborted before that (with a fatalError call), it doesn't crash.
    Any tips/hints/suggestions?

    You should write your own Applet, where you can easily get the visual component (getVisualComponent())and show it directly in your Applet (you call it "embedded"). As far as I know, all examples (AVReceive* etc.) use the component which opens a new window.
    Best regards from Germany,
    r.v.

  • Sending Strings Over GKSession - How to stop some craziness?

    Sounds simple, right? But the tricky part is I am trying to retain the header structure from GKTank... I am quite desperate for help at this point as I've been flailing around on this all day and all night....
    All my other events use this structure already and work just fine..and after a ton of trial and error I'm very close... hoping I can get one of you experts to take a look. The issue is that when my strings are less than 8 characters, the results get very strange....
    Here's the relevant code: (kMaxPacketSize is a constant of 1024)
    To send Data: (this is straight from GKTank, actually)
    - (void)sendNetworkPacket:(GKSession *)session packetID:(int)packetID withData:(void *)data ofLength:(int)length reliable:(BOOL)howtosend {
    static unsigned char networkPacket[kMaxPacketSize];
    const unsigned int packetHeaderSize = 2 * sizeof(int); // we have two "ints" for our header
    if(length < (kMaxPacketSize - packetHeaderSize)) { // our networkPacket buffer size minus the size of the header info
    int *pIntData = (int *)&networkPacket[0];
    // header info
    pIntData[0] = packetNumber++;
    pIntData[1] = packetID;
    // copy data in after the header
    memcpy( &networkPacket[packetHeaderSize], data, length );
    NSData *packet = [NSData dataWithBytes: networkPacket length: (length+8)];
    if(howtosend == YES) {
    [session sendDataToAllPeers:packet withDataMode:GKSendDataReliable error:nil];
    } else {
    [session sendDataToAllPeers:packet withDataMode:GKSendDataUnreliable error:nil];
    In this particular case, I began by calling the above method thusly:
    NSString *myText = self.myLabel.text
    NSInteger len = [myText length];
    [self sendNetworkPacket:mySession packetID:NETWORKTEXTEVENT withData:myText ofLength:(len*2)+1 reliable:YES];
    and unwrapping like this on the other end:
    NSString *pStringData = (NSString *)&incomingPacket[8];
    Works like a charm... strings show up just fine on the other device.... except when the string is less than 8 characters...this causes crashes of EXCBADACCESS on the receiving device. When I check values for these short strings prior to sending over GKSession, the memcpy command does not properly embed the string into 'networkPacket' and keeps remnants from the last string that was transmitted.
    So, in an attempt to work around what is probably a flaw in my logic, I decided to see what happens if I pad the beginning and end of these short strings to make them over 8 characters, by defining another string 'spacer' and then sending a padded string instead of myText:
    NSString *spacer = @"zZzZ";
    NSString *bufText = [spacer stringByAppendingString:[myText stringByAppendingString:spacer]];
    len = [bufText length];
    [self sendNetworkPacket:mySession packetID:NETWORKTEXTEVENT withData:bufText ofLength:(len*2)+1 reliable:YES];
    This got rid of the issues with memcpy, and now all strings are embedded in 'networkPacket' properly, some just have the spacers on the beginning and end... no problem, right? I figured I'd just filter out the spacers on the other end, but guess what? I have even tried using the same code to disassemble the packet, prior to sending it, exactly the way I do on the receiving device... it disassembles fine, and I can re-create the string from the raw packet I send....
    However... (and this ONLY happens on the strings that have been padded) when I receive the data through GKSession I get totally random characters and even lengths! Sometimes I get odd system strings like 'tpenable' or 'uni0164' ... it's so bizarre... I don't understand what is making the padded strings get treated differently.... I tried padding all strings just to check and then they all act like this when transmitted... and again when I use the following code, prior to sending the packet, both test1 and test2 look fine:
    NSString *test1 = (NSString *)&networkPacket[8];
    unsigned char *testPacket = (unsigned char *)[packet bytes];
    NSString *test2 = (NSString *)&testPacket[8];
    NSLog (@"netPacket");
    NSLog (test1);
    NSLog (@"Packet");
    NSLog (test2);
    If you have any ideas, I'd really appreciate it!
    Message was edited by: Tech Guru

    [dataString bytes] returns a +const void*+ type. The compiler is complaining because you passed that +const void*+ pointer to a method that declared the 3rd arg to be a void*. The difference between the two pointers is that the first type doesn't want you to change the bytes that it's pointing to, while the second type doesn't care.
    For example:
    - myMethod:(const char *)foo {
    foo[3] = 'A'; // changing the value of the 4th byte at address foo
    In the above, the compiler should warn that your method changed the data which was referenced by a const char* type.
    But sendNetworkPacket doesn't do anything naughty like the above, it just copies the data at the given addy into a buffer. So you could have declared the data param as const void* like this:
    - (void)sendNetworkPacket:(GKSession *)session packetID:(int)packetID withData:(const void *)data ofLength:(int)length reliable:(BOOL)howtosend;
    The above change should get rid of the warning. If the compiler thinks you're changing that data in sendNetworkPacket (we know you're not doing that, but it's hard to argue with a compiler), you'll then get a new warning to that effect. In that case you might as well put a type cast in the call. I.e. take 'const' back out of the method declaration, and cast the arg in the call like this:
    [self sendNetworkPacket:mySession packetID:NETWORKTEXTEVENT withData:(void*)[dataString bytes] ofLength:len reliable:YES];
    The first try is preferable, since we like to avoid type casts, and since (I assume) sendNetworkPacket really doesn't want to change that data. But if the compiler won't cooperate, the second way will always work for you.
    Btw, putting the text into a NSData object is fine by me, but you could've also used any number of NSString methods that aren't deprecated (e.g. [myText UTF8String]). No need to go there now though. I'm guessing your early problems with some perfectly good methods were due to data type glitches. Because of mismatched data types, you may have abandoned the correct approach and gone down the wrong path.
    Once things got to the point where a NSString pointer was sent to memcpy, I think all of us were at risk of falling into darkness. I stared at the code for a very long time, wondering if everyone in the World but me knew that trick. Next time you get a data type error, maybe post the code here and let us try and help out while the problem is still easy to solve, ok?
    All the best,
    Ray

  • Throw Error in Module Adapter EJB

    Hi experts,
    In order to make some validations when getting file in File Adapter, was developed a EJB Module Adapter. When the validation failed, it must to be generate a throw error with a text that appears in Runtime workbench.
    throw new ModuleException("Error al crear objeto Archivo para procesar el legacy: "+legacy);
    But, it doens't happen. In Runtime workbench I just can see a Exception null . 
    Follow Below the Java Code of Module EJB:
    package clasesSox;
    import java.io.IOException;
    import java.io.InputStream;
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    import java.util.StringTokenizer;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    import com.sap.aii.af.mp.module.ModuleException;
    @author martin.j.rodriguez
    public class Archivo extends XMLParser {
         private Log log = LogFactory.getLog(Archivo.class);
         private Config config;
        private String nombre, tipoSistema, pais;
        private Date fecha;
        //private boolean procesado;
         //private org.xml.sax.XMLReader xr;
         private double totimp, importeParcial;
        private String buscaTOTIMP, regImporte, buscaTOTLIN;
        private String [] tags;
        private InputStream inputStream;
        private int totlin, regCuenta;
        public Archivo(InputStream is, String legacy) throws ModuleException {
             super();
             Map properties = getConfig().getConfig(legacy);
              if (properties == null) {
                   if (log.isErrorEnabled()){
                        log.error("Error al crear objeto Archivo para procesar el legacy: "legacy" - No se encontro la configuración.");
                   throw new ModuleException("Error al crear objeto Archivo para procesar el legacy: "+legacy);
              this.buscaTOTIMP = (String)properties.get(Config.CAMPO_IMPORTE_TOTAL);
              this.regImporte =  (String)properties.get(Config.CAMPO_IMPORTE);
              this.buscaTOTLIN = (String)properties.get(Config.CAMPO_LINEAS_TOTAL);
              String tagstosearch = (String)properties.get(Config.CAMPO_LINEAS_CONTAR);
              StringTokenizer st = new StringTokenizer(tagstosearch, ",");
              tags = new String[st.countTokens()];
              int i=0;
              while(st.hasMoreTokens()){
                   String token = st.nextToken();
                   tags[i++] = token.trim();
              setInputStream(is);
        public List validaArchivo() throws ParserConfigurationException, SAXException, IOException {
              regCuenta = 0;
             importeParcial = 0;
              DefaultHandler handler = this;
              SAXParserFactory factory = SAXParserFactory.newInstance();
              SAXParser saxParser = factory.newSAXParser();
              saxParser.parse(inputStream, handler);
              String s = "";
              roundValues();
              String stotimp = new BigDecimal(totimp).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
              String simporteParcial = new BigDecimal(importeParcial).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
              if (log.isDebugEnabled()){
                   log.debug("Resultados: TOTIMP: "stotimp" - CONTEO: "+simporteParcial);
                   log.debug("Resultados: TOTLIN: "totlin" - CONTEO: "+regCuenta);
              List results = new ArrayList();
              if (totimp != importeParcial) {
                   s = "Error al contar el total del importe, deberia ser: "stotimp" y el calculado es: "+simporteParcial;
                   if (log.isDebugEnabled()){
                        log.debug(s);
                   results.add(s);
              if (totlin != regCuenta) {
                   s = "Error al contar el total del lineas, deberia ser: "totlin" y el calculado es: "+regCuenta;
                   if (log.isDebugEnabled()){
                        log.debug(s);
                   results.add(s);
              return results;
         private void roundValues() {
              totimp = roundValue(totimp);
              importeParcial = roundValue(importeParcial);
    redondea un numero a 2 decimales
         private double roundValue(double d) {
              BigDecimal bd = new BigDecimal(d);
              bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
              return bd.doubleValue();
         public void startElement(String namespaceURI, String lName, String qName, org.xml.sax.Attributes attrs) throws org.xml.sax.SAXException {
              String etiqueta = getTagName(qName, lName);
              //niveles.add(etiqueta);
              // Cuenta registros
              for (int i = 0;i< tags.length; i++){
                   if (etiqueta.equals(tags+)){
                        regCuenta++;
                        break;
         public void endElement(String namespaceURI, String lName, String qName)     throws org.xml.sax.SAXException     {
              String etiqueta = getTagName(qName, lName);
              //niveles.remove(niveles.size() - 1);
              // set valor totlin
              if (buscaTOTLIN.equals(etiqueta)){
                   totlin = parseInt(valor);
              // set valor totimp
              if (buscaTOTIMP.equals(etiqueta)){
                   totimp = parseDouble(valor);
              // suma importe parcial
              if (regImporte.equals(etiqueta)){
                   importeParcial += parseDouble(valor);
        public InputStream getInputStream() {
            return inputStream;
        public void setInputStream(InputStream texto) {
            this.inputStream = texto;
        public String getNombre() {
            return nombre;
        public void setNombre(String nombre) {
            this.nombre = nombre;
        public String getTipoSistema() {
            return tipoSistema;
        public void setTipoSistema(String tipoSistema) {
            this.tipoSistema = tipoSistema;
        public String getPais() {
            return pais;
        public void setPais(String pais) {
            this.pais = pais;
        public java.util.Date getFecha() {
            return fecha;
        public void setFecha(java.util.Date fecha) {
            this.fecha = fecha;
         public static void main(String args[]) {
                   String fileName = "FI_MAS_SAP_RENBAN_####_AAAAMMDD_HHMMSS.TXT";
                   java.util.StringTokenizer st = new java.util.StringTokenizer(fileName, "_");
                   for (int i = 0; i < 5; i++)
                        st.nextToken();
                   String anioMes = st.nextToken();
                   if (anioMes != null)
                        if (anioMes.length() > 5) {
                             System.out.println(anioMes);
                             System.out.println(anioMes.substring(0, 4) + " " + anioMes.substring(4, 6));
         private double parseDouble(String number){
              if (number == null || number.trim().length()==0 || number.trim().equals("/"))
                   return 0;
              // remuevo los 0 a la izquierda que afectan al parseint
              number = number.trim().replaceAll("^0+","");
              number = number.replaceAll(",",".");
              double result = 0;
              try {
                   result = Double.parseDouble(number);
              catch (NumberFormatException nfe){
                   System.err.println("Error parseando numero "+number);
              return result;
         private int parseInt(String number){
              if (number == null || number.trim().length()==0 || number.trim().equals("/"))
                   return 0;
              // remuevo los 0 a la izquierda que afectan al parseint
              number = number.trim().replaceAll("^0+","");
              number = number.replaceAll(",",".");
              int result = 0;
              try {
                   result = Integer.parseInt(number);
              catch (NumberFormatException nfe){
                   System.err.println("Error parseando numero "+number);
              return result;
    Carga la configuracion
    @return
         protected Config getConfig(){
              if (config == null){
                   ConfigParser cp = new ConfigParser();
                   config = cp.readConfig();
              return config;
    Could anyone help me about this problem ?
    Thanks in advance.+

    Hi,
    do u think, u will get the error text in the RWB ? I don't think so, it will provide the output in the RWB.
    The output of the Adapter module is nothing but XI -XML message. So this will not come
    check it out for the how to work on Adapter Modules-
    https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/f013e82c-e56e-2910-c3ae-c602a67b918e
    Hope this helps,
    Regards,
    Moorthy

  • Fresh install... can't SSH in through Putty

    Hi,
    I just now installed archlinux on my server machine, and for some reason I cannot connect to it via PuTTY on my windows machine. It's saying connection timed out. I did /etc/rc.d/sshd restart, and it seems to be started just fine. What do I need to do for this to work?

    fukawi2 wrote:
    You'll also need to adjust /etc/hosts.allow
    Have you followed the Wiki for setting up OpenSSH?
    http://wiki.archlinux.org/index.php/SSH … _others_in
    Thanks for your reply.
    Yes, I did read that article but as you can see I ran into some unexpected problems. I already had my hosts.allow file set to ALL. SSH works fine at this point, I just need to get my domain name working.
    UPDATE:
    I found this article on the internet just now and it explains how the hosts file must be modified if using DHCP. The syntax seems rather obscure, unobvious, confusing, and mostly hacky. Can anyone explain the weird syntax? It looks like the IP address 127.0.0.1 is being assigned to the hostname itself as well as the "localhost" name.
    Last edited by void.pointer (2008-07-31 04:12:30)

Maybe you are looking for

  • Preserving Chapter Cross References when going to Structured Framemaker

    Hello, I am trying to preserve all of my cross references that link from chapter to chapter, within the same book. If I convert files one at a time, then FrameMaker has trouble finding the link in the destination chapter - because that chapter has no

  • Cant play full screen

    I upgraded my qt 6 pro on my power book and now I cant play fullscreen movies. Surely I dont have to buy qt pro again for the version mac gave as a free update so I can have full screen again

  • Cable connection between card and dri

    Looking for a round cable to replace flat cable that connects sound card to dri've! I know they make round cables for other dri'ves to dress up tower looks and air flow but does anyone make one for the Creative dri've and card connection?

  • Copying the error records in a custom table

    Hi, I  have a report program which is fetching Invoice header and line items . I need to copy the error records (records having a custom field ZZKUNNR as blank) in a custom table . I am executing this report in background daily . The records in the c

  • Book, calendar  in Portugal

    Hi, I live in Portugal and there isn't a book/calendar iPhoto service here. But can I order my book/calendar from Spain (throw iPhoto of course)? And be delivered here in Portugal?