Example #1
0
/*
******** nrrdSave
**
** save a given nrrd to a given filename, with cleverness to guess
** format if not specified by the caller
**
** currently, for NRRD format files, we play the detached header game
** whenever the filename ends in NRRD_EXT_NHDR, and when we play this
** game, the data file is ALWAYS header relative.
*/
int
nrrdSave(const char *filename, const Nrrd *nrrd, NrrdIoState *nio) {
    char me[]="nrrdSave", err[BIFF_STRLEN];
    FILE *file;
    airArray *mop;

    if (!(nrrd && filename)) {
        sprintf(err, "%s: got NULL pointer", me);
        biffAdd(NRRD, err);
        return 1;
    }
    mop = airMopNew();
    if (!nio) {
        nio = nrrdIoStateNew();
        if (!nio) {
            sprintf(err, "%s: couldn't alloc local NrrdIoState", me);
            biffAdd(NRRD, err);
            return 1;
        }
        airMopAdd(mop, nio, (airMopper)nrrdIoStateNix, airMopAlways);
    }
    if (_nrrdEncodingMaybeSet(nio)
            || _nrrdFormatMaybeGuess(nrrd, nio, filename)) {
        sprintf(err, "%s: ", me);
        biffAdd(NRRD, err);
        airMopError(mop);
        return 1;
    }

    if (nrrdFormatNRRD == nio->format
            && airEndsWith(filename, NRRD_EXT_NHDR)) {
        nio->detachedHeader = AIR_TRUE;
        _nrrdSplitName(&(nio->path), &(nio->base), filename);
        /* nix the ".nhdr" suffix */
        nio->base[strlen(nio->base) - strlen(NRRD_EXT_NHDR)] = 0;
        /* nrrdFormatNRRD->write will do the rest */
    } else {
        nio->detachedHeader = AIR_FALSE;
    }

    if (!( file = airFopen(filename, stdout, "wb") )) {
        sprintf(err, "%s: couldn't fopen(\"%s\",\"wb\"): %s",
                me, filename, strerror(errno));
        biffAdd(NRRD, err);
        airMopError(mop);
        return 1;
    }
    airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);

    if (nrrdWrite(file, nrrd, nio)) {
        sprintf(err, "%s:", me);
        biffAdd(NRRD, err);
        airMopError(mop);
        return 1;
    }

    airMopOkay(mop);
    return 0;
}
Example #2
0
/*
** _nrrdWrite
**
** Write a nrrd to given file or string (allocated by nrrd), using the
** format and and encoding indicated in nio.  Cleverness should be
** isolated and collected here: by the time nio->format->write() is
** called, all writing parameters must be given explicitly, and their
** appropriateness is explicitly tested
*/
int
_nrrdWrite(FILE *file, char **stringP, const Nrrd *nrrd, NrrdIoState *_nio)
{
    char me[]="_nrrdWrite", err[BIFF_STRLEN];
    NrrdIoState *nio;
    airArray *mop;

    if (!((file || stringP) && nrrd))
    {
        sprintf(err, "%s: got NULL pointer", me);
        biffAdd(NRRD, err);
        return 1;
    }
    if (file && stringP)
    {
        sprintf(err, "%s: can't write to both file and string", me);
        biffAdd(NRRD, err);
        return 1;
    }
    if (nrrdCheck(nrrd))
    {
        sprintf(err, "%s:", me);
        biffAdd(NRRD, err);
        return 1;
    }
    mop = airMopNew();
    if (_nio)
    {
        nio = _nio;
    }
    else
    {
        nio = nrrdIoStateNew();
        if (!nio)
        {
            sprintf(err, "%s: couldn't alloc local NrrdIoState", me);
            biffAdd(NRRD, err);
            airMopError(mop);
            return 1;
        }
        airMopAdd(mop, nio, (airMopper)nrrdIoStateNix, airMopAlways);
    }
    if (_nrrdEncodingMaybeSet(nio)
            || _nrrdFormatMaybeSet(nio))
    {
        sprintf(err, "%s: ", me);
        biffAdd(NRRD, err);
        airMopError(mop);
        return 1;
    }
    if (nio->byteSkip || nio->lineSkip)
    {
        /* NOTE: unu make bypasses this by calling nrrdFormatNRRD->write()
           directly */
        sprintf(err, "%s: can't generate line or byte skips on data write", me);
        biffAdd(NRRD, err);
        airMopError(mop);
        return 1;
    }

    if (stringP)
    {
        if (nrrdFormatNRRD != nio->format)
        {
            sprintf(err, "%s: sorry, can only write %s files to strings (not %s)",
                    me, nrrdFormatNRRD->name, nio->format->name);
            biffAdd(NRRD, err);
            airMopError(mop);
            return 1;
        }
        /* we do this in two passes; first see how much room is needed
           for the header, then allocate, then write the header */
        nio->learningHeaderStrlen = AIR_TRUE;
        if (nio->format->write(NULL, nrrd, nio))
        {
            sprintf(err, "%s:", me);
            biffAdd(NRRD, err);
            airMopError(mop);
            return 1;
        }
        *stringP = (char*)malloc(nio->headerStrlen + 1);
        if (!*stringP)
        {
            sprintf(err, "%s: couldn't allocate header string (%u len )",
                    me, nio->headerStrlen);
            biffAdd(NRRD, err);
            airMopError(mop);
            return 1;
        }
        nio->learningHeaderStrlen = AIR_FALSE;
        nio->headerStringWrite = *stringP;
        if (nio->format->write(NULL, nrrd, nio))
        {
            sprintf(err, "%s:", me);
            biffAdd(NRRD, err);
            airMopError(mop);
            return 1;
        }
    }
    else
    {
        /* call the writer appropriate for the format */
        if (nio->format->write(file, nrrd, nio))
        {
            sprintf(err, "%s:", me);
            biffAdd(NRRD, err);
            airMopError(mop);
            return 1;
        }
    }

    airMopOkay(mop);
    return 0;
}