6894b3e9c5590a37147afd1485f21f07285c7ed1 galt Mon Sep 19 17:10:21 2016 -0700 Renamed phyloGif to phloPng for greater accuracy in the name. Because when we switched to PNG, only 16-bit color palettes are supported now. We lost the ability to do 8-bit color palette which is needed by GIF. diff --git src/hg/phyloGif/phyloGif.c src/hg/phyloGif/phyloGif.c deleted file mode 100644 index 4103ca5..0000000 --- src/hg/phyloGif/phyloGif.c +++ /dev/null @@ -1,770 +0,0 @@ -/* Copyright (C) 2012 The Regents of the University of California - * See README in this or parent directory for licensing information. */ - -/* phyloGif.c for parsing phylo tree and outputting a gif. - * - * Author: Galt Barber 2006 - * - * Designed to be run either as a cgi or as a command-line utility. - * The input file spec matches the .nh tree format e.g. (cat:0.5,dog:0.6):1.2; - * The output gif layout was originally designed to ignore branch lengths. - * However, options have now been added to allow it to use branchlengths, - * and to label the length of the branches. - * Any _suffix is stripped from labels both because pyloTree.c - * can't tolerate underscores and because we don't want suffixes anyway. - * A semi-colon is automatically appended to the input if left off. - * Because phyloTree.c does errAbort on bad input, this causes cgi err 500 - * if the input data has incorrect syntax. See the apache error_log. - * Added another option to place form output in a static html page - * so that we can prevent IE6 save-as bug, and FF auto-shrunk output. - * Added an option to display a length-scale legend or ruler at the bottom. - * Added an option to preserve underscores in input as spaces in output. - * - * - * One may use as a cgi in html GET: - * - * - * Or as cgi in html POST: -
- - - - - -
width:
height:
tree:
 
-
- - */ - - -#include "common.h" -#include "linefile.h" -#include "dystring.h" -#include "net.h" -#include "cheapcgi.h" -#include "errAbort.h" -#include "phyloTree.h" -#include "portable.h" -#include "memgfx.h" - -#include "cart.h" -#include "hui.h" -#include "htmshell.h" -#include "web.h" - - -#include "errAbort.h" -#include "errCatch.h" - - -struct cart *cart=NULL; /* The user's ui state. */ -struct hash *oldVars = NULL; -boolean onWeb = FALSE; - -int width=240,height=512; -boolean branchLengths = FALSE; /* branch lengths */ -boolean lengthLegend = FALSE; /* length ruler*/ -boolean branchLabels = FALSE; /* labelled branch lengths */ -boolean htmlPageWrapper = FALSE; /* wrap output in an html page */ -boolean stripUnderscoreSuff = FALSE; /* strip underscore suffixes from labels in input */ -boolean dashToSpace = FALSE; /* convert dash to space */ -boolean underToSpace = FALSE; /* convert underscore to space */ -boolean monospace = FALSE; /* use monospace font */ -int branchDecimals = 2; /* show branch label length to two decimals by default */ -int branchMultiplier = 1; /* multiply branch length by factor */ -char layoutErrMsg[1024] = ""; - -/* Null terminated list of CGI Variables we don't want to save - * permanently. */ -char *excludeVars[] = {"Submit", "submit", "phyloGif_submit", "phyloGif_restore", NULL}; - -void usage(char *msg) -/* Explain usage and exit. */ -{ -errAbort( - "%s\n\n" - "phyloGif - parse and display phyloGenetic tree\n" - "\n" - "Command-line Usage Examples:\n" - " phyloGif -phyloGif_tree=tree.nh [options] > phylo.gif \n" - " phyloGif -phyloGif_tree='(A:0.1,B:0.1)' [options] > phylo.gif \n" - "CGI Usage Examples:\n" - " Create an interactive form:\n" - " http://someserver.com/cgi-bin/phyloGif\n" - " Create an image dynamically via URL:\n" - " http://someserver.com/cgi-bin/phyloGif?phyloGif_tree=(A:0.1,B:0.1)\n" - "Options/CGI-vars:\n" - " -phyloGif_width=N - width of output GIF, default %d\n" - " -phyloGif_height=N - height of output GIF, default %d\n" - " -phyloGif_tree= - data in format (nodeA:0.5,nodeB:0.6):1.2;\n" - " If running at the command-line, can put filename here or stdin\n" - " (this is actually required)\n" - " -phyloGif_branchLengths - use branch lengths for layout\n" - " -phyloGif_lengthLegend - show length ruler at bottom\n" - " -phyloGif_branchLabels - show length of branch as label\n" - " (used with -phyloGif_branchLengths)\n" - " -phyloGif_branchDecimals=N - show length of branch to N decimals, default %d\n" - " -phyloGif_branchMultiplier=N - multiply branch length by N default %d\n" - " -phyloGif_htmlPage - wrap the output in an html page (cgi only)\n" - " -phyloGif_underscores - preserve underscores in input as spaces in output\n" - " -phyloGif_monospace - use a monospace proportional font\n" - , msg, width, height, branchDecimals, branchMultiplier); -} - -struct phyloLayout -{ - int depth; /* leaves have depth=0 */ - double vPos; /* vertical position */ - double hPos; /* horizontal position */ -}; - - - -void stripUnderscoreSuffixes(char *s) -/* Strip out underscores in labels, modifies s. */ -{ -char *j=s; -char c = ' '; -boolean inUnderScore = FALSE; -while(TRUE) - { - c = *s++; - if (c == 0) - break; - if (inUnderScore) - { - if (!isalnum(c)) - { - *j++ = c; - inUnderScore = FALSE; - } - } - else - { - if (c=='_') - { - inUnderScore = TRUE; - } - else - { - *j++ = c; - } - } - } -*j = 0; -} - - -#define MARGIN 10 - -static void phyloTreeLayoutBL(struct phyloTree *phyloTree, - int *pMaxDepth, int *pNumLeafs, int depth, - MgFont *font, int *pMaxLabelWidth, int width, double *pMinMaxFactor, double parentHPos) -/* do a depth-first recursion over the tree, assigning depth and vPos to each node - * and keeping track of maxDepth and numLeafs to return */ -{ -struct phyloLayout *this = NULL; -if (depth > *pMaxDepth) - *pMaxDepth = depth; -phyloTree->priv = (void *) needMem(sizeof(struct phyloLayout)); -this = (struct phyloLayout *) phyloTree->priv; -this->hPos = parentHPos + phyloTree->ident->length; -if (branchLengths && phyloTree->ident->length == 0 && depth != 0) - safef(layoutErrMsg,sizeof(layoutErrMsg),"Branch length is missing for %s.\n", - phyloTree->ident->name ? phyloTree->ident->name : "an internal node"); -if (phyloTree->numEdges == 2) /* node */ - { - int maxDepth = 0; - struct phyloLayout *that = NULL; - double vPos = 0; - phyloTreeLayoutBL(phyloTree->edges[0], pMaxDepth, pNumLeafs, depth+1, - font, pMaxLabelWidth, width, pMinMaxFactor, this->hPos); - phyloTreeLayoutBL(phyloTree->edges[1], pMaxDepth, pNumLeafs, depth+1, - font, pMaxLabelWidth, width, pMinMaxFactor, this->hPos); - that = (struct phyloLayout *) phyloTree->edges[0]->priv; - if (that->depth > maxDepth) - maxDepth = that->depth; - vPos += that->vPos; - that = (struct phyloLayout *) phyloTree->edges[1]->priv; - if (that->depth > maxDepth) - maxDepth = that->depth; - vPos += that->vPos; - this->depth=maxDepth+1; - this->vPos=vPos/2; - } -else if (phyloTree->numEdges == 0) /* leaf */ - { - int w=0; - double factor=0.0; - this->depth=0; - this->vPos=*pNumLeafs; - (*pNumLeafs)++; - - if(!phyloTree->ident->name) - { - safef(layoutErrMsg,sizeof(layoutErrMsg), - "leaf is missing label\n"); - return; - } - - if(dashToSpace) - { - char *temp = phyloTree->ident->name; - phyloTree->ident->name = replaceChars(temp,"-"," "); - freez(&temp); - } - - if(underToSpace) - { - char *temp = phyloTree->ident->name; - phyloTree->ident->name = replaceChars(temp,"_"," "); - freez(&temp); - } - - /* strip underscore suffixes option */ - if (stripUnderscoreSuff) - stripUnderscoreSuffixes(phyloTree->ident->name); - - w=mgFontStringWidth(font,phyloTree->ident->name); - if (w > *pMaxLabelWidth) - *pMaxLabelWidth = w; - factor = (width - 3*MARGIN - w) / this->hPos; - if (*pMinMaxFactor == 0.0 || factor < *pMinMaxFactor) - *pMinMaxFactor = factor; - } -else - { - safef(layoutErrMsg,sizeof(layoutErrMsg), - "Expected tree nodes to have 0 or 2 edges, found %d.\n" - "Check for missing commas or missing data.\n" - ,phyloTree->numEdges); - } - -} - -static void phyloTreeGif(struct phyloTree *phyloTree, - int maxDepth, int numLeafs, int maxLabelWidth, - int width, int height, struct memGfx *mg, MgFont *font) -/* do a depth-first recursion over the tree, printing tree to gif */ -{ -struct phyloLayout *this = (struct phyloLayout *) phyloTree->priv; -int fHeight = mgFontPixelHeight(font); -int vdelta = numLeafs < 2 ? 0 : (height - 2*MARGIN - fHeight) / (numLeafs - 1); -int v = MARGIN + this->vPos * vdelta; -int h = width - MARGIN - maxLabelWidth; -int hl = MARGIN; -int hr = h - MARGIN; -int hw = hr - hl; -int deltaH = hw / (maxDepth+1); -if (phyloTree->parent) - { - struct phyloLayout *that = (struct phyloLayout *) phyloTree->parent->priv; - mgDrawLine(mg, hr-that->depth*deltaH, v+fHeight/2, hr-this->depth*deltaH, v+fHeight/2, MG_BLACK); - } - -if (phyloTree->numEdges == 2) - { - struct phyloLayout *that0 = (struct phyloLayout *) phyloTree->edges[0]->priv; - struct phyloLayout *that1 = (struct phyloLayout *) phyloTree->edges[1]->priv; - phyloTreeGif(phyloTree->edges[0], maxDepth, numLeafs, maxLabelWidth, width, height, mg, font); - phyloTreeGif(phyloTree->edges[1], maxDepth, numLeafs, maxLabelWidth, width, height, mg, font); - mgDrawLine(mg, hr-this->depth*deltaH, that0->vPos*vdelta+fHeight/2+MARGIN, - hr-this->depth*deltaH, that1->vPos*vdelta+fHeight/2+MARGIN, MG_BLACK); - if (phyloTree->ident->name) - mgText(mg, h, v, MG_BLACK, font, phyloTree->ident->name); - } -else if (phyloTree->numEdges == 0) - { - mgText(mg, h, v, MG_BLACK, font, phyloTree->ident->name); - } -else - errAbort("expected tree nodes to have 0 or 2 edges, found %d\n", phyloTree->numEdges); - - -} - -static void phyloTreeGifBL(struct phyloTree *phyloTree, - int maxDepth, int numLeafs, int maxLabelWidth, - int width, int height, struct memGfx *mg, MgFont *font, double minMaxFactor, boolean isRightEdge) -/* do a depth-first recursion over the tree, printing tree to gif */ -{ -struct phyloLayout *this = (struct phyloLayout *) phyloTree->priv; -int fHeight = mgFontPixelHeight(font); -int vdelta = numLeafs < 2 ? 0 : (height - 2*MARGIN - fHeight) / (numLeafs - 1); -int v = MARGIN + this->vPos * vdelta; -mgDrawLine(mg, MARGIN+(this->hPos-phyloTree->ident->length)*minMaxFactor, v+fHeight/2, - MARGIN+this->hPos*minMaxFactor, v+fHeight/2, MG_BLACK); -if (branchLabels) - { - if (phyloTree->ident->length > 0.0 && this->hPos > 0.0) - { - char patt[16]; - char label[256]; - safef(patt,sizeof(patt),"%%%d.%df",branchDecimals+2,branchDecimals); - safef(label,sizeof(label),patt,(phyloTree->ident->length)*branchMultiplier); /* was %6.4f */ - mgTextCentered(mg, MARGIN+(this->hPos-phyloTree->ident->length)*minMaxFactor, v+(fHeight/2)*(isRightEdge?1:-1), - phyloTree->ident->length*minMaxFactor, fHeight, MG_BLACK, font, label); - } - } - -if (phyloTree->numEdges == 2) - { - struct phyloLayout *that0 = (struct phyloLayout *) phyloTree->edges[0]->priv; - struct phyloLayout *that1 = (struct phyloLayout *) phyloTree->edges[1]->priv; - phyloTreeGifBL(phyloTree->edges[0], maxDepth, numLeafs, maxLabelWidth, width, height, mg, font, minMaxFactor, FALSE); - phyloTreeGifBL(phyloTree->edges[1], maxDepth, numLeafs, maxLabelWidth, width, height, mg, font, minMaxFactor, TRUE); - mgDrawLine(mg, MARGIN+this->hPos*minMaxFactor, that0->vPos*vdelta+fHeight/2+MARGIN, - MARGIN+this->hPos*minMaxFactor, that1->vPos*vdelta+fHeight/2+MARGIN, MG_BLACK); - if (phyloTree->ident->name) - mgText(mg, MARGIN+this->hPos*minMaxFactor+MARGIN, v, MG_BLACK, font, phyloTree->ident->name); - } -else if (phyloTree->numEdges == 0) - { - mgText(mg, MARGIN+this->hPos*minMaxFactor+MARGIN, v, MG_BLACK, font, phyloTree->ident->name); - } -else - errAbort("expected tree nodes to have 0 or 2 edges, found %d\n", phyloTree->numEdges); - - -} - - -int main(int argc, char *argv[]) -{ -char *phyloData = NULL, *temp = NULL; -struct phyloTree *phyloTree = NULL; -int maxDepth = 0, numLeafs = 0, maxLabelWidth = 0; -double minMaxFactor = 0.0; -struct memGfx *mg = NULL; -boolean useCart = FALSE; -oldVars = hashNew(8); -onWeb = cgiIsOnWeb(); -boolean isMSIE = FALSE; -char *userAgent = getenv("HTTP_USER_AGENT"); -if (userAgent && strstr(userAgent ,"MSIE")) - isMSIE = TRUE; - - -cgiSpoof(&argc, argv); -setUdcCacheDir(); -if (argc != 1) - usage("wrong number of args"); - -if (onWeb) - { - /* this will cause it to kick out the set-cookie: http response header line */ - cart = cartAndCookieNoContent(hUserCookie(), excludeVars, oldVars); - } -else - { - if (!cgiOptionalString("phyloGif_tree")) - usage("-phyloGif_tree is a required 'option' or cgi variable."); - } - -//cartWarnCatcher(doMiddle, cart, cartEarlyWarningHandler); - - -useCart = (!cgiOptionalString("phyloGif_tree") || cgiVarExists("phyloGif_restore")); - -htmlPageWrapper = cgiVarExists("phyloGif_htmlPage"); /* wrap output in a page */ - -if (onWeb && sameString(getenv("REQUEST_METHOD"),"HEAD")) - { /* tell browser it's static just so it can save it */ - if (htmlPageWrapper) - printf("Content-type: text/html\r\n"); - else - printf("Content-type: image/gif\r\n"); - printf("\r\n"); - return 0; - } - -if (useCart) - { - width = cartUsualInt(cart,"phyloGif_width",width); - height = cartUsualInt(cart,"phyloGif_height",height); - phyloData = cloneString(cartOptionalString(cart,"phyloGif_tree")); - branchLengths = cartVarExists(cart,"phyloGif_branchLengths"); - lengthLegend = cartVarExists(cart,"phyloGif_lengthLegend"); - branchLabels = cartVarExists(cart,"phyloGif_branchLabels"); - branchDecimals = cartUsualInt(cart,"phyloGif_branchDecimals", branchDecimals); - branchMultiplier = cartUsualInt(cart,"phyloGif_branchMultiplier", branchMultiplier); - stripUnderscoreSuff = cartVarExists(cart,"phyloGif_undersuff_strip"); - dashToSpace = cartVarExists(cart,"phyloGif_dash_to_space"); - underToSpace = cartVarExists(cart,"phyloGif_under_to_space"); - monospace = cartVarExists(cart, "phyloGif_monospace"); - } -else - { - width = cgiUsualInt("phyloGif_width",width); - height = cgiUsualInt("phyloGif_height",height); - phyloData = cloneString(cgiOptionalString("phyloGif_tree")); - branchLengths = cgiVarExists("phyloGif_branchLengths"); - lengthLegend = cgiVarExists("phyloGif_lengthLegend"); - branchLabels = cgiVarExists("phyloGif_branchLabels"); - branchDecimals = cgiUsualInt("phyloGif_branchDecimals", branchDecimals); - branchMultiplier = cgiUsualInt("phyloGif_branchMultiplier", branchMultiplier); - stripUnderscoreSuff = cgiVarExists("phyloGif_undersuff_strip"); - dashToSpace = cgiVarExists("phyloGif_dash_to_space"); - underToSpace = cgiVarExists("phyloGif_under_to_space"); - monospace = cgiVarExists("phyloGif_monospace"); - } - -if (useCart) - { - if (onWeb) - { - printf("Content-type: text/html\r\n"); - printf("\r\n"); - cartWebStart(cart, NULL, "%s", "phyloGif Interactive Phylogenetic Tree Gif Maker"); - - if (isMSIE) /* cannot handle long urls */ - puts("
"); - else - puts(""); - - cartSaveSession(cart); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - puts(""); - - printf(""); - puts(""); - puts("
Width:"); cartMakeIntVar(cart, "phyloGif_width", width, 4); puts("
Height:"); cartMakeIntVar(cart, "phyloGif_height", height, 4); puts("
Use branch lengths?"); cartMakeCheckBox(cart, "phyloGif_branchLengths", branchLengths); puts("
  Show length ruler?"); cartMakeCheckBox(cart, "phyloGif_lengthLegend", lengthLegend); puts("
  Show length values?"); cartMakeCheckBox(cart, "phyloGif_branchLabels", branchLabels); puts("
  How many decimal places?"); cartMakeIntVar(cart, "phyloGif_branchDecimals", branchDecimals,1); puts("
  Multiply branch length by factor?"); cartMakeIntVar(cart, "phyloGif_branchMultiplier", branchMultiplier,5); puts("
Strip underscore-suffixes?"); cartMakeCheckBox(cart, "phyloGif_undersuff_strip", stripUnderscoreSuff); puts("
Change dash to space?"); cartMakeCheckBox(cart, "phyloGif_dash_to_space", dashToSpace); puts("
Change underscore to space?"); cartMakeCheckBox(cart, "phyloGif_under_to_space", underToSpace); puts("
Wrap in html page?"); cartMakeCheckBox(cart, "phyloGif_htmlPage", htmlPageWrapper); puts("
Monospace font?"); cartMakeCheckBox(cart, "phyloGif_monospace", monospace); puts("
TREE:"); - puts("

"); - - puts("
"); - puts("
 "); - puts(""); - puts("
"); - puts("
"); - webNewSection("Notes"); - puts( -"\n" -"1. Length-ruler and length-values cannot be shown unless use-branch-lengths is also checked.
\n" -"
\n" -"2. If \"Strip underscore-suffixes?\" is checked, underscores and anything following them are stripped from node labels.
\n" -"
\n" -"3. For backwards compatibility, options exist to convert a dash or underscore to a space in a node label.
\n" -"
\n" -"4. The tree is in the phastCons or .nh format name:length. Parentheses create a parent.\n" -"Parents must have two children. Length is not required if use-branch-lengths is not checked.\n" -"The length of the root branch is usually not specified.
\n" -"
\n" -"Examples:
\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"
\n"
-"((A:0.1,B:0.1):0.2,C:0.15);\n"
-"
\n" -"\n" -"
\n"
-"((A:0.1,B:0.1)D:0.2,C:0.15)E;\n"
-"
\n" -"\n" -"
(internal or ancestral node labels)\n" -"
\n"
-"  ((((\n"
-"   (\n"
-"     ((mouse,rat),human),\n"
-"       (dog,cow)\n"
-"    ),\n"
-"     opossum),\n"
-"     chicken),\n"
-"     xenopus),\n"
-"    (tetraodon,zebrafish));\n"
-"
\n" -"\n" -"
\n" -"We have extended the Newick format to allow spaces
\n" -"and other non-alphanumeric characters in node labels.
\n" -"If you need a backslash, comma, semi-colon, colon, or parenthesis,
\n" -"it must be escaped with a back-slash character.
\n" -"
\n"
-"((Brandt's myotis \\(bat\\):0.1,\n"
-"  White-tailed eagle:0.1):0.2,\n"
-" S. purpuratus:0.15);\n"
-"
\n" -"\n" -"
\n" -"5. PhastCons branch lengths are expected substitutions per site, allowing for\n" -"multiple hits. So a branch length of 0.5 means an average of one\n" -"substitution every two nucleotide sites, but the percent id will be\n" -"less than 50% because some of those substitutions are obscured by\n" -"subsequent substitutions. They are estimated from neutral sites,\n" -"sometimes fourfold degenerate sites in coding regions, or sometimes\n" -"\"nonconserved\" sites according to phastCons. The numbers are significant\n" -"to two or three figures.
\n" -"
\n" -"6. Wrap-in-html is useful when the browser automatically shinks a large image.\n" -"This option keeps the image view full in the browser automatically.\n" -"However, do not use with IE6 when performing save-as.\n" -"
" - ); - cartWebEnd(); - return 0; - } - else - usage("-phyloGif_tree is a required 'option' or cgi variable."); - } - -if (htmlPageWrapper) - { - printf("Content-type: text/html\r\n"); - printf("\r\n"); - puts("Phylogenetic Tree"); - printf(""); - freez(&phyloData); - return 0; - } - - - -if (!onWeb && phyloData[0] != '(') - { - int fd = 0; /* default to stdin */ - if (!sameString(phyloData,"stdin")) - fd = open(phyloData,O_RDONLY); - struct dyString *dy = netSlurpFile(fd); - if (fd) - close(fd); - freez(&phyloData); - phyloData = dyStringCannibalize(&dy); - } - -/* remove carriage returns which are a side-effect of html forms */ -if (strchr(phyloData,'\r')) - { - char *temp = phyloData; - phyloData = replaceChars(temp,"\r",""); - freez(&temp); - } - -/* add trailing semi-colon if it got stripped off */ -if (!strchr(phyloData,';')) - { - temp = phyloData; - phyloData = addSuffix(phyloData,";"); - freez(&temp); - } - -/* parse phyloTree, but catch errAborts if any */ - -{ -struct errCatch *errCatch = errCatchNew(); -char *errMsg = NULL; -if (errCatchStart(errCatch)) - { - phyloTree = phyloParseString(phyloData); - } -errCatchEnd(errCatch); -if (errCatch->gotError) - { - errMsg = cloneString(errCatch->message->string); - } -errCatchFree(&errCatch); -if (errMsg) - { - if (onWeb) - { - printf("Content-type: text/html\r\n"); - printf("\r\n"); - puts("PhyloTree parse error
");
-	/* we dont think the specific error message coming back are correct or useful
-	 * so supply a generic err msg */
-    	htmlPrintf("Original input tree:\n[%s]\n\n",cgiString("phyloGif_tree"));
-    	htmlPrintf("Input tree as passed to parser:\n[%s]\n\n",phyloData);
-    	printf("Parser syntax error:\n%s",errMsg);
-    	puts("
"); - } - else - { - warn("%s", errMsg); - } - freez(&errMsg); - freez(&phyloData); - return 0; - } -} - - - -MgFont *font = NULL; -if (monospace) - font = mgMenloMediumFont(); -else - font = mgMediumBoldFont(); - - -if (phyloTree) - { - mg = mgNew(width,height); - mgClearPixels(mg); - - lengthLegend = lengthLegend && branchLengths; /* moot without lengths */ - if (lengthLegend) - { - int fHeight = mgFontPixelHeight(font); - height -= (MARGIN+2*fHeight); - } - - phyloTreeLayoutBL(phyloTree, &maxDepth, &numLeafs, 0, font, &maxLabelWidth, width, &minMaxFactor, 0.0); - - if (layoutErrMsg[0] != 0) - { - if (onWeb) - { - printf("Content-type: text/html\r\n"); - printf("\r\n"); - puts("PhyloTree error
");
-	    printf("input tree: [%s]\n\n%s",cgiString("phyloGif_tree"),layoutErrMsg);
-	    puts("
"); - } - else - { - warn("%s", layoutErrMsg); - } - freez(&phyloData); - mgFree(&mg); - return 0; - } - - if (branchLengths) - phyloTreeGifBL(phyloTree, maxDepth, numLeafs, maxLabelWidth, width, height, - mg, font, minMaxFactor, FALSE); - else - phyloTreeGif(phyloTree, maxDepth, numLeafs, maxLabelWidth, width, height, mg, font); - - if (lengthLegend) - { - int i = 0; - char out[256]; - double scaleEnd = (width - 2*MARGIN); - int fHeight = mgFontPixelHeight(font); - int x=0; - int dh=0; - - mgDrawLine(mg, MARGIN, height+fHeight/2, - width-MARGIN, height+fHeight/2, MG_BLACK); - while(TRUE) - { - x=((minMaxFactor*i)/10); - if (x >= scaleEnd) - break; - if ((i % 5) == 0) - { - int y = mgFontCharWidth(font,'0'); - y += 0.5*mgFontCharWidth(font,'.'); - safef(out,sizeof(out),"%3.2f",branchMultiplier*i/10.0); - if (branchMultiplier > 10) - safef(out,sizeof(out),"%3.0f",branchMultiplier*i/10.0); - mgText(mg, MARGIN+x-y, height+fHeight, MG_BLACK, font, out); - dh=fHeight/2; - } - else - { - dh = fHeight / 4; - } - mgDrawLine(mg, MARGIN+x, height+fHeight/2-dh, - MARGIN+x, height+fHeight/2+dh, MG_BLACK); - ++i; - } - - - } - - } - -if (onWeb) - { - printf("Content-type: image/png\r\n"); - printf("\r\n"); - } - -if (!mgSaveToPng(stdout, mg, FALSE)) - { - errAbort("Couldn't save png to stdout"); - } - -if (cgiOptionalString("phyloGif_submit")) - cartCheckout(&cart); - -/* there's no code for freeing the phyloTree yet in phyloTree.c */ - -mgFree(&mg); -freez(&phyloData); - - -return 0; -} -