void psOutput(int *hist, char *psFile)
/* Output histogram in postscript format. */
{
double labelSize = 72.0/2;
double psInnerSize = psSize - labelSize;
double tickSize = labelSize/4;
double textSize = labelSize - tickSize;
struct psGfx *ps = psOpen(psFile, psSize, psSize, psSize, psSize, margin);
double val, maxVal = findMaxVal(hist);
int x, y, both;
double grayScale;
double xPos, yPos, xMid;
double xBinPts = psInnerSize/xBins;
double yBinPts = psInnerSize/yBins;

grayScale = 1.0 / maxVal * postScale;
for (y=0; y<yBins; ++y)
    {
    int yg = yBins-1-y;
    yPos = yg*yBinPts;
    for (x=0; x<xBins; ++x)
        {
	xPos = x * xBinPts + labelSize;
	both = y*xBins + x;
	val = mightLog(hist[both]) * grayScale;
	if (val > 1.0) val = 1.0;
	if (val < 0.0) val = 0.0;
	psSetGray(ps, 1.0 - val);
	boxOut(ps, xPos, yPos, xBinPts, yBinPts);
	}
    }

/* Draw ticks and labels. */
psSetGray(ps, 0);
yPos = psInnerSize;
for (x=labelStep; x<xBins; x += labelStep)
    {
    char buf[16];
    sprintf(buf, "%d", x*xBinSize+xMin);
    xPos = x * xBinPts + labelSize;
    xMid = xPos;
    psDrawBox(ps, xPos, yPos, 1, tickSize);
    psTextDown(ps, xPos, yPos+tickSize+2, buf);
    }
for (y=labelStep; y<yBins; y += labelStep)
    {
    char buf[16];
    int yg = yBins-y;
    sprintf(buf, "%d", y*yBinSize+yMin);
    yPos = yg*yBinPts;
    psDrawBox(ps, textSize, yPos, tickSize, 1);
    psTextAt(ps, 0, yPos, buf);
    }
psClose(&ps);
}
void pscmClose(struct pscmGfx **pPscm)
/* Finish writing out and free structure. */
{
struct pscmGfx *pscm = *pPscm;
if (pscm != NULL)
    {
    psClose(&pscm->ps);
    colHashFree(&pscm->colorHash);
    freez(pPscm);
    }
}