Beispiel #1
0
EXPORT(WORD) ipGetImageTraits (
    IP_HANDLE         hJob,          /* in:  handle to conversion job */
    LPIP_IMAGE_TRAITS pInputTraits,  /* out: traits of input image */
    LPIP_IMAGE_TRAITS pOutputTraits) /* out: traits of output image */
{
    PINST       g;
    PXFORM_INFO pTail;

    PRINT0 (_T("ipGetImageTraits: hJob=%p\n"), (void*)hJob);
    HANDLE_TO_PTR (hJob, g);
    INSURE (g->xfCount > 0);
    pTail = &(g->xfArray[g->xfCount-1]);

    if (pInputTraits != NULL) {
        INSURE (g->xfArray[0].eState > XS_PARSING_HEADER);
        *pInputTraits = g->xfArray[0].inTraits;
        PRINT0 (_T("InputTraits: hJob=%p PixelsPerRow=%d BitsPerPixel=%d ComponentsPerPixel=%d HorzDPI=%ld VertDPI=%ld Rows=%ld Pages=%d PageNum=%d\n"), 
                       (void*)hJob, pInputTraits->iPixelsPerRow, pInputTraits->iBitsPerPixel, pInputTraits->iComponentsPerPixel, pInputTraits->lHorizDPI, 
                        pInputTraits->lVertDPI, pInputTraits->lNumRows, pInputTraits->iNumPages, pInputTraits->iPageNum);
    }

    if (pOutputTraits != NULL) {
        INSURE (pTail->eState > XS_PARSING_HEADER);
        *pOutputTraits = pTail->outTraits;
        PRINT0 (_T("OutputTraits: hJob=%p PixelsPerRow=%d BitsPerPixel=%d ComponentsPerPixel=%d HorzDPI=%ld VertDPI=%ld Rows=%ld Pages=%d PageNum=%d\n"), 
                       (void*)hJob, pOutputTraits->iPixelsPerRow, pOutputTraits->iBitsPerPixel, pOutputTraits->iComponentsPerPixel, pOutputTraits->lHorizDPI, 
                        pOutputTraits->lVertDPI, pOutputTraits->lNumRows, pOutputTraits->iNumPages, pOutputTraits->iPageNum);
    }

    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
void USE_LENGTH_UNITS(CANON_UNITS in_unit)
{
    if (in_unit IS CANON_UNITS_INCHES)
    {
        PRINT0("USE_LENGTH_UNITS(CANON_UNITS_INCHES)\r\n");
        if (_length_unit_type IS CANON_UNITS_MM)
        {
            _length_unit_type SET_TO CANON_UNITS_INCHES;
            _length_unit_factor SET_TO 25.4;
            _program_origin_x SET_TO (_program_origin_x / 25.4);
            _program_origin_y SET_TO (_program_origin_y / 25.4);
            _program_origin_z SET_TO (_program_origin_z / 25.4);
            _program_position_x SET_TO (_program_position_x / 25.4);
            _program_position_y SET_TO (_program_position_y / 25.4);
            _program_position_z SET_TO (_program_position_z / 25.4);
        }
    }
    else if (in_unit IS CANON_UNITS_MM)
    {
        PRINT0("USE_LENGTH_UNITS(CANON_UNITS_MM)\r\n");
        if (_length_unit_type IS CANON_UNITS_INCHES)
        {
            _length_unit_type SET_TO CANON_UNITS_MM;
            _length_unit_factor SET_TO 1.0;
            _program_origin_x SET_TO (_program_origin_x * 25.4);
            _program_origin_y SET_TO (_program_origin_y * 25.4);
            _program_origin_z SET_TO (_program_origin_z * 25.4);
            _program_position_x SET_TO (_program_position_x * 25.4);
            _program_position_y SET_TO (_program_position_y * 25.4);
            _program_position_z SET_TO (_program_position_z * 25.4);
        }
    }
    else
        PRINT0("USE_LENGTH_UNITS(UNKNOWN)\r\n");
}
extern void SET_MOTION_CONTROL_MODE(CANON_MOTION_MODE mode)
{
    if (mode IS CANON_EXACT_STOP)
    {
        PRINT0("SET_MOTION_CONTROL_MODE(CANON_EXACT_STOP)\r\n");
        _motion_mode SET_TO CANON_EXACT_STOP;
    }
    else if (mode IS CANON_EXACT_PATH)
    {
        PRINT0("SET_MOTION_CONTROL_MODE(CANON_EXACT_PATH)\r\n");
        _motion_mode SET_TO CANON_EXACT_PATH;
    }
    else if (mode IS CANON_CONTINUOUS)
    {
        PRINT0("SET_MOTION_CONTROL_MODE(CANON_CONTINUOUS)\r\n");
        _motion_mode SET_TO CANON_CONTINUOUS;
    }
    else
        PRINT0("SET_MOTION_CONTROL_MODE(UNKNOWN)\r\n");
}
Beispiel #4
0
static void deleteMidBufs (PINST g)
{
    PRINT0 (_T("deleteMidBufs\n"));

    if (g->pbMidInBuf != NULL)
        IP_MEM_FREE (g->pbMidInBuf);

    if (g->pbMidOutBuf != NULL)
        IP_MEM_FREE (g->pbMidOutBuf);

    g->pbMidInBuf  = NULL;
    g->pbMidOutBuf = NULL;
}
Beispiel #5
0
EXPORT(WORD) ipGetClientDataPtr (
    IP_HANDLE  hJob,            /* in:  handle to conversion job */
    PVOID     *ppvClientData)   /* out: ptr to client's memory area */
{
    PINST g;

    PRINT0 (_T("ipGetClientDataPtr\n"));
    HANDLE_TO_PTR (hJob, g);
    *ppvClientData = (PVOID)((PBYTE)g + sizeof(INST));
    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
void ThreadedAudioDevice::waitForThread(int waitMs)
{
	if (!isPassive()) {
		assert(_thread != 0);	// should not get called again!
		PRINT1("ThreadedAudioDevice::waitForThread: waiting for thread to finish\n");
		if (pthread_join(_thread, NULL) == -1) {
			PRINT0("ThreadedAudioDevice::doStop: terminating thread!\n");
			// JWM: pthread_cancel is not available in Android
			//pthread_cancel(_thread);
			//_thread = 0;
		}
		PRINT1("\tThreadedAudioDevice::waitForThread: thread done\n");
	}
}
Beispiel #7
0
EXPORT(WORD) ipResultMask (
    IP_HANDLE  hJob,     /* in:  handle to conversion job */
    WORD       wMask)    /* in:  result bits you are interested in */
{
    PINST g;

    PRINT0 (_T("ipResultMask: hJob=%p, wMask=%04x\n"), (void*)hJob, wMask);
    HANDLE_TO_PTR (hJob, g);
    g->wResultMask = wMask | PERMANENT_RESULTS;
    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
Beispiel #8
0
EXPORT(WORD) ipInsertedData (
    IP_HANDLE  hJob,         /* in: handle to conversion job */
    DWORD      dwNumBytes)   /* in: # of bytes of additional data written */
{
    PINST       g;
    PXFORM_INFO pTail;

    PRINT0 (_T("ipInsertedData: hJob=%p, dwNumBytes=%d\n"), (void*)hJob, dwNumBytes);
    HANDLE_TO_PTR (hJob, g);
    INSURE (g->xfCount > 0);
    pTail = &(g->xfArray[g->xfCount-1]);
    INSURE (pTail->eState > XS_PARSING_HEADER);
    INSURE (g->gbOut.dwValidLen == 0);   /* output genbuf must be empty */

    pTail->pXform->insertedData (pTail->hXform, dwNumBytes);
    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
Beispiel #9
0
EXPORT(WORD) ipGetFuncPtrs (LPIP_JUMP_TBL lpJumpTbl)
{
    PRINT0 (_T("ipGetFuncPtrs\n"));
    INSURE (lpJumpTbl!=NULL && lpJumpTbl->wStructSize==sizeof(IP_JUMP_TBL));

    lpJumpTbl->ipOpen                  = (LPVOID) ipOpen;
    lpJumpTbl->ipConvert               = (LPVOID) ipConvert;
    lpJumpTbl->ipClose                 = (LPVOID) ipClose;
    lpJumpTbl->ipGetClientDataPtr      = (LPVOID) ipGetClientDataPtr;
    lpJumpTbl->ipResultMask            = (LPVOID) ipResultMask;
    lpJumpTbl->ipSetDefaultInputTraits = (LPVOID) ipSetDefaultInputTraits;     
    lpJumpTbl->ipGetImageTraits        = (LPVOID) ipGetImageTraits;
    lpJumpTbl->ipInsertedData          = (LPVOID) ipInsertedData;
    lpJumpTbl->ipOverrideDPI           = (LPVOID) ipOverrideDPI;
    lpJumpTbl->ipGetOutputTraits       = (LPVOID) ipGetOutputTraits;

    return IP_DONE;    

    fatal_error:
    return IP_FATAL_ERROR;
}
Beispiel #10
0
EXPORT(WORD) ipOverrideDPI (
    IP_HANDLE hJob,        /* in: handle to conversion job */
    DWORD     dwHorizDPI,  /* in: horiz DPI as 16.16; 0 means no override */
    DWORD     dwVertDPI)   /* in: vert  DPI as 16.16; 0 means no override */
{
    PINST g;

    PRINT0 (_T("ipOverrideDPI: dwHorizDPI=%x, dwVertDPI=%x\n"),
            dwHorizDPI, dwVertDPI);
    HANDLE_TO_PTR (hJob, g);

    /* Convert from integer to fixed-pt if necessary */
    if (dwHorizDPI < 0x10000) dwHorizDPI <<= 16;
    if (dwVertDPI  < 0x10000) dwVertDPI  <<= 16;

    g->dwForcedHorizDPI = dwHorizDPI;
    g->dwForcedVertDPI  = dwVertDPI;
    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
Beispiel #11
0
EXPORT(WORD) ipClose (IP_HANDLE hJob)
{
    PINST       g;
    PXFORM_INFO pXform;
    WORD        n;

    PRINT0 (_T("ipClose: hJob=%p\n"), (void*)hJob);
    HANDLE_TO_PTR (hJob, g);

    /**** Delete All Buffers ****/

    deleteMidBufs (g);
    g->dwMidLen      = 0;
    g->dwMidValidLen = 0;

    if (g->gbIn.pbBuf  != NULL) IP_MEM_FREE (g->gbIn.pbBuf);
    if (g->gbOut.pbBuf != NULL) IP_MEM_FREE (g->gbOut.pbBuf);

    /**** Delete All Xform Instances ****/

    for (n=0; n<g->xfCount; n++) {
        pXform = &(g->xfArray[n]);
        if (pXform->hXform != NULL)
            pXform->pXform->closeXform (pXform->hXform);
    }

    IP_MEM_FREE (g);   /* Delete our instance, and we're done */

#ifdef HPIP_DEBUG
    close(infd); 
    close(outfd); 
#endif

    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
Beispiel #12
0
EXPORT(WORD) ipSetDefaultInputTraits (
    IP_HANDLE         hJob,       /* in: handle to conversion job */
    LPIP_IMAGE_TRAITS pTraits)    /* in: default image traits */
{
    PINST g;
    PIP_IMAGE_TRAITS p;

    PRINT0 (_T("ipSetDefaultInputTraits: hJob=%p PixelsPerRow=%d BitsPerPixel=%d ComponentsPerPixel=%d HorzDPI=%ld VertDPI=%ld Rows=%ld Pages=%d PageNum=%d\n"), 
                       (void*)hJob, pTraits->iPixelsPerRow, pTraits->iBitsPerPixel, pTraits->iComponentsPerPixel, pTraits->lHorizDPI, 
                        pTraits->lVertDPI, pTraits->lNumRows, pTraits->iNumPages, pTraits->iPageNum);
    HANDLE_TO_PTR (hJob, g);
    INSURE (g->xfArray[0].eState == XS_NONEXISTENT);
    g->xfArray[0].inTraits = *pTraits;   /* a structure copy */

    /* Convert DPI from integer to 16.16 fixed-pt if necessary */
    p = &(g->xfArray[0].inTraits);
    if (p->lHorizDPI < 0x10000) p->lHorizDPI <<= 16;
    if (p->lVertDPI  < 0x10000) p->lVertDPI  <<= 16;

    return IP_DONE;

    fatal_error:
    return IP_FATAL_ERROR;
}
void FLOOD_OFF()
{
    PRINT0("FLOOD_OFF()\r\n");
    _flood SET_TO 0;
}
void ENABLE_SPEED_OVERRIDE()
{PRINT0("ENABLE_SPEED_OVERRIDE()\r\n");}
void DISABLE_SPEED_OVERRIDE()
{PRINT0("DISABLE_SPEED_OVERRIDE()\r\n");}
void USE_NO_SPINDLE_FORCE()
{PRINT0("USE_NO_SPINDLE_FORCE()\r\n");}
void OPTIONAL_PROGRAM_STOP()
{PRINT0("OPTIONAL_PROGRAM_STOP()\r\n");}
void TURN_PROBE_ON()
{PRINT0("TURN_PROBE_ON()\r\n");}
void MIST_ON()
{
    PRINT0("MIST_ON()\r\n");
    _mist SET_TO 1;
}
void FLOOD_ON()
{
    PRINT0("FLOOD_ON()\r\n");
    _flood SET_TO 1;
}
void MIST_OFF()
{
    PRINT0("MIST_OFF()\r\n");
    _mist SET_TO 0;
}
void STOP_SPEED_FEED_SYNCH()
{PRINT0 ("STOP_SPEED_FEED_SYNCH()\r\n");}
void PALLET_SHUTTLE()
{PRINT0("PALLET_SHUTTLE()\r\n");}
   /* Spindle Functions */
void SPINDLE_RETRACT_TRAVERSE()
{PRINT0("SPINDLE_RETRACT_TRAVERSE()\r\n");}
void PROGRAM_STOP()
{PRINT0("PROGRAM_STOP()\r\n");}
void START_SPINDLE_COUNTERCLOCKWISE()
{
    PRINT0("START_SPINDLE_COUNTERCLOCKWISE()\r\n");
    _spindle_turning SET_TO ((_spindle_speed IS 0) ? CANON_STOPPED :
    CANON_COUNTERCLOCKWISE);
}
void PROGRAM_END()
{PRINT0("PROGRAM_END()\r\n");}
void STOP_SPINDLE_TURNING()
{
    PRINT0("STOP_SPINDLE_TURNING()\r\n");
    _spindle_turning SET_TO CANON_STOPPED;
}
Beispiel #29
0
int CHOLMOD(metis)
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* matrix to order */
    Int *fset,		/* subset of 0:(A->ncol)-1 */
    size_t fsize,	/* size of fset */
    int postorder,	/* if TRUE, follow with etree or coletree postorder */
    /* ---- output --- */
    Int *Perm,		/* size A->nrow, output permutation */
    /* --------------- */
    cholmod_common *Common
)
{
    double d ;
    Int *Iperm, *Iwork, *Bp, *Bi ;
    idxtype *Mp, *Mi, *Mperm, *Miperm ;
    cholmod_sparse *B ;
    Int i, j, n, nz, p, identity, uncol ;
    int Opt [8], nn, zero = 0 ;
    size_t n1, s ;
    int ok = TRUE ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (FALSE) ;
    RETURN_IF_NULL (A, FALSE) ;
    RETURN_IF_NULL (Perm, FALSE) ;
    RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
    Common->status = CHOLMOD_OK ;

    /* ---------------------------------------------------------------------- */
    /* quick return */
    /* ---------------------------------------------------------------------- */

    n = A->nrow ;
    if (n == 0)
    {
	return (TRUE) ;
    }
    n1 = ((size_t) n) + 1 ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    /* s = 4*n + uncol */
    uncol = (A->stype == 0) ? A->ncol : 0 ;
    s = CHOLMOD(mult_size_t) (n, 4, &ok) ;
    s = CHOLMOD(add_size_t) (s, uncol, &ok) ;
    if (!ok)
    {
	ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
	return (FALSE) ;
    }

    CHOLMOD(allocate_work) (n, s, 0, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
	return (FALSE) ;
    }
    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* convert the matrix to adjacency list form */
    /* ---------------------------------------------------------------------- */

    /* The input graph for METIS must be symmetric, with both upper and lower
     * parts present, and with no diagonal entries.  The columns need not be
     * sorted.
     * B = A+A', A*A', or A(:,f)*A(:,f)', upper and lower parts present */
    if (A->stype)
    {
	/* Add the upper/lower part to a symmetric lower/upper matrix by
	 * converting to unsymmetric mode */
	/* workspace: Iwork (nrow) */
	B = CHOLMOD(copy) (A, 0, -1, Common) ;
    }
    else
    {
	/* B = A*A' or A(:,f)*A(:,f)', no diagonal */
	/* workspace: Flag (nrow), Iwork (max (nrow,ncol)) */
	B = CHOLMOD(aat) (A, fset, fsize, -1, Common) ;
    }
    ASSERT (CHOLMOD(dump_sparse) (B, "B for NodeND", Common) >= 0) ;
    if (Common->status < CHOLMOD_OK)
    {
	return (FALSE) ;
    }
    ASSERT (B->nrow == A->nrow) ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    Iwork = Common->Iwork ;
    Iperm = Iwork ;		/* size n (i/i/l) */

    Bp = B->p ;
    Bi = B->i ;
    nz = Bp [n] ;

    /* ---------------------------------------------------------------------- */
    /* METIS does not have a SuiteSparse_long integer version */
    /* ---------------------------------------------------------------------- */

#ifdef LONG
    if (sizeof (Int) > sizeof (idxtype) && MAX (n,nz) > INT_MAX / sizeof (int))
    {
	/* CHOLMOD's matrix is too large for METIS */
	CHOLMOD(free_sparse) (&B, Common) ;
	return (FALSE) ;
    }
#endif

    /* B does not include the diagonal, and both upper and lower parts.
     * Common->anz includes the diagonal, and just the lower part of B */
    Common->anz = nz / 2 + n ;

    /* ---------------------------------------------------------------------- */
    /* set control parameters for METIS_NodeND */
    /* ---------------------------------------------------------------------- */

    Opt [0] = 0 ;	/* use defaults */
    Opt [1] = 3 ;	/* matching type */
    Opt [2] = 1 ;	/* init. partitioning algo*/
    Opt [3] = 2 ;	/* refinement algorithm */
    Opt [4] = 0 ;	/* no debug */
    Opt [5] = 1 ;	/* initial compression */
    Opt [6] = 0 ;	/* no dense node removal */
    Opt [7] = 1 ;	/* number of separators @ each step */

    /* ---------------------------------------------------------------------- */
    /* allocate the METIS input arrays, if needed */
    /* ---------------------------------------------------------------------- */

    if (sizeof (Int) == sizeof (idxtype))
    {
	/* This is the typical case. */
	Miperm = (idxtype *) Iperm ;
	Mperm  = (idxtype *) Perm ;
	Mp     = (idxtype *) Bp ;
	Mi     = (idxtype *) Bi ;
    }
    else
    {
	/* allocate graph for METIS only if Int and idxtype differ */
	Miperm = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
	Mperm  = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
	Mp     = CHOLMOD(malloc) (n1, sizeof (idxtype), Common) ;
	Mi     = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
	if (Common->status < CHOLMOD_OK)
	{
	    /* out of memory */
	    CHOLMOD(free_sparse) (&B, Common) ;
	    CHOLMOD(free) (n,  sizeof (idxtype), Miperm, Common) ;
	    CHOLMOD(free) (n,  sizeof (idxtype), Mperm, Common) ;
	    CHOLMOD(free) (n1, sizeof (idxtype), Mp, Common) ;
	    CHOLMOD(free) (nz, sizeof (idxtype), Mi, Common) ;
	    return (FALSE) ;
	}
	for (j = 0 ; j <= n ; j++)
	{
	    Mp [j] = Bp [j] ;
	}
	for (p = 0 ; p < nz ; p++)
	{
	    Mi [p] = Bi [p] ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* METIS workarounds */
    /* ---------------------------------------------------------------------- */

    identity = FALSE ;
    if (nz == 0)
    {
	/* The matrix has no off-diagonal entries.  METIS_NodeND fails in this
	 * case, so avoid using it.  The best permutation is identity anyway,
	 * so this is an easy fix. */
	identity = TRUE ;
	PRINT1 (("METIS:: no nz\n")) ;
    }
    else if (Common->metis_nswitch > 0)
    {
	/* METIS_NodeND in METIS 4.0.1 gives a seg fault with one matrix of
	 * order n = 3005 and nz = 6,036,025, including the diagonal entries.
	 * The workaround is to return the identity permutation instead of using
	 * METIS for matrices of dimension 3000 or more and with density of 66%
	 * or more - admittedly an uncertain fix, but such matrices are so dense
	 * that any reasonable ordering will do, even identity (n^2 is only 50%
	 * higher than nz in this case).  CHOLMOD's nested dissection method
	 * (cholmod_nested_dissection) has no problems with the same matrix,
	 * even though it too uses METIS_NodeComputeSeparator.  The matrix is
	 * derived from LPnetlib/lpi_cplex1 in the UF sparse matrix collection.
	 * If C is the lpi_cplex matrix (of order 3005-by-5224), A = (C*C')^2
	 * results in the seg fault.  The seg fault also occurs in the stand-
	 * alone onmetis program that comes with METIS.  If a future version of
	 * METIS fixes this problem, then set Common->metis_nswitch to zero.
	 */
	d = ((double) nz) / (((double) n) * ((double) n)) ;
	if (n > (Int) (Common->metis_nswitch) && d > Common->metis_dswitch)
	{
	    identity = TRUE ;
	    PRINT1 (("METIS:: nswitch/dswitch activated\n")) ;
	}
    }

    if (!identity && !metis_memory_ok (n, nz, Common))
    {
	/* METIS might ask for too much memory and thus terminate the program */
	identity = TRUE ;
    }

    /* ---------------------------------------------------------------------- */
    /* find the permutation */
    /* ---------------------------------------------------------------------- */

    if (identity)
    {
	/* no need to do the postorder */
	postorder = FALSE ;
	for (i = 0 ; i < n ; i++)
	{
	    Mperm [i] = i ;
	}
    }
    else
    {
#ifdef DUMP_GRAPH
	/* DUMP_GRAPH */ printf ("Calling METIS_NodeND n "ID" nz "ID""
	"density %g\n", n, nz, ((double) nz) / (((double) n) * ((double) n)));
	dumpgraph (Mp, Mi, n, Common) ;
#endif

	nn = n ;
	METIS_NodeND (&nn, Mp, Mi, &zero, Opt, Mperm, Miperm) ;
	n = nn ;

	PRINT0 (("METIS_NodeND done\n")) ;
    }

    /* ---------------------------------------------------------------------- */
    /* free the METIS input arrays */
    /* ---------------------------------------------------------------------- */

    if (sizeof (Int) != sizeof (idxtype))
    {
	for (i = 0 ; i < n ; i++)
	{
	    Perm [i] = (Int) (Mperm [i]) ;
	}
	CHOLMOD(free) (n,   sizeof (idxtype), Miperm, Common) ;
	CHOLMOD(free) (n,   sizeof (idxtype), Mperm, Common) ;
	CHOLMOD(free) (n+1, sizeof (idxtype), Mp, Common) ;
	CHOLMOD(free) (nz,  sizeof (idxtype), Mi, Common) ;
    }

    CHOLMOD(free_sparse) (&B, Common) ;

    /* ---------------------------------------------------------------------- */
    /* etree or column-etree postordering, using the Cholesky Module */
    /* ---------------------------------------------------------------------- */

    if (postorder)
    {
	Int *Parent, *Post, *NewPerm ;
	Int k ;

	Parent = Iwork + 2*((size_t) n) + uncol ;   /* size n = nrow */
	Post   = Parent + n ;			    /* size n */

	/* workspace: Iwork (2*nrow+uncol), Flag (nrow), Head (nrow+1) */
	CHOLMOD(analyze_ordering) (A, CHOLMOD_METIS, Perm, fset, fsize,
		Parent, Post, NULL, NULL, NULL, Common) ;
	if (Common->status == CHOLMOD_OK)
	{
	    /* combine the METIS permutation with its postordering */
	    NewPerm = Parent ;	    /* use Parent as workspace */
	    for (k = 0 ; k < n ; k++)
	    {
		NewPerm [k] = Perm [Post [k]] ;
	    }
	    for (k = 0 ; k < n ; k++)
	    {
		Perm [k] = NewPerm [k] ;
	    }
	}
    }

    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
    PRINT1 (("cholmod_metis done\n")) ;
    return (Common->status == CHOLMOD_OK) ;
}
void SPINDLE_RETRACT()
{PRINT0("SPINDLE_RETRACT()\r\n");}