/* * MandelVroom 2.0 * * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA * * All rights reserved. * * Permission is hereby granted to distribute this program's source * executable, and documentation for non-comercial purposes, so long as the * copyright notices are not removed from the sources, executable or * documentation. This program may not be distributed for a profit without * the express written consent of the author Kevin L. Clague. * * This program is not in the public domain. * * Fred Fish is expressly granted permission to distribute this program's * source and executable as part of the "Fred Fish freely redistributable * Amiga software library." * * Permission is expressly granted for this program and it's source to be * distributed as part of the Amicus Amiga software disks, and the * First Amiga User Group's Hot Mix disks. * * contents: this file contains the functions to open, draw and close the * histogram window. */ #include "mandp.h" UBYTE HistOpen; struct Window *HistWind; struct NewWindow NewHist = { 0,200-80, /* start position */ 280,80, /* width, height */ (UBYTE) 0, (UBYTE) -1, /* detail pen, block pen */ NULL, /* IDCMP flags */ /* MandWind flags */ WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|NOCAREREFRESH|SMART_REFRESH, (struct Gadget *) NULL, /* first gadget */ (struct Image *) NULL, /* user checkmark */ (UBYTE *) "Histogram", /* window title */ (struct Screen *) NULL, /* pointer to screen */ (struct BitMap *) NULL, /* pointer to superbitmap */ 80,80,-1,-1, /* sizing */ CUSTOMSCREEN /* type of screen */ }; struct Histogram * AllocHist( size ) int size; { struct Histogram *Hist; Hist = AllocHistStruct(); if (Hist != NULL) { if (Hist->Table == NULL) { Hist->Table = AllocHistTable(size); if (Hist->Table == NULL) { FreeHistStruct(Hist); return( NULL ); } Hist->TableSize = size; } } return( Hist ); } FreeHist( Hist ) struct Histogram *Hist; { if (Hist) { if (Hist->Table) { FreeHistTable( Hist ); } FreeHistStruct( Hist ); } } ReDoHist( Pict ) register struct Picture *Pict; { if (Pict == NULL || Pict->Counts == NULL || Pict->Flags & NO_RAM_GENERATE || HistWind == NULL) { return(UNSUCCESSFUL ); } CalcHist(Pict); PlotHist(Pict); } /* * */ CalcHist(Pict) register struct Picture *Pict; { register int i, n, size, *Table; register SHORT *Counts; /* make sure the histogram is available */ if (Pict->Hist) { FreeHist( Pict->Hist ); Pict->Hist = NULL; } if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE || Pict->Counts == NULL) { return; } Pict->Hist = AllocHist( Pict->MaxIteration ); if (Pict->Hist == NULL) { return; } Table = Pict->Hist->Table; size = Pict->Hist->TableSize; for (i = 0; i < size; i++) { Table[i] = 0; } Counts = Pict->Counts; size = Pict->CountX*Pict->CountY; for (i = 0; i < size; i++) { if ( (n = *Counts++) > 0 && n < Pict->Hist->TableSize) { Table[ n ]++; } } } PlotHist( Pict ) struct Picture *Pict; { register struct Histogram *Hist; int *Table; int Size; int max, locmax, maxnum; struct IntuiText *intui; BorderWindow( HistWind ); Hist = Pict->Hist; if (Hist == NULL) { return; } Table = (int *) Hist->Table; Size = Hist->TableSize; /* Find Max of all iteration counts */ { int i,n; max = 0; for (i = 0; i < Size; i++) { if ((n = *Table++) > max) { max = n; } } } #define BOX_BOT 24 #define BOX_LEFT 17 #define BOX_TOP 22 Table = (int *) Hist->Table; /* Plot scaled versions of this histogram */ { int bot,right,half; int i, j, k, n, height,width; int num_entries; float scale; register struct RastPort *Rp = HistWind->RPort; if (XScale) { k = 2; } else { k = 4; } num_entries = 1024/k; right = BOX_LEFT + num_entries; half = num_entries/2 + BOX_LEFT; bot = HistWind->Height - BOX_BOT; scale = (float)(bot-BOX_TOP)/(float)max; Rp = HistWind->RPort; SetAPen( Rp, NORMALPEN ); RectFill( Rp, LEFTMARG, TOPMARG, HistWind->Width-2, HistWind->Height-2); /* Draw plot border */ SetAPen(Rp,SHADOWPEN); Move(Rp,right+1, bot+1); /* Lower right */ Draw(Rp,right+1, BOX_TOP); /* Upper right */ Draw(Rp,BOX_LEFT,BOX_TOP); /* Upper left */ Draw(Rp,BOX_LEFT,bot+1); /* Lower left */ Draw(Rp,right+1, bot+1); /* Lower right */ Move(Rp,BOX_LEFT,bot+2); /* Lower left tic */ Draw(Rp,BOX_LEFT,bot+3); /* Do altitude tick marks */ for (i = 0; i < num_entries; i += 16<CountX*Pict->CountY/10; int thresh, cur; cur = 0; thresh = tick; for (i = Size-1; i >= 0; i--) { cur += Table[i]; if (cur > thresh) { Move(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-1); Draw(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-2); thresh += tick; } } } for (i = 0; i < Size; i += k) { n = Table[i]; locmax = n; maxnum = i; for (j = 0; j < 4; j++) { n = Table[i+j]; if (n > locmax) { locmax = n; maxnum = i+j; } } if ( locmax > 0 ) { height = bot - (int) (scale * locmax); if (right < HistWind->Width && height >= 0 && height < HistWind->Height) { SetAPen( Rp, Pict->ClrXlate[maxnum] ); Move(Rp, right, bot); Draw(Rp, right, height); } } right -= 1; } } } AutoContour( Pict, Mode ) struct Picture *Pict; { int num_conts,i,j,prev_i; float tick; float thresh, cur; if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE || Pict->Counts == NULL) { return; } CalcHist(Pict); if (Pict->Hist == NULL) return; /* find pattern range length */ for (num_conts = 255; num_conts >= 0 && Pict->Pens[num_conts] == 1; num_conts--); if (num_conts == 0) return; /* Set up contours */ j = 0; for (i = 0 ; i < Pict->Hist->TableSize - 1; i++) { j += Pict->Hist->Table[i]; } thresh = tick = (float) (j) / (float) num_conts; cur = 0.0; Pict->Heights[0] = Pict->MaxIteration; j = 1; prev_i = 0; for (i = Pict->Hist->TableSize - 2; i >= 0 && j < num_conts-1; i--) { cur += Pict->Hist->Table[i]; if (cur > thresh) { Pict->Heights[j++] = i; if (Mode == 1 && i+1 == prev_i) { break; /* out of the loop */ } prev_i = i; while ( cur > thresh ) thresh += tick; } } if (i < 0) i = 0; for (; j < num_conts-1; j++) { if (i > 0) i--; Pict->Heights[j] = i; } Pict->Heights[j] = 0; if (ContWind) { ModAll(); } ReColor( Pict ); } /* * Open the Hist window */ OpenHistWind() { if (CurPict == NULL) return; if ( HistWind == NULL ) { HistWind = OpenMyWind( &NewHist, screen, NULL,280<LeftEdge; NewHist.TopEdge = HistWind->TopEdge; CloseMyWind(HistWind,NULL); } HistWind = NULL; } /* CloseHistWind */