home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff214.lzh / MandelVroom / src / hist.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  9KB  |  420 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains the functions to open, draw and close the
  25.  * histogram window.
  26.  */
  27.  
  28. #include "mandp.h"
  29.  
  30. UBYTE HistOpen;
  31.  
  32. struct Window          *HistWind;
  33.  
  34. struct NewWindow NewHist = {
  35.    0,200-80,                 /* start position           */
  36.    280,80,                   /* width, height            */
  37.    (UBYTE) 0, (UBYTE) -1,    /* detail pen, block pen    */
  38.    NULL,                     /* IDCMP flags */
  39.                              /* MandWind flags */
  40.    WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|NOCAREREFRESH|SMART_REFRESH,
  41.    (struct Gadget *) NULL,   /* first gadget             */
  42.    (struct Image *) NULL,    /* user checkmark           */
  43.    (UBYTE *) "Histogram",     /* window title             */
  44.    (struct Screen *) NULL,   /* pointer to screen        */
  45.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  46.    80,80,-1,-1,              /* sizing                   */
  47.    CUSTOMSCREEN              /* type of screen           */
  48.    };
  49.  
  50. struct Histogram *
  51. AllocHist( size )
  52.   int size;
  53. {
  54.   struct Histogram *Hist;
  55.  
  56.   Hist = AllocHistStruct();
  57.  
  58.   if (Hist != NULL) {
  59.  
  60.     if (Hist->Table == NULL) {
  61.  
  62.       Hist->Table = AllocHistTable(size);
  63.  
  64.       if (Hist->Table == NULL) {
  65.  
  66.         FreeHistStruct(Hist);
  67.         return( NULL );
  68.       }
  69.  
  70.       Hist->TableSize = size;
  71.     }
  72.   }
  73.   return( Hist );
  74. }
  75.  
  76. FreeHist( Hist )
  77.   struct Histogram *Hist;
  78. {
  79.   if (Hist) {
  80.  
  81.     if (Hist->Table) {
  82.       FreeHistTable( Hist );
  83.     }
  84.     FreeHistStruct( Hist );
  85.   }
  86. }
  87.  
  88. ReDoHist( Pict )
  89.   register struct Picture *Pict;
  90. {
  91.   if (Pict == NULL || Pict->Counts == NULL ||
  92.       Pict->Flags & NO_RAM_GENERATE || HistWind == NULL) {
  93.  
  94.     return(UNSUCCESSFUL );
  95.   }
  96.   CalcHist(Pict);
  97.   PlotHist(Pict);
  98. }
  99.  
  100. /*
  101.  *
  102.  */
  103. CalcHist(Pict)
  104.   register struct Picture *Pict;
  105. {
  106.   register int i, n, size, *Table;
  107.   register SHORT *Counts;
  108.  
  109.   /* make sure the histogram is available */
  110.  
  111.   if (Pict->Hist) {
  112.     FreeHist( Pict->Hist );
  113.     Pict->Hist = NULL;
  114.   }
  115.  
  116.   if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE ||
  117.       Pict->Counts == NULL) {
  118.  
  119.     return;
  120.   }
  121.  
  122.   Pict->Hist = AllocHist( Pict->MaxIteration );
  123.  
  124.   if (Pict->Hist == NULL) {
  125.     return;
  126.   }
  127.  
  128.   Table = Pict->Hist->Table;
  129.   size  = Pict->Hist->TableSize;
  130.  
  131.   for (i = 0; i < size; i++) {
  132.     Table[i] = 0;
  133.   }
  134.  
  135.   Counts = Pict->Counts;
  136.   size   = Pict->CountX*Pict->CountY;
  137.  
  138.   for (i = 0; i < size; i++) {
  139.  
  140.     if ( (n = *Counts++) > 0 && n < Pict->Hist->TableSize) {
  141.  
  142.       Table[ n ]++;
  143.     }
  144.   }
  145. }
  146.  
  147. PlotHist( Pict )
  148.   struct Picture *Pict;
  149. {
  150.   register struct Histogram *Hist;
  151.   int *Table; int  Size;
  152.   int  max, locmax, maxnum;
  153.  
  154.   struct IntuiText *intui;
  155.  
  156.   BorderWindow( HistWind );
  157.  
  158.   Hist = Pict->Hist;
  159.  
  160.   if (Hist == NULL) {
  161.     return;
  162.   }
  163.  
  164.   Table = (int *) Hist->Table;
  165.   Size  = Hist->TableSize;
  166.  
  167.   /* Find Max of all iteration counts */
  168.  
  169.   { int i,n;
  170.  
  171.     max = 0;
  172.  
  173.     for (i = 0; i < Size; i++) {
  174.       if ((n = *Table++) > max) {
  175.         max = n;
  176.       }
  177.     }
  178.   }
  179.  
  180. #define BOX_BOT  24
  181. #define BOX_LEFT 17
  182. #define BOX_TOP  22
  183.  
  184.   Table = (int *) Hist->Table;
  185.  
  186.   /* Plot scaled versions of this histogram */
  187.  
  188.   { int bot,right,half;
  189.     int i, j, k, n, height,width;
  190.     int num_entries;
  191.     float scale;
  192.     register struct RastPort *Rp = HistWind->RPort;
  193.  
  194.     if (XScale) {
  195.       k = 2;
  196.     } else {
  197.       k = 4;
  198.     }
  199.  
  200.     num_entries = 1024/k;
  201.     right = BOX_LEFT + num_entries;
  202.     half = num_entries/2 + BOX_LEFT;
  203.     bot  = HistWind->Height - BOX_BOT;
  204.     scale = (float)(bot-BOX_TOP)/(float)max;
  205.  
  206.     Rp = HistWind->RPort;
  207.  
  208.     SetAPen(  Rp, NORMALPEN );
  209.     RectFill( Rp, LEFTMARG, TOPMARG, HistWind->Width-2, HistWind->Height-2);
  210.  
  211.     /* Draw plot border */
  212.  
  213.     SetAPen(Rp,SHADOWPEN);
  214.     Move(Rp,right+1,  bot+1);     /* Lower right */
  215.     Draw(Rp,right+1,  BOX_TOP);   /* Upper right */
  216.     Draw(Rp,BOX_LEFT,BOX_TOP);   /* Upper left  */
  217.     Draw(Rp,BOX_LEFT,bot+1);     /* Lower left  */
  218.     Draw(Rp,right+1,  bot+1);     /* Lower right */
  219.  
  220.     Move(Rp,BOX_LEFT,bot+2);     /* Lower left tic */
  221.     Draw(Rp,BOX_LEFT,bot+3);
  222.  
  223.     /* Do altitude tick marks */
  224.  
  225.     for (i = 0; i < num_entries; i += 16<<XScale) {
  226.       Move(Rp, right - i + 1, bot+2);
  227.       Draw(Rp, right - i + 1, bot+3);
  228.     }
  229.  
  230.     intui = ShadowIntui("1023", BOX_LEFT-16, bot + 5);
  231.     PrintIText( Rp, intui, 0, 0);
  232.     FreeIntui(intui);
  233.  
  234.     intui = ShadowIntui("512", half-12, bot + 5);
  235.     PrintIText( Rp, intui, 0, 0);
  236.     FreeIntui(intui);
  237.  
  238.     intui = ShadowIntui("0", right-4, bot + 5);
  239.     PrintIText( Rp, intui, 0, 0);
  240.     FreeIntui(intui);
  241.  
  242.     intui = ShadowIntui("Height", half-24, bot + 13);
  243.     PrintIText( Rp, intui, 0, 0);
  244.     FreeIntui(intui);
  245.  
  246.     intui = ShadowIntui("Percentage (10%/Tick)", half-84, BOX_TOP-11);
  247.     PrintIText( Rp, intui, 0, 0);
  248.     FreeIntui(intui);
  249.  
  250.     /* Do percentage tick marks */
  251.  
  252.     SetAPen(Rp,HIGHLIGHTPEN);
  253.     Move(Rp,right+1,  BOX_TOP-1); /* right */
  254.     Draw(Rp,right+1,  BOX_TOP-2);
  255.     Move(Rp,BOX_LEFT,BOX_TOP-1); /* left  */
  256.     Draw(Rp,BOX_LEFT,BOX_TOP-2);
  257.  
  258.     { int tick = Pict->CountX*Pict->CountY/10;
  259.       int thresh, cur;
  260.  
  261.       cur = 0;
  262.       thresh = tick;
  263.  
  264.       for (i = Size-1; i >= 0; i--) {
  265.         cur += Table[i];
  266.         if (cur > thresh) {
  267.           Move(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-1);
  268.           Draw(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-2);
  269.           thresh += tick;
  270.         }
  271.       }
  272.     }
  273.  
  274.     for (i = 0; i < Size; i += k) {
  275.  
  276.       n = Table[i];
  277.       locmax = n;
  278.       maxnum = i;
  279.  
  280.       for (j = 0; j < 4; j++) {
  281.  
  282.         n = Table[i+j];
  283.  
  284.         if (n > locmax) {
  285.           locmax = n;
  286.           maxnum = i+j;
  287.         }
  288.       }
  289.  
  290.       if ( locmax > 0 ) {
  291.  
  292.         height = bot - (int) (scale * locmax);
  293.  
  294.         if (right   < HistWind->Width && height >= 0 &&
  295.             height < HistWind->Height) {
  296.  
  297.           SetAPen( Rp, Pict->ClrXlate[maxnum] );
  298.  
  299.           Move(Rp, right, bot);
  300.           Draw(Rp, right, height);
  301.         }
  302.       }
  303.       right -= 1;
  304.     }
  305.   }
  306. }
  307.  
  308. AutoContour( Pict, Mode )
  309.   struct Picture *Pict;
  310. {
  311.   int num_conts,i,j,prev_i;
  312.  
  313.   float tick;
  314.   float thresh, cur;
  315.  
  316.   if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE ||
  317.       Pict->Counts == NULL) {
  318.     return;
  319.   }
  320.  
  321.   CalcHist(Pict);
  322.  
  323.   if (Pict->Hist == NULL)
  324.     return;
  325.  
  326.   /* find pattern range length */
  327.  
  328.   for (num_conts = 255; num_conts >= 0 && Pict->Pens[num_conts] == 1;
  329.        num_conts--);
  330.  
  331.   if (num_conts == 0)
  332.     return;
  333.  
  334.   /* Set up contours */
  335.  
  336.   j = 0;
  337.  
  338.   for (i = 0 ; i < Pict->Hist->TableSize - 1; i++) {
  339.      j += Pict->Hist->Table[i];
  340.   }
  341.  
  342.   thresh = tick = (float) (j) / (float) num_conts;
  343.   cur = 0.0;
  344.  
  345.   Pict->Heights[0] = Pict->MaxIteration;
  346.   j = 1;
  347.   prev_i = 0;
  348.  
  349.   for (i = Pict->Hist->TableSize - 2; i >= 0 && j < num_conts-1; i--) {
  350.  
  351.     cur += Pict->Hist->Table[i];
  352.  
  353.     if (cur > thresh) {
  354.  
  355.       Pict->Heights[j++] = i;
  356.  
  357.       if (Mode == 1 && i+1 == prev_i) {
  358.         break;   /* out of the loop */
  359.       }
  360.       prev_i = i;
  361.  
  362.       while ( cur > thresh )
  363.         thresh += tick;
  364.     }
  365.   }
  366.   if (i < 0)
  367.     i = 0;
  368.  
  369.   for (; j < num_conts-1; j++) {
  370.  
  371.     if (i > 0) i--;
  372.  
  373.     Pict->Heights[j] = i;
  374.   }
  375.   Pict->Heights[j] = 0;
  376.   if (ContWind) {
  377.     ModAll();
  378.   }
  379.   ReColor( Pict );
  380. }
  381.  
  382. /*
  383.  * Open the Hist window
  384.  */
  385. OpenHistWind()
  386. {
  387.  
  388.   if (CurPict == NULL)
  389.     return;
  390.  
  391.   if ( HistWind == NULL ) {
  392.  
  393.     HistWind = OpenMyWind( &NewHist, screen, NULL,280<<XScale,96+32*YScale);
  394.  
  395.     if ( HistWind == NULL ) {
  396.       return;
  397.     }
  398.   } else {
  399.     WindowToFront( HistWind );
  400.   }
  401.   ReDoHist(CurPict);
  402.   HistOpen = 1;
  403. } /* OpenHistWind */
  404.  
  405. /*
  406.  * Close the Hist window
  407.  */
  408. CloseHistWind()
  409. {
  410.   if (HistWind != NULL) {
  411.  
  412.     NewHist.LeftEdge = HistWind->LeftEdge;
  413.     NewHist.TopEdge  = HistWind->TopEdge;
  414.  
  415.     CloseMyWind(HistWind,NULL);
  416.   }
  417.   HistWind = NULL;
  418. } /* CloseHistWind */
  419.  
  420.