From: robert@texas.asd.sgi.com (Robert Skinner)
Newsgroups: comp.graphics.explorer
Subject: Re: PseudocolorImg
Date: 13 Aug 92 23:01:41 GMT
Reply-To: robert@sgi.com
Organization: Silicon Graphics Inc., Advanced Systems Division

In article <1992Jul23.030121.22502@qdpii.comp.qdpi.oz.au>, dres@qdpii.comp.qdpi.oz.au (Drought Research Account) writes:
|> Recently I pulled SGI's PseudocolorImg module off the edinburgh ftp site.
|> It works fine on byte lattices, but doesn't seem to cope with other
|> primitive data types. If it really only wants byte data, it should have
|> its input port so configured, invoking the automatic type coercion. If
|> not, what else does it need to work with other data types ? Any clues 
|> anyone  (especially SGI) ? I checked the mres file, and it is currently set
|> to allow any primitive data type.
|> 

PseudocolorImg didn't properly scale float and double outputs.
Here is the updated code:


#include <malloc.h>

#include <cx/DataTypes.h>
#include <cx/DataAccess.h>
#include <cx/Lookup.h>

void pseudo(cxLattice *inLat, cxLattice *cMap, cxLattice **outLat)
{
    long nDim, *dims, hasData, hasCoord, nCoordVar, nDataVar;
    long newDataVar, number,i, size, j;
    cxPrimType primType;
    cxCoordType coordType;
    cxCoord *coordStruct;
    cxLookup *clut;
    float color_array[4], data, *ivec, *cptr;
    void *oldDataVals;
    void *newDataVals;
    unsigned char *uc_data, *cc_data;
    short *sc_data, hi_val, lo_val, tot_vals;

    cxLatDescGet(inLat,&nDim, &dims, &hasData, &nDataVar, &primType,
	 &hasCoord, &nCoordVar, &coordType);

    newDataVar = 3;
    size = 4;
    *outLat = cxLatDataNew(nDim, dims, newDataVar, cx_prim_byte);
    cxLatPtrGet(inLat, NULL, &oldDataVals, &coordStruct, NULL);
    cxLatPtrSet(*outLat, NULL, NULL, coordStruct, NULL);
    cxLatPtrGet(*outLat,NULL,&newDataVals,NULL,NULL);
    uc_data = newDataVals;
    cc_data = oldDataVals;
    sc_data = oldDataVals;
    clut = cxLookupCreate(cMap,0);
    number = cxDimsProd(nDim, dims, nDataVar);
    switch (primType){
        case cx_prim_byte:
	      cptr = (float *)malloc(4*256*sizeof(float));
	      ivec = (float *)malloc(256*sizeof(float));
	      for(i=0;i<256;i++){
		   ivec[i] = i;
	      }
	      cxLookupInterpV(clut,256,ivec,cptr);
	      free(ivec);
	      for(i=0;i<number;i++)
	         for(j=0;j<newDataVar;j++){
		     uc_data[i*newDataVar+j] = cptr[cc_data[i]*4 + j] * 255.;
	         }
	      free(cptr);
	      break;
        case cx_prim_short:
	      cxLatPtrGet(cMap,NULL,NULL,NULL,&cptr);
	      lo_val = cptr[0];
	      hi_val = cptr[1];
	      tot_vals = hi_val-lo_val+1;
	      cptr = (float *)malloc(4*tot_vals*sizeof(float));
	      ivec = (float *)malloc(tot_vals*sizeof(float));
	      for(i=0; i< tot_vals; i++)
		  ivec[i] = lo_val + i;
	      cxLookupInterpV(clut,tot_vals,ivec,cptr);
	      free(ivec);
	      for(i=0;i<number;i++)
		  if(sc_data[i] <= lo_val){
			uc_data[i*newDataVar  ] = cptr[0]*255;
			uc_data[i*newDataVar+1] = cptr[1]*255;
			uc_data[i*newDataVar+2] = cptr[2]*255;
			uc_data[i*newDataVar+3] = cptr[3]*255;
		  }else if(sc_data[i] >= hi_val){
			uc_data[i*newDataVar  ] = cptr[4*tot_vals  ]*255;
			uc_data[i*newDataVar+1] = cptr[4*tot_vals+1]*255;
			uc_data[i*newDataVar+2] = cptr[4*tot_vals+2]*255;
			uc_data[i*newDataVar+3] = cptr[4*tot_vals+3]*255;
		  }else{
	              for(j=0;j<newDataVar;j++)
		     		uc_data[i*newDataVar+j] = cptr[(sc_data[i]-lo_val)*4 + j] * 255.;
	         }
	      free(cptr);
	      break;
	 case cx_prim_long:
    	    for(i=0; i<number;i++){
	      data = ((long *)oldDataVals)[i];
	      cxLookupInterp(clut, &data,color_array);
	      for(j=0;j<newDataVar;j++){
		   uc_data[i*newDataVar+j] = color_array[j] * 255.;
	      }
	    }
	    break;
	 case cx_prim_float:
    	    for(i=0; i<number;i++){
	      data = ((float *)oldDataVals)[i];
	      cxLookupInterp(clut, &data,color_array);
	      for(j=0;j<newDataVar;j++){
		   uc_data[i*newDataVar+j] = color_array[j] * 255.;
	      }
	    }
	    break;
	 case cx_prim_double:
    	    for(i=0; i<number;i++){
	      data = ((double *)oldDataVals)[i];
	      cxLookupInterp(clut, &data,color_array);
	      for(j=0;j<newDataVar;j++){
		   uc_data[i*newDataVar+j] = color_array[j] * 255.;
	      }
	    }
	    break;
    }
    cxLookupDestroy(clut);
}

-- 

Robert Skinner
robert@sgi.com

	"I don't know about you, but I've always assumed that the TV
ratings were based on the viewing habits of people who could easily
fit their cerebral cortices inside a standard cold capsule.  I based
this opinion on such evidence as the extreme popularity of the show
"Wheel of Fortune".  Every time I tune it in, there's a contestant
frowning with intense concentration at a group of letters like
"H-A-P-P-Y B-I-R-T-H-D-A-(blank),"  then guessing that the missing
letter is: "W."  Then the lovely Miss Vanna White, displaying the
poise and talent that have made her one of the most respected, if not
THE most respected, bimbos in the Free World, turns over the blank to
reveal -- oh, no! -- a Y, causing the live studio audience to react
with an outpouring of grief of the type normally associated with the
loss of a popular family member."

				Dave Barry
Newsgroups: comp.graphics.explorer