static CONDITION parseImageInstanceUID(DCM_OBJECT ** object, int *elementCount) { static DCM_FLAGGED_ELEMENT localList[] = { {DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, sizeof(q.Image.ImageUID), (void *) &q.Image.ImageUID[0], DB_K_QIMAGEUID, &q.Image.Query_Flag}, }; CONDITION cond; DCM_ELEMENT e; U32 l; char *c; int index; cond = DCM_GetElementSize(object, DCM_IDSOPINSTANCEUID, &l); if (cond != DCM_NORMAL) { (void) COND_PopCondition(FALSE); return IAP_NORMAL; } cond = DCM_GetElement(object, DCM_IDSOPINSTANCEUID, &e); if (cond != DCM_NORMAL) { (void) COND_PopCondition(FALSE); return IAP_NORMAL; } if (e.multiplicity == 1) { cond = DCM_ParseObject(object, NULL, 0, localList, (int) DIM_OF(localList), elementCount); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "parseImageInstanceUID"); q.Image.Query_Flag |= DB_K_QIMAGEUID; q.Image.ImageMultUIDCount = 0; q.Image.ImageMultUID = NULL; }else{ c = malloc((l + 1) + (e.multiplicity * sizeof(char *))); if (c == NULL) return COND_PushCondition(IAP_MALLOCFAILURE, IAP_Message(IAP_MALLOCFAILURE), (l + 1) + (e.multiplicity * sizeof(char *)), "parseImageInstanceUID"); q.Image.ImageMultUIDCount = e.multiplicity; q.Image.ImageMultUID = (char **) c; c += e.multiplicity * sizeof(char *); e.d.string = c; cond = DCM_ParseObject(object, &e, 1, NULL, 0, elementCount); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "parseImageInstanceUID"); for (index = 0; (unsigned long) index < e.multiplicity; index++) { q.Image.ImageMultUID[index] = c; while ((*c != '\\') && (*c != '\0')){ c++; } *c++ = '\0'; } q.Image.Query_Flag |= DB_K_QIMAGEMULTUID; } return IAP_NORMAL; }
CONDITION DCM_DefaultFileMeta(DCM_OBJECT ** object, DCM_FILE_META ** fileMeta) { DCM_ELEMENT e[] = { {DCM_IDSOPCLASSUID, DCM_UI, "", 1, DICOM_UI_LENGTH + 1, NULL}, {DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, DICOM_UI_LENGTH + 1, NULL}, }; CONDITION cond; *fileMeta = calloc(1, sizeof(DCM_FILE_META)); if (*fileMeta == NULL) return 0; /* repair */ memset((*fileMeta)->preamble, 0, sizeof((*fileMeta)->preamble)); (*fileMeta)->fileMetaInformationVersion[0] = 0x00; (*fileMeta)->fileMetaInformationVersion[1] = 0x01; e[0].d.string = (*fileMeta)->mediaStorageSOPClassUID; e[1].d.string = (*fileMeta)->mediaStorageSOPInstanceUID; cond = DCM_ParseObject(object, e, (int) DIM_OF(e), NULL, 0, NULL); if (cond != DCM_NORMAL) return 0; /* repair */ strcpy((*fileMeta)->transferSyntaxUID, DICOM_TRANSFERLITTLEENDIAN); strcpy((*fileMeta)->implementationClassUID, MIR_IMPLEMENTATIONCLASSUID); strcpy((*fileMeta)->implementationVersionName, MIR_IMPLEMENTATIONVERSIONNAME); (*fileMeta)->flag |= DCM_FILEMETA_IMPLEMENTATIONVERSIONNAME; return DCM_NORMAL; }
CONDITION DDR_GetFileSetID(DCM_OBJECT ** obj, DDR_FILESETID * fileSetID) { static long flag; DCM_ELEMENT e = {DCM_DIRFILESETID, DCM_CS, "", 1, DICOM_CS_LENGTH + 1, NULL}; DCM_FLAGGED_ELEMENT optionalElements[] = { {DCM_DIRFILESETDESCRFILEID, DCM_CS, "", 1, DICOM_CS_LENGTH + 1, NULL, 0, &flag}, {DCM_DIRSPECIFICCHARACTER, DCM_CS, "", 1, DICOM_CS_LENGTH + 1, NULL, 0, &flag} }; CONDITION cond; memset(fileSetID, 0, sizeof(fileSetID)); e.d.string = fileSetID->FileSetID; optionalElements[0].e.d.string = fileSetID->DescriptorFileID; optionalElements[1].e.d.string = fileSetID->SpecificCharacterSet; cond = DCM_ParseObject(obj, &e, 1, optionalElements, (int) DIM_OF(optionalElements), NULL); if (cond != DCM_NORMAL) return DDR_ERROR; return DDR_NORMAL; }
static CONDITION addSeriesRecord(DCM_OBJECT ** seriesObject, LST_HEAD ** lst) { CONDITION cond; DDR_SERIES record, *seriesPtr; DCM_ELEMENT required[] = { {DCM_IDMODALITY, DCM_CS, "", 1, sizeof(record.Modality), NULL}, {DCM_RELSERIESINSTANCEUID, DCM_UI, "", 1, sizeof(record.SeriesInstanceUID), NULL}, {DCM_RELSERIESNUMBER, DCM_IS, "", 1, sizeof(record.SeriesNumber), NULL}, {DCM_DIRLOWERLEVELOFFSET, DCM_UL, "", 1, sizeof(record.LeafLinkOffset), NULL} }; required[0].d.string = record.Modality; required[1].d.string = record.SeriesInstanceUID; required[2].d.string = record.SeriesNumber; required[3].d.ul = &record.LeafLinkOffset; memset(&record, 0, sizeof(record)); cond = DCM_ParseObject(seriesObject, required, (int) DIM_OF(required), NULL, 0, NULL); if (cond != DCM_NORMAL) { return 0; /* repair */ } seriesPtr = malloc(sizeof(*seriesPtr)); if (seriesPtr == NULL) { return 0; /* repair */ } memcpy(seriesPtr, &record, sizeof(record)); LST_Enqueue(lst, seriesPtr); return DDR_NORMAL; }
CONDITION IAP_ObjectToQuery(DCM_OBJECT ** object, char *SOPClass, Query * query, int *elementCount) { CONDITION cond, returnCondition; int index; void *ctx; U32 l; long flag; static char queryLevelString[48] = ""; /* Initialize for AIX compiler bug */ DCM_ELEMENT queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), (void *) &queryLevelString[0]}; *elementCount = 0; q.QueryState = 0; q.Patient.Query_Flag = 0; q.Study.Query_Flag = 0; q.Series.Query_Flag = 0; q.Image.Query_Flag = 0; ctx = NULL; returnCondition = IAP_NORMAL; cond = DCM_GetElementValue(object, &queryLevelElement, &l, &ctx); if (cond != DCM_NORMAL) { if (cond == DCM_ILLEGALOBJECT){ return COND_PushCondition(IAP_ILLEGALOBJECT, "IAP_ObjectToQuery"); }else{ (void) COND_PopCondition(FALSE); (void) COND_PushCondition(IAP_QUERYLEVELMISSING, "IAP_ObjectToQuery"); returnCondition = IAP_INCOMPLETEOBJECT; } }else{ queryLevelString[l] = '\0'; if (queryLevelString[l - 1] == ' ') queryLevelString[l - 1] = '\0'; for (index = 0; index < DIM_OF(levelMap); index++) { if (strcmp(levelMap[index].queryLevel, queryLevelString) == 0) q.QueryState |= levelMap[index].flag; } } flag = 0; for (index = 0; index < DIM_OF(classMap); index++) { if (strcmp(classMap[index].SOPClass, SOPClass) == 0) flag |= classMap[index].flag; } if (flag == 0) { (void) COND_PushCondition(IAP_SOPCLASSMISSING, ""); returnCondition = IAP_INCOMPLETEOBJECT; } q.QueryState |= flag; cond = DCM_ParseObject(object, NULL, 0, list, (int) DIM_OF(list), elementCount); if (cond != DCM_NORMAL) return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_ObjectToQuery"); cond = parseImageInstanceUID(object, elementCount); if (cond != IAP_NORMAL) return cond; *query = q; return returnCondition; }
static void* extractPixelsMONOCHROME2(DCM_OBJECT** obj, PARAMS *p) { void *pixels = NULL; int byteCount; int pixelCount; DCM_ELEMENT e; CONDITION cond; pixelCount = p->rows * p->columns; byteCount = p->rows * p->columns; if (p->bitsAllocated > 8) byteCount *= 2; if (pixels == NULL) { pixels = malloc(byteCount); if (pixels == NULL) { fprintf(stderr, "Could not allocated %d bytes for pixel data\n", byteCount); exit(7); } } memset(&e, 0, sizeof(e)); e.tag = DCM_PXLPIXELDATA; e.representation = DCM_OW; e.length = byteCount; e.d.ot = pixels; cond = DCM_ParseObject(obj, &e, 1, NULL, 0, NULL); if (cond != DCM_NORMAL && cond != DCM_GETINCOMPLETE) { fprintf(stderr, "Could not extract pixels: %d %d %d %d\n", p->rows, p->columns, p->bitsAllocated, byteCount); COND_DumpConditions(); exit(8); } if (p->bitsAllocated == 8) { unsigned char* p1; U16* p2; int index; p2 = malloc(pixelCount * 2); p1 = (unsigned char*) pixels; for (index = 0; index < pixelCount; index++) { p2[index] = p1[index]; } free(pixels); pixels = p2; } return pixels; }
static U32 offsetNextRecord(DCM_OBJECT ** obj) { CONDITION cond; U32 offset; DCM_ELEMENT e = {DCM_DIRNEXTRECORDOFFSET, DCM_UL, "", 1, sizeof(offset), NULL}; e.d.ul = &offset; cond = DCM_ParseObject(obj, &e, 1, NULL, 0, NULL); if (cond != DCM_NORMAL) { return 0; /* repair */ } return offset; }
static void addImageLeafAttributes(DCM_OBJECT ** leafObject, DDR_SERIES_LEAF * leaf) { CONDITION cond; DCM_ELEMENT required[] = { {DCM_RELIMAGENUMBER, DCM_IS, "", 1, sizeof(leaf->specific.image.ImageNumber), NULL} }; required[0].d.string = leaf->specific.image.ImageNumber; cond = DCM_ParseObject(leafObject, required, (int) DIM_OF(required), NULL, 0, NULL); if (cond != DCM_NORMAL) { COND_DumpConditions(); exit(1); /* repair */ } }
static CONDITION addLeafRecord(DCM_OBJECT ** leafObject, LST_HEAD ** lst) { CONDITION cond; DDR_SERIES_LEAF record, *leafPtr; DCM_ELEMENT required[] = { {DCM_DIRRECORDTYPE, DCM_CS, "", 1, sizeof(record.RecordType), NULL}, {DCM_DIRREFERENCEDFILEID, DCM_CS, "", 1, sizeof(record.FileID), NULL}, {DCM_DIRREFSOPCLASSUID, DCM_UI, "", 1, sizeof(record.SOPClassUID), NULL}, {DCM_DIRREFSOPINSTANCEUID, DCM_UI, "", 1, sizeof(record.SOPInstanceUID), NULL}, {DCM_DIRREFTRANSFERSYNTAXUID, DCM_UI, "", 1, sizeof(record.TransferSyntaxUID), NULL} }; required[0].d.string = record.RecordType; required[1].d.string = record.FileID; required[2].d.string = record.SOPClassUID; required[3].d.string = record.SOPInstanceUID; required[4].d.string = record.TransferSyntaxUID; memset(&record, 0, sizeof(record)); cond = DCM_ParseObject(leafObject, required, (int) DIM_OF(required), NULL, 0, NULL); if (cond != DCM_NORMAL) { return 0; /* repair */ } if (strcmp(record.RecordType, "IMAGE") == 0) addImageLeafAttributes(leafObject, &record); leafPtr = malloc(sizeof(*leafPtr)); if (leafPtr == NULL) { return 0; /* repair */ } memcpy(leafPtr, &record, sizeof(record)); LST_Enqueue(lst, leafPtr); return DDR_NORMAL; }
static CONDITION addStudyRecord(DCM_OBJECT ** studyObject, LST_HEAD ** lst) { CONDITION cond; DDR_STUDY record, *studyPtr; DCM_ELEMENT required[] = { {DCM_IDSTUDYDATE, DCM_DA, "", 1, sizeof(record.StudyDate), NULL}, {DCM_IDSTUDYTIME, DCM_TM, "", 1, sizeof(record.StudyTime), NULL}, {DCM_IDSTUDYDESCRIPTION, DCM_LO, "", 1, sizeof(record.StudyDescription), NULL}, {DCM_RELSTUDYINSTANCEUID, DCM_UI, "", 1, sizeof(record.StudyInstanceUID), NULL}, {DCM_RELSTUDYID, DCM_SH, "", 1, sizeof(record.StudyID), NULL}, {DCM_IDACCESSIONNUMBER, DCM_SH, "", 1, sizeof(record.AccessionNumber), NULL}, {DCM_DIRLOWERLEVELOFFSET, DCM_UL, "", 1, sizeof(record.SeriesLinkOffset), NULL} }; required[0].d.string = record.StudyDate; required[1].d.string = record.StudyTime; required[2].d.string = record.StudyDescription; required[3].d.string = record.StudyInstanceUID; required[4].d.string = record.StudyID; required[5].d.string = record.AccessionNumber; required[6].d.ul = &record.SeriesLinkOffset; memset(&record, 0, sizeof(record)); cond = DCM_ParseObject(studyObject, required, (int) DIM_OF(required), NULL, 0, NULL); if (cond != DCM_NORMAL) { return 0; /* repair */ } studyPtr = malloc(sizeof(*studyPtr)); if (studyPtr == NULL) { return 0; /* repair */ } memcpy(studyPtr, &record, sizeof(record)); LST_Enqueue(lst, studyPtr); return DDR_NORMAL; }
static char* getString(DCM_OBJECT* obj, DCM_TAG tag) { DCM_ELEMENT e; CONDITION cond; memset(&e, 0, sizeof(e)); e.tag = tag; cond = DCM_GetElement(&obj, tag, &e); if (cond != DCM_NORMAL) return 0; e.d.string = malloc(e.length + 1); cond = DCM_ParseObject(&obj, &e, 1, 0, 0, 0); if (cond != DCM_NORMAL) { COND_DumpConditions(); exit(1); } return e.d.string; }
CONDITION DDR_RootDirectory(DCM_OBJECT ** obj) { U32 offset = 0; DCM_ELEMENT e = {DCM_DIRFIRSTOFFSET, DCM_UL, "", 1, sizeof(offset), NULL}; CONDITION cond; #if 0 e.d.ul = &offset; cond = DCM_ParseObject(obj, &e, 1, NULL, 0, NULL); if (cond != DCM_NORMAL) return DDR_ERROR; cond = DCM_GetSequenceByOffset(obj, DCM_DIRRECORDSEQUENCE, offset); #endif return DDR_NORMAL; }
CONDITION DCM_GetFileMeta(DCM_OBJECT ** callerObject, DCM_FILE_META ** fileMeta) { CONDITION cond; PRIVATE_OBJECT **object; object = (PRIVATE_OBJECT **) callerObject; cond = checkObject(object, "DCM_GetFileMeta"); if (cond != DCM_NORMAL) return cond; memset(&meta, 0, sizeof(meta)); cond = DCM_ParseObject(callerObject, metaRequired, (int) DIM_OF(metaRequired), metaOptional, (int) DIM_OF(metaOptional), NULL); if (cond != DCM_NORMAL) return cond; /* repair */ *fileMeta = CTN_MALLOC(sizeof(DCM_FILE_META)); if (*fileMeta == NULL) return 0; /* repair */ **fileMeta = meta; return DCM_NORMAL; }
CONDITION HAP_ParseResults(DCM_OBJECT ** object, HIS_ResultsLevel * xl) { CONDITION cond; int x; memset(&p, 0, sizeof p); cond = DCM_ParseObject(object, NULL, 0, list, (int) DIM_OF(list), NULL); if (cond != DCM_NORMAL) return HAP_ILLEGALOBJECT; x = r_parseSequence(object); if (x < 0) return 0; *xl = p; return HAP_NORMAL; }
CONDITION HAP_ParseVisit(DCM_OBJECT ** object, HIS_VisitLevel * xl) { CONDITION cond; int x; memset(&p, 0, sizeof p); cond = DCM_ParseObject(object, NULL, 0, list, (int) DIM_OF(list), NULL); if (cond != DCM_NORMAL) return HAP_ILLEGALOBJECT; x = v_parseSequence(object); if (x < 0) return 0; /* needs repair */ *xl = p; return HAP_NORMAL; }
CONDITION DDR_GetPatientList(DCM_OBJECT ** obj, LST_HEAD ** lst) { U32 offset = 0; DCM_ELEMENT e = {DCM_DIRFIRSTOFFSET, DCM_UL, "", 1, sizeof(offset), NULL}; DCM_OBJECT *patObject; CONDITION cond; e.d.ul = &offset; /* * Find the first offset in the DICOMDIR object. That should point to a * patient */ cond = DCM_ParseObject(obj, &e, 1, NULL, 0, NULL); if (cond != DCM_NORMAL) return DDR_ERROR; /* * Walk through the chain of patient records. Each time we find one, * call another * function to parse that patient record and add it to the * caller's list. */ while (offset != 0) { cond = DCM_GetSequenceByOffset(obj, DCM_DIRRECORDSEQUENCE, offset, &patObject); if (cond != DCM_NORMAL) { exit(1); /* repair */ } addPatientRecord(&patObject, lst); offset = offsetNextRecord(&patObject); } return DDR_NORMAL; }
/* extractAccessionNumber ** ** Purpose: ** Extract the Accession number from a DICOM image file. ** ** Parameter Dictionary: ** file Name of the file ** ** Return Values: ** Accession number if found, else NULL ** ** Notes: ** ** Algorithm: ** Description of the algorithm (optional) and any other notes. */ static char * extractAccessionNumber(char *file) { DCM_OBJECT * object = NULL; DCM_ELEMENT element; CONDITION cond; cond = DCM_OpenFile(file, DCM_ORDERLITTLEENDIAN, &object); if (cond != DCM_NORMAL) { printf("DCM_Openfile failed on %s\n", file); if (verbose == TRUE) COND_DumpConditions(); return (NULL); } element.tag = DCM_IDACCESSIONNUMBER; element.d.string = (char *) malloc(DICOM_CS_LENGTH + 1); element.length = DICOM_CS_LENGTH + 1; cond = DCM_LookupElement(&element); if (cond != DCM_NORMAL) { printf("DCM_LookupElement failed\n"); if (verbose == TRUE) COND_DumpConditions(); return (NULL); } cond = DCM_ParseObject(&object, &element, 1, NULL, 0, NULL); if (cond != DCM_NORMAL) { printf("DCM Parse Object failed\n"); if (verbose == TRUE) COND_DumpConditions(); return (NULL); } return (element.d.string); }
static CONDITION addPatientRecord(DCM_OBJECT ** patObject, LST_HEAD ** lst) { CONDITION cond; DDR_PATIENT patientRecord, *patientPtr; DCM_ELEMENT required[] = { {DCM_PATNAME, DCM_PN, "", 1, sizeof(patientRecord.PatientName), NULL}, {DCM_PATID, DCM_LO, "", 1, sizeof(patientRecord.PatientID), NULL}, {DCM_DIRLOWERLEVELOFFSET, DCM_UL, "", 1, sizeof(patientRecord.StudyLinkOffset), NULL}, }; DCM_FLAGGED_ELEMENT optional[] = { {DCM_PATBIRTHDATE, DCM_DA, "", 1, sizeof(patientRecord.BirthDate), NULL, 0, NULL}, {DCM_PATSEX, DCM_CS, "", 1, sizeof(patientRecord.Sex), NULL, 0, NULL} }; required[0].d.string = patientRecord.PatientName; required[1].d.string = patientRecord.PatientID; required[2].d.ul = &patientRecord.StudyLinkOffset; optional[0].e.d.string = patientRecord.BirthDate; optional[0].flagAddress = &patientRecord.optionFlag; optional[1].e.d.string = patientRecord.Sex; optional[1].flagAddress = &patientRecord.optionFlag; memset(&patientRecord, 0, sizeof(patientRecord)); cond = DCM_ParseObject(patObject, required, 3, optional, 2, NULL); if (cond != DCM_NORMAL) { return 0; /* repair */ } patientPtr = malloc(sizeof(*patientPtr)); if (patientPtr == NULL) { return 0; /* repair */ } memcpy(patientPtr, &patientRecord, sizeof(patientRecord)); LST_Enqueue(lst, patientPtr); return DDR_NORMAL; }
static void* extractFPixelsMONOCHROME2(DCM_OBJECT** obj, PARAMS *p) { void *pixels = NULL; void *fpixels = NULL; int byteCount; int pixelCount; DCM_ELEMENT e; CONDITION cond; S16* p1; /* 16 bit pointer for Pixel Rep = 1 (pet) */ U16* p0; /* 16 bit data Pixel Rep = 0 (mr) */ float* pf; /* Pointer to the float data */ int index; /* pixel index */ pixelCount = p->rows * p->columns; byteCount = p->rows * p->columns; if (p->bitsAllocated > 8)byteCount *= 4; /* 4 bytes are in 32 bits */ if (pixels == NULL) { pixels = malloc(byteCount); /* 16 bit pixels */ if (pixels == NULL) { fprintf(stderr, "Could not allocated %d bytes for pixel data\n", byteCount); exit(7); } } memset(&e, 0, sizeof(e)); e.tag = DCM_PXLPIXELDATA; e.representation = DCM_OW; e.length = byteCount; e.d.ot = pixels; cond = DCM_ParseObject(obj, &e, 1, NULL, 0, NULL); if (cond != DCM_NORMAL && cond != DCM_GETINCOMPLETE) { fprintf(stderr, "Could not extract pixels: %d %d %d %d\n", p->rows, p->columns, p->bitsAllocated, byteCount); COND_DumpConditions(); exit(8); } pf = malloc(pixelCount * sizeof(float)); p1 = pixels; p0 = pixels; if (p->pixelRepresentation == 1){ for (index = 0; index < pixelCount; index++) { pf[index] = p1[index]; } }else{ for (index = 0; index < pixelCount; index++) { pf[index] = p0[index]; } } free(pixels); fpixels = pf; /* fpixels now points to pf */ return fpixels; /* fpixels should be freed in the calling routine */ }