home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / hips / sources / 3dscale_geom / scaleg_main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-08  |  8.9 KB  |  316 lines

  1. /*
  2. % scaleg_main:    main program for 3D image scaling
  3. %
  4. % This program is a hack from the 'zoom' program by Paul Heckbert, UC Berkeley
  5. % The zoom program was modified to work with the Hips file format.
  6. %    -Brian Tierney, LBL  9/89
  7. %
  8. %   terminology:
  9. %    x = colums
  10. %    y = rows
  11. %
  12. % see additional comments in scale_g.c and pic.3
  13. %
  14. % Modified:    6/15/91    for 3-dimensional handling - Jin Guojun
  15. %        8/15/92    for handling color
  16. */
  17.  
  18. #include <math.h>
  19.  
  20. #include "hips.h"
  21. #include "simple.h"
  22. #include "pic.h"
  23. #include "filt.h"
  24. #include "scaleg.h"
  25. #include "scanline.h"
  26.  
  27. #define FILTER_DEFAULT "triangle"
  28. #define WINDOW_DEFAULT "blackman"
  29.  
  30. U_IMAGE    uimg;
  31. arg_fmt_list_string    arg_fmts[] =    {
  32.     {"-#", "%f", 0, 1, 1,
  33.         "image will be shrinked or enlarged # times (-5.0 ~ +5.0)\n\
  34.     -# means '-real_number', such as: -1.1, --4.75, ..."},
  35.     {"-blur", "%g %g %g", -1., 3, 1,
  36.         "blur factor: > 1 is blurry, < 1 is sharp"},
  37.     {"-c", "%b", True, 1, 0, "output color (RLE) image"},
  38.     {"-D", "%d %d %d", 0, 3, 2,
  39.         "number of cols, rows, [frames] in file dest file"},
  40.     {"-d[c][r][f]", "%d %d %d %d", 0, 1, 1,
  41.         "number of cols, [rows], [frames] in destination file\n\
  42.             (default = source size)"},
  43.     {"-filt", "%s %s %s", No, 3, 0, "\n\
  44.     filter name in x, y, and z (default = triangle)\n\
  45.         \"-filt '?'\" prints a filter catalog"},
  46.     {"-s",  "%d %d %d %d", 0, 4, 4, "source box (row col #rows #cols)"},
  47.     {"-supp", "%g %g %g", -1, 3, 1, "filter support radius"},
  48.     {"-window", "%s %s", NULL, 2, 1,
  49.         "window an IIR filter (default = blackman)"},
  50.     {"-xy", "%b", True, 1, 0, "filter x before y"},
  51.     {"-yx", "%b", False,1, 0, "filter y before x"},
  52.     {"-debug", "%f", 0, 1, 1, "print filter coefficients"},
  53.     {"-v", "%b", True, 1, 0, "verbose"},
  54.     {"-plain", "%b", True, 1, 0, "\bdisable filter coercion"},
  55.     {"-keep0", "%b", True, 1, 0, "\bkeep zeros in xfilter"},
  56.     {"-i", "%b", True, 1, 0, "integer scale"},
  57.     {" [ < ] input [ > | ] output\n", NULL, 0, 0, 0, "end of usage"},
  58.     NULL    };
  59.  
  60.  
  61. main(ac, av)
  62. int    ac;
  63. char    **av;
  64. {
  65. char    *xfiltname=FILTER_DEFAULT, *yfiltname=0, *zfiltname=0,
  66.     *xwindowname=0, *ywindowname=0, **fl;
  67. int    nocoerce, square, intscale, keepzeros, i, v_pic_c=0;
  68. float    scale_factor;
  69. double    xsupp, ysupp = -1., zsupp = -1.,
  70.     xblur, yblur = -1., zblur = -1.;
  71. Pic    *apic, *bpic;
  72. Window_box    a,    /* src window */
  73.         b;    /* dest window */
  74. Filt    *xfilt, *yfilt, *zfilt, xf, yf, zf;
  75.  
  76. a.x0 = a.y0 = a.z0 = a.x1 = a.y1 = a.z1 = a.nx = a.ny = a.nz = 0;
  77. b.x0 = b.y0 = b.z0 = b.x1 = b.y1 = b.z1 = b.nx = b.ny = b.nz = 0;
  78. square = intscale = 0;
  79. nocoerce = keepzeros = 0;
  80.  
  81. p_use_pound_sign(True);
  82.     if ((i=parse_argus(&fl, ac, av, arg_fmts, &scale_factor,
  83.     &xblur, &yblur, &zblur,
  84.     &uimg.color_dpy,
  85.     &b.nx, &b.ny, &b.nz,
  86.     &b.nx, &b.nx, &b.ny, &b.nz,
  87.     &xfiltname, &yfiltname, &zfiltname,
  88.     &a.x0, &a.y0, &a.nx, &a.ny,
  89.     &xsupp, &ysupp, &zsupp,
  90.     &xwindowname, &ywindowname,
  91.     &zoom_xy, &zoom_xy,
  92.     &zoom_debug, &v_pic_c,
  93.     &nocoerce, &keepzeros,
  94.     &intscale)) < 0)    exit(i);
  95.  
  96.     if (v_pic_c)
  97.     pic_catalog(),    exit(0);
  98.  
  99.     if (str_eq(xfiltname, "?")) {
  100.     filt_catalog();    exit(0);
  101.     }
  102.  
  103.     if (fabs(scale_factor) > 5.)
  104. info:    parse_usage(arg_fmts),    exit(-1);
  105.  
  106. format_init(&uimg, IMAGE_INIT_TYPE, uimg.color_dpy ? RLE : HIPS, -1, *av, "M5-3");
  107.  
  108.     if (i && !(in_fp=freopen(uimg.name=fl[0], "rb", stdin))    )
  109.     syserr("can't open %s", uimg.name);
  110.     io_test(fileno(in_fp), goto    info);
  111.  
  112.     zoom_coerce = !nocoerce;
  113.     zoom_trimzeros = !keepzeros;
  114.  
  115.     /* for I/O files */
  116.     apic = pic_open("stdin", "r");
  117.     bpic = pic_open("stdout", "w");
  118.  
  119.     /* check input image size */
  120.     if (a.x0 > uimg.width || a.y0 > uimg.height ||
  121.     a.nx > uimg.width || a.ny > uimg.height)
  122.     prgmerr(1, "\n Error: input image is not that big. \n\n");
  123.     /*
  124.      * set defaults
  125.      */
  126.     if (a.nx == 0)
  127.     a.nx = uimg.width;
  128.     if (a.ny == 0)
  129.     a.ny = uimg.height;
  130.     if (!a.nz)
  131.     a.nz = uimg.frames;
  132.     /* want square pixels, so scale x or y to the appr. value */
  133.     if (b.nx == 0 && b.ny == 0) {
  134.     b.nx = a.nx;
  135.     b.ny = a.ny;
  136.     }
  137.     if (b.nx == 0)
  138.     b.nx = (int) ((b.ny * a.nx) / (float) a.ny + .5);
  139.     if (b.ny == 0)
  140.     b.ny = (int) ((b.nx * a.ny) / (float) a.nx + .5);
  141.     if (!b.nz)
  142.     if (a.nz == 1 || uimg.color_dpy)
  143.         b.nz = a.nz;
  144.     else if (b.nx == b.ny)
  145.         b.nz = b.nx;
  146.     else    b.nz = (b.nx * a.nz) / (float) a.nx + .5;
  147.  
  148.     if (scale_factor > 0)    {
  149.     b.nx = a.nx * scale_factor;
  150.     b.ny = a.ny * scale_factor;
  151.     if (!uimg.color_dpy)    b.nz = a.nz * scale_factor;    /* no 3D color */
  152.     }
  153.     else if (scale_factor < 0)    {
  154.     scale_factor = -scale_factor;
  155.     b.nx = a.nx / scale_factor;
  156.     b.ny = a.ny / scale_factor;
  157.     if (!uimg.color_dpy)    b.nz = a.nz / scale_factor;
  158.     }
  159.     if (!b.nz)
  160.     b.nz++;
  161.     if (b.nx > XMAX || b.ny > YMAX)
  162.     prgmerr(2, "\ndestination file must be smaller than %d by %d \n\n",
  163.         XMAX, YMAX);
  164.  
  165.     uimg.width = b.nx;
  166.     uimg.height = b.ny;        /* must do this after call to zoom */
  167.     uimg.frames = b.nz;
  168.     if (uimg.o_type == HIPS)
  169.     (*uimg.header_handle)(HEADER_WRITE, &uimg, ac, av, True);
  170.  
  171.     /* sets x1 and y1 values */
  172.     window_box_set_max(&a);
  173.     window_box_set_max(&b);
  174.  
  175.     if (!yfiltname)
  176.     yfiltname = xfiltname;
  177.     if (!zfiltname)
  178.     zfiltname = xfiltname;
  179.     xfilt = filt_find(xfiltname);
  180.     yfilt = filt_find(yfiltname);
  181.     zfilt = filt_find(zfiltname);
  182.     if (!xfilt | !yfilt | !zfilt)
  183.     prgmerr(1, "can't find filters %s or %s or %s\n",
  184.         xfiltname, yfiltname, zfiltname);
  185.     /* copy the filters before modifying them */
  186.     xf = *xfilt;
  187.     xfilt = &xf;
  188.     yf = *yfilt;
  189.     yfilt = &yf;
  190.     zf = *zfilt;
  191.     zfilt = &zf;
  192.     if (xsupp >= 0.)
  193.     xfilt->supp = xsupp;
  194.     if (xsupp >= 0. && ysupp < 0.)
  195.     ysupp = xsupp;
  196.     if (ysupp >= 0.)
  197.     yfilt->supp = ysupp;
  198.     if (xsupp >= 0. && zsupp < 0.)
  199.     zsupp = xsupp;
  200.     if (zsupp >= 0.)
  201.     zfilt->supp = zsupp;
  202.     if (xblur >= 0.)
  203.     xfilt->blur = xblur;
  204.     if (xblur >= 0. && yblur < 0.)
  205.     yblur = xblur;
  206.     if (yblur >= 0.)
  207.     yfilt->blur = yblur;
  208.     if (xblur >= 0. && zblur < 0.)
  209.     zblur = xblur;
  210.     if (zblur >= 0.)
  211.     zfilt->blur = zblur;
  212.  
  213.     if (!ywindowname)
  214.     ywindowname = xwindowname;
  215.     if (xwindowname || xfilt->windowme) {
  216.     if (!xwindowname)
  217.         xwindowname = WINDOW_DEFAULT;
  218.     xfilt = filt_window(xfilt, xwindowname);
  219.     }
  220.     if (ywindowname || yfilt->windowme) {
  221.     if (!ywindowname)
  222.         ywindowname = WINDOW_DEFAULT;
  223.     yfilt = filt_window(yfilt, ywindowname);
  224.     }
  225.     if (xfilt->printproc) {
  226.     mesg("xfilt: ");
  227.     filt_print_client(xfilt);
  228.     }
  229.     if (yfilt->printproc) {
  230.     mesg("yfilt: ");
  231.     filt_print_client(yfilt);
  232.     }
  233.     /* process each of the frames */
  234.     if (a.nz == b.nz)
  235.     for (i=0; i < uimg.frames; i++) {
  236.     Hips    *save_a = apic->data, *save_b = bpic->data;
  237.     int    rf_size = save_a->dx * save_a->dy, wf_size;
  238.         if (uimg.frames > 1)
  239.             msg("\r    processsing frame %d ...", i);
  240.         if (load_hips_frame(&uimg, apic->data) < rf_size)    break;
  241.         zoom_opt(apic, &a, bpic, &b, xfilt, yfilt, square, intscale);
  242.         if (isColorImage(uimg.color_form))    {
  243.             wf_size = save_b->dx * save_b->dy;
  244.             save_a->ibuf += rf_size;
  245.             save_b->ibuf += wf_size;
  246.             zoom_opt(apic, &a, bpic, &b, xfilt, yfilt, square, intscale);
  247.             save_a->ibuf += rf_size;
  248.             save_b->ibuf += wf_size;
  249.             zoom_opt(apic, &a, bpic, &b, xfilt, yfilt, square, intscale);
  250.             save_a->ibuf -= rf_size << 1;
  251.             save_b->ibuf -= wf_size << 1;
  252.             if (uimg.in_type==RLE)    i = -1;
  253.         }
  254.         store_hips_frame(bpic->data);
  255.         if (i < 0)
  256.         if ((*uimg.header_handle)(HEADER_READ, &uimg, 0, Yes, 0))
  257.             break;
  258.         else if (uimg.dpy_channels == 3)
  259.             uimg.color_form = CFM_SEPLANE,    uimg.frames = 1;
  260.     }    else    {
  261.     int    j, z, line, n;
  262.     Mapping    m;
  263.     Filtpar    az;
  264.     Pixel1    *fbuf = zalloc(8, b.nx*b.ny, "fbuf"), *itmp, *ibuf;
  265.     Weighttab    zweight;
  266.     Pixel4    *accum = nzalloc(sizeof(*accum), b.nx*b.ny, "accum");
  267.  
  268.     m.sz = (double)b.nz / a.nz;
  269.     m.tz = b.z0 - .5 - m.sz*(a.z0 - .5);
  270.     az.scale = zfilt->blur*MAX(1., 1./m.sz);
  271.     az.supp = MAX(.5, az.scale*zfilt->supp);
  272.     az.wid = ceil(2.*az.supp);
  273.     m.uz = b.z0 - m.sz*(a.z0 - .5) - m.tz;
  274.     zweight.weight = zalloc(sizeof(*zweight.weight), az.wid, "zweight");
  275.  
  276.     for (i=0; i<MIN(8, a.nz); i++)    {
  277.         load_hips_frame(&uimg, apic->data);
  278.         zoom_opt(apic, &a, bpic, &b, xfilt, yfilt, square, intscale);
  279.         memcpy(fbuf+b.nx*b.ny*i, ((Hips*)bpic->data)->ibuf, b.nx*b.ny);
  280.     }
  281.     for (j=0; j<b.nz; j++)    {
  282.         make_weighttab(b.z0+j, MAP(j, m.sz, m.uz),
  283.                 zfilt, az, a.nz, 0, &zweight);
  284.         while (zweight.i1 >= i && i < a.nz)    {
  285.         load_hips_frame(&uimg, apic->data);
  286.         zoom_opt(apic, &a, bpic, &b, xfilt, yfilt, square, intscale);
  287.         memcpy(fbuf+b.nx*b.ny*(i&7), ((Hips*)bpic->data)->ibuf, b.nx*b.ny);
  288.         i++;
  289.         }
  290.         for (line=0; line<b.ny; line++)    {
  291.         register Pixel4    *ap=accum;
  292.         bzero(ap, b.nx<<2);
  293.         for (z=b.nx; z--;)
  294. /*            --*ap++;    */
  295.             *ap++ = (1 << CHANBITS) - 1;
  296.         itmp = fbuf + line*b.nx;
  297.         for (z=zweight.i0; z<zweight.i1; z++){
  298.         register short    weight = zweight.weight[z-zweight.i0];
  299.             ap = accum;
  300.             ibuf = (z&7) * b.nx*b.ny + itmp;
  301.             for (n=b.nx; n--;)
  302.             *ap++ += *ibuf++ * weight;
  303.         }
  304.         ibuf = ((Hips*)bpic->data)->ibuf + b.nx*line;
  305.         ap = accum;
  306.         for (n=b.nx; n--;)
  307.             *ibuf++ = *ap++ >> CHANBITS+6; /* sacle need */
  308.         }
  309.     store_hips_frame(bpic->data);
  310.     }
  311.     }
  312.  
  313. message("%s : done\n", Progname);
  314. return (0);
  315. }
  316.