18 #pragma warning ( disable : 4786 )
27 #if defined(__BORLANDC__)
30 #endif // defined(__BORLANDC__)
34 #define KEY_PREFIX "NRRD_"
40 return dim <= NRRD_DIM_MAX;
44 return dim <= NRRD_DIM_MAX - 1;
57 #if defined(__BORLANDC__)
59 _control87(MCW_EM, MCW_EM);
60 #endif // defined(__BORLANDC__)
61 switch( nrrdComponentType )
115 #if defined(__BORLANDC__)
117 _control87(MCW_EM, MCW_EM);
118 #endif // defined(__BORLANDC__)
119 switch( itkComponentType )
122 return nrrdTypeUnknown;
128 return nrrdTypeUChar;
131 return nrrdTypeShort;
134 return nrrdTypeUShort;
140 return airMy32Bit ? nrrdTypeInt : nrrdTypeLLong;
143 return airMy32Bit ? nrrdTypeUInt : nrrdTypeULLong;
152 return nrrdTypeFloat;
155 return nrrdTypeDouble;
158 return nrrdTypeUnknown;
165 return nrrdTypeUnknown;
170 #if defined(__BORLANDC__)
172 _control87(MCW_EM, MCW_EM);
173 #endif // defined(__BORLANDC__)
177 std::string fname = filename;
180 itkDebugMacro(<<
"No filename specified.");
184 bool extensionFound =
false;
185 std::string::size_type nrrdPos = fname.rfind(
".nrrd");
186 if ((nrrdPos != std::string::npos)
187 && (nrrdPos == fname.length() - 5))
189 extensionFound =
true;
192 std::string::size_type nhdrPos = fname.rfind(
".nhdr");
193 if ((nhdrPos != std::string::npos)
194 && (nhdrPos == fname.length() - 5))
196 extensionFound =
true;
199 if( !extensionFound )
201 itkDebugMacro(<<
"The filename extension is not recognized");
207 std::ifstream inputStream;
209 inputStream.open( filename, std::ios::in | std::ios::binary );
211 if( inputStream.fail() )
216 char magic[5] = {
'\0',
'\0',
'\0',
'\0',
'\0'};
217 inputStream.read(magic,4*
sizeof(
char));
219 if( inputStream.eof() )
225 if( strcmp(magic,
"NRRD") == 0 )
237 #if defined(__BORLANDC__)
239 _control87(MCW_EM, MCW_EM);
240 #endif // defined(__BORLANDC__)
254 Nrrd *nrrd = nrrdNew();
255 NrrdIoState *nio = nrrdIoStateNew();
259 nrrdIoStateSet(nio, nrrdIoStateSkipData, 1);
262 char *err = biffGetDone(NRRD);
263 itkExceptionMacro(
"ReadImageInformation: Error reading "
267 if (nrrdTypeBlock == nrrd->type)
269 itkExceptionMacro(
"ReadImageInformation: Cannot currently "
270 "handle nrrdTypeBlock");
272 if ( nio->endian == airEndianLittle )
276 else if (nio->endian == airEndianBig )
285 if ( nio->encoding == nrrdEncodingAscii )
299 itkExceptionMacro(
"Nrrd type " << airEnumStr(nrrdType, nrrd->type)
300 <<
" could not be mapped to an ITK component type");
305 unsigned int domainAxisNum, domainAxisIdx[NRRD_DIM_MAX],
306 rangeAxisNum, rangeAxisIdx[NRRD_DIM_MAX];
307 domainAxisNum = nrrdDomainAxesGet(nrrd, domainAxisIdx);
308 rangeAxisNum = nrrdRangeAxesGet(nrrd, rangeAxisIdx);
309 if (nrrd->spaceDim && nrrd->spaceDim != domainAxisNum)
311 itkExceptionMacro(
"ReadImageInformation: nrrd's # independent axes ("
312 << domainAxisNum <<
") doesn't match dimension of space"
313 " in which orientation is defined ("
314 << nrrd->spaceDim <<
"); not currently handled");
318 if (0 == rangeAxisNum)
325 else if (1 == rangeAxisNum)
328 unsigned int kind = nrrd->axis[rangeAxisIdx[0]].kind;
329 unsigned int size = nrrd->axis[rangeAxisIdx[0]].size;
338 itkExceptionMacro(
"ReadImageInformation: range axis kind ("
339 << airEnumStr(nrrdKind, kind) <<
") seems more "
340 "like a domain axis than a range axis");
348 case nrrdKindRGBColor:
353 case nrrdKindRGBAColor:
358 case nrrdKind2Vector:
359 case nrrdKind3Vector:
360 case nrrdKind4Vector:
369 case nrrdKindCovariantVector:
370 case nrrdKind3Gradient:
372 case nrrdKind3Normal:
376 case nrrdKind3DSymMatrix:
381 case nrrdKind3DMaskedSymMatrix:
387 case nrrdKindComplex:
391 case nrrdKindHSVColor:
392 case nrrdKindXYZColor:
393 case nrrdKindQuaternion:
394 case nrrdKind2DSymMatrix:
395 case nrrdKind2DMaskedSymMatrix:
396 case nrrdKind2DMatrix:
397 case nrrdKind2DMaskedMatrix:
398 case nrrdKind3DMatrix:
404 itkExceptionMacro(
"ReadImageInformation: nrrdKind " << kind
411 itkExceptionMacro(
"ReadImageInformation: nrrd has "
413 <<
" dependent axis (not 1); not currently handled");
417 double spaceDir[NRRD_SPACE_DIM_MAX];
418 std::vector<double> spaceDirStd(domainAxisNum);
422 for (
unsigned int iI=0; iI<3; iI++ )
424 iFlipFactors[iI] = 1;
427 for (
unsigned int axii=0; axii < domainAxisNum; axii++)
429 unsigned int naxi = domainAxisIdx[axii];
431 spacingStatus = nrrdSpacingCalculate(nrrd, naxi, &spacing, spaceDir);
433 switch(spacingStatus)
435 case nrrdSpacingStatusNone:
439 case nrrdSpacingStatusScalarNoSpace:
442 case nrrdSpacingStatusDirection:
443 if (AIR_EXISTS(spacing))
449 case nrrdSpaceRightAnteriorSuperior:
452 iFlipFactors[0] = -1;
453 iFlipFactors[1] = -1;
455 case nrrdSpaceLeftAnteriorSuperior:
457 iFlipFactors[0] = -1;
459 case nrrdSpaceLeftPosteriorSuperior:
469 for (
unsigned int saxi=0; saxi < nrrd->spaceDim; saxi++)
471 spaceDirStd[saxi] = spaceDir[saxi];
477 case nrrdSpacingStatusUnknown:
478 itkExceptionMacro(
"ReadImageInformation: Error interpreting "
479 "nrrd spacing (nrrdSpacingStatusUnknown)");
481 case nrrdSpacingStatusScalarWithSpace:
482 itkExceptionMacro(
"ReadImageInformation: Error interpreting "
483 "nrrd spacing (nrrdSpacingStatusScalarWithSpace)");
491 if (AIR_EXISTS(nrrd->spaceOrigin[0]))
494 double spaceOrigin[NRRD_SPACE_DIM_MAX];
495 for (
unsigned int saxi=0; saxi < nrrd->spaceDim; saxi++)
497 spaceOrigin[saxi] = nrrd->spaceOrigin[saxi];
502 case nrrdSpaceRightAnteriorSuperior:
503 spaceOrigin[0] *= -1;
504 spaceOrigin[1] *= -1;
506 case nrrdSpaceLeftAnteriorSuperior:
507 spaceOrigin[0] *= -1;
509 case nrrdSpaceLeftPosteriorSuperior:
517 for (
unsigned int saxi=0; saxi < nrrd->spaceDim; saxi++)
519 this->
SetOrigin(saxi, spaceOrigin[saxi]);
525 double spaceOrigin[NRRD_DIM_MAX];
526 int originStatus = nrrdOriginCalculate(nrrd, domainAxisIdx, domainAxisNum,
527 nrrdCenterCell, spaceOrigin);
528 for (
unsigned int saxi=0; saxi < domainAxisNum; saxi++)
530 switch (originStatus)
532 case nrrdOriginStatusNoMin:
533 case nrrdOriginStatusNoMaxOrSpacing:
537 case nrrdOriginStatusOkay:
538 this->
SetOrigin(saxi, spaceOrigin[saxi]);
541 case nrrdOriginStatusUnknown:
542 case nrrdOriginStatusDirection:
543 itkExceptionMacro(
"ReadImageInformation: Error interpreting "
544 "nrrd origin status");
551 char key[AIR_STRLEN_SMALL];
558 for (
unsigned int kvpi=0; kvpi < nrrdKeyValueSize(nrrd); kvpi++)
560 nrrdKeyValueIndex(nrrd, &keyPtr, &valPtr, kvpi);
561 EncapsulateMetaData<std::string>(thisDic, std::string(keyPtr),
562 std::string(valPtr));
563 keyPtr = (
char *)airFree(keyPtr);
564 valPtr = (
char *)airFree(valPtr);
575 for (
unsigned int axii=0; axii < domainAxisNum; axii++)
577 unsigned int axi = domainAxisIdx[axii];
578 naxis = nrrd->axis + axi;
579 if (AIR_EXISTS(naxis->thickness))
582 airEnumStr(nrrdField, nrrdField_thicknesses), axii);
583 EncapsulateMetaData<double>(thisDic, std::string(key),
589 airEnumStr(nrrdField, nrrdField_centers), axii);
590 val = airEnumStr(nrrdCenter, naxis->center);
591 EncapsulateMetaData<std::string>(thisDic, std::string(key),
597 airEnumStr(nrrdField, nrrdField_kinds), axii);
598 val = airEnumStr(nrrdKind, naxis->kind);
599 EncapsulateMetaData<std::string>(thisDic, std::string(key),
602 if (airStrlen(naxis->label))
605 airEnumStr(nrrdField, nrrdField_labels), axii);
606 EncapsulateMetaData<std::string>(thisDic, std::string(key),
607 std::string(naxis->label));
610 if (airStrlen(nrrd->content))
613 airEnumStr(nrrdField, nrrdField_content));
614 EncapsulateMetaData<std::string>(thisDic, std::string(key),
615 std::string(nrrd->content));
617 if (AIR_EXISTS(nrrd->oldMin))
620 airEnumStr(nrrdField, nrrdField_old_min));
621 EncapsulateMetaData<double>(thisDic, std::string(key), nrrd->oldMin);
623 if (AIR_EXISTS(nrrd->oldMax))
626 airEnumStr(nrrdField, nrrdField_old_max));
627 EncapsulateMetaData<double>(thisDic, std::string(key), nrrd->oldMax);
632 airEnumStr(nrrdField, nrrdField_space));
633 val = airEnumStr(nrrdSpace, nrrd->space);
641 case nrrdSpaceRightAnteriorSuperior:
642 case nrrdSpaceLeftAnteriorSuperior:
643 case nrrdSpaceLeftPosteriorSuperior:
645 EncapsulateMetaData<std::string>(thisDic, std::string(key),
646 std::string( airEnumStr(nrrdSpace, nrrdSpaceLeftPosteriorSuperior )));
651 EncapsulateMetaData<std::string>(thisDic, std::string(key),
657 if (AIR_EXISTS(nrrd->measurementFrame[0][0]))
660 airEnumStr(nrrdField, nrrdField_measurement_frame));
661 std::vector<std::vector<double> > msrFrame(domainAxisNum);
667 for (
unsigned int saxi=0; saxi < domainAxisNum; saxi++)
669 msrFrame[saxi].resize(domainAxisNum);
670 for (
unsigned int saxj=0; saxj < domainAxisNum; saxj++)
672 if ( domainAxisNum<=3 )
674 msrFrame[saxi][saxj] = iFlipFactors[saxj]*nrrd->measurementFrame[saxi][saxj];
678 msrFrame[saxi][saxj] = nrrd->measurementFrame[saxi][saxj];
682 EncapsulateMetaData<std::vector<std::vector<double> > >(thisDic,
687 nrrd = nrrdNix(nrrd);
688 nio = nrrdIoStateNix(nio);
694 #if defined(__BORLANDC__)
696 _control87(MCW_EM, MCW_EM);
697 #endif // defined(__BORLANDC__)
699 Nrrd *nrrd = nrrdNew();
700 unsigned int baseDim;
711 nrrdAllocated =
true;
720 nrrdAllocated =
false;
743 char *err = biffGetDone(NRRD);
744 itkExceptionMacro(
"Read: Error reading "
748 unsigned int rangeAxisNum, rangeAxisIdx[NRRD_DIM_MAX];
749 rangeAxisNum = nrrdRangeAxesGet(nrrd, rangeAxisIdx);
751 if ( rangeAxisNum > 1)
753 itkExceptionMacro(
"Read: handling more than one non-scalar axis "
754 "not currently handled");
756 if (1 == rangeAxisNum && 0 != rangeAxisIdx[0])
761 Nrrd *ntmp = nrrdNew();
762 unsigned int axmap[NRRD_DIM_MAX];
763 axmap[0] = rangeAxisIdx[0];
764 for (
unsigned int axi=1; axi<nrrd->dim; axi++)
766 axmap[axi] = axi - (axi <= rangeAxisIdx[0]);
770 if (nrrdCopy(ntmp, nrrd)
771 || nrrdAxesPermute(nrrd, ntmp, axmap))
773 char *err = biffGetDone(NRRD);
774 itkExceptionMacro(
"Read: Error permuting independent axis in "
785 if (nrrdKind3DMaskedSymMatrix == nrrd->axis[0].kind
789 size_t size[NRRD_DIM_MAX], minIdx[NRRD_DIM_MAX], maxIdx[NRRD_DIM_MAX];
790 for (
unsigned int axi=0; axi<nrrd->dim; axi++)
792 minIdx[axi] = (0 == axi) ? 1 : 0;
793 maxIdx[axi] = nrrd->axis[axi].size-1;
794 size[axi] = maxIdx[axi] - minIdx[axi] + 1;
796 Nrrd *ntmp = nrrdNew();
797 if (nrrdCopy(ntmp, nrrd)
799 nrrdWrap_nva(nrrd, buffer, ntmp->type, ntmp->dim, size))
800 || nrrdCrop(nrrd, ntmp, minIdx, maxIdx))
802 char *err = biffGetDone(NRRD);
803 itkExceptionMacro(
"Read: Error copying, crapping or cropping:\n"
813 memcpy(buffer, nrrd->data,
814 nrrdElementSize(nrrd)*nrrdElementNumber(nrrd));
829 #if defined(__BORLANDC__)
831 _control87(MCW_EM, MCW_EM);
832 #endif // defined(__BORLANDC__)
834 std::string filename = name;
840 std::string::size_type nrrdPos = filename.rfind(
".nrrd");
841 if ((nrrdPos != std::string::npos)
842 && (nrrdPos == filename.length() - 5))
847 std::string::size_type nhdrPos = filename.rfind(
".nhdr");
848 if ((nhdrPos != std::string::npos)
849 && (nhdrPos == filename.length() - 5))
859 #if defined(__BORLANDC__)
861 _control87(MCW_EM, MCW_EM);
862 #endif // defined(__BORLANDC__)
870 #if defined(__BORLANDC__)
872 _control87(MCW_EM, MCW_EM);
873 #endif // defined(__BORLANDC__)
875 Nrrd *nrrd = nrrdNew();
876 NrrdIoState *nio = nrrdIoStateNew();
877 int kind[NRRD_DIM_MAX];
878 size_t size[NRRD_DIM_MAX];
879 unsigned int nrrdDim, baseDim, spaceDim;
880 double spaceDir[NRRD_DIM_MAX][NRRD_SPACE_DIM_MAX];
881 double origin[NRRD_DIM_MAX];
890 kind[0] = nrrdKindRGBColor;
893 kind[0] = nrrdKindRGBAColor;
896 kind[0] = nrrdKindPoint;
899 kind[0] = nrrdKindCovariantVector;
903 kind[0] = nrrdKind3DSymMatrix;
906 kind[0] = nrrdKindComplex;
912 kind[0] = nrrdKindVector;
916 for (
unsigned int saxi=0; saxi < spaceDim; saxi++)
918 spaceDir[0][saxi] = AIR_NAN;
926 nrrdDim = baseDim + spaceDim;
927 std::vector<double> spaceDirStd(spaceDim);
929 for (axi=0; axi < spaceDim; axi++)
932 kind[axi+baseDim] = nrrdKindDomain;
936 for (
unsigned int saxi=0; saxi < spaceDim; saxi++)
938 spaceDir[axi+baseDim][saxi] = spacing*spaceDirStd[saxi];
941 if (nrrdWrap_nva(nrrd, const_cast<void *>(buffer),
943 nrrdDim, size) || (3 == spaceDim
945 ? nrrdSpaceSet(nrrd, nrrdSpaceLeftPosteriorSuperior)
946 : nrrdSpaceDimensionSet(nrrd, spaceDim)) ||
947 nrrdSpaceOriginSet(nrrd, origin))
949 char *err = biffGetDone(NRRD);
950 itkExceptionMacro(
"Write: Error wrapping nrrd for "
953 nrrdAxisInfoSet_nva(nrrd, nrrdAxisInfoKind, kind);
954 nrrdAxisInfoSet_nva(nrrd, nrrdAxisInfoSpaceDirection, spaceDir);
959 std::vector<std::string> keys = thisDic.
GetKeys();
960 std::vector<std::string>::const_iterator keyIt;
961 const char *keyField, *field;
962 for( keyIt = keys.begin(); keyIt != keys.end(); keyIt++ )
966 keyField = (*keyIt).c_str() + strlen(
KEY_PREFIX);
968 field = airEnumStr(nrrdField, nrrdField_thicknesses);
969 if (!strncmp(keyField, field, strlen(field)))
971 if (1 == sscanf(keyField + strlen(field),
"[%d]", &axi)
972 && axi + baseDim < nrrd->dim)
974 double thickness = 0.0;
975 ExposeMetaData<double>(thisDic, *keyIt, thickness);
976 nrrd->axis[axi+baseDim].thickness = thickness;
979 field = airEnumStr(nrrdField, nrrdField_centers);
980 if (!strncmp(keyField, field, strlen(field)))
982 if (1 == sscanf(keyField + strlen(field),
"[%d]", &axi)
983 && axi + baseDim < nrrd->dim)
986 ExposeMetaData<std::string>(thisDic, *keyIt, value);
987 nrrd->axis[axi+baseDim].center = airEnumVal(nrrdCenter,
991 field = airEnumStr(nrrdField, nrrdField_kinds);
992 if (!strncmp(keyField, field, strlen(field)))
994 if (1 == sscanf(keyField + strlen(field),
"[%d]", &axi)
995 && axi + baseDim < nrrd->dim)
998 ExposeMetaData<std::string>(thisDic, *keyIt, value);
999 nrrd->axis[axi+baseDim].kind = airEnumVal(nrrdKind,
1003 field = airEnumStr(nrrdField, nrrdField_labels);
1004 if (!strncmp(keyField, field, strlen(field)))
1006 if (1 == sscanf(keyField + strlen(field),
"[%d]", &axi)
1007 && axi + baseDim < nrrd->dim)
1010 ExposeMetaData<std::string>(thisDic, *keyIt, value);
1011 nrrd->axis[axi+baseDim].label = airStrdup(value.c_str());
1014 field = airEnumStr(nrrdField, nrrdField_old_min);
1015 if (!strncmp(keyField, field, strlen(field)))
1017 ExposeMetaData<double>(thisDic, *keyIt, nrrd->oldMin);
1019 field = airEnumStr(nrrdField, nrrdField_old_max);
1020 if (!strncmp(keyField, field, strlen(field)))
1022 ExposeMetaData<double>(thisDic, *keyIt, nrrd->oldMax);
1025 field = airEnumStr(nrrdField, nrrdField_space);
1026 if (!strncmp(keyField, field, strlen(field)))
1030 ExposeMetaData<std::string>(thisDic, *keyIt, value);
1031 space = airEnumVal(nrrdSpace, value.c_str());
1032 if (nrrdSpaceDimension(space) == nrrd->spaceDim)
1035 nrrd->space = space;
1039 field = airEnumStr(nrrdField, nrrdField_content);
1040 if (!strncmp(keyField, field, strlen(field)))
1043 ExposeMetaData<std::string>(thisDic, *keyIt, value);
1044 nrrd->content = airStrdup(value.c_str());
1046 field = airEnumStr(nrrdField, nrrdField_measurement_frame);
1047 if (!strncmp(keyField, field, strlen(field)))
1049 std::vector<std::vector<double> > msrFrame;
1050 ExposeMetaData<std::vector<std::vector<double> > >(thisDic,
1052 for (
unsigned int saxi=0; saxi < nrrd->spaceDim; saxi++)
1054 for (
unsigned int saxj=0; saxj < nrrd->spaceDim; saxj++)
1056 if (saxi < msrFrame.size() &&
1057 saxj < msrFrame[saxi].size())
1059 nrrd->measurementFrame[saxi][saxj] = msrFrame[saxi][saxj];
1070 nrrd->measurementFrame[saxi][saxj] = 666666;
1080 ExposeMetaData<std::string>(thisDic, *keyIt, value);
1081 nrrdKeyValueAdd(nrrd, (*keyIt).c_str(), value.c_str());
1087 && nrrdEncodingGzip->available())
1090 nio->encoding = nrrdEncodingGzip;
1100 nio->encoding = nrrdEncodingRaw;
1103 nio->encoding = nrrdEncodingAscii;
1114 nio->endian = airEndianUnknown;
1117 nio->endian = airEndianBig;
1120 nio->endian = airEndianLittle;
1127 char *err = biffGetDone(NRRD);
1128 itkExceptionMacro(
"Write: Error writing "
1133 nrrd = nrrdNix(nrrd);
1134 nio = nrrdIoStateNix(nio);