Skip to content

Instantly share code, notes, and snippets.

@kusnier
Forked from marcochiesa/App.java
Created March 8, 2022 08:29
Show Gist options
  • Save kusnier/49876b784b78316f2680b28ef4658c05 to your computer and use it in GitHub Desktop.
Save kusnier/49876b784b78316f2680b28ef4658c05 to your computer and use it in GitHub Desktop.
Create dicomdir file using dcm4che based on code from dcmdir command line tool
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.Tag;
import org.dcm4che3.data.UID;
import org.dcm4che3.data.VR;
import org.dcm4che3.io.DicomEncodingOptions;
import org.dcm4che3.io.DicomInputStream;
import org.dcm4che3.media.DicomDirReader;
import org.dcm4che3.media.DicomDirWriter;
import org.dcm4che3.media.RecordFactory;
import org.dcm4che3.media.RecordType;
import org.dcm4che3.tool.common.FilesetInfo;
import org.dcm4che3.util.UIDUtils;
import java.io.File;
import java.io.IOException;
/*
* This Java source file was generated by the Gradle 'init' task.
*/
public class App {
// The dicomdir_filename file to create
File dicomdir_filename;
// The directory containing the DCM files
File dicom_dirname;
DicomEncodingOptions encOpts = DicomEncodingOptions.DEFAULT;
FilesetInfo fsInfo = new FilesetInfo();
boolean checkDuplicate = false;
RecordFactory recFact = new RecordFactory();
DicomDirReader in;
DicomDirWriter out;
public App(String dicomdir_filename, String dicom_dirname) {
this.dicomdir_filename = new File(dicomdir_filename);
this.dicom_dirname = new File(dicom_dirname);
}
public static void main(String[] args) throws Exception {
//System.out.println(new File(".").getAbsolutePath());
App app = new App("DICOMDIR","DICOM");
app.start();
}
public void start() throws IOException {
create(this.dicomdir_filename);
int num = 0;
num = addReferenceTo(this.dicom_dirname);
close();
}
protected void create(File file) throws IOException {
DicomDirWriter.createEmptyDirectory(file,
UIDUtils.createUIDIfNull(fsInfo.getFilesetUID()),
fsInfo.getFilesetID(),
fsInfo.getDescriptorFile(),
fsInfo.getDescriptorFileCharset());
in = out = DicomDirWriter.open(file);
out.setEncodingOptions(encOpts);
}
protected int addReferenceTo(File f) throws IOException {
int n = 0;
if (f.isDirectory()) {
for (String s : f.list())
n += addReferenceTo(new File(f, s));
return n;
}
// do not add reference to DICOMDIR
if (f.equals(this.dicomdir_filename))
return 0;
Attributes fmi;
Attributes dataset;
DicomInputStream din = null;
try {
din = new DicomInputStream(f);
din.setIncludeBulkData(DicomInputStream.IncludeBulkData.NO);
fmi = din.readFileMetaInformation();
dataset = din.readDataset(-1, Tag.PixelData);
} catch (IOException e) {
System.out.println("failed to parse image '" + f + "' - " + e.getMessage());
return 0;
} finally {
if (din != null)
try { din.close(); } catch (Exception ignore) {}
}
char prompt = '.';
if (fmi == null) {
fmi = dataset.createFileMetaInformation(UID.ImplicitVRLittleEndian);
prompt = 'F';
}
String iuid = fmi.getString(Tag.MediaStorageSOPInstanceUID, null);
if (iuid == null) {
System.out.println("skip DICOM file '" + f + "' without SOP Instance UID (0008, 0018)");
return 0;
}
return addRecords(dataset, n, out.toFileIDs(f), prompt, iuid, fmi);
}
private int addRecords(Attributes dataset, int num, String[] fileIDs, char prompt, String iuid, Attributes fmi)
throws IOException {
String pid = dataset.getString(Tag.PatientID, null);
String styuid = dataset.getString(Tag.StudyInstanceUID, null);
String seruid = dataset.getString(Tag.SeriesInstanceUID, null);
if (styuid != null) {
if (pid == null) {
dataset.setString(Tag.PatientID, VR.LO, pid = styuid);
prompt = prompt == 'F' ? 'P' : 'p';
}
Attributes patRec = in.findPatientRecord(pid);
if (patRec == null) {
patRec = recFact.createRecord(RecordType.PATIENT, null,
dataset, null, null);
out.addRootDirectoryRecord(patRec);
num++;
}
Attributes studyRec = in.findStudyRecord(patRec, styuid);
if (studyRec == null) {
studyRec = recFact.createRecord(RecordType.STUDY, null,
dataset, null, null);
out.addLowerDirectoryRecord(patRec, studyRec);
num++;
}
if (seruid != null) {
Attributes seriesRec = in.findSeriesRecord(studyRec, seruid);
if (seriesRec == null) {
seriesRec = recFact.createRecord(RecordType.SERIES, null,
dataset, null, null);
out.addLowerDirectoryRecord(studyRec, seriesRec);
num++;
}
if (iuid != null) {
Attributes instRec;
if (checkDuplicate) {
instRec = in.findLowerInstanceRecord(seriesRec, false, iuid);
if (instRec != null) {
System.out.print('-');
return 0;
}
}
instRec = recFact.createRecord(dataset, fmi, fileIDs);
out.addLowerDirectoryRecord(seriesRec, instRec);
num++;
}
}
} else {
if (iuid != null) {
if (checkDuplicate) {
if (in.findRootInstanceRecord(false, iuid) != null) {
System.out.print('-');
return 0;
}
}
Attributes instRec = recFact.createRecord(dataset, fmi, fileIDs);
out.addRootDirectoryRecord(instRec);
prompt = prompt == 'F' ? 'R' : 'r';
num++;
}
}
System.out.print(prompt);
return num;
}
protected void close() {
if (in != null) {
try {
in.close();
} catch (IOException ignore) {
}
}
in = null;
out = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment