home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / alv.sun / alv.lha / src / dsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-08  |  11.2 KB  |  497 lines

  1. #include "defs.h"
  2. #include <fcntl.h>
  3.  
  4. #define DEFAULT_WIN_XSIZE    850
  5. #define DEFAULT_WIN_YSIZE    1000
  6. #define MIN_WIN_XSIZE        200
  7. #define MIN_WIN_YSIZE        200
  8.  
  9. Frame   frame;
  10. anvas  canvas;
  11. ursor  cursor;
  12. con    icon;
  13. anel   panel;
  14. anel_item window_slider, level_slider;
  15. ixwin *pw, *fpw;
  16. ixrect *pr, *dpr, *icon_pr, *backing_pixrect, *mem_create();
  17.  
  18. tatic short dspicon[] =
  19. {
  20. #include "../images/icons/dsp.icon"
  21. };
  22. EFINE_ICON_FROM_IMAGE(bwicon, dspicon);
  23.  
  24. enu    canvas_menu;
  25. tatic void
  26. etcoords(), window_proc(), level_proc(), canvas_proc(),
  27. epaint_canvas(), resize_canvas();
  28.  
  29. har    cmsname[BUFSIZ];
  30. _char  red[256], green[256], blue[256];
  31. har   *progname;
  32. har   *filename;
  33. har   *eight_to_one;
  34. har    buf1[BUFSIZ];
  35. nt     window, level;
  36. nt     old_level, old_window;
  37. nt     max_level, min_level;
  38. nt     lower, upper;
  39. nt     table[10000];
  40. nt     winxsize, winysize;
  41. nt     size, wl, colour;
  42. olormap_t colormap;
  43. anel_item next_butt, prev_butt;
  44. tatic void dummy_proc(), canvas_event_proc();
  45.  
  46. #ifdef STANDALONE
  47. ain(argc, argv, envp)
  48. #else
  49. sp_main(argc, argv, envp)
  50. #endif
  51.     int     argc;
  52.     char  **argv;
  53.     char  **envp;
  54. {
  55.     int     i;
  56.     int     scroll_thickness;
  57.     float   calc_mean();
  58.     Pixrect *call_dither();
  59.  
  60.     eight_to_one = NULL;
  61.     progname = strsave(argv[0]);
  62.     parse_profile(&argc, argv, envp);
  63.  
  64.     filename = strsave("stdin");
  65.     while ((gc = getopt(argc, argv, "W:bc8:")) != EOF)
  66.         switch (gc) {
  67.         case '8':
  68.             eight_to_one = strsave(optarg);
  69.             break;
  70.         case '?':
  71.             errflag++;
  72.             break;
  73.         }
  74.  
  75.     if (errflag)
  76.         error((char *) 0, "Usage: %s: [-8 program] [infile]\n", progname);
  77.  
  78.     for (stream = 0; optind < argc; stream++, optind++)
  79.         if (stream == 0 && strcmp(argv[optind], "-") != 0) {
  80.             filename = strsave(argv[optind]);
  81.             if (freopen(argv[optind], mode[stream], f[stream]) == NULL)
  82.                 error("%s %s", PR_IO_ERR_INFILE, argv[optind]);
  83.         }
  84.     if (eight_to_one == NULL)
  85.         eight_to_one = strsave(FILTER8TO1);
  86.  
  87.     if ((pr = pr_load(stdin, &colormap)) == NULL)
  88.         error(PR_IO_ERR_RASREAD);
  89.  
  90.     frame = window_create(NULL, FRAME, FRAME_NO_CONFIRM, TRUE, 0);
  91.     canvas = window_create(frame, CANVAS, 0);
  92.     pw = canvas_pixwin(canvas);
  93.     colour = iscolour(pw);
  94.     window_destroy(frame);
  95.  
  96.     if (!colour) {
  97.         if (pr->pr_depth == 8)
  98.             pr = call_dither(pr);
  99.         if (pr->pr_depth > 8)
  100.             error("Input depth not supported on this workstation");
  101.     }
  102.  
  103.     setup_windowsizes();
  104.  
  105.     scroll_thickness = defaults_get_integer("/Scrollbar/Thickness", 14, 0);
  106.     frame = window_create(NULL, FRAME,
  107.                   FRAME_LABEL, filename,
  108.                   WIN_HEIGHT, winysize + scroll_thickness + 7,
  109.                   WIN_WIDTH, winxsize + scroll_thickness + 10,
  110.                   FRAME_ARGS, argc, argv,
  111.                   0);
  112.  
  113.         if (colour) {
  114.         setup_colourmap();
  115.         if (colormap.length != 0) {
  116.             if (!mono_override)
  117.                 allow_mono(pr);
  118.             }
  119.         }
  120.  
  121.     max_level = calc_max(pr)+1;
  122.     if (pr->pr_depth > 8 && colormap.length == 0) {
  123.         window = MAXLEVEL(8);
  124.         level = (int) calc_mean(pr);
  125.         old_window = max_level;
  126.         old_level = max_level / 2;
  127.         setup_scrollbars();
  128.     }
  129.     cursor = cursor_create(
  130.                    CURSOR_OP, PIX_SRC ^ PIX_DST,
  131.                    CURSOR_CROSSHAIR_LENGTH, 20,
  132.                    CURSOR_SHOW_CROSSHAIRS, TRUE,
  133.                    0);
  134.  
  135.     canvas = window_create(frame, CANVAS,
  136.                    WIN_CURSOR, cursor,
  137.                    CANVAS_HEIGHT, pr->pr_size.y,
  138.                    CANVAS_WIDTH, pr->pr_size.x,
  139.                    CANVAS_AUTO_SHRINK, FALSE,
  140.                    WIN_EVENT_PROC, canvas_event_proc,
  141.                    WIN_CONSUME_PICK_EVENT, LOC_MOVE,
  142.                    0);
  143.  
  144.     if (pr->pr_depth > 8)
  145.         window_set(canvas, WIN_BELOW, panel, WIN_X, 0, 0);
  146.  
  147.     pw = canvas_pixwin(canvas);
  148.  
  149.     window_set(canvas,
  150.            WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),
  151.            WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(0),
  152.            0);
  153.  
  154.     if (pr->pr_depth <= 8)
  155.         dpr = pr;
  156.     else {
  157.         if ((dpr = mem_create(pr->pr_size.x, pr->pr_size.y, 8)) == NULL)
  158.             error("mem_create returned NULL");
  159.         min_level = 0;
  160.         setup_table();
  161.         convert_to_8bits(pr, dpr);
  162.     }
  163.  
  164.     if (pr->pr_depth == 1 || !colour)
  165.         window_set(frame, FRAME_ICON, &bwicon, 0);
  166.     else {
  167.         icon_pr = mem_create(64, 64, 8);
  168.         paint_icon();
  169.     }
  170.  
  171.     pw_rop(pw, 0, 0, dpr->pr_size.x, pr->pr_size.y, PIX_SRC, dpr, 0, 0);
  172.     window_main_loop(frame);
  173. }
  174. aint_icon()
  175. {
  176.     subsample(dpr, icon_pr);
  177.  
  178.     icon = icon_create(ICON_IMAGE, icon_pr, 0);
  179.     window_set(frame, FRAME_ICON, icon, 0);
  180. }
  181. ubsample(in, out)
  182.     Pixrect *in, *out;
  183. {
  184.     int     cvx, cvy, lcx, lcy, hcx, hcy;
  185.     register int i, j, i1, j1;
  186.     int     total;
  187.  
  188.     cvx = (100 * in->pr_size.x) / out->pr_size.x;
  189.     cvy = (100 * in->pr_size.y) / out->pr_size.y;
  190.  
  191.     for (j = 0; j < out->pr_size.y; j++)
  192.         for (i = 0; i < out->pr_size.x; i++) {
  193.             hcx = i * cvx / 100;
  194.             hcy = j * cvy / 100;
  195.             lcx = (i - 1) * cvx / 100 + 1;
  196.             lcy = (j - 1) * cvy / 100 + 1;
  197.             lcx = (lcx < 0) ? 0 : (lcx > hcx) ? hcx : lcx;
  198.             lcy = (lcy < 0) ? 0 : (lcy > hcy) ? hcy : lcy;
  199.  
  200.             total = 0;
  201.             for (j1 = lcy; j1 <= hcy; j1++)
  202.                 for (i1 = lcx; i1 <= hcx; i1++)
  203.                     total += pr_get(in, i1, j1);
  204.             pr_put(out, i, j, (total / ((hcx + 1 - lcx) * (hcy + 1 - lcy))));
  205.         }
  206. }
  207. etup_scrollbars()
  208. {
  209.     setup_font();
  210.  
  211.     panel = window_create(frame, PANEL,
  212.                   WIN_WIDTH, WIN_EXTEND_TO_EDGE,
  213.                   0);
  214.  
  215.     window_slider = panel_create_item(panel, PANEL_SLIDER,
  216.                       PANEL_ITEM_X, ATTR_COL(0),
  217.                       PANEL_ITEM_Y, ATTR_ROW(0),
  218.                       PANEL_LABEL_FONT, font,
  219.                       PANEL_LABEL_STRING, "Window:",
  220.                       PANEL_VALUE, window,
  221.                       PANEL_MIN_VALUE, 0,
  222.                       PANEL_MAX_VALUE, max_level,
  223.                       PANEL_NOTIFY_PROC, window_proc,
  224.                       0);
  225.  
  226.     level_slider = panel_create_item(panel, PANEL_SLIDER,
  227.                      PANEL_ITEM_X, ATTR_COL(0),
  228.                      PANEL_ITEM_Y, ATTR_ROW(1),
  229.                      PANEL_LABEL_FONT, font,
  230.                      PANEL_LABEL_STRING, "Level :",
  231.                      PANEL_VALUE, level,
  232.                      PANEL_MIN_VALUE, 0,
  233.                      PANEL_MAX_VALUE, max_level,
  234.                      PANEL_NOTIFY_PROC, level_proc,
  235.                      0);
  236.  
  237.     window_fit_height(panel);
  238. }
  239.  
  240. tatic void
  241. indow_proc(item, value, event)
  242.     Panel_item item;
  243.     int     value;
  244.     Event  *event;
  245. {
  246.     int     ol;
  247.  
  248.     ol = level;
  249.     window = value;
  250.  
  251.     if (level + window / 2 >= max_level)
  252.         level = max_level - window / 2;
  253.     if (level - window / 2 < min_level)
  254.         level = window / 2;
  255.     if (ol != level)
  256.         panel_set(level_slider, PANEL_VALUE, level, 0);
  257.     setup_table();
  258.     convert_to_8bits(pr, dpr);
  259.     pw_rop(pw, 0, 0, dpr->pr_size.x, pr->pr_size.y, PIX_SRC, dpr, 0, 0);
  260.     paint_icon();
  261. }
  262.  
  263. tatic void
  264. evel_proc(item, value, event)
  265.     Panel_item item;
  266.     int     value;
  267.     Event  *event;
  268. {
  269.     level = value;
  270.  
  271.     if (level + window / 2 >= max_level)
  272.         level = max_level - window / 2;
  273.     if (level - window / 2 < min_level)
  274.         level = window / 2;
  275.     if (level != value)
  276.         panel_set(level_slider, PANEL_VALUE, level, 0);
  277.     setup_table();
  278.     convert_to_8bits(pr, dpr);
  279.     pw_rop(pw, 0, 0, dpr->pr_size.x, pr->pr_size.y, PIX_SRC, dpr, 0, 0);
  280.     paint_icon();
  281. }
  282. /* initialise lookup table for current window & level */
  283. etup_table()
  284. {
  285.     register int i;
  286.     register int *t;
  287.     register int new_lower, new_upper;
  288.     int     old_lower, old_upper;
  289.     double  m, cumulative_greylevel;
  290.  
  291.     if (window != 0)
  292.         m = (253.) / (float) (window);    /* 253 = No. greylevels
  293.                          * - 1 */
  294.  
  295.     cumulative_greylevel = 1.;
  296.     new_lower = level - window / 2;
  297.     new_upper = level + window / 2;
  298.     old_lower = old_level - old_window / 2;
  299.     old_upper = old_level + old_window / 2;
  300.  
  301.     lower = MIN(old_lower, new_lower);
  302.     upper = MAX(old_upper, new_upper);
  303.  
  304.     lower = 0;
  305.     upper = max_level;
  306.     t = &table[lower];
  307.     for (i = lower; i < upper; i++)
  308.         if (i <= new_lower)
  309.             *t++ = 1;
  310.         else if (i >= new_upper)
  311.             *t++ = 254;
  312.         else {
  313.             *t++ = cumulative_greylevel;
  314.             cumulative_greylevel += m;
  315.         }
  316.     old_level = level;
  317.     old_window = window;
  318. }
  319. onvert_to_8bits(in, out)
  320.     Pixrect *in, *out;
  321. {
  322.     short  *ptr16;
  323.     int    *ptr32;
  324.     char   *ptr8;
  325.     register int i;
  326.     int     n;
  327.     int     mode = TRUE;
  328.  
  329. #define ALL_PIXELS    TRUE
  330.  
  331.     ptr8 = (char *) mpr_d(out)->md_image;
  332.     n = in->pr_size.x * in->pr_size.x;
  333.  
  334.     switch (in->pr_depth) {
  335.     case 16:
  336.         ptr16 = (short *) mpr_d(in)->md_image;
  337.         for (i = 0; i < n; i++) {
  338.             if ((mode == ALL_PIXELS) || ((*ptr16 >= lower) && (*ptr16 <= upper)))
  339.                 *ptr8 = *(table + (*ptr16));
  340.             ptr8++;
  341.             ptr16++;
  342.         }
  343.         break;
  344.     case 32:
  345.         ptr32 = (int *) mpr_d(in)->md_image;
  346.         for (i = 0; i < n; i++) {
  347.             if ((mode == ALL_PIXELS) || ((*ptr32 >= lower) && (*ptr32 <= upper)))
  348.                 *ptr8 = *(table + (*ptr32));
  349.             ptr8++;
  350.             ptr16++;
  351.         }
  352.         break;
  353.     }
  354. }
  355. etup_windowsizes()
  356. {
  357.     if (pr->pr_size.x > DEFAULT_WIN_XSIZE)
  358.         winxsize = DEFAULT_WIN_XSIZE;
  359.     else
  360.         winxsize = MAX(pr->pr_size.x, MIN_WIN_XSIZE)+3;
  361.  
  362.     if (pr->pr_size.y > DEFAULT_WIN_YSIZE)
  363.         winysize = DEFAULT_WIN_YSIZE;
  364.     else
  365.         winysize = MAX(pr->pr_size.y, MIN_WIN_YSIZE)+17;
  366. }
  367. etup_colourmap()
  368. {
  369.     register int i;
  370.  
  371.     for (i = 0; i < 256; i++) {
  372.         red[i] = green[i] = blue[i] = -1;
  373.     }
  374.     fpw = (Pixwin *) window_get(frame, WIN_PIXWIN);
  375.  
  376.     if (colormap.type == RMT_NONE || colormap.length == 0) {
  377.         sprintf(cmsname, "greyscale%d", pr->pr_depth);
  378.  
  379.         pw_setcmsname(fpw, cmsname);
  380.  
  381.         for (i = 1; i < 255; i++) {
  382.             red[i] = i;
  383.             green[i] = i;
  384.             blue[i] = i;
  385.         }
  386.         if (mono_override) {
  387.             red[255] = blue[255] = green[255] = 255;
  388.             red[0] = blue[0] = green[0] = 0;
  389.         }
  390.         pw_putcolormap(fpw, 0, 256, red, green, blue);
  391.     } else {
  392.         pw_setcmsname(fpw, "non_greyscale");
  393.         pw_putcolormap(fpw, 0, colormap.length, colormap.map[0], colormap.map[1], colormap.map[2]);
  394.     }
  395.     window_set(frame, FRAME_INHERIT_COLORS, TRUE, 0);
  396. }
  397.  
  398. loat
  399. alc_mean(pr)
  400.     Pixrect *pr;
  401. {
  402.     register int i, j;
  403.     int     sum;
  404.  
  405.     sum = 0;
  406.     for (j = 0; j < pr->pr_size.y; j++)
  407.         for (i = 0; i < pr->pr_size.x; i++)
  408.             sum += pr_get(pr, i, j);
  409.  
  410.     return (sum / (pr->pr_size.x * pr->pr_size.y));
  411. }
  412.  
  413. tatic void
  414. anvas_event_proc(canvas, event, arg)
  415.     Canvas  canvas;
  416.     Event  *event;
  417.     caddr_t arg;
  418. {
  419.     char    buf[BUFSIZ];
  420.  
  421.     if (event_id(event) == LOC_MOVE || event_is_button(event)) {
  422.         sprintf(buf, "%s - %d, %d = %d", filename, event_x(event), event_y(event), pr_get(pr, event_x(event), event_y(event)));
  423.         window_set(frame, FRAME_LABEL, buf, 0);
  424.     }
  425. }
  426. scolour(pw)
  427.     Pixwin *pw;
  428. {
  429.  
  430.     return ((pw->pw_pixrect->pr_depth > 1) ? TRUE : FALSE);
  431. }
  432.  
  433. ixrect *
  434. all_dither(in)
  435.     Pixrect *in;
  436. {
  437.     Pixrect *out, *pr_load();
  438.     FILE   *fp_tochild;
  439.     FILE   *fp_fromchild;
  440.     int     childpid;
  441.     int     pfdout[2], pfdin[2];
  442.     int     c, numfds;
  443.  
  444.     if (pipe(pfdout) == -1 || pipe(pfdin) == -1) {
  445.         perror(progname);
  446.         exit(1);
  447.     }
  448.     switch (childpid = fork()) {
  449.     case -1:
  450.         perror(progname);
  451.         exit(1);
  452.     case 0:
  453.         if (close(0) == -1)
  454.             perror(progname);
  455.         if (dup(pfdout[0]) != 0)
  456.             perror(progname);
  457.         if (close(1) == -1)
  458.             perror(progname);
  459.         if (dup(pfdin[1]) != 1)
  460.             perror(progname);
  461.         if (close(pfdout[0]) == -1 || close(pfdout[1]) == -1 || close(pfdin[0]) == -1 || close(pfdin[1]) == -1)
  462.             perror(progname);
  463.         execlp(eight_to_one, eight_to_one, 0);
  464.         perror(eight_to_one);
  465.         exit(1);
  466.     default:
  467.         if (close(pfdout[0]) == -1 || close(pfdin[1]) == -1)
  468.             perror(progname);
  469.  
  470.         if ((fp_tochild = fdopen(pfdout[1], "w")) == NULL)
  471.             error("Can't get file descriptor to write to child process");
  472.         if (pr_dump(in, fp_tochild, NULL, RT_STANDARD, 0) == PIX_ERR)
  473.             error("pr_dump returned PIX_ERR");
  474.         fclose(fp_tochild);
  475.  
  476.         if ((fp_fromchild = fdopen(pfdin[0], "r")) == NULL)
  477.             error("Can't get file descriptor to read from child process");
  478.         if ((out = pr_load(fp_fromchild, NULL)) == NULL)
  479.             error("pr_load returned NULL");
  480.         fclose(fp_tochild);
  481.     }
  482.     return out;
  483. }
  484.  
  485. llow_mono(pr)
  486. ixrect *pr;
  487. {
  488.     register int i, j, pix;
  489.  
  490.     for(i=0;i<pr->pr_size.x;i++)
  491.         for(j=0;j<pr->pr_size.y;j++)
  492.             if ((pix = pr_get(pr, i, j)) == 255 || pix == 254)
  493.                 pr_put(pr, i, j, 253);
  494.             else if (pix == 0)
  495.                 pr_put(pr, i, j, 1);
  496. }
  497.