예제 #1
0
Texture *
LoadGIF(FILE *fp, char *fname )
{
  Texture           *texture;
  int                filesize, numcols;
  register unsigned  char ch, ch1;
  register byte     *ptr, *ptr1;
  register int   i;

  BitOffset=0;
  XC=0;
  YC=0;
  Pass=0;
  
  /* find the size of the file */
  fseek(fp, 0L, 2);
  filesize = ftell(fp);
  fseek(fp, 0L, 0);

  if (!(ptr = RawGIF = (byte *) malloc(filesize)))
    fatal_error("not enough memory to read gif file");

  if (!(Raster = (byte *) malloc(filesize))) {
    free( ptr );
    fatal_error("not enough memory to read gif file");
  }

  if (fread(ptr, filesize, 1, fp) != 1)
    fatal_error("GIF data read failed");
  
  if (strncmp(ptr, id, 6))
    fatal_error("not a GIF file");

  ptr += 6;

/* Get variables from the GIF screen descriptor */

  ch           = NEXTBYTE;
  RWidth       = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */
  ch           = NEXTBYTE;
  RHeight      = ch + 0x100 * NEXTBYTE;

  if (Verbose)
    fprintf(stderr, "screen dims: %dx%d.\n", RWidth, RHeight);

  ch           = NEXTBYTE;
  HasColormap  = ((ch & COLORMAPMASK) ? True : False);

  BitsPerPixel = (ch & 7) + 1;
  numcols      = ColorMapSize = 1 << BitsPerPixel;
  BitMask      = ColorMapSize - 1;

  printf("ColorMapSize = %d\n",ColorMapSize);
  
  Background   = NEXTBYTE;		/* background color... not used. */
  
  if (NEXTBYTE)		/* supposed to be NULL */
    fatal_error("corrupt GIF file (bad screen descriptor)");

/* Read in global colormap. */

  if (HasColormap) {
    if (Verbose)
      fprintf(stderr, "%s is %dx%d, %d bits per pixel, (%d colors).\n",
	      fname, RWidth,RHeight,BitsPerPixel, ColorMapSize);

    for (i = 0; i < ColorMapSize; i++) {
      Red[i]   = NEXTBYTE;
      Green[i] = NEXTBYTE;
      Blue[i]  = NEXTBYTE;
      used[i]  = 0;
    }

    numused = 0;
  } /* else no colormap in GIF file */

/* Check for image seperator */

  if (NEXTBYTE != IMAGESEP)
    fatal_error("corrupt GIF file (no image separator)");

/* Now read in values from the image descriptor */

  ch        = NEXTBYTE;
  LeftOfs   = ch + 0x100 * NEXTBYTE;
  ch        = NEXTBYTE;
  TopOfs    = ch + 0x100 * NEXTBYTE;
  ch        = NEXTBYTE;
  Width     = ch + 0x100 * NEXTBYTE;
  ch        = NEXTBYTE;
  Height    = ch + 0x100 * NEXTBYTE;
  Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);

  if (Verbose)
    fprintf(stderr, "Reading a %d by %d %sinterlaced image...",
	    Width, Height, (Interlace) ? "" : "non-");

  texture = new_texture( Width, Height );

/* Note that I ignore the possible existence of a local color map.
 * I'm told there aren't many files around that use them, and the spec
 * says it's defined for future use.  This could lead to an error
 * reading some files. 
 */

/* Start reading the raster data. First we get the intial code size
 * and compute decompressor constant values, based on this code size.
 */

    CodeSize  = NEXTBYTE;
    ClearCode = (1 << CodeSize);
    EOFCode   = ClearCode + 1;
    FreeCode  = FirstFree = ClearCode + 2;

/* The GIF spec has it that the code size is the code size used to
 * compute the above values is the code size given in the file, but the
 * code size used in compression/decompression is the code size given in
 * the file plus one. (thus the ++).
 */

    CodeSize++;
    InitCodeSize = CodeSize;
    MaxCode      = (1 << CodeSize);
    ReadMask     = MaxCode - 1;

/* Read the raster data.  Here we just transpose it from the GIF array
 * to the Raster array, turning it from a series of blocks into one long
 * data stream, which makes life much easier for ReadCode().
 */

    ptr1 = Raster;
    do {
	ch = ch1 = NEXTBYTE;
	while (ch--) *ptr1++ = NEXTBYTE;
	if ((ptr - Raster) > filesize)
	    fatal_error("corrupt GIF file (unblock)");
    } while(ch1);

    free(RawGIF);		/* We're done with the raw data now... */

    if (Verbose) {
	fprintf(stderr, "done.\n");
	fprintf(stderr, "Decompressing...");
    }

    Image               = texture->texels;
    BytesPerScanline    = Width;


/* Decompress the file, continuing until you see the GIF EOF code.
 * One obvious enhancement is to add checking for corrupt files here.
 */

    Code = ReadCode();
    while (Code != EOFCode) {

/* Clear code sets everything back to its initial value, then reads the
 * immediately subsequent code as uncompressed data.
 */

	if (Code == ClearCode) {
	    CodeSize = InitCodeSize;
	    MaxCode  = (1 << CodeSize);
	    ReadMask = MaxCode - 1;
	    FreeCode = FirstFree;
	    CurCode  = OldCode = Code = ReadCode();
	    FinChar  = CurCode & BitMask;
	    AddToPixel(FinChar);
	}
	else {

/* If not a clear code, then must be data: save same as CurCode and InCode */

	    CurCode = InCode = Code;

/* If greater or equal to FreeCode, not in the hash table yet;
 * repeat the last character decoded
 */

	    if (CurCode >= FreeCode) {
		CurCode = OldCode;
		OutCode[OutCount++] = FinChar;
	    }

/* Unless this code is raw data, pursue the chain pointed to by CurCode
 * through the hash table to its end; each code in the chain puts its
 * associated output code on the output queue.
 */

	    while (CurCode > BitMask) {
		if (OutCount > 1024) {
		    fprintf(stderr,"\nCorrupt GIF file (OutCount)!\n");
                    exit(1);  /* calling 'exit(-1)' dumps core, so I don't */
                    }
		OutCode[OutCount++] = Suffix[CurCode];
		CurCode = Prefix[CurCode];
	    }

/* The last code in the chain is treated as raw data. */

	    FinChar             = CurCode & BitMask;
	    OutCode[OutCount++] = FinChar;

/* Now we put the data out to the Output routine.
 * It's been stacked LIFO, so deal with it that way...
 */

	    for (i = OutCount - 1; i >= 0; i--)
		AddToPixel(OutCode[i]);
	    OutCount = 0;

/* Build the hash table on-the-fly. No table is stored in the file. */

	    Prefix[FreeCode] = OldCode;
	    Suffix[FreeCode] = FinChar;
	    OldCode          = InCode;

/* Point to the next slot in the table.  If we exceed the current
 * MaxCode value, increment the code size unless it's already 12.  If it
 * is, do nothing: the next code decompressed better be CLEAR
 */

	    FreeCode++;
	    if (FreeCode >= MaxCode) {
		if (CodeSize < 12) {
		    CodeSize++;
		    MaxCode *= 2;
		    ReadMask = (1 << CodeSize) - 1;
		}
	    }
	}
	Code = ReadCode();
    }

    free(Raster);

    if (Verbose)
	fprintf(stderr, "done.\n");
    else
        fprintf(stderr,"(of which %d are used)\n",numused);

  remap(texture);
  
  return texture;
}
예제 #2
0
int CCDSim::DrawImageStar(CCDChip *targetChip, float mag,float x,float y)
{
    //float d;
    //float r;
    int sx,sy;
    int drew=0;
    int boxsizex=5;
    int boxsizey=5;
    float flux;
    float ExposureTime;

    if (targetChip->getXRes() == 500)
        ExposureTime = GuideExposureRequest*4;
    else
        ExposureTime = ExposureRequest;


    if((x<0)||(x>targetChip->getXRes()/targetChip->getBinX())||(y<0)||(y>targetChip->getYRes()/targetChip->getBinY()))
    {
        //  this star is not on the ccd frame anyways
        return 0;
    }



    //  calculate flux from our zero point and gain values
    flux=pow(10,((mag-z)*k/-2.5));

    //  ok, flux represents one second now
    //  scale up linearly for exposure time
    flux=flux*ExposureTime;

    float qx;
    //  we need a box size that gives a radius at least 3 times fwhm
    qx=seeing/ImageScalex;
    qx=qx*3;
    boxsizex=(int)qx;
    boxsizex++;
    qx=seeing/ImageScaley;
    qx=qx*3;
    boxsizey=(int)qx;
    boxsizey++;

    //IDLog("BoxSize %d %d\n",boxsizex,boxsizey);


    for(sy=-boxsizey; sy<=boxsizey; sy++) {
        for(sx=-boxsizey; sx<=boxsizey; sx++) {
            int rc;
            float dc;   //  distance from center
            float fp;   //  flux this pixel;

            //  need to make this account for actual pixel size
            dc=sqrt(sx*sx*ImageScalex*ImageScalex+sy*sy*ImageScaley*ImageScaley);
            //  now we have the distance from center, in arcseconds
            //  This should be gaussian, but, for now we'll just go with
            //  a simple linear function
            float fa;
            fa=exp(-2.0*0.7*(dc*dc)/seeing/seeing);
            fp=fa*flux*targetChip->getBinX()*targetChip->getBinY();


            if(fp < 0) fp=0;

            /*
            if(dc < boxsize) {
                dc=boxsize-dc;
                dc=dc/boxsize;
                fp=dc*flux;
            } else {
                fp=0;
            }
            */
            rc=AddToPixel(targetChip, x+sx,y+sy,fp);
            if(rc != 0) drew=1;
        }
    }
    return drew;
}
예제 #3
0
BYTE *
Decompress(GIFIMAGEDESC *GifImageDesc, GIFHEAD *GifHead)
{
    int i;

    XC = 0;
    YC = 0;
    Pass = 0;
    OutCount = 0;
    BitOffset = 0;

    DataMask = (1 << ((GifHead->PackedField & 0x07) +1)) -1;
    Raster = GifImageDesc->GIFImage;

    /* Check for image seperator */

    /* Now read in values from the image descriptor */
    IWidth = GifImageDesc->ImageWidth;
    IHeight = GifImageDesc->ImageHeight;
    Interlace = GifImageDesc->PackedField & 0x40;

    /*
     * Note that I ignore the possible existence of a local color map.  I'm
     * told there aren't many files around that use them, and the spec says
     * it's defined for future use.  This could lead to an error reading some
     * files.
     */

    /*
     * Start reading the raster data. First we get the WORDial code size and
     * compute decompressor constant values, based on this code size.
     */

    CodeSize = GifImageDesc->CodeSize;
    ClearCode = (1 << CodeSize);
    EOFCode = ClearCode + 1;
    FreeCode = FirstFree = ClearCode + 2;

    /*
     * The GIF spec has it that the code size is the code size used to compute
     * the above values is the code size given in the file, but the code size
     * used in compression/decompression is the code size given in the file
     * plus one. (thus the ++).
     */

    CodeSize++;
    InitCodeSize = CodeSize;
    MaxCode = (1 << CodeSize);
    ReadMask = MaxCode - 1;

    /*
     * Read the raster data.  Here we just transpose it from the GIF array to
     * the Raster array, turning it from a series of blocks WORDo one long
     * data stream, which makes life much easier for ReadCode().
     */

    /* Allocate the Image */

    if (!(Image = (BYTE *)malloc((size_t)IWidth*(size_t)IHeight))) {
        printf("Out of memory");
        exit(EXIT_FAILURE);
    }

    BytesPerScanline = IWidth;

    /*
     * Decompress the file, continuing until you see the GIF EOF code.  One
     * obvious enhancement is to add checking for corrupt files here.
     */

    Code = ReadCode();

    while (Code != EOFCode) {
        /*
         * Clear code sets everything back to its initial value, then reads
         * the immediately subsequent code as uncompressed data.
         */
        if (Code == ClearCode) {
            CodeSize = InitCodeSize;
            MaxCode = (1 << CodeSize);
            ReadMask = MaxCode - 1;
            FreeCode = FirstFree;
            CurCode = OldCode = Code = ReadCode();
            FinChar = CurCode & DataMask;
            AddToPixel((BYTE)FinChar);
        } else {
            /*
             * If not a clear code, then must be data: save same as CurCode
             * and InCode
             */
            CurCode = InCode = Code;

            /*
             * If greater or equal to FreeCode, not in the hash table yet;
             * repeat the last character decoded
             */
            if (CurCode >= FreeCode) {
                CurCode = OldCode;
                OutCode[OutCount++] = FinChar;
            }

            /*
             * Unless this code is raw data, pursue the chain poWORDed to by
             * CurCode through the hash table to its end; each code in the
             * chain puts its associated output code on the output queue.
             */
            while (CurCode > DataMask) {
                if (OutCount > 1024) {
                    /*return error message*/
                }

                OutCode[OutCount++] = Suffix[CurCode];
                CurCode = Prefix[CurCode];
            }

            /* The last code in the chain is treated as raw data. */
            FinChar = CurCode & DataMask;
            OutCode[OutCount++] = FinChar;

            /*
             * Now we put the data out to the Output routine. It's been
             * stacked LIFO, so deal with it that way...
             */
            for (i = OutCount - 1; i >= 0; i--)
                AddToPixel((BYTE)OutCode[i]);

            OutCount = 0;

            /*
             * Build the hash table on-the-fly. No table is stored in the
             * file.
             */
            Prefix[FreeCode] = OldCode;
            Suffix[FreeCode] = FinChar;
            OldCode = InCode;

            /*
             * PoWORD to the next slot in the table.  If we exceed the current
             * MaxCode value, increment the code size unless it's already 12.
             * If it is, do nothing: the next code decompressed better be
             * CLEAR
             */
            FreeCode++;

            if (FreeCode >= MaxCode)
                if (CodeSize < 12) {
                    CodeSize++;
                    MaxCode *= 2;
                    ReadMask = (1 << CodeSize) - 1;
                }
        }

        Code = ReadCode();
    }

    return Image;
}
예제 #4
0
int CCDSim::DrawCcdFrame(CCDChip *targetChip)
{
    //  Ok, lets just put a silly pattern into this
    //  CCd frame is 16 bit data
    unsigned short int *ptr;
    unsigned short int val;
    float ExposureTime;
    float targetFocalLength;

    ptr=(unsigned short int *) targetChip->getFrameBuffer();

    if (targetChip->getXRes() == 500)
    {
        targetFocalLength = guider_focallength;
        ExposureTime = GuideExposureRequest*4;
    }
    else
    {
        targetFocalLength = focallength;
        ExposureTime = ExposureRequest;
    }


    if(ShowStarField)
    {
        char gsccmd[250];
        FILE *pp;
        int stars=0;
        int lines=0;
        int drawn=0;
        int x,y;
        float PEOffset;
        float PESpot;
        double rad;  //  telescope ra in degrees
        double rar;  //  telescope ra in radians
        double decr; //  telescope dec in radians;


        double timesince;
        time_t now;
        time(&now);

        //  Lets figure out where we are on the pe curve
        timesince=difftime(now,RunStart);
        //  This is our spot in the curve
        PESpot=timesince/PEPeriod;
        //  Now convert to radians
        PESpot=PESpot*2.0*3.14159;

        PEOffset=PEMax*sin(PESpot);
        //fprintf(stderr,"PEOffset = %4.2f arcseconds timesince %4.2f\n",PEOffset,timesince);
        PEOffset=PEOffset/3600;     //  convert to degrees
        //PeOffset=PeOffset/15;       //  ra is in h:mm

        //  Start by clearing the frame buffer
        memset(targetChip->getFrameBuffer(),0,targetChip->getFrameBufferSize());


        //  Spin up a set of plate constants that will relate
        //  ra/dec of stars, to our fictitious ccd layout

        //  to account for various rotations etc
        //  we should spin up some plate constants here
        //  then we can use these constants to rotate and offset
        //  the standard co-ordinates on each star for drawing
        //  a ccd frame;
        double pa,pb,pc,pd,pe,pf;
        //  Since this is a simple ccd, correctly aligned
        //  for now we cheat
        //  no offset or rotation for and y axis means
        pb=0.0;
        pc=targetChip->getXRes()/2/targetChip->getBinX();
        pd=0.0;
        pf=targetChip->getYRes()/2/targetChip->getBinY();
        //  and we do a simple scale for x and y locations
        //  based on the focal length and pixel size
        //  focal length in mm, pixels in microns
        pa=targetFocalLength/targetChip->getPixelSizeX()*1000/targetChip->getBinX();
        pe=targetFocalLength/targetChip->getPixelSizeY()*1000/targetChip->getBinY();

        //IDLog("Pixels are %4.2f %4.2f  pa %6.4f  pe %6.4f\n",PixelSizex,PixelSizey,pa,pe);

        //  these numbers are now pixels per radian
        float Scalex;
        float Scaley;
        Scalex=pa*0.0174532925;    //  pixels per degree
        Scalex=Scalex/3600.0;           // pixels per arcsecond
        Scalex=1.0/Scalex;  //  arcseconds per pixel

        Scaley=pe*0.0174532925;    //  pixels per degree
        Scaley=Scaley/3600.0;           // pixels per arcsecond
        Scaley=1.0/Scaley;  //  arcseconds per pixel
        //qq=qq/3600; //  arcseconds per pixel

        //IDLog("Pixel scale is %4.2f x %4.2f\n",Scalex,Scaley);
        ImageScalex=Scalex;
        ImageScaley=Scaley;

        //  calc this now, we will use it a lot later
        rad=raPEC*15.0;
        rar=rad*0.0174532925;
        //  offsetting the dec by the guide head offset
        float cameradec;
        cameradec=decPEC+OAGoffset/60;
        decr=cameradec*0.0174532925;

        //fprintf(stderr,"decPEC %7.5f  cameradec %7.5f  CenterOffsetDec %4.4f\n",decPEC,cameradec,CenterOffsetDec);
        //  now lets calculate the radius we need to fetch
        float radius;

        radius=sqrt((Scalex*Scalex*targetChip->getXRes()/2.0*targetChip->getXRes()/2.0)+(Scaley*Scaley*targetChip->getYRes()/2.0*targetChip->getYRes()/2.0));
        //  we have radius in arcseconds now
        radius=radius/60;   //  convert to arcminutes
        //fprintf(stderr,"Lookup radius %4.2f\n",radius);
        //radius=radius*2;

        //  A saturationmag star saturates in one second
        //  and a limitingmag produces a one adu level in one second
        //  solve for zero point and system gain

        k=(saturationmag-limitingmag)/((-2.5*log(maxval))-(-2.5*log(1.0/2.0)));
        z=saturationmag-k*(-2.5*log(maxval));
        //z=z+saturationmag;

        //IDLog("K=%4.2f  Z=%4.2f\n",k,z);

        //  Should probably do some math here to figure out the dimmest
        //  star we can see on this exposure
        //  and only fetch to that magnitude
        //  for now, just use the limiting mag number with some room to spare
        float lookuplimit;

        lookuplimit=limitingmag;
        lookuplimit=lookuplimit;
        if(radius > 60) lookuplimit=11;

        //  if this is a light frame, we need a star field drawn
        if(targetChip->getFrameType()==CCDChip::LIGHT_FRAME)
        {
            //sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r 120 -m 0 9.1",rad+PEOffset,decPEC);
            sprintf(gsccmd,"gsc -c %8.6f %+8.6f -r %4.1f -m 0 %4.2f -n 3000",rad+PEOffset,cameradec,radius,lookuplimit);
            //fprintf(stderr,"gsccmd %s\n",gsccmd);
            pp=popen(gsccmd,"r");
            if(pp != NULL) {
                char line[256];
                while(fgets(line,256,pp)!=NULL)
                {
                    //fprintf(stderr,"%s",line);

                    //  ok, lets parse this line for specifcs we want
                    char id[20];
                    char plate[6];
                    char ob[6];
                    float mag;
                    float mage;
                    float ra;
                    float dec;
                    float pose;
                    int band;
                    float dist;
                    int dir;
                    int c;
                    int rc;

                    rc=sscanf(line,"%10s %f %f %f %f %f %d %d %4s %2s %f %d",
                            id,&ra,&dec,&pose,&mag,&mage,&band,&c,plate,ob,&dist,&dir);
                    //fprintf(stderr,"Parsed %d items\n",rc);
                    if(rc==12) {
                        lines++;
                        //if(c==0) {
                        stars++;
                        //fprintf(stderr,"%s %8.4f %8.4f %5.2f %5.2f %d\n",id,ra,dec,mag,dist,dir);

                        //  Convert the ra/dec to standard co-ordinates
                        double sx;   //  standard co-ords
                        double sy;   //
                        double srar;        //  star ra in radians
                        double sdecr;       //  star dec in radians;
                        double ccdx;
                        double ccdy;

                        //fprintf(stderr,"line %s",line);
                        //fprintf(stderr,"parsed %6.5f %6.5f\n",ra,dec);

                        srar=ra*0.0174532925;
                        sdecr=dec*0.0174532925;
                        //  Handbook of astronomical image processing
                        //  page 253
                        //  equations 9.1 and 9.2
                        //  convert ra/dec to standard co-ordinates

                        sx=cos(decr)*sin(srar-rar)/( cos(decr)*cos(sdecr)*cos(srar-rar)+sin(decr)*sin(sdecr) );
                        sy=(sin(decr)*cos(sdecr)*cos(srar-rar)-cos(decr)*sin(sdecr))/( cos(decr)*cos(sdecr)*cos(srar-rar)+sin(decr)*sin(sdecr) );

                        //  now convert to microns
                        ccdx=pa*sx+pb*sy+pc;
                        ccdy=pd*sx+pe*sy+pf;


                        rc=DrawImageStar(targetChip, mag,ccdx,ccdy);
                        drawn+=rc;
                        if(rc==1)
                        {
                            //fprintf(stderr,"star %s scope %6.4f %6.4f star %6.4f %6.4f  ccd %6.2f %6.2f\n",id,rad,decPEC,ra,dec,ccdx,ccdy);
                            //fprintf(stderr,"star %s ccd %6.2f %6.2f\n",id,ccdx,ccdy);
                        }
                    }
                }
                pclose(pp);
            } else
            {
                IDMessage(getDeviceName(),"Error looking up stars, is gsc installed with appropriate environment variables set ??");
                //fprintf(stderr,"Error doing gsc lookup\n");
            }
            if(drawn==0)
            {
                IDMessage(getDeviceName(),"Got no stars, is gsc installed with appropriate environment variables set ??");

            }
        }
        //fprintf(stderr,"Got %d stars from %d lines drew %d\n",stars,lines,drawn);

        //  now we need to add background sky glow, with vignetting
        //  this is essentially the same math as drawing a dim star with
        //  fwhm equivalent to the full field of view

        CCDChip::CCD_FRAME ftype = targetChip->getFrameType();

        if((ftype==CCDChip::LIGHT_FRAME)||(ftype==CCDChip::FLAT_FRAME))
        {
            float skyflux;
            float glow;
            //  calculate flux from our zero point and gain values
            glow=skyglow;
            if(ftype==CCDChip::FLAT_FRAME)
            {
                //  Assume flats are done with a diffuser
                //  in broad daylight, so, the sky magnitude
                //  is much brighter than at night
                glow=skyglow/10;
            }

            //fprintf(stderr,"Using glow %4.2f\n",glow);

            skyflux=pow(10,((glow-z)*k/-2.5));
            //  ok, flux represents one second now
            //  scale up linearly for exposure time
            skyflux=skyflux*ExposureTime*targetChip->getBinX()*targetChip->getBinY();
           //IDLog("SkyFlux = %g ExposureRequest %g\n",skyflux,ExposureTime);

            unsigned short *pt;

            int nwidth  = targetChip->getXRes()/targetChip->getBinX();
            int nheight = targetChip->getYRes()/targetChip->getBinY();
            pt=(unsigned short int *)targetChip->getFrameBuffer();

            for(int y=0; y< nheight; y++)
            {
                for(int x=0; x< nwidth; x++)
                {
                    float dc;   //  distance from center
                    float fp;   //  flux this pixel;
                    float sx,sy;
                    float vig;

                    sx=targetChip->getXRes()/2/targetChip->getBinX();
                    sx=sx-x;
                    sy=targetChip->getYRes()/2/targetChip->getBinY();
                    sy=sy-y;

                    vig=targetChip->getXRes()/targetChip->getBinX();
                    vig=vig*ImageScalex;
                    //  need to make this account for actual pixel size
                    dc=sqrt(sx*sx*ImageScalex*ImageScalex+sy*sy*ImageScaley*ImageScaley);
                    //  now we have the distance from center, in arcseconds
                    //  now lets plot a gaussian falloff to the edges
                    //
                    float fa;
                    fa=exp(-2.0*0.7*(dc*dc)/vig/vig);

                    //  get the current value
                    fp=pt[0];

                    //  Add the sky glow
                    fp+=skyflux;

                    //  now scale it for the vignetting
                    fp=fa*fp;

                    //  clamp to limits
                    if(fp > maxval) fp=maxval;
                    if (fp > maxpix) maxpix = fp;
                    if (fp < minpix) minpix = fp;
                    //  and put it back
                    pt[0]=fp;
                    pt++;

                }
            }
        }


        //  Now we add some bias and read noise
        for(x=0; x<targetChip->getXRes(); x++) {
            for(y=0; y<targetChip->getYRes(); y++) {
                int noise;

                noise=random();
                noise=noise%maxnoise; //

                //IDLog("noise is %d\n", noise);
                AddToPixel(targetChip, x,y,bias+noise);
            }
        }


    } else {
        testvalue++;
        if(testvalue > 255) testvalue=0;
        val=testvalue;

        int nbuf    = targetChip->getXRes()*targetChip->getYRes();

        for(int x=0; x<nbuf; x++)
        {
            *ptr=val++;
            ptr++;
        }

    }
    return 0;
}