home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / desklib / examples / DeskLib / Examples / Widget5 / !Widget5 / c / GreyEdWin < prev    next >
Encoding:
Text File  |  1995-05-05  |  26.8 KB  |  1,005 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *        File: GreyEdWin.c                                             *
  4.  *                                                                      *
  5.  *     Purpose: Provides user interface to edit greylevels process      *
  6.  *                                                                      *
  7.  ************************************************************************/
  8.  
  9. #include "DeskLib:WimpSWIs.h"          /* Low-level WIMP commands         */
  10. #include "DeskLib:Window.h"            /* Window handling automation      */
  11. #include "DeskLib:Core.h"              /* usefull core functions          */
  12. #include "DeskLib:Error.h"             /* Error despatcher                */
  13. #include "DeskLib:Event.h"             /* Event despatcher                */
  14. #include "DeskLib:EventMsg.h"          /* Wimp Message event dispatcher   */
  15. #include "DeskLib:File.h"              /* Low level file handling         */
  16. #include "DeskLib:Msgs.h"              /* Message translation code        */
  17. #include "DeskLib:Resource.h"          /* Handles finding resource files  */
  18. #include "DeskLib:Sound.h"             /* Beep!                           */
  19. #include "DeskLib:Template.h"          /* Template loading and caching    */
  20. #include "DeskLib:Icon.h"              /* Icon handling automation        */
  21. #include "DeskLib:Menu.h"              /* Menu create & show support      */
  22. #include "DeskLib:Screen.h"            /* Caching screen info             */
  23. #include "DeskLib:Sprite.h"            /* Sprite handling routines        */
  24. #include "DeskLib:File.h"              /* OS file IO                      */
  25. #include "DeskLib:KeyCodes.h"          /* Codes for wimp returned keys    */
  26. #include "DeskLib:Hourglass.h"         /* control hourglass               */
  27. #include "DeskLib:Coord.h"
  28.  
  29. #include "SpriteWin.h"
  30. #include "CheckBanks.h"
  31. #include "Process.h"
  32. #include "Widget5.h"
  33. #include "Misc.h"
  34. #include "Configure.h"
  35.  
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <math.h>
  40.                         
  41. extern window_handle db;
  42.  
  43. #define total_GREYBARS 65
  44.  
  45. typedef struct {
  46.    window_handle window;
  47.    int sourceimage;
  48.    int destimage;
  49.    unsigned int oldidletime;
  50.    char greybarmap[total_GREYBARS];
  51.    char greymap[256];
  52. } greyed_block;
  53.  
  54. #define idletime_BARS 0
  55.  
  56. #define icon_IMAGEX       1
  57. #define icon_IMAGEY       3
  58.  
  59. #define icon_REALTIME     11
  60. #define icon_CLOSE        12
  61. #define icon_MAP          13
  62. #define icon_NORMDRAW     6
  63. #define icon_SMOOTHDRAW   7
  64. #define icon_VSMOOTHDRAW  8
  65. #define icon_HEIGHTDISP   25
  66. #define icon_WIDTHDISP    10
  67. #define icon_BARBACK      14
  68. #define icon_BARMIN       26
  69. #define icon_BARMAX       90
  70. #define icon_MAXHEIGHT    256
  71. #define icon_PROCESSES    5
  72.  
  73. #define bar_WIDTH 4
  74. #define border_WIDTH 4
  75.  
  76. static BOOL Click_greyedwin(event_pollblock *event, void *reference);
  77. static BOOL Null_updatebars(event_pollblock *event, void *reference);
  78. static BOOL Null_checksourcebank(event_pollblock *event, void *reference);
  79. static void close_greyedwin(BOOL ok, BOOL keepopen, greyed_block *block);
  80. static BOOL UserDrag_updatebars(event_pollblock *event, void *reference);
  81. static BOOL MenuChoice_processmenu(event_pollblock *event, void *reference);
  82. void NoMemEdit(void);
  83. void bar_setheight(window_handle window, icon_handle icon, int barheight, BOOL redraw);
  84. void map_linear(greyed_block *block);
  85. void map_invert(greyed_block *block);
  86. void map_histeq(greyed_block *block);
  87. void map_gamma(greyed_block *block);
  88. void map_threshold(greyed_block *block);
  89. void map_slce(greyed_block *block);
  90. void refresh_map(window_handle window);
  91. void barmap2map(char (*greybarmap)[], char (*greymap)[]);
  92. void map2barmap(char (*greybarmap)[], char (*greymap)[]);
  93. void addtomaps(greyed_block *block, int greybarno, int barheight);
  94.  
  95. /* process menu */
  96. static menu_ptr processmenu = NULL;
  97. static menu_ptr gammasubmenu = NULL;
  98. static menu_ptr threshsubmenu = NULL;
  99. static char gammavalue[5];
  100. static char threshvalue[4];
  101. static greyed_block *currentblock = NULL;
  102.  
  103. /* process menu items */
  104. #define processmenu_LINEAR 0
  105. #define processmenu_INVERT 1
  106. #define processmenu_THRESH 2
  107. #define processmenu_GAMMA  3
  108. #define processmenu_HISTEQ 4
  109. #define processmenu_SLCE   5
  110.  
  111. /******************************************************************************
  112.  *                            extern routines                                 *
  113.  ******************************************************************************/
  114.  
  115. extern void GreyEdWin_Init(void)
  116. {
  117.  /*
  118.   * initialisation to be done on startup
  119.   */
  120.   char menudescription[260];
  121.   char menutitle[15];
  122.  
  123.  /*
  124.   * build menus
  125.   */
  126.   Msgs_Lookup("title.greyproc", menutitle, 15);
  127.   Msgs_Lookup("menu.greyproc", menudescription, 260);
  128.   processmenu = Menu_New(menutitle, menudescription);
  129.  
  130.   Msgs_Lookup("title.threshval", menutitle, 15);
  131.   threshsubmenu = Menu_New(menutitle,"    ");
  132.   Menu_AddSubMenu(processmenu, processmenu_THRESH, threshsubmenu);
  133.   Menu_MakeWritable(threshsubmenu, 0, threshvalue, 4, "a0-9");
  134.  
  135.   Msgs_Lookup("title.gammaval", menutitle, 15);
  136.   gammasubmenu = Menu_New(menutitle,"    ");
  137.   Menu_AddSubMenu(processmenu, processmenu_GAMMA, gammasubmenu);
  138.   Menu_MakeWritable(gammasubmenu, 0, gammavalue, 5, "a0-9.");
  139.  
  140.   Event_Claim(event_MENU, event_ANY, event_ANY, MenuChoice_processmenu, NULL);
  141.  
  142.  /*
  143.   * default values
  144.   */
  145.   strcpy(threshvalue, "128");
  146.   strcpy(gammavalue, "1.00");
  147. }
  148.  
  149. /******************************************************************************/
  150.  
  151. extern void GreyEdWin_Open(int source, int dest, wimp_point *openpos)
  152. {
  153.   greyed_block *block;
  154.   char text[20];
  155.  
  156.  /*
  157.   * allocate memory for range info block and return if fails
  158.   */
  159.   block = malloc(sizeof(greyed_block));
  160.   if(block == NULL){
  161.      NoMemEdit();
  162.      return;
  163.   }
  164.  
  165.  /*
  166.   * initialise window and block
  167.   */
  168.   block->window = Window_Create("GreyEdit", template_TITLEMIN);
  169.   block->sourceimage = source;
  170.   block->destimage = dest;
  171.  
  172.  /*
  173.   * initialise both source image bank numbers
  174.   */
  175.   Msgs_Lookup("txt.image", text, 19);
  176.   Icon_printf(block->window, icon_IMAGEX, "%s %i", text, block->sourceimage);
  177.   Icon_printf(block->window, icon_IMAGEY, "%s %i", text, block->destimage);
  178.  
  179.  /*
  180.   * setup realtime and smooth draw icons
  181.   */
  182.   Icon_Deselect(block->window, icon_REALTIME);
  183.   if(block->sourceimage == block->destimage)
  184.      Icon_Shade(block->window, icon_REALTIME);
  185.   else
  186.      Icon_SetSelect(block->window, icon_REALTIME, realtime); /* default state */
  187.  
  188.   Icon_SetRadios(block->window, icon_NORMDRAW, icon_VSMOOTHDRAW,
  189.                  icon_NORMDRAW + drawtype);
  190.  
  191.  /*
  192.   * clear position display
  193.   */
  194.   Icon_SetText(block->window, icon_HEIGHTDISP, ""); 
  195.   Icon_SetText(block->window, icon_WIDTHDISP, "");
  196.  
  197.  /*
  198.   * initialise map to linear
  199.   */
  200.   map_linear(block);
  201.  
  202.   Event_Claim(event_NULL, event_ANY, event_ANY, Null_checksourcebank, block);
  203.   Event_Claim(event_CLICK, block->window, event_ANY, Click_greyedwin, block);
  204.  
  205.   Window_ShowPos(block->window, openpos);
  206.   
  207. }
  208.  
  209. /******************************************************************************
  210.  *                              Click handlers                                *
  211.  ******************************************************************************/
  212.  
  213. static BOOL Click_greyedwin(event_pollblock *event, void *reference)
  214. {
  215.   greyed_block *block = reference;
  216.   convert_block convert;
  217.   window_state state;
  218.   drag_block dragdata;
  219.   icon_block bicon;
  220.  
  221.   if(event->data.mouse.icon == icon_BARBACK ||
  222.     ((event->data.mouse.icon >= icon_BARMIN) && (event->data.mouse.icon <= icon_BARMAX))){
  223.  
  224.     /*
  225.      * start drag of greylevel mapping bars
  226.      */
  227.      block->oldidletime = idletime;
  228.      idletime = idletime_BARS;
  229.  
  230.      Event_Claim(event_NULL, event_ANY, event_ANY, Null_updatebars, block);
  231.      Event_Claim(event_USERDRAG, event_ANY, event_ANY, UserDrag_updatebars, block);
  232.  
  233.     /*
  234.      * get background icon position in workarea coords
  235.      */
  236.      Wimp_GetIconState(block->window, icon_BARBACK, &bicon);
  237.  
  238.     /*
  239.      * setup convert block for workarea to screen coord conversion
  240.      */
  241.      Wimp_GetWindowState(block->window, &state);
  242.      convert.screenrect = state.openblock.screenrect;
  243.      convert.scroll = state.openblock.scroll;
  244.      
  245.     /*
  246.      * setup drag block
  247.      */
  248.      dragdata.window = block->window;
  249.      dragdata.type = drag_INVISIBLE;
  250.      dragdata.screenrect = state.openblock.screenrect;   /* dragged box not used */
  251.  
  252.     /*
  253.      * set drag area to background icon (screen coords)
  254.      */
  255.      dragdata.parent.min.x = bicon.workarearect.min.x + border_WIDTH;
  256.      dragdata.parent.max.x = bicon.workarearect.max.x - border_WIDTH;
  257.      dragdata.parent.min.y = bicon.workarearect.min.y + border_WIDTH;
  258.      dragdata.parent.max.y = bicon.workarearect.max.y - border_WIDTH;
  259.      Coord_RectToScreen(&dragdata.parent, &convert);
  260.  
  261.      Wimp_DragBox(&dragdata);
  262.  
  263.      return(TRUE);
  264.   }
  265.  
  266.   switch(event->data.mouse.icon)
  267.   {
  268.     case icon_PROCESSES:
  269.        currentblock = block;
  270.        Popup_menu(block->window, icon_PROCESSES, processmenu);
  271.        break;
  272.  
  273.     case icon_NORMDRAW: case icon_SMOOTHDRAW: case icon_VSMOOTHDRAW:
  274.        Icon_Select(block->window, event->data.mouse.icon);
  275.        break;
  276.     
  277.     case icon_CLOSE:
  278.        close_greyedwin(FALSE, FALSE, block);
  279.        break;
  280.  
  281.     case icon_MAP: 
  282.        close_greyedwin(TRUE, event->data.mouse.button.data.adjust, block);
  283.        break;
  284.       
  285.   }
  286.   return(TRUE);
  287. }
  288.  
  289. /******************************************************************************
  290.  *                                null handlers                               *
  291.  ******************************************************************************/
  292.  
  293. static BOOL Null_updatebars(event_pollblock *event, void *reference)
  294. {
  295.   mouse_block ptrinfo;
  296.   greyed_block *block = reference;
  297.   convert_block convert;
  298.   window_state state;
  299.   icon_block bicon;
  300.   int greybarheight;
  301.   int barheight;
  302.   int greybarnumber;
  303.   char postext[5];
  304.   int bariconnumber;
  305.   int newgreybarheight;
  306.   int across;
  307.  
  308.   Wimp_GetPointerInfo(&ptrinfo);
  309.   Icon_SetInteger(db, 3, ptrinfo.pos.x);
  310.   Icon_SetInteger(db, 4, ptrinfo.pos.y);
  311.  
  312.  
  313.  /*
  314.   * setup convert block for workarea to screen coord conversion
  315.   */
  316.   Wimp_GetWindowState(block->window, &state);
  317.   convert.screenrect = state.openblock.screenrect;
  318.   convert.scroll = state.openblock.scroll;
  319.  
  320.  /*
  321.   * get background icon position in workarea coords
  322.   */
  323.   Wimp_GetIconState(block->window, icon_BARBACK, &bicon);
  324.  
  325.  /*
  326.   * convert mouse position to workarea coords
  327.   */
  328.   Coord_PointToWorkArea(&ptrinfo.pos, &convert);
  329.  
  330.  /*
  331.   * height of bar in workarea terms
  332.   */
  333.   barheight = ptrinfo.pos.y - (bicon.workarearect.min.y + border_WIDTH);
  334.  
  335.  /*
  336.   * number of greylevel bar (first is 0)
  337.   */
  338.   greybarnumber = (ptrinfo.pos.x - (bicon.workarearect.min.x + border_WIDTH) ) >> 2;
  339.   if( !(greybarnumber < total_GREYBARS) )
  340.      greybarnumber = total_GREYBARS - 1;
  341.  
  342.  /*
  343.   * update greybarmap
  344.   */
  345.   greybarheight = barheight;
  346.   if(greybarheight > 255)
  347.      greybarheight = 255;
  348.  
  349.  /*
  350.   * update bar on screen
  351.   */
  352.   bariconnumber = greybarnumber + icon_BARMIN;
  353.   addtomaps(block, greybarnumber, greybarheight);
  354.  
  355.  /*
  356.   * update height display
  357.   */
  358.   sprintf(postext, "%i", greybarheight);
  359.   if( strcmp(Icon_GetTextPtr(block->window, icon_HEIGHTDISP), postext) != 0 )
  360.      Icon_SetText(block->window, icon_HEIGHTDISP, postext);
  361.   across = greybarnumber << 2;
  362.   if(across > 255)
  363.      across = 255;
  364.   sprintf(postext, "%i", across);
  365.   if( strcmp(Icon_GetTextPtr(block->window, icon_WIDTHDISP), postext) != 0 ) 
  366.      Icon_SetText(block->window, icon_WIDTHDISP, postext);
  367.  
  368.  /*
  369.   * if smooth draw is on then update both other bars
  370.   */
  371.  
  372.   if(Icon_GetSelect(block->window, icon_VSMOOTHDRAW)){
  373.  
  374.      if(bariconnumber > (icon_BARMIN + 2)){
  375.         newgreybarheight = (block->greybarmap[greybarnumber - 3] + greybarheight) >> 1;
  376.         addtomaps(block, greybarnumber - 2, newgreybarheight);
  377.      }
  378.  
  379.      if(bariconnumber < (icon_BARMAX - 2)){
  380.         newgreybarheight = (block->greybarmap[greybarnumber + 3] + greybarheight) >> 1;
  381.         addtomaps(block, greybarnumber + 2, newgreybarheight);
  382.      }
  383.   }
  384.  
  385.   if( Icon_GetSelect(block->window, icon_SMOOTHDRAW) ||
  386.       Icon_GetSelect(block->window, icon_VSMOOTHDRAW) ){
  387.  
  388.      if(bariconnumber > (icon_BARMIN + 1)){
  389.         newgreybarheight = (block->greybarmap[greybarnumber - 2] + greybarheight) >> 1;
  390.         addtomaps(block, greybarnumber - 1, newgreybarheight);
  391.      }
  392.  
  393.      if(bariconnumber < (icon_BARMAX - 1)){
  394.         newgreybarheight = (block->greybarmap[greybarnumber + 2] + greybarheight) >> 1;
  395.         addtomaps(block, greybarnumber + 1, newgreybarheight);
  396.      }
  397.   }
  398.  
  399.   return(TRUE);
  400. }
  401.  
  402. /******************************************************************************/
  403.  
  404. static BOOL Null_checksourcebank(event_pollblock *event, void *reference)
  405. {
  406.   greyed_block *block = reference;
  407.  
  408.  /*
  409.   * close process window if the source bank become free
  410.   */
  411.   if( SpriteWin_FreeImage(block->sourceimage) )
  412.      close_greyedwin(FALSE, FALSE, block);
  413.  
  414.   return(FALSE);
  415. }
  416.  
  417. /******************************************************************************
  418.  *                             userdrag handlers                              *
  419.  ******************************************************************************/
  420.  
  421. static BOOL UserDrag_updatebars(event_pollblock *event, void *reference)
  422. {
  423.   greyed_block *block = reference;
  424.  
  425.   Wimp_DragBox((drag_block *) -1);
  426.   Event_Release(event_USERDRAG, event_ANY, event_ANY, UserDrag_updatebars, block);
  427.   Event_Release(event_NULL, event_ANY, event_ANY, Null_updatebars, block);
  428.  
  429.  /*
  430.   * if realtime is on then update destination
  431.   */
  432.   if(Icon_GetSelect(block->window, icon_REALTIME))
  433.      close_greyedwin(TRUE, TRUE, block);
  434.  
  435.  /*
  436.   * reset wimp_poll idletime
  437.   */
  438.   idletime = block->oldidletime;
  439.  
  440.  /*
  441.   * clear position display
  442.   */
  443.   Icon_SetText(block->window, icon_HEIGHTDISP, "");
  444.   Icon_SetText(block->window, icon_WIDTHDISP, "");
  445.  
  446.  
  447.   if(Icon_GetSelect(block->window, icon_REALTIME))
  448.      close_greyedwin(TRUE, TRUE, block);
  449.  
  450.   return(TRUE);
  451. }
  452.  
  453. /******************************************************************************
  454.  *                               close handlers                               *
  455.  ******************************************************************************/
  456.  
  457. static void close_greyedwin(BOOL ok, BOOL keepopen, greyed_block *block)
  458. {
  459.   wimp_point *size;
  460.  
  461.   if(ok == TRUE){
  462.  
  463.     /*
  464.      * process the image
  465.      */
  466.      size = SpriteWin_GetSize(block->sourceimage);
  467.  
  468.     /*
  469.      * create destination if not created and return if creation fails
  470.      */
  471.      if( SpriteWin_FreeImage(block->destimage) ){
  472.  
  473.         if( !SpriteWin_Create(size, block->destimage) )
  474.            return;
  475.      }
  476.  
  477.      Process_GreyMap(block->sourceimage, block->destimage, size, &(block->greymap));
  478.      
  479.     /*
  480.      * refresh destination image
  481.      */
  482.      SpriteWin_RefreshWin(block->destimage);
  483.      
  484.   }
  485.  
  486.   if(keepopen == FALSE){
  487.  
  488.      Event_Release(event_NULL, event_ANY, event_ANY, Null_checksourcebank, block);
  489.      Window_Delete(block->window);
  490.      free(block);
  491.   }
  492.  
  493. }
  494.  
  495. /******************************************************************************
  496.  *                           menu choice handlers                             *
  497.  ******************************************************************************/
  498.  
  499. static BOOL MenuChoice_processmenu(event_pollblock *event, void *reference)
  500. {
  501.   mouse_block ptr;
  502.  
  503.   if (menu_currentopen != processmenu) /* Only respond to the processmenu */
  504.     return(FALSE);
  505.  
  506.  
  507.   switch(event->data.selection[0])
  508.   {
  509.      case processmenu_LINEAR:
  510.         map_linear(currentblock);
  511.         break;
  512.  
  513.      case processmenu_INVERT:
  514.         map_invert(currentblock);
  515.         break;
  516.  
  517.      case processmenu_THRESH:
  518.         map_threshold(currentblock);
  519.         break;
  520.         
  521.      case processmenu_GAMMA:
  522.         map_gamma(currentblock);
  523.         break;
  524.  
  525.      case processmenu_HISTEQ:
  526.         map_histeq(currentblock);
  527.         break;
  528.  
  529.      case processmenu_SLCE:
  530.         map_slce(currentblock);
  531.         break;
  532.  
  533.   }
  534.  
  535.   if(Icon_GetSelect(currentblock->window, icon_REALTIME))
  536.      close_greyedwin(TRUE, TRUE, currentblock);
  537.  
  538.  
  539.   Wimp_GetPointerInfo(&ptr);               /* If ADJUST was used to select, */
  540.   if (ptr.button.data.adjust)              /* then we keep the menu open.   */
  541.     Menu_ShowLast();
  542.  
  543.   return(TRUE);
  544. }
  545.  
  546. /******************************************************************************
  547.  *                             misc routines                                  *
  548.  ******************************************************************************/
  549.  
  550. void NoMemEdit(void)
  551. {
  552.   char err_msg[128];
  553.  
  554.   Msgs_Lookup("err.nomemproc", err_msg, 127);
  555.   Error_Report(1,err_msg);
  556.  
  557. }
  558.  
  559. /******************************************************************************/
  560.  
  561. void bar_setheight(window_handle window, icon_handle icon, int barheight, BOOL redraw)
  562. {
  563.   icon_createblock icreate;
  564.   icon_handle iconhandle;
  565.   window_redrawblock r;
  566.  
  567.   icreate.window = window;
  568.   Wimp_GetIconState(window, icon, &icreate.icondata);
  569.   Wimp_DeleteIcon(window, icon);
  570.  
  571.  /*
  572.   * setup redraw block to redraw difference between both icons
  573.   */
  574.   r.window = window;
  575.   r.rect = icreate.icondata.workarearect;
  576.  
  577.   if(barheight < 4)
  578.      barheight = 4;
  579.   if(barheight == 255)
  580.      barheight = 256;
  581.   icreate.icondata.workarearect.max.y = icreate.icondata.workarearect.min.y + barheight;
  582.   Wimp_CreateIcon(&icreate, &iconhandle);
  583.  
  584.   if(redraw){
  585.  
  586.     if(r.rect.max.y > icreate.icondata.workarearect.max.y){ /* icon is shorter */
  587.  
  588.         r.rect.min.y = icreate.icondata.workarearect.max.y;
  589.      }
  590.      else{ /* icon is longer */
  591.  
  592.         r.rect.min.y = r.rect.max.y;
  593.         r.rect.max.y = icreate.icondata.workarearect.max.y;
  594.      }
  595.      Wimp_ForceRedraw(&r);
  596.   }
  597.  
  598. }
  599.  
  600. /******************************************************************************/
  601.  
  602. void map_linear(greyed_block *block)
  603. {
  604.   int bar;
  605.   int greylevel;
  606.  
  607.  /*
  608.   * make greymap linear
  609.   */
  610.   for(greylevel = 0; greylevel < 256; greylevel++)
  611.       block->greymap[greylevel] = greylevel;
  612.  
  613.  /*
  614.   * update greybarmap
  615.   */
  616.   map2barmap(&(block->greybarmap), &(block->greymap));
  617.  
  618.  
  619.  /*
  620.   * update bars on screen
  621.   */
  622.   for(bar = 0; bar < total_GREYBARS ; bar++)
  623.       bar_setheight(block->window, bar + icon_BARMIN, block->greybarmap[bar], FALSE);
  624.  
  625.  /*
  626.   * refresh bars on screen
  627.   */
  628.   refresh_map(block->window);
  629.   
  630. }
  631.  
  632. /******************************************************************************/
  633.  
  634. void map_invert(greyed_block *block)
  635. {
  636.   int bar;
  637.   int greylevel;
  638.  
  639.  /*
  640.   * make greymap inverted linear
  641.   */
  642.   for(greylevel = 0; greylevel < 256; greylevel++)
  643.       block->greymap[greylevel] = 255 - greylevel;
  644.  
  645.  /*
  646.   * update greybarmap
  647.   */
  648.   map2barmap(&(block->greybarmap), &(block->greymap));
  649.  
  650.  
  651.  /*
  652.   * update bars on screen
  653.   */
  654.   for(bar = 0; bar < total_GREYBARS ; bar++)
  655.       bar_setheight(block->window, bar + icon_BARMIN, block->greybarmap[bar], FALSE);
  656.  
  657.  /*
  658.   * refresh bars on screen
  659.   */
  660.   refresh_map(block->window);
  661.   
  662. }
  663.  
  664. /******************************************************************************/
  665.  
  666. void map_histeq(greyed_block *block)
  667. {
  668.  /*
  669.   * make greymap histogram equalized
  670.   */
  671.   wimp_point *size;
  672.   int bar;
  673.  
  674.   size = SpriteWin_GetSize(block->sourceimage);
  675.  
  676.   Process_HistogramEq(block->sourceimage, size, &(block->greymap));
  677.  
  678.  /*
  679.   * update greybarmap
  680.   */
  681.   map2barmap(&(block->greybarmap), &(block->greymap));
  682.  
  683.  
  684.  /*
  685.   * update bars on screen
  686.   */
  687.   for(bar = 0; bar < total_GREYBARS ; bar++)
  688.       bar_setheight(block->window, bar + icon_BARMIN, block->greybarmap[bar], FALSE);
  689.  
  690.  /*
  691.   * refresh bars on screen
  692.   */
  693.   refresh_map(block->window);
  694.  
  695. }
  696.  
  697. /******************************************************************************/
  698.  
  699. void map_gamma(greyed_block *block)
  700. {
  701.  /*
  702.   * produce gamma corrected greymap
  703.   */
  704.   int bar;
  705.   int greylevel;
  706.   int newgrey;
  707.   double gamma;
  708.   double factor;
  709.  
  710.   factor = 1.0 / 255.0;
  711.  
  712.   gamma = atof(gammavalue);
  713.  
  714.   if(gamma == 0){
  715.  
  716.      Menu_SetText(gammasubmenu, 0, "0.00");
  717.  
  718.      for(greylevel = 0; greylevel < 256; greylevel++)
  719.          block->greymap[greylevel] = 255;
  720.  
  721.   }
  722.   else{
  723.  
  724.      block->greymap[0] = 0;
  725.  
  726.      for(greylevel = 1; greylevel < 256; greylevel++){
  727.  
  728.          newgrey = (int) ( ( pow((double) greylevel * factor, gamma) * 255.0 ) + 0.5 );
  729.  
  730.          if(newgrey > 255)
  731.             newgrey = 255;
  732.          block->greymap[greylevel] = newgrey;
  733.      }
  734.   }
  735.  
  736.  /*
  737.   * update greybarmap
  738.   */
  739.   map2barmap(&(block->greybarmap), &(block->greymap));
  740.  
  741.  
  742.  /*
  743.   * update bars on screen
  744.   */
  745.   for(bar = 0; bar < total_GREYBARS ; bar++)
  746.       bar_setheight(block->window, bar + icon_BARMIN, block->greybarmap[bar], FALSE);
  747.  
  748.  /*
  749.   * refresh bars on screen
  750.   */
  751.   refresh_map(block->window);
  752.   
  753.  
  754. }
  755.  
  756. /******************************************************************************/
  757.  
  758. void map_threshold(greyed_block *block)
  759. {
  760.  /*
  761.   * make greymap thresholded
  762.   */
  763.   int greylevel;
  764.   int bar;
  765.   int threshold;
  766.  
  767.   threshold = atoi(threshvalue);
  768.  
  769.   if(threshold == 0)
  770.      Menu_SetText(threshsubmenu, 0, "0");
  771.  
  772.   if(threshold > 255){
  773.      threshold = 255;
  774.      Menu_SetText(threshsubmenu, 0, "255");
  775.   }
  776.  
  777.   for(greylevel = 0; greylevel < threshold; greylevel++)
  778.       block->greymap[greylevel] = 0;
  779.  
  780.   for(greylevel = threshold; greylevel < 256; greylevel++)
  781.       block->greymap[greylevel] = 255;
  782.  
  783.  /*
  784.   * update greybarmap
  785.   */
  786.   map2barmap(&(block->greybarmap), &(block->greymap));
  787.  
  788.  
  789.  /*
  790.   * update bars on screen
  791.   */
  792.   for(bar = 0; bar < total_GREYBARS ; bar++)
  793.       bar_setheight(block->window, bar + icon_BARMIN, block->greybarmap[bar], FALSE);
  794.  
  795.  /*
  796.   * refresh bars on screen
  797.   */
  798.   refresh_map(block->window);
  799.  
  800. }
  801.  
  802. /******************************************************************************/
  803.  
  804. void map_slce(greyed_block *block)
  805. {
  806.  /*
  807.   * make SLCE greymap
  808.   */
  809.   wimp_point *size;
  810.   int bar;
  811.  
  812.   size = SpriteWin_GetSize(block->sourceimage);
  813.  
  814.  /*
  815.   * calculate SLCE greymap
  816.   */
  817.   Process_SLCE(block->sourceimage, size, &(block->greymap));
  818.  
  819.  /*
  820.   * update greybarmap
  821.   */
  822.   map2barmap(&(block->greybarmap), &(block->greymap));
  823.  
  824.  
  825.  /*
  826.   * update bars on screen
  827.   */
  828.   for(bar = 0; bar < total_GREYBARS ; bar++)
  829.       bar_setheight(block->window, bar + icon_BARMIN, block->greybarmap[bar], FALSE);
  830.  
  831.  /*
  832.   * refresh bars on screen
  833.   */
  834.   refresh_map(block->window);
  835.  
  836. }
  837.  
  838. /******************************************************************************/
  839.  
  840. void refresh_map(window_handle window)
  841. {
  842.   window_redrawblock r;
  843.   icon_block iconinfo;
  844.  
  845.   Wimp_GetIconState(window, icon_BARBACK, &iconinfo);
  846.  
  847.   r.window = window;
  848.   r.rect.min.x = iconinfo.workarearect.min.x + border_WIDTH;
  849.   r.rect.max.x = iconinfo.workarearect.max.x - border_WIDTH;
  850.   r.rect.min.y = iconinfo.workarearect.min.y + border_WIDTH;
  851.   r.rect.max.y = iconinfo.workarearect.max.y - border_WIDTH;
  852.   Wimp_ForceRedraw(&r);
  853.  
  854. }
  855.  
  856. /******************************************************************************/
  857.  
  858. void barmap2map(char (*greybarmap)[], char (*greymap)[])
  859. {
  860.  /*
  861.   * calculate greymap from greybarmap
  862.   */
  863.   int greylevel;
  864.   int barlevel;
  865.  
  866.  /*
  867.   * up to 251 they are 4 apart
  868.   */
  869.   for(greylevel = 0; greylevel < 252; greylevel += 4){
  870.  
  871.      barlevel = greylevel >> 2;
  872.  
  873.      (*greymap)[greylevel]     = (*greybarmap)[barlevel];
  874.  
  875.      (*greymap)[greylevel + 1] = ( (3 * (*greybarmap)[barlevel    ]) >> 2 ) +
  876.                                  ( (    (*greybarmap)[barlevel + 1]) >> 2 );
  877.  
  878.      (*greymap)[greylevel + 2] = ( (    (*greybarmap)[barlevel    ]) >> 1 ) +
  879.                                  ( (    (*greybarmap)[barlevel + 1]) >> 1 );
  880.  
  881.      (*greymap)[greylevel + 3] = ( (    (*greybarmap)[barlevel    ]) >> 2 ) +
  882.                                  ( (3 * (*greybarmap)[barlevel + 1]) >> 2 );
  883.  
  884.   }
  885.  
  886.  /*
  887.   * 252 and over they are 3 apart
  888.   */
  889.   greylevel = 252;
  890.   barlevel = greylevel >> 2;
  891.  
  892.   (*greymap)[greylevel]     = (*greybarmap)[barlevel];
  893.  
  894.   (*greymap)[greylevel + 1] = ( (2 * (*greybarmap)[barlevel    ]) / 3 ) +
  895.                               ( (    (*greybarmap)[barlevel + 1]) / 3 );
  896.  
  897.   (*greymap)[greylevel + 2] = ( (    (*greybarmap)[barlevel    ]) / 3 ) +
  898.                               ( (2 * (*greybarmap)[barlevel + 1]) / 3 );
  899.  
  900.   (*greymap)[greylevel + 3] = (*greybarmap)[barlevel + 1];
  901.  
  902. }
  903.  
  904. /******************************************************************************/
  905.  
  906. void map2barmap(char (*greybarmap)[], char (*greymap)[])
  907. {
  908.  /*
  909.   * convert greymap to greybarmap
  910.   */
  911.   int bar;
  912.  
  913.  /*
  914.   * all bars exept last are 4 apart
  915.   */
  916.   for(bar = 0; bar < (total_GREYBARS - 1); bar++){
  917.  
  918.       (*greybarmap)[bar] = (*greymap)[bar << 2];
  919.   }
  920.  
  921.  /*
  922.   * last bar is 3 apart
  923.   */
  924.   bar = total_GREYBARS - 1;
  925.   (*greybarmap)[bar] = (*greymap)[255];
  926.  
  927. }
  928.  
  929. /******************************************************************************/
  930.  
  931. void addtomaps(greyed_block *block, int greybarno, int barheight)
  932. {
  933.  /*
  934.   * adds value to greybarmap, barmap and to bar on screen
  935.   */
  936.   int greylevel;
  937.  
  938.  /*
  939.   * put barheight into greybarmap
  940.   */
  941.   block->greybarmap[greybarno] = barheight;
  942.  
  943.  /*
  944.   * calculate central greylevel in greymap and place in central value
  945.   */
  946.   greylevel = greybarno << 2;
  947.   block->greymap[greylevel] = barheight;
  948.  
  949.  /*
  950.   * up to 251 they are 4 apart
  951.   */
  952.  
  953.   /* do 3 above greybar */
  954.   if( (greybarno >= 0) && (greybarno < (total_GREYBARS - 2)) ){
  955.  
  956.      block->greymap[greylevel + 1] = ( (3 * block->greybarmap[greybarno    ]) >> 2 ) +
  957.                                      ( (    block->greybarmap[greybarno + 1]) >> 2 );
  958.  
  959.      block->greymap[greylevel + 2] = ( (    block->greybarmap[greybarno    ]) >> 1 ) +
  960.                                      ( (    block->greybarmap[greybarno + 1]) >> 1 );
  961.  
  962.      block->greymap[greylevel + 3] = ( (    block->greybarmap[greybarno    ]) >> 2 ) +
  963.                                      ( (3 * block->greybarmap[greybarno + 1]) >> 2 );
  964.  
  965.   }
  966.  
  967.   /* do 3 below greybar */
  968.   if( (greybarno > 0) && (greybarno <= (total_GREYBARS - 2)) ){
  969.  
  970.      block->greymap[greylevel - 3] = ( (3 * block->greybarmap[greybarno - 1]) >> 2 ) +
  971.                                      ( (    block->greybarmap[greybarno    ]) >> 2 );
  972.  
  973.      block->greymap[greylevel - 2] = ( (    block->greybarmap[greybarno - 1]) >> 1 ) +
  974.                                      ( (    block->greybarmap[greybarno    ]) >> 1 );
  975.  
  976.      block->greymap[greylevel - 1] = ( (    block->greybarmap[greybarno - 1]) >> 2 ) +
  977.                                      ( (3 * block->greybarmap[greybarno    ]) >> 2 );
  978.  
  979.   }
  980.  
  981.   /* do 2 above second from last greybar */
  982.   if(greybarno == total_GREYBARS - 2){
  983.  
  984.      block->greymap[greylevel + 1] = ( (2 * block->greybarmap[greybarno    ]) / 3 ) +
  985.                                      ( (    block->greybarmap[greybarno + 1]) / 3 );
  986.  
  987.      block->greymap[greylevel + 2] = ( (    block->greybarmap[greybarno    ]) / 3 ) +
  988.                                      ( (2 * block->greybarmap[greybarno + 1]) / 3 );
  989.  
  990.   }
  991.  
  992.   /* do 2 below top greybar */
  993.   if(greybarno == total_GREYBARS - 1){
  994.  
  995.      block->greymap[greylevel - 2] = ( (2 * block->greybarmap[greybarno - 1]) / 3 ) +
  996.                                      ( (    block->greybarmap[greybarno    ]) / 3 );
  997.  
  998.      block->greymap[greylevel - 1] = ( (    block->greybarmap[greybarno - 1]) / 3 ) +
  999.                                      ( (2 * block->greybarmap[greybarno    ]) / 3 );
  1000.  
  1001.   }
  1002.  
  1003.   bar_setheight(block->window, greybarno + icon_BARMIN, barheight, TRUE);
  1004. }
  1005.