#include #include #include /* compile this file with cc -o adsc2sgi adsc2sgi.c -lm */ #define TRUE 1 #define FALSE 0 /* global notifier of frame byte=order */ int swap_bytes = FALSE; /* frame handling routines */ FILE *GetFrame(char *filename); typedef struct _SGIHeader { short Magic; /* Identification number (474) */ char storage; /* Compression flag */ char bpc; /* Bytes per pixel */ unsigned short int dimension; /* Number of image dimensions */ unsigned short int xsize; /* Width of image in pixels */ unsigned short int ysize; /* Height of image in pixels */ unsigned short int zsize; /* Number of bit planes */ long pixmin; /* Smallest pixel value */ long pixmax; /* Largest pixel value */ char dummy1[4]; /* Not used */ char name[80]; /* Name of image */ long colormap; /* Format of pixel data */ char dummy2[404]; /* Not used */ } SGIHEAD; main(int argv, char** argc) { /* exit status */ int return_code = 0; /* utility variables */ int i; char *filename; FILE *frame = NULL; unsigned short int **image; /* frame information variables */ int record_size; int num_records; int pixels_per_line; int image_width; int image_height; float eight; /* indicies */ int x, z; int overloads = 0; /* limits */ int high = 0; int low = 0xFFFF; double sum = 0; double sigma = 0; double scale = 0; double zoom = 1; int negate = 0; int start_x = 0; int start_y = 0; int stop_x = 0; int stop_y = 0; /* storage */ unsigned short int *record; unsigned short int *swapped; unsigned short int *temp; /* output RGB stuff */ SGIHEAD SGIhead; unsigned char *SGIdata; FILE *rgbout = NULL; char outfilename[256] = "new.rgb"; /* begin progam here */ printf("ADSC2SGI 1.0.1\t\tby James Holton 3-4-99\n\n"); /* check argument list */ for(i=1; i= (i+1))) { scale = atof(argc[i+1]); } if(strstr(argc[i], "-zoom") && (argv >= (i+1))) { zoom = atof(argc[i+1]); } if(strstr(argc[i], "-box") && (argv >= (i+4))) { start_x = atol(argc[i+1]); start_y = atol(argc[i+2]); stop_x = atol(argc[i+3]); stop_y = atol(argc[i+4]); } } } if(frame != NULL) { /* Print intentions */ printf("converting %s to %s\n", filename, outfilename); printf("scaling size by %g\n", zoom); if(scale == 0) { printf("autoscaling intensity \n"); } else { printf("intensity scale set to %g\n", scale); } printf("\n"); /* Filename */ printf("reading %s ", filename); record_size = 4608; num_records = 2304; pixels_per_line = 2304; if((stop_x == 0)||(stop_x > pixels_per_line)) stop_x = pixels_per_line; if((stop_y == 0)||(stop_y > num_records)) stop_y = num_records; if(stop_x < start_x) {i = start_x; start_x = stop_x; stop_x = i;} if(stop_y < start_y) {i = start_y; start_y = stop_y; stop_y = i;} image_width = stop_x - start_x; image_height = stop_y - start_y; printf("box from (%d,%d) to (%d,%d)\n", start_x, start_y, stop_x, stop_y); /* allocate space for memeory-resident image */ image = (unsigned short int **) calloc(sizeof(unsigned short int *), image_height); /* need a little extra memory for swapping bytes */ if(swap_bytes == TRUE) { swapped = calloc(1, image_width*2); printf("swapping bytes...\n"); } /* load appropriate records (line) into memory */ for(z = 0; z < image_height; ++z) { /* allocate space for this line */ record = calloc(2, image_width); /* position file at beginning of the desired scan line */ fseek(frame, ((z+start_y)*record_size)+(start_x*2)+512, SEEK_SET); /* read the record into memory */ fread(record, 2, image_width, frame); /* Account for byte swapping */ if(swap_bytes == TRUE) { /* preserve location of read-in pixels */ temp = record; /* swab() can only COPY swapped bytes */ swab((char*)record, (char*)swapped, image_width*2); record = swapped; /* exchange buffers for next time */ swapped = temp; } /* enter this record into the image */ image[z] = record; /* do statistics on pixel values */ for(x = 0; x < image_width; ++x) { /* i = start_x + x; /* initialize from words in file */ if(record[x] == 0xFFFF) { ++overloads; } else { sigma += ( (double) image[z][x]) * ((double) image[z][x]); } /* debug * printf("reading (%d,%d) ", z, x); printf("from (%d+%d)*%d+%d*2+512 ", z, start_y, record_size, start_x ); printf(" = %d \n", image[z][x]); /* */ } } /* image has now been completely read into memory */ fclose(frame); /* do some statistics */ sigma /= (double) (image_width * image_height); sigma = sqrt(sigma); /* autoscale output image to 5-sigma cuttoff */ if(scale == 0) { scale = 256.0/(5*sigma); printf("intensity scale set to %g\n", scale); } /* construct RGB image header */ SGIhead.Magic = 474; /* always 474 for RGB */ SGIhead.storage = 0; /* uncompressed */ SGIhead.bpc = 1; /* one byte per pixel (channel) */ SGIhead.dimension = 2; /* 2D image */ SGIhead.xsize = image_width*zoom; /* */ SGIhead.ysize = image_height*zoom; /* */ SGIhead.zsize = 1; /* one z-pixel (* channels) */ SGIdata = (unsigned char *) calloc(SGIhead.xsize*SGIhead.ysize*SGIhead.zsize, SGIhead.bpc); strncpy(SGIhead.dummy1, SGIdata, 4); strncpy(SGIhead.dummy2, SGIdata, 404); SGIhead.pixmin = 0; /* minimum pixel value */ SGIhead.pixmax = 255; /* maximum pixel value */ strcpy(SGIhead.name, "no name"); /* set to origional image name */ SGIhead.colormap = 0; /* grayscale/RGB */ /* convert and copy all image data into new RGB file */ printf("transforming data ...\n"); for(z = 0; z < SGIhead.ysize; ++z) { for(x = 0; x < SGIhead.xsize; ++x) { /* debug * printf("xform (%d,%d) -> (%d,%d) = ", (int)(z/zoom), (int)(x/zoom), z, x); printf("%d\n", image[(int)(z*zoom)][(int)(x/zoom)]); /* */ /* transform frame image */ sum = scale*image[(int)(z/zoom)][(int)(x/zoom)]; if(sum > 255) sum = 255; if(negate) sum = 255-sum; SGIdata[(z*SGIhead.xsize)+x] = (unsigned char) sum; } } /* write out the RGB image */ rgbout = fopen(outfilename, "wb"); if(rgbout != NULL) { printf("writing %s\n", outfilename); fwrite(&SGIhead, 512, 1, rgbout); fwrite(SGIdata, SGIhead.bpc, SGIhead.xsize*SGIhead.ysize*SGIhead.zsize, rgbout); fclose(rgbout); } else { printf("ERROR: could not open %s\n", outfilename); } } else { printf("usage: %s framefile.img [outfile.rgb] [-zoom factor] [-box x1 y1 x2 y2] [-negate]\n", argc[0]); printf("\n\t framefile.img - the ADSC CCD image file you want to convert\n"); printf( "\t outfile.rgb - name of output SGI RGB file.\n"); printf( "\t factor - zoom in by this factor.\n"); printf( "\t x1 y1 x2 y2 - corners of box to convert (original image pixel coordinates).\n"); printf( "\t -negate - black spots on white background\n"); printf("\n"); printf( "NOTE:\t denzo/mosflm (X,Y) detector coordinates are (Y,X) here."); printf("\n"); /* report unhappy ending */ return_code = 1; } return return_code; } FILE *GetFrame(char *filename) { FILE *frame; unsigned char header[512]; unsigned char *string; unsigned char *byte_order; typedef union { unsigned char string[2]; unsigned short integer; } TWOBYTES; TWOBYTES twobytes; twobytes.integer = 24954; frame = fopen(filename, "rb"); if(frame != NULL) { fread(header, 1, 512, frame); /* What kind of file is this? */ string = header; if(0!=strncmp(string, "{\nHEADER_BYTES= 512;\nDIM=2;\nBYTE_ORDER=", 40)) { /* probably not an ADSC frame */ /* inform the user */ printf("ERROR: %s does not look like an ADSC frame!\n", filename); /* skip this file */ fclose(frame); frame = NULL; } else { /* determine byte order on this machine */ if(0==strncmp(twobytes.string, "az", 2)) { byte_order = "big_endian"; } else { byte_order = "little_endian"; } /* see if we will need to swap bytes */ string = (char *) strstr(header, "BYTE_ORDER=")+11; if(0==strncmp(byte_order, string, 10)) { swap_bytes = FALSE; } else { swap_bytes = TRUE; } } } else { /* fopen() failed */ perror("adsc2sgi"); } return frame; }