home *** CD-ROM | disk | FTP | other *** search
- /*
- % DCVtoB . C
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- This software is copyright (C) by the Lawrence Berkeley Laboratory.
- Permission is granted to reproduce this software for non-commercial
- purposes provided that this notice is left intact.
-
- It is acknowledged that the U.S. Government has rights to this software
- under Contract DE-AC03-765F00098 between the U.S. Department of Energy
- and the University of California.
-
- This software is provided as a professional and academic contribution
- for joint exchange. Thus, it is experimental, and is provided ``as is'',
- with no warranties of any kind whatsoever, no support, no promise of
- updates, or printed documentation. By using this software, you
- acknowledge that the Lawrence Berkeley Laboratory and Regents of the
- University of California shall have no liability with respect to the
- infringement of other copyrights by any part of this software.
-
- For further information about this notice, contact William Johnston,
- Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- (wejohnston@lbl.gov)
-
- For further information about this software, contact:
- Jin Guojun
- Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- g_jin@lbl.gov
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % This program convert following format image to Byte image:
- %
- % float complex
- % double, double complex
- % float vfft 2D, float vfft 3D
- % double vfft 2D, double vfft 3D
- %
- % Also converting VFFT and double VFFT to corresponding complex FFT.
- */
- char usage[]="options\n\
- [-div #] maximum input value divident for auto scale. \n\
- The large value results a bright picture \n\
- [-fflip] do fast quad flip on regular complex format for view only\n\
- [-flip ] do regular quadrant flip on regular complex format \n\
- [-maxi #] specify the maximum input value(range) \n\
- [-Complex] VFFT to Complex (FFT) \n\
- [-Float] output Float format instead of Bytes \n\
- [-nonscale] output non scaled conversion \n\
- [-regular] output original VFFT spectrum, not quad flipped \n\
- [-selfscale] re-scaling for each frame \n\
- (regular scale calculation done at first frame) \n\
- [<] input [> byte_image]\n";
- /*
- % compile:
- % cc -O -o DEST/dcvtob dcvtob.c -lscs3 -lccs -lhips -lrle -ltiff -lm
- %
- % AUTHOR: Guojun Jin - LBL 5/1/91
- */
-
- #include <math.h>
- #include "complex.h"
- #include "header.def"
- #include "imagedef.h"
-
- U_IMAGE uimg;
-
- #define inbuf uimg.src
- #define obuf uimg.dest
- #define frm uimg.frames
- #define cln uimg.width
- #define row uimg.height
-
- #ifdef _DEBUG_
- extern int debug;
- #endif
- bool verbose, spectrum=True, fflip, flip, selfscale, v2dtoc;
-
-
- main(argc, argv)
- int argc;
- char* argv[];
- {
- int i, f, fsize, dimen1len, vfsize;
- double *dbuf, *vbuf, *cvt, maxi=0, scale=0, divident=1.;
-
- format_init(&uimg, IMAGE_INIT_TYPE, HIPS, -1, *argv, "S20-1");
- uimg.pxl_out = 1;
-
- for (i=1; i<argc; i++)
- if (strcmp(argv[i], "-v")==0) verbose++;
- else if (!strncmp(argv[i], "-m", 2) && i+1 < argc)
- maxi = atof(argv[++i]);
- else if (!strncmp(argv[i], "-di", 3) && i+1 < argc)
- divident = atof(argv[++i]);
- else if (!strncmp(argv[i], "-C", 2))
- v2dtoc++;
- else if (!strncmp(argv[i], "-F", 2))
- uimg.pxl_out = sizeof(float);
- else if (!strncmp(argv[i], "-ff", 3))
- flip = ++fflip;
- else if (!strncmp(argv[i], "-fl", 3))
- flip++;
- else if (!strncmp(argv[i], "-r", 2))
- spectrum=0;
- else if (!strncmp(argv[i], "-s", 2))
- selfscale++;
- else if (!strcmp(argv[i], "-n"))
- scale = 1.;
- else if ((in_fp=freopen(argv[i], "rb", stdin))==0)
- info: usage_n_options(usage, i, argv[i]);
-
- io_test(fileno(in_fp), goto info);
-
- (*uimg.header_handle)(HEADER_READ, &uimg, 0, 0);
-
- if (uimg.in_form<IFMT_COMPLEX || uimg.in_form>IFMT_DBLCOM &&
- (uimg.in_form < IFMT_VFFT3D || uimg.in_form > IFMT_DVVFFT3D))
- syserr("not in double, complex or vfft format");
-
- if (uimg.pxl_out == 1)
- uimg.o_form = IFMT_BYTE;
- else uimg.o_form = IFMT_FLOAT;
- if (v2dtoc)
- if (uimg.in_form < IFMT_VFFT3D && uimg.in_form > IFMT_DVFFT2D)
- v2dtoc = False;
- else
- mesg("VFFT to Complex FFT\n"),
- uimg.o_form = IFMT_COMPLEX,
- uimg.pxl_out = 8<<(uimg.in_form>=IFMT_DVFFT3D);
-
- dimen1len = (cln>>1) + 1;
- fsize = row * cln;
- if (uimg.in_form > IFMT_DBLCOM)
- vfsize = row * dimen1len;
- else vfsize = fsize;
-
- dbuf = nzalloc(vfsize, uimg.pxl_in, "dbuf");
- obuf = nzalloc(fsize, uimg.pxl_out, "obuf");
- if (vfsize != fsize || flip && uimg.in_form < IFMT_VFFT3D)
- vbuf = nzalloc(fsize, sizeof(*vbuf), "vbuf");
-
- (*uimg.header_handle)(HEADER_WRITE, &uimg, argc, argv, True);
-
- if (v2dtoc) /* 2D VFFT to complex */
- for (f=0; f<frm; f++) {
- int r_len = row+1>>1, c_len = cln+1>>1;
-
- i=upread(dbuf, uimg.pxl_in, vfsize, in_fp);
- if (i != vfsize)
- syserr("[%d] read %d", vfsize, i);
- if (uimg.in_form==IFMT_VFFT2D || uimg.in_form==IFMT_VFFT3D){
- register float vscale=scale;
- register COMPLEX *c_in = PrtCAST dbuf, *cp=obuf;
-
- if (!vscale) vscale /= fsize * (uimg.in_form & 1 ? frm : 1);
-
- cp->re = c_in->re * vscale;
- cp->im = c_in->im * vscale;
- for (i=1; i<c_len; i++) {
- cp[cln-i].re = cp[i].re = c_in[i].re * vscale;
- cp[cln-i].im = -(cp[i].im = c_in[i].im * vscale);
- }
- if ((cln & 1)==0){
- cp[i].re = c_in[i].re * vscale;
- cp[i].im = c_in[i].im * vscale;
- }
-
- for (i=1; i<r_len; i++) { /* dis for conjugate symmetry */
- register int j=0, dis=(row-(i<<1))*dimen1len,
- dis1=cln*(row-(i<<1)), dis0=dis1+cln;
- cp += cln;
- c_in += dimen1len;
- cp->re = c_in[j].re * vscale;
- cp->im = c_in[j].im * vscale;
- cp[dis1].re = c_in[dis].re * vscale;
- cp[dis1].im = c_in[dis].im * vscale;
- for (j=1; j<c_len;j++) {
- cp[dis0-j].re = cp[j].re = c_in[j].re * vscale;
- cp[dis0-j].im = -(cp[j].im = c_in[j].im * vscale);
- cp[cln-j].re = cp[dis1+j].re = c_in[dis+j].re * vscale;
- cp[cln-j].im = -(cp[dis1+j].im = c_in[dis+j].im * vscale);
- }
- if ((cln & 1)==0) {
- cp[j].re = c_in[j].re * vscale;
- cp[j].im = c_in[j].im * vscale;
- cp[dis1+j].re = c_in[dis+j].re * vscale;
- cp[dis1+j].im = c_in[dis+j].im * vscale;
- }
- }
- if ((row & 1)==0) {
- cp += cln;
- c_in += dimen1len;
- cp->re = c_in->re * vscale;
- cp->im = c_in->im * vscale;
- for (i=1; i<c_len; i++) {
- cp[cln-i].re = cp[i].re = c_in[i].re * vscale;
- cp[cln-i].im = -(cp[i].im = c_in[i].im * vscale);
- }
- if ((cln & 1)==0){
- cp[i].re = c_in[i].re * vscale;
- cp[i].im = c_in[i].im * vscale;
- }
- }
- }
- else {
- register double *ibp = dbuf, vscale=scale;
-
- if (!vscale) vscale /= fsize * (uimg.in_form & 1 ? frm : 1);
- for (i=0; i<row; i++){
- register int j;
- register DBCOMPLEX *cp=obuf;
- cp += i*cln;
- cp->re = *ibp++ * vscale;
- cp->im = *ibp++ * vscale;
- for (j=1; j<cln+1>>1;j++){
- cp[cln-j].re = cp[j].re = *ibp++ * vscale;
- cp[cln-j].im = -(cp[j].im = *ibp++ * vscale);
- }
- if ((cln & 1)==0){
- cp[cln>>1].re = *ibp++ * vscale;
- cp[cln>>1].im = *ibp++ * vscale;
- }
- }
- }
- if ((i=fwrite(obuf, uimg.pxl_out, fsize, out_fp)) != fsize)
- syserr("[%d] write %d", fsize, i);
- }
- else for (f=0; f<frm; f++){
- register double *dp;
-
- cvt = dbuf;
- if ((i=upread(dbuf, uimg.pxl_in, vfsize, in_fp)) != vfsize)
- syserr("[%d] Read %d", vfsize, i);
- if (uimg.in_form==IFMT_COMPLEX)
- complex_to_d(dbuf, vfsize);
- else if (uimg.in_form == IFMT_DBLCOM)
- dcomplex_to_d(dbuf, vfsize);
- else if (uimg.in_form > IFMT_DBLCOM)
- vfft_handle(uimg.in_form, dbuf, cvt=vbuf, row, cln, dimen1len);
- if (uimg.in_form < IFMT_VFFT3D)
- if (fflip)
- Dcom_fflip(dbuf, cvt=vbuf, row, cln);
- else if (flip)
- Dcom_flip(dbuf, cvt=vbuf, row, cln);
-
- dp = cvt;
-
- if (uimg.o_form == IFMT_BYTE){
- register byte *bp = obuf;
- double imin;
-
- if (scale != 1. && f==0 || selfscale || scale > 1.7e308){
- register double min=1.7e308, max=1.7e-308, value;
- for (i=0; i<fsize; i++){
- value = dp[i];
- if (value < min) min = value;
- else if (value > max) max = value;
- }
- if (verbose || uimg.in_form > IFMT_DBLCOM)
- message("%s: min_in=%f, max_in=%f\n", Progname, min, max);
- if (maxi)
- max = maxi;
- else max /= divident;
- scale = 255. / (max - min);
- imin = min;
- if (verbose || uimg.in_form > IFMT_DBLCOM)
- message("%s: max_in set to=%4.4f, scale=%f\n",
- Progname, max, scale);
- }
- {
- register double bscale = scale, min = imin;
- if (bscale > 1.7e308)
- bscale = 1.;
- for (i=0; i<fsize; i++){
- register int tmp = bscale * (dp[i] - min);
- if (tmp > 255)
- bp[i] = 255;
- else bp[i] = tmp;
- }
- }
- }
- else{
- register float *fp = obuf;
- if (uimg.in_form > IFMT_DBLCOM){
- register double fscale = 1. / fsize;
- for (i=0; i<fsize; i++)
- *fp++ = fscale * *dp++;
- }
- else for (i=0; i<fsize; i++)
- *fp++ = *dp++;
- }
- if ((i=fwrite(obuf, uimg.pxl_out, fsize, out_fp)) != fsize)
- syserr("[%d] write %d", fsize, i);
- }
- }
-
-
- /* float complex to double */
- complex_to_d(buf, size)
- VType *buf;
- {
- register float *fp = buf;
- register double *op = buf;
- register int i;
-
- if (verbose) mesg("converting complex to double\n");
- for (i=0; i<size; i++){
- register double value = *fp * *fp;
- fp++;
- value += *fp * *fp;
- fp++;
- *op++ = sqrt(value);
- }
- }
-
- /* double complex to real double */
- dcomplex_to_d(buf, size)
- register double *buf;
- {
- register double *ibp = buf;
- register int i;
-
- if (verbose) mesg("converting double complex to double\n");
- for (i=0; i<size; i++){
- register double value = *ibp * *ibp;
- ibp++;
- value += *ibp * *ibp;
- ibp++;
- *buf++ = sqrt(value);
- }
- }
-
-
- /*===============================================
- % This routine convert vfft to spectrum. %
- % It is exactly transform. %
- ===============================================*/
- vfft_handle(vform, ibuf, o_buf, rows, cols, dimen1len)
- double *ibuf, *o_buf;
- {
- int vsize = rows * dimen1len;
-
- switch(vform){
- case IFMT_VFFT2D:
- case IFMT_VFFT3D: complex_to_d(ibuf, vsize);
- break;
- case IFMT_DVFFT2D:
- case IFMT_DVFFT3D: dcomplex_to_d(ibuf, vsize);
- break;
- }
-
- if (spectrum) { /* VFFT spectrum */
- register int i, j, dc=dimen1len-(dimen1len&1);
- register double *src=ibuf + (vsize>>1), *dst=o_buf + dimen1len-1,
- *dstcs=o_buf + rows*cols - (dimen1len + (cols&1));
- /* like in v2dtoc, we can use integer dis instead of using *dstcs
- for computing conjugate symmetry distance */
- for (i=0; i<rows>>1; i++) {
- *dst = *dstcs = *src++;
- for (j=1; j<dc; j++)
- dstcs[-j] = dst[j] = *src++;
- if (dimen1len & 1) /* throw away the Nyquist since just display */
- src++;
- dst += cols; dstcs -= cols;
- }
-
- for (src=ibuf; i<rows; i++) {
- *dst = *dstcs = *src++;
- for (j=1; j<dc; j++)
- dstcs[-j] = dst[j] = *src++;
- if (dimen1len & 1)
- src++;
- dst += cols; dstcs -= cols;
- }
- }
- else {
- register int i, j, dis=cols*rows; /* conjugately symmetric distance */
- register double *src=ibuf, *dst=o_buf;
- for (i=0; i<rows; i++) {
- *dst = *src++;
- for (j=1; j<dimen1len; j++)
- dst[dis-j] = dst[j] = *src++;
- dst += cols; dis -= cols << 1;
- }
- }
- }
-
- /* Double Complex Flip Quadrant */
- Dcom_flip(ibuf, o_buf, rows, cols)
- double *ibuf, *o_buf;
- {
- int hcols=cols>>1;
- register int i, j;
- register double *src=ibuf + (rows*cols>>1), *dst=o_buf + hcols;
- for (i=0; i<rows>>1; i++){
- for (j=0; j<hcols; j++)
- dst[-j-1] = dst[j] = *src++;
- dst += cols; src += hcols;
- }
- for (src=ibuf; i<rows; i++){
- for (j=0; j<hcols; j++)
- dst[-j-1] = dst[j] = *src++;
- dst += cols; src += hcols;
- }
- }
-
- /*===============================================
- % left half is one line higher than %
- % right half. It does not effect view, %
- % but may not use for real application %
- ===============================================*/
- Dcom_fflip(ibuf, o_buf, rows, cols)
- double *ibuf, *o_buf;
- {
- register int i;
- register double *src=ibuf + (cols*(rows+1) >> 1), *dst = o_buf;
-
- for (i=cols*(rows-1) >> 1; i--;)
- *dst++ = *src++;
- src = ibuf;
- for (i=cols*(rows+1) >> 1; i--;)
- *dst++ = *src++;
- }
-