aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorallen <allen@eff87b29-5268-4891-90a3-a07138403961>2000-09-20 10:58:58 +0000
committerallen <allen@eff87b29-5268-4891-90a3-a07138403961>2000-09-20 10:58:58 +0000
commitff5c80e7f3d2d2d3f8ca612488aa229c27bbdd89 (patch)
tree7ae01c14349fe8782c95facb9951f9d365470d89 /src
parent8297f44fc3400c0e6ed380c35db318a18bf89c47 (diff)
This commit was generated by cvs2svn to compensate for changes in r2, which
included commits to RCS files with non-trunk default branches. git-svn-id: http://svn.cactuscode.org/arrangements/CactusIO/IOJpeg/trunk@3 eff87b29-5268-4891-90a3-a07138403961
Diffstat (limited to 'src')
-rw-r--r--src/DumpVar.c155
-rw-r--r--src/GHExtension.c104
-rw-r--r--src/IOJpeg.h56
-rw-r--r--src/JPEG.c301
-rw-r--r--src/Output2D.c182
-rw-r--r--src/ParseGeometry.c142
-rw-r--r--src/Startup.c47
-rw-r--r--src/Write2D.c168
-rw-r--r--src/make.code.defn9
9 files changed, 1164 insertions, 0 deletions
diff --git a/src/DumpVar.c b/src/DumpVar.c
new file mode 100644
index 0000000..96613da
--- /dev/null
+++ b/src/DumpVar.c
@@ -0,0 +1,155 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "CactusPUGH/PUGHSlab/src/PUGHSlab.h"
+#include "IOJpeg.h"
+
+int IOJpeg_Output(cGH *GH, int index, int timelevel, CCTK_REAL *data,
+ int sdim, int *hsize, int vtype, FILE *fid);
+
+
+int IOJpeg_DumpVar (cGH *GH, int index, int timelevel, IOJpegGeo_t *geo, FILE *fid)
+{
+ DECLARE_CCTK_PARAMETERS
+ void *data=NULL;
+ int *hsizes, slabstart[SLABSKEL_MAXDIM];
+ IOJpegGH *ssGH;
+ int vtype;
+ int idim, vdim;
+
+ int sdir[3] = {0,0,0};
+
+ /* Get the handle for StreamedHDF5 extensions */
+ ssGH = (IOJpegGH *) GH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ /* Allocate buffer to hold actual slab sizes */
+ hsizes = (int*)malloc(geo->sdim*sizeof(int));
+
+ vdim= geo->vdim;
+
+ /* Checks for vartype can go here */
+ vtype = CCTK_VarTypeI (index);
+
+ /* TEMPORARY FIX DUE TO INCONSISTENT DIR SPECIFICATION */
+ /* direction vector of 1d line in 3d volume */
+ if (geo->sdim==1) {
+ sdir[0] = (geo->direction[0]==0) ? 1:0;
+ sdir[1] = (geo->direction[0]==1) ? 1:0;
+ sdir[2] = (geo->direction[0]==2) ? 1:0;
+ }
+ /* norm vector of 2d surface in 3d volume */
+ else if (geo->sdim==2)
+ {
+ sdir[0] = ((geo->direction[0]==1)&&(geo->direction[1]==2)) ? 1:0;
+ sdir[1] = ((geo->direction[0]==0)&&(geo->direction[1]==2)) ? 1:0;
+ sdir[2] = ((geo->direction[0]==0)&&(geo->direction[1]==1)) ? 1:0;
+ }
+ /* spanning directions for 3d */
+ else if (geo->sdim==3)
+ {
+ sdir[0] = geo->direction[0];
+ sdir[1] = geo->direction[1];
+ sdir[2] = geo->direction[2];
+ }
+ else
+ {
+ char *fullname = CCTK_FullName (index);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No 0-dim extraction possible: '%s'", fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* Get the start indices for the slab from slab_start. */
+ /* Slab_start from the geo structure is not a true start index, it is currently
+ used as the intersection point of n surfaces , that's why two entries
+ have to be set to zero in the case of a surface (one entry for line) FIXME */
+ for (idim=0;idim<vdim;idim++)
+ slabstart[idim] = geo->slab_start[idim];
+ for (idim=0;idim<geo->sdim;idim++)
+ slabstart[geo->direction[idim]]=0;
+
+ /* Data Extraction takes place, data will be gathered onto processor 0
+ hyperslab data will be in data,
+ hyperslab sizes: hsizes[SLAB_DIM].
+ */
+ if (Hyperslab_GetHyperslab (GH, 0, index, timelevel, geo->sdim, slabstart,
+ sdir, geo->length, geo->downs,
+ &data, hsizes) < 0)
+ {
+ char *fullname = CCTK_FullName (index);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Failed to extract hyperslab for variable '%s'", fullname);
+ free (fullname);
+ return (-1);
+ }
+
+ /* Output routine for valid fid (was set in Write nD) */
+ if (fid)
+ {
+ if (IOJpeg_Output(GH, index, timelevel, data,
+ geo->sdim, hsizes, vtype, fid)<0) {
+ char *fullname = CCTK_FullName (index);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOJpeg_Output failed for variable '%s'", fullname);
+ free (fullname);
+ return (-1);
+ }
+ }
+
+ if (data)
+ free (data);
+
+ return (0);
+}
+
+
+
+int IOJpeg_Output(cGH *GH, int index, int timelevel, CCTK_REAL *data,
+ int sdim, int *hsize, int vtype, FILE *fid)
+{
+ DECLARE_CCTK_PARAMETERS
+
+ unsigned char *dataout=(unsigned char *)malloc(3*hsize[0]*hsize[1]);
+ CCTK_REAL min,max;
+
+ if (sdim!=2) return(-1);
+
+ if (CCTK_Equals(colormap,"custom"))
+ {
+ min = colormap_min;
+ max = colormap_max;
+ }
+ else
+ {
+ int reduction_handle,ierr;
+ reduction_handle = CCTK_ReductionHandle ("maximum");
+ ierr = CCTK_Reduce (GH, 0, reduction_handle, 1,
+ CCTK_VARIABLE_REAL,&max, 1, index);
+ reduction_handle = CCTK_ReductionHandle ("minimum");
+ ierr = CCTK_Reduce (GH, 0, reduction_handle, 1,
+ CCTK_VARIABLE_REAL,&min, 1, index);
+ }
+
+ AutoColorDataSlice(hsize[0],
+ hsize[1],
+ data,
+ dataout,
+ min,
+ max,
+ colormap_bias,
+ colormap_factor);
+
+ WriteJPEGToFileRGB(hsize[0],
+ hsize[1],
+ dataout,
+ colormap_quality,
+ fid);
+
+ return(1);
+}
+
diff --git a/src/GHExtension.c b/src/GHExtension.c
new file mode 100644
index 0000000..a82d359
--- /dev/null
+++ b/src/GHExtension.c
@@ -0,0 +1,104 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+
+#include "CactusPUGH/PUGH/src/include/pugh.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "IOJpeg.h"
+
+void IOJpeg_DefaultGeo(cGH *GH, int sdim, IOJpegGeo_t *geo);
+
+void *IOJpeg_SetupGH (tFleshConfig *config, int convergence_level, cGH *GH)
+{
+ int numvars,iv;
+ IOJpegGH *newGH;
+
+ numvars = CCTK_NumVars ();
+
+ newGH = (IOJpegGH *) malloc (sizeof (IOJpegGH));
+ newGH->do_out2D = (char *) malloc (numvars * sizeof (char));
+ newGH->out2D_last = (int *) malloc (numvars * sizeof (int));
+
+ /* Allocate geometry structure for each grid variable/array */
+ newGH->out_geo = (IOJpegGeo_t**) malloc(SLABSKEL_MAXDIM * sizeof (IOJpegGeo_t));
+ for (iv=0;iv<numvars;iv++)
+ newGH->out_geo[iv] = (IOJpegGeo_t*) malloc(SLABSKEL_MAXDIM * sizeof (IOJpegGeo_t));
+
+ return (newGH);
+}
+
+
+int IOJpeg_InitGH (cGH *GH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int inum;
+ IOJpegGH *myGH;
+ const cParamData *paramdata;
+
+ myGH = (IOJpegGH *) GH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ myGH->out2D_every = out_every > 0 ? out_every : -1;
+ if (out2D_every > 0)
+ myGH->out2D_every = out2D_every;
+ IOUtil_ParseVarsForOutput (out2D_vars, myGH->do_out2D);
+
+ for (inum=0; inum<CCTK_NumVars(); inum++)
+ {
+ myGH->out2D_last [inum] = -1;
+ }
+
+ /* Deal with the output directories */
+ /* Check whether "outdirXD" was set.
+ If so take this dir otherwise default to "IO::outdir" */
+ paramdata = CCTK_ParameterData ("out2D_dir", CCTK_THORNSTRING);
+ myGH->outdir2D = (paramdata && paramdata->n_set > 0) ?
+ strdup (out2D_dir) : strdup (outdir);
+
+ /* create the output dir */
+ if (CCTK_MyProc (GH) == 0)
+ {
+ int i;
+ i = CCTK_CreateDirectory (0755, myGH->outdir2D);
+ if (i < 0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOASCII_InitGH: Problem creating 2D output directory '%s'",
+ myGH->outdir2D);
+ }
+ if (i > 0)
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOASCII_InitGH: 2D output directory '%s' already exists",
+ myGH->outdir2D);
+ }
+ }
+
+ myGH->fileList_2D = NULL;
+ return (0);
+}
+
+
+
+void IOJpeg_SliceCenterSetup(CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_PARAMETERS
+ int inum,idim;
+ IOJpegGeo_t geo_default;
+ IOJpegGH *myGH;
+
+ myGH = (IOJpegGH *) cctkGH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ /* Loop over all slab dimension */
+ for (idim=0;idim<SLABSKEL_MAXDIM;idim++) {
+ IOJpeg_DefaultGeo(cctkGH, idim, &geo_default);
+
+ /* Set the default HDF5 slab geometry for slab with dimension -idim-*/
+ for (inum=0; inum<CCTK_NumVars(); inum++)
+ myGH->out_geo[inum][idim] = geo_default;
+ }
+
+}
diff --git a/src/IOJpeg.h b/src/IOJpeg.h
new file mode 100644
index 0000000..75355e2
--- /dev/null
+++ b/src/IOJpeg.h
@@ -0,0 +1,56 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SLABSKEL_MAXDIM 4
+
+#include "StoreNamedData.h"
+
+/* structure holding information on the output geometry */
+typedef struct IOJpegGeo
+{
+ int vdim; /* dimension of the gridvariable (dynamic) */
+ int sdim; /* dimension of the slab (dynamic) */
+ int direction[SLABSKEL_MAXDIM]; /* direction of slab (by parameter) */
+ int slab_start[SLABSKEL_MAXDIM];/* global start index (by parameter) */
+ int length[SLABSKEL_MAXDIM]; /* requested index slab length (by parameter) */
+ int actlen[SLABSKEL_MAXDIM]; /* actual index slab length (by PUGHSlab)*/
+ int downs[SLABSKEL_MAXDIM]; /* downsampling (by parameter) */
+} IOJpegGeo_t;
+
+
+/* IOJpeg GH extension structure */
+typedef struct IOJpegGH {
+
+ /* how often to output */
+ int out2D_every;
+
+ /* flags indicating output for var [i] */
+ char *do_out2D;
+
+ /* directories in which to output */
+ char *outdir2D;
+
+ /* the last iteration output */
+ int *out2D_last;
+
+ /* geometry information (downsampling, zooming, etc.) */
+ IOJpegGeo_t **out_geo;
+
+ /* database for names of output files that were already created */
+ pNamedData *fileList_2D;
+
+
+} IOJpegGH;
+
+/* function prototypes */
+int IOJpeg_Write3D (cGH *GH, int index, const char *alias);
+int IOJpeg_Write2D (cGH *GH, int index, const char *alias);
+int IOJpeg_Write1D (cGH *GH, int index, const char *alias);
+
+int IOJpeg_DumpVar (cGH *GH, int index, int timelevel, IOJpegGeo_t *geo, FILE *fid);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/src/JPEG.c b/src/JPEG.c
new file mode 100644
index 0000000..0faee6a
--- /dev/null
+++ b/src/JPEG.c
@@ -0,0 +1,301 @@
+#include "cctk.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <jconfig.h>
+#include <jpeglib.h>
+
+typedef struct jpeg_compress_struct JpgComp;
+
+#ifndef JpgErr
+typedef struct jpeg_error_mgr JpgErr;
+#endif
+
+/*
+ Image data is an array of unsigned character array of
+ RGB data. The data is stored in interleaved order.
+ IE, the first three elements are a byte of Red followed
+ by a byte of Green and then a byte of Blue for the first
+ pixel. Data is stored in fortran order (ie. x is fastest
+ moving dimension).
+ */
+int WriteJPEGToFileRGB(int nx, /* width of image in pixels */
+ int ny, /* height of the image in pixels */
+ void *data, /* buffer containing image data */
+ int Quality, /* Integer from 0 to 100 */
+ FILE* outfile){ /* name of file to store in */
+ JpgComp cinfo;
+ JpgErr jerr;
+ /* FILE * outfile;*/
+ unsigned char *dataRGB = (unsigned char *)data;
+ JSAMPROW row_pointer=(JSAMPROW)dataRGB;
+
+ memset (&cinfo,0,sizeof(cinfo));
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ /* Setup JPEG */
+ cinfo.image_width = nx ; /* image width and height, in pixels */
+ cinfo.image_height = ny;
+ cinfo.input_components = 3; /* # of color components per pixel=3 RGB */
+ cinfo.in_color_space = JCS_RGB;
+ /* if ((outfile = fopen(FileName, "wb")) == NULL) {
+ printf("Cannot open file [%s]\n",FileName);
+ return 0;
+ } */
+ jpeg_stdio_dest(&cinfo, outfile);
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality (&cinfo,Quality,TRUE);
+ /* Starting compress */
+ jpeg_start_compress(&cinfo, TRUE);
+ /* Now compress everything one scanline at-a-time */
+ while (cinfo.next_scanline < cinfo.image_height) {
+ row_pointer = (JSAMPROW)(dataRGB+(cinfo.next_scanline*3*nx)); /* in bytes or words? */
+ jpeg_write_scanlines(&cinfo, &row_pointer, 1);
+ }
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ /* All done! */
+ /* fclose(outfile);*/
+ return 1;
+}
+
+/*--------------
+ A hack to hijack JPEG's innards to write into a memory buffer
+----------------
+/ this defines a new destination manager to store images in memory
+/ derived by jdatadst.c */
+typedef struct {
+ struct jpeg_destination_mgr pub; /* public fields */
+ JOCTET *buffer; /* start of buffer */
+ int bufsize; /* buffer size */
+ int datacount; /* finale data size */
+} memory_destination_mgr;
+
+typedef memory_destination_mgr *mem_dest_ptr;
+
+/*----------------------------------------------------------------------------
+ / Initialize destination --- called by jpeg_start_compress before any data is actually written. */
+
+METHODDEF(void)
+init_destination (j_compress_ptr cinfo)
+{
+ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = dest->bufsize;
+ dest->datacount=0;
+}
+
+
+
+/*----------------------------------------------------------------------------
+ / Empty the output buffer --- called whenever buffer fills up. */
+METHODDEF(boolean)
+empty_output_buffer (j_compress_ptr cinfo)
+{
+ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = dest->bufsize;
+
+ return TRUE;
+}
+
+
+/*----------------------------------------------------------------------------
+
+ / Terminate destination --- called by jpeg_finish_compress
+ / after all data has been written. Usually needs to flush buffer. */
+METHODDEF(void)
+term_destination (j_compress_ptr cinfo)
+{
+ /* expose the finale compressed image size */
+
+ mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
+ dest->datacount = dest->bufsize - dest->pub.free_in_buffer;
+
+}
+
+/*----------------------------------------------------------------------------
+/ Prepare for output to a memory buffer. The caller must have allocate memory
+/ to store the compressed image, and supply its size */
+GLOBAL(void)
+jpeg_memory_dest (j_compress_ptr cinfo, JOCTET *buffer,int bufsize)
+{
+ mem_dest_ptr dest;
+ if (cinfo->dest == NULL) { /* first time for this JPEG object? */
+ cinfo->dest = (struct jpeg_destination_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof(memory_destination_mgr));
+ }
+
+ dest = (mem_dest_ptr) cinfo->dest;
+ dest->bufsize=bufsize;
+ dest->buffer=buffer;
+ dest->pub.init_destination = init_destination;
+ dest->pub.empty_output_buffer = empty_output_buffer;
+ dest->pub.term_destination = term_destination;
+}
+
+/********************************************
+Identical in nearly every way to WriteJPEGToFileRGB(), but
+it writes into the memory buffer specified. To be safe, its
+good to make the memorybuffer the same size as the input image
++ 1024 bytes. It is guaranteed that the image will be less
+than this size. In fact, if you use a typical "quality" level
+of 75, you can get away with an image which is one quarter that
+size.
+
+ ******************************************** */
+int WriteJPEGToMemoryRGB(int nx,int ny, void *data, int Quality, char *memorybuffer,int bufsize){
+ JpgComp cinfo;
+ JpgErr jerr;
+ FILE * outfile;
+ unsigned char *dataRGB = (unsigned char *)data;
+ JSAMPROW row_pointer=(JSAMPROW)dataRGB;
+ JOCTET *jpgbuff;
+ mem_dest_ptr dest;
+ int csize=0;
+
+ /* zero out the compresion info structures and
+ allocate a new compressor handle */
+ memset (&cinfo,0,sizeof(cinfo));
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ /* Setup JPEG datastructures */
+ cinfo.image_width = nx ; /* image width and height, in pixels */
+ cinfo.image_height = ny;
+ cinfo.input_components = 3; /* # of color components per pixel=3 RGB */
+ cinfo.in_color_space = JCS_RGB;
+ jpgbuff = (JOCTET*)memorybuffer;
+
+ /* Setup compression and do it */
+ jpeg_memory_dest(&cinfo,jpgbuff,bufsize);
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality (&cinfo,Quality,TRUE);
+ jpeg_start_compress(&cinfo, TRUE);
+ /* compress each scanline one-at-a-time */
+ while (cinfo.next_scanline < cinfo.image_height) {
+ row_pointer = (JSAMPROW)(dataRGB+(cinfo.next_scanline*3*nx));
+ jpeg_write_scanlines(&cinfo, &row_pointer, 1);
+ }
+ jpeg_finish_compress(&cinfo);
+ /* Now extract the size of the compressed buffer */
+ dest=(mem_dest_ptr)cinfo.dest;
+ csize=dest->datacount; /* the actual compressed datasize */
+ /* destroy the compressor handle */
+ jpeg_destroy_compress(&cinfo);
+ return csize;
+}
+
+#define ClampToByte(f) (unsigned char)(f=(f>255)?255:f)
+/* Werner's nifty non-linear red-to-blue auto-colormap.
+ I faked a CCTK_REAL, you can make it the right thing
+ when integrated with cactus.
+
+ Anyways, the "rdfac" concentrates the colormap when you
+ use higher values. Typical default value is 32 based
+ on the current JPEG thorn.
+
+ Next step is to embed some IDL colormaps into the
+ program. I can do that a bit later.
+*/
+
+void AutoColorDataSlice(int nx,int ny, /* size of the image x & y */
+ CCTK_REAL *datain, /* 2D slice of data input */
+ unsigned char *dataout, /* RGB image data output */
+ CCTK_REAL min,CCTK_REAL max, /* range of the entire 3D dataset
+ This could be ranged based
+ on the values of the slice,
+ but then that would be a
+ bit untrustworthy. Its
+ best to pass in the
+ range for the entire
+ dataset or a pre-defined
+ fixed range. It does
+ handle clamping of the
+ range. */
+ CCTK_REAL bias,
+ int rdfac){
+ /* Bias allows you to move the spectrum from the Red to the
+ Blue. A value of 0.5 is the median. So 0.4 biases towards
+ the Red and 0.6 would bias a little towards the blue.
+ The range for this parameter would be -1.0 to +1.0. */
+ /* CCTK_REAL bias=0.4;*/
+ int i,last;
+ CCTK_REAL F=(CCTK_REAL)rdfac; /* cast to CCTK_REAL... don't know how the original worked at all without a cast */
+ for(i=0,last=nx*ny;i<last;i++,dataout+=3){
+ CCTK_REAL f=bias-(*datain++ - min)/(max-min);
+ /* f-=(max-min); zero-center it */
+ /* well it can't be less than 0 */
+ if(f>0){
+ f*=F;
+ /* Color components biased towards blue */
+ dataout[0]=ClampToByte(f);
+ f*=F;
+ dataout[1]=ClampToByte(f);
+ f*=F;
+ dataout[2]=ClampToByte(f);
+ }
+ else { /* f<0 */
+ f=-f;
+ f*=F;
+ /* reverse color components to bias towards red */
+ dataout[2]=ClampToByte(f);
+ f*=F;
+ dataout[1]=ClampToByte(f);
+ f*=F;
+ dataout[0]=ClampToByte(f);
+ }
+ }
+}
+
+#ifdef 0
+int main(int argc,char *argv[]){
+ /* OK, lets create a bogus image */
+ int nx=512,ny=512;
+ unsigned char *datargb=(unsigned char *)malloc(3*nx*ny);
+ CCTK_REAL *data= (CCTK_REAL*)malloc(nx*ny*sizeof(CCTK_REAL));
+ int i,j,idx=0;
+ CCTK_REAL radius=((CCTK_REAL)(nx/4));
+ CCTK_REAL min=(CCTK_REAL)(nx*ny),max=-1.0;
+ int bufsize = nx*ny*3+1024;
+ char *memorybuffer=(char *)malloc(bufsize); /* safe size for membuf */
+ int compressed_size=0;
+ FILE *outfile;
+ /* compute a circle by the most inefficient means possible */
+ for(j=0,idx=0;j<ny;j++){
+ CCTK_REAL y=((CCTK_REAL)(j-ny/2));
+ y*=y;
+ /* fprintf(stderr,"\n"); */
+ for(i=0;i<nx;i++,idx++){
+ CCTK_REAL x = ((CCTK_REAL)(i-nx/2));
+ CCTK_REAL val;
+ x*=x;
+ data[idx]= val=sqrt(x+y);
+
+ if(val>max) max=val;
+ if(val<min) min=val;
+ }
+ }
+ printf("Slice Data Min=%g Max=%g\n",min,max);
+ /* Autocolor extracted from Werner's JPEG thorn */
+ AutoColorDataSlice(nx,ny,data,datargb,min,max,32);
+ WriteJPEGToFileRGB(nx,ny, datargb,75, "write2file.jpg");
+ /* write to mem: It returns the size of the compressed image
+ cdntained in the memorybuffer */
+ compressed_size = WriteJPEGToMemoryRGB(nx,ny, datargb,75, memorybuffer,bufsize);
+ if ((outfile = fopen("write2mem.jpg", "wb")) == NULL) {
+ printf("Cannot open file write2mem.jpg\n");
+ return 0; /* failure */
+ }
+ fwrite(memorybuffer,1,compressed_size,outfile);
+ fclose(outfile);
+ return 1;
+}
+#endif
diff --git a/src/Output2D.c b/src/Output2D.c
new file mode 100644
index 0000000..f68e99c
--- /dev/null
+++ b/src/Output2D.c
@@ -0,0 +1,182 @@
+
+ /*@@
+ @routine IOJpeg_Output2DGH
+ @date Thu Sep 14 10:47:58 2000
+ @author Gerd Lanfermann
+ @desc
+ Preparing 2D data for output
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "IOJpeg.h"
+
+
+
+/* function prototypes */
+int IOJpeg_TimeFor2D (cGH *GH, int index);
+int IOJpeg_Output2DVarAs (cGH *GH, const char *var, const char *alias);
+static void CheckSteerableParameters (IOJpegGH *myGH);
+
+
+int IOJpeg_Output2DGH (cGH *GH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int i;
+ IOJpegGH *myGH;
+ const char *name;
+ char *fullname;
+ int ierr=0;
+
+ /* Get the GH extension for IOJpeg */
+ myGH = (IOJpegGH *) GH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ CheckSteerableParameters (myGH);
+
+ if (myGH->out2D_every <= 0)
+ return (0);
+
+ /* Loop over all variables */
+ for (i = 0; i < CCTK_NumVars (); i++)
+ {
+
+ if (IOJpeg_TimeFor2D (GH, i))
+ {
+
+ name = CCTK_VarName (i);
+ fullname = CCTK_FullName (i);
+
+ if (!CCTK_Equals(verbose,"no"))
+ CCTK_VInfo (CCTK_THORNSTRING, "IOJpeg_Output2DGH: fullname / name = "
+ "%s / %s", fullname, name);
+
+ ierr=IOJpeg_Output2DVarAs (GH, fullname, name);
+
+ free (fullname);
+
+ /* Register variable as having 2D output this iteration */
+ myGH->out2D_last [i] = GH->cctk_iteration;
+ }
+ }
+ if (!CCTK_Equals(verbose,"no"))
+ CCTK_INFO("IOJpeg_Output2DGH Done");
+
+ return (ierr);
+}
+
+
+int IOJpeg_Output2DVarAs (cGH *GH, const char *fullname, const char *alias)
+{
+ DECLARE_CCTK_PARAMETERS
+ int index,ierr=0;
+
+ index = CCTK_VarIndex (fullname);
+
+ /* first, check if variable has storage assigned */
+ if (! CCTK_QueryGroupStorageI (GH, CCTK_GroupIndexFromVarI (index)))
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "No IOJpeg 2D output for '%s' (no storage)", fullname);
+ return(-1);
+ }
+
+ if (!CCTK_Equals(verbose,"no"))
+ CCTK_VInfo (CCTK_THORNSTRING, "IOJpeg_Output2DVarAs: fullname, alias, "
+ "index = (%s, %s, %d)", fullname, alias, index);
+
+ /* Do the 2D output */
+ ierr=IOJpeg_Write2D (GH, index, alias);
+
+ return (ierr);
+}
+
+int IOJpeg_TimeFor2D (cGH *GH, int index)
+{
+ IOJpegGH *myGH;
+
+
+ /* Get the GH extension for IOJpeg */
+ myGH = (IOJpegGH *) GH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ CheckSteerableParameters (myGH);
+
+ /* Check if any output was requested */
+ if(myGH->out2D_every <= 0)
+ return (0);
+
+ /* Check this variable should be output */
+ if (! (myGH->do_out2D [index] && GH->cctk_iteration % myGH->out2D_every == 0))
+ return (0);
+
+
+ /* Check variable not already output this iteration */
+ if (myGH->out2D_last [index] == GH->cctk_iteration)
+ {
+ CCTK_WARN (2, "Already done 2D output in IOJpeg");
+ return (0);
+ }
+
+ return (1);
+}
+
+int IOJpeg_TriggerOutput2D (cGH *GH, int index)
+{
+ DECLARE_CCTK_PARAMETERS
+ IOJpegGH *myGH;
+ const char *varname;
+ int ierr=0;
+
+ varname = CCTK_VarName (index);
+
+ myGH = (IOJpegGH *) GH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ if (!CCTK_Equals(verbose,"no"))
+ CCTK_VInfo (CCTK_THORNSTRING, "IOJpeg_TriggerOutput2D: varname, index = "
+ "(%s, %d)", varname, index);
+
+ /* Do the 2D output */
+ ierr=IOJpeg_Write2D (GH, index, varname);
+
+ /* Register variable as having 2D output this iteration */
+ myGH->out2D_last [index] = GH->cctk_iteration;
+
+ return (ierr);
+}
+
+
+/**************************** local functions ******************************/
+static void CheckSteerableParameters (IOJpegGH *myGH)
+{
+ DECLARE_CCTK_PARAMETERS
+ int out2D_vars_current_nset;
+ static int out2D_vars_lastset = 0;
+
+
+ /* How often to output */
+ myGH->out2D_every = out_every > 0 ? out_every : -1;
+ if (out2D_every > 0)
+ myGH->out2D_every = out2D_every;
+
+ /* re-parse the 'out2D_vars' parameter if it was changed */
+ out2D_vars_current_nset = CCTK_ParameterQueryTimesSet ("out2D_vars",
+ CCTK_THORNSTRING);
+ if (out2D_vars_current_nset != out2D_vars_lastset)
+ {
+ IOUtil_ParseVarsForOutput (out2D_vars, myGH->do_out2D);
+
+ /* Save the last setting of 'out2D_vars' parameter */
+ out2D_vars_lastset = out2D_vars_current_nset;
+ }
+}
diff --git a/src/ParseGeometry.c b/src/ParseGeometry.c
new file mode 100644
index 0000000..b060708
--- /dev/null
+++ b/src/ParseGeometry.c
@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "util_String.h"
+#include "IOJpeg.h"
+#include "CactusBase/IOASCII/src/ioASCIIGH.h"
+
+void IOJpeg_DefaultGeo(cGH *GH, int sdim, IOJpegGeo_t *geo) {
+ DECLARE_CCTK_PARAMETERS
+
+ asciiioGH *asGH;
+ int idim,ti;
+ const char *tmp_origin, *tmp_downs, *tmp_length;
+ const char *token;
+
+ asGH = (asciiioGH *) GH->extensions
+ [CCTK_GHExtensionHandle ("IOASCII")];
+
+ geo->vdim = -1;
+ geo->sdim = -1;
+
+ for (idim=0;idim<SLABSKEL_MAXDIM;idim++) {
+ geo->direction[idim] = idim;
+ geo->slab_start[idim]= 0;
+ geo->length[idim] =-1;
+ geo->actlen[idim] =-1;
+ geo->downs[idim] = 1;
+ }
+
+ /* FIXME: we use spxyz, which is hardcoded to 3D */
+ for (idim=0;idim<3;idim++)
+ geo->slab_start[idim]=asGH->spxyz[2][(idim+1)%3][idim];
+
+ /* Parse the parameter of the requested dimension */
+ switch (sdim) {
+ case 2:
+ tmp_origin = origin2D;
+ tmp_downs = downsampling2D;
+ tmp_length = length2D;
+ break;
+ default:
+ tmp_origin = origin2D;
+ tmp_downs = downsampling2D;
+ tmp_length = length2D;
+ break;
+ }
+
+ /* Origin, set from parameter only if parameter value .ne. -1 */
+ idim=0;
+ while((token = Util_StrSep(&tmp_origin,","))) {
+ ti=atoi(token);
+ if (ti>-1) geo->slab_start[idim++] = ti;
+ }
+ ti = atoi(tmp_origin);
+ if (ti>-1) geo->slab_start[idim] = ti;
+
+ /* Downsample */
+ idim=0;
+ while((token = Util_StrSep(&tmp_downs,","))) {
+ geo->downs[idim++]=atoi(token);
+ }
+ geo->downs[idim] = atoi(tmp_downs);
+
+ /* Length */
+ idim=0;
+ while((token = Util_StrSep(&tmp_length,","))) {
+ geo->length[idim++]=atoi(token);
+ }
+ geo->length[idim] = atoi(tmp_length);
+}
+
+
+int IOJpeg_NumDirection(int sdim, int vdim)
+{
+ int numdir=-1;
+ if (vdim==3) {
+ switch (sdim) {
+ case 1: return(3);
+ case 2: return(3);
+ case 3: return(1);
+ }
+ } else if (vdim==2) {
+ switch (sdim) {
+ case 1: return(2);
+ case 2: return(1);
+ }
+ }
+ else if (vdim==1) {
+ switch (sdim) {
+ case 1: return(1);
+ }
+ }
+ else printf("Bad dimension: %d \n",vdim);
+ return(numdir);
+}
+
+int IOJpeg_SetDirection(int vdim, int sdim, int ci, int *direction)
+{
+ int retval=0;
+
+ if (sdim>vdim) {
+ printf("SetDirection: slabdim gt vdim");
+ return(-1);
+ }
+
+ if (vdim==3) {
+ if (sdim==2) {
+ switch (ci) {
+ case 0: direction[0]=0; direction[1]=1; break;
+ case 1: direction[0]=0; direction[1]=2; break;
+ case 2: direction[0]=1; direction[1]=2; break;
+ }
+ }
+ else if (sdim==1) {
+ switch (ci) {
+ case 0: direction[0]=0; break;
+ case 1: direction[0]=1; break;
+ case 2: direction[0]=2; break;
+ }
+ }
+ }
+ else if (vdim==2) {
+ if (sdim==2) {
+ direction[0]=0; direction[1]=1;
+ } else if (sdim==1) {
+ switch (ci) {
+ case 0: direction[0]=0; break;
+ case 1: direction[0]=1; break;
+ }
+ }
+ } else retval = -1;
+ return(retval);
+}
+
+
+
+
diff --git a/src/Startup.c b/src/Startup.c
new file mode 100644
index 0000000..323ffd0
--- /dev/null
+++ b/src/Startup.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+
+int IOJpeg_Output2DGH(cGH *GH);
+int IOJpeg_TriggerOutput2D(cGH *GH, int);
+int IOJpeg_TimeFor2D(cGH *GH, int);
+int IOJpeg_Output2DVarAs(cGH *GH, const char *var, const char *alias);
+
+void *IOJpeg_SetupGH (tFleshConfig *config, int convergence_level, cGH *GH);
+int IOJpeg_InitGH (cGH *GH);
+
+void IOJpeg_Startup (void)
+{
+ DECLARE_CCTK_PARAMETERS
+ int IO_GHExtension;
+ int IOMethod;
+
+
+ if (CCTK_GHExtensionHandle ("IO") < 0)
+ {
+ CCTK_WARN (1, "Thorn IOUtil was not activated. "
+ "No IOJpeg IO methods will be enabled.");
+ return;
+ }
+ if (CCTK_GHExtensionHandle ("PUGH") < 0)
+ {
+ CCTK_WARN (1, "Thorn PUGH was not activated. "
+ "No IOJpeg IO methods will be enabled.");
+ return;
+ }
+
+ IO_GHExtension = CCTK_RegisterGHExtension ("IOJpeg");
+ CCTK_RegisterGHExtensionSetupGH (IO_GHExtension, IOJpeg_SetupGH);
+ CCTK_RegisterGHExtensionInitGH (IO_GHExtension, IOJpeg_InitGH);
+
+ /* Register the 2D IOJpeg routines as output methods */
+
+ IOMethod = CCTK_RegisterIOMethod ("IOJpeg_2D");
+ CCTK_RegisterIOMethodOutputGH (IOMethod, IOJpeg_Output2DGH);
+ CCTK_RegisterIOMethodOutputVarAs (IOMethod, IOJpeg_Output2DVarAs);
+ CCTK_RegisterIOMethodTimeToOutput (IOMethod, IOJpeg_TimeFor2D);
+ CCTK_RegisterIOMethodTriggerOutput (IOMethod, IOJpeg_TriggerOutput2D);
+
+}
diff --git a/src/Write2D.c b/src/Write2D.c
new file mode 100644
index 0000000..874ec76
--- /dev/null
+++ b/src/Write2D.c
@@ -0,0 +1,168 @@
+
+#include "cctk.h"
+#include "cctk_Parameters.h"
+#include "CactusBase/IOUtil/src/ioGH.h"
+#include "IOJpeg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* local function prototypes */
+int IOJpeg_NumDirection(int sdim, int vdim);
+int IOJpeg_SetDirection(int vdim, int sdim, int ci, int *direction);
+
+static int *advertised;
+
+int IOJpeg_Write2D (cGH *GH, int index, const char *alias)
+{
+ DECLARE_CCTK_PARAMETERS
+ int timelevel;
+ ioGH *ioUtilGH;
+ IOJpegGH *ssGH;
+ IOJpegGeo_t geo;
+ FILE **fdset_2D; /* array of output file pointers */
+ int SDIM;
+ int si,max_slabs;
+ int ierr=0;
+
+ /* Get the handle for IO extensions */
+ ioUtilGH = (ioGH *) GH->extensions [CCTK_GHExtensionHandle ("IO")];
+ ssGH = (IOJpegGH *) GH->extensions [CCTK_GHExtensionHandle ("IOJpeg")];
+
+ /* The dimension of the slab - HARDCODED */
+ SDIM = 2;
+
+ /* Get the slab geometry for 2D slabs */
+ geo = ssGH->out_geo[index][SDIM];
+ /* Set geo.sdim to announce 2D output */
+ geo.sdim = SDIM;
+ /* get the dimension of the variable */
+ geo.vdim = CCTK_GroupDimFromVarI(index);
+
+ if (!CCTK_Equals(verbose,"no"))
+ CCTK_VInfo (CCTK_THORNSTRING, "IOJpeg %dD-output of variable '%s', "
+ "downsampling parameters (%d, %d, %d)", SDIM, alias,
+ geo.downs[0], geo.downs [1], geo.downs [2]);
+
+ /* get the current timelevel */
+ timelevel = CCTK_NumTimeLevelsFromVarI (index) - 1;
+ if (timelevel > 0)
+ timelevel--;
+
+ /* Maximal number of slabs (dimension sdim) in
+ given volume (dimension vdim) */
+ if ((max_slabs=IOJpeg_NumDirection(SDIM, geo.vdim))<0)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Cannot get valid number of slabs (%d) for given volume (%d).\n",
+ SDIM, geo.vdim);
+ return(-1);
+ }
+
+ /* see if output file for this alias name was already created */
+ fdset_2D = (FILE **) GetNamedData (ssGH->fileList_2D, alias);
+ /* if (fdset_2D == NULL) */
+ {
+ char *fname;
+
+ fdset_2D = (FILE **) malloc (max_slabs * sizeof (FILE *));
+ fname = (char *) malloc ((strlen (ssGH->outdir2D) + strlen (alias) + 20)*sizeof(char));
+
+ /* Set flags for remembering if files have been advertised */
+ if (!advertised)
+ {
+ advertised = (int *)malloc(max_slabs*sizeof(int));
+ for (si=0;si<max_slabs;si++)
+ {
+ advertised[si] = 0;
+ }
+ }
+
+ /* Loop over all possible choices */
+ for (si=0;si<max_slabs;si++) {
+
+ /* Get the next set of slab directions */
+ if (IOJpeg_SetDirection(geo.vdim, SDIM, si, geo.direction)<0) {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Cannot set direction for slab (#%d) in given volume (%d).\n",
+ si, geo.vdim);
+ continue;
+ }
+
+
+ /* **********************************************
+ File open procedures which are more complex,
+ like for HDF5 can go here and you would pass
+ the file ID through to DumpVar. He we set fid=1
+ for proc0 and make it available as a flag
+ ********************************************** */
+
+ if (CCTK_MyProc (GH) == 0)
+ {
+ IOUtil_AdvertisedFileDesc_t advertised_file;
+ const char *extensions [3] = {"yz", "xz", "xy"};
+
+ if (CCTK_Equals(mode,"remove"))
+ {
+ sprintf (fname, "%s/%s_2d_%s.jpeg", ssGH->outdir2D,alias,
+ extensions [si]);
+ }
+ else
+ {
+ sprintf (fname, "%s/%s_2d_%s.%d.jpeg", ssGH->outdir2D,alias,
+ extensions [si],GH->cctk_iteration);
+ }
+
+ fdset_2D [si] = fopen (fname, "w");
+ if (! fdset_2D [si])
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Cannot open 2D output file '%s'", fname);
+ return;
+ }
+
+ /* advertise the file for downloading */
+ if (CCTK_Equals(mode,"remove") && advertised[si] == 0)
+ {
+ advertised_file.slice = (char *) extensions [si];
+ advertised_file.thorn = CCTK_THORNSTRING;
+ advertised_file.varname = CCTK_FullName (index);
+ advertised_file.description = "Jpegs of slices";
+ advertised_file.mimetype = "image/jpeg";
+
+ IOUtil_AdvertiseFile (GH, fname, &advertised_file);
+ advertised[si] = 1;
+ free (advertised_file.varname);
+ }
+ }
+
+ /* store file desriptors in database */
+ StoreNamedData (&ssGH->fileList_2D, alias, fdset_2D);
+
+ /* **********************************************
+ The call to the actual data collection and
+ lowlevel output routine.
+ ********************************************** */
+
+ ierr = IOJpeg_DumpVar(GH, index, timelevel, &geo, fdset_2D[si]);
+ if (ierr<0) CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "IOJpeg_DumpVar failed for GF index: %d\n",
+ index);
+
+ /* **********************************************
+ File close procedures which are more complex,
+ like for HDF5 can go here.
+ ********************************************** */
+
+ /* Close the file */
+ close (fdset_2D [si]);
+
+ }
+
+ free(fname);
+
+ }
+
+ return(ierr);
+}
diff --git a/src/make.code.defn b/src/make.code.defn
new file mode 100644
index 0000000..096edce
--- /dev/null
+++ b/src/make.code.defn
@@ -0,0 +1,9 @@
+# Main make.code.defn file for thorn IOSkeleton
+# $Header$
+
+# Source files in this directory
+SRCS = DumpVar.c Output2D.c Write2D.c Startup.c ParseGeometry.c GHExtension.c JPEG.c
+
+# Subdirectories containing source files
+SUBDIRS =
+