diff --git a/.travis.yml b/.travis.yml index 80b8b2bb..70a5c92a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,8 @@ before_install: - git submodule update --init --depth=3 dcm_qa_uih script: - - mkdir build && cd build && cmake -DBATCH_VERSION=ON -DUSE_OPENJPEG=ON -DUSE_JPEGLS=true -DZLIB_IMPLEMENTATION=Cloudflare .. && make && cd - + # - mkdir build && cd build && cmake -DBATCH_VERSION=ON -DUSE_OPENJPEG=ON -DUSE_JPEGLS=true -DZLIB_IMPLEMENTATION=Cloudflare .. && make && cd - + - mkdir build && cd build && cmake -DBATCH_VERSION=OFF -DUSE_OPENJPEG=ON -DUSE_JPEGLS=true -DZLIB_IMPLEMENTATION=Cloudflare .. && make && cd - - export PATH=$PWD/build/bin:$PATH - cd dcm_qa && ./batch.sh && cd - - cd dcm_qa_nih && ./batch.sh && cd - diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt index 6e5628be..6599ca09 100644 --- a/console/CMakeLists.txt +++ b/console/CMakeLists.txt @@ -187,4 +187,15 @@ if(BATCH_VERSION) list(APPEND PROGRAMS dcm2niibatch) endif() + +if(APPLE) + message("-- Adding Apple plist") + set_target_properties(dcm2niix PROPERTIES LINK_FLAGS "-Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_SOURCE_DIR}/Info.plist") + #Apple notarization requires a Info.plist + # For .app bundles, the Info.plist is a separate file, for executables it is appended as a section + #you can check that the Info.plist section has been inserted with either of these commands + # otool -l ./dcm2niix | grep info_plist -B1 -A10 + # launchctl plist ./dcm2niix +endif() + install(TARGETS ${PROGRAMS} DESTINATION bin) diff --git a/console/Info.plist b/console/Info.plist new file mode 100644 index 00000000..d470b8ed --- /dev/null +++ b/console/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleExecutable + dcm2niix + CFBundleIdentifier + com.mricro.dcm2niix + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + dcm2niix + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + CFBundleSupportedPlatforms + + MacOSX + + CFBundlePackageType + APPL + + diff --git a/console/makefile b/console/makefile index 27c34705..acfb0dc4 100644 --- a/console/makefile +++ b/console/makefile @@ -20,8 +20,13 @@ ifneq ($(OS),Windows_NT) OS = $(shell uname) ifeq "$(OS)" "Darwin" #CFLAGS=-dead_strip -O3 - CFLAGS= - #CFLAGS=-O2 + #CFLAGS= -O3 + CFLAGS=-O3 -sectcreate __TEXT __info_plist Info.plist + #Apple notarization requires a Info.plist + # For .app bundles, the Info.plist is a separate file, for executables it is appended as a section + #you can check that the Info.plist section has been inserted with either of these commands + # otool -l ./dcm2niix | grep info_plist -B1 -A10 + # launchctl plist ./dcm2niix endif endif all: diff --git a/console/nii_dicom_batch.cpp b/console/nii_dicom_batch.cpp index 65d3a4ce..b9bd8243 100644 --- a/console/nii_dicom_batch.cpp +++ b/console/nii_dicom_batch.cpp @@ -4573,7 +4573,6 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[],struct TDICOMdata dc unsigned char *imgM = (unsigned char *)malloc(imgsz* (uint64_t)nConvert); memcpy(&imgM[0], &img[0], imgsz); free(img); - bool isReorder = false; //printMessage(" %d %d %d %d %lu\n", hdr0.dim[1], hdr0.dim[2], hdr0.dim[3], hdr0.dim[4], (unsigned long)[imgM length]); if (nConvert > 1) { //next: detect trigger time see example https://www.slicer.org/wiki/Documentation/4.4/Modules/MultiVolumeExplorer @@ -4674,8 +4673,7 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[],struct TDICOMdata dc dx = intersliceDistance(dcmList[dcmSort[0].indx],dcmList[dcmSort[1].indx]); indx0 = dcmSort[0].indx; if (nConvert > 1) indx1 = dcmSort[1].indx; - isReorder = true; - #endif + #endif bool dxVaries = false; for (int i = 1; i < nConvert; i++) if (!isSameFloatT(dx,intersliceDistance(dcmList[dcmSort[i-1].indx],dcmList[dcmSort[i].indx]),0.2)) @@ -4737,7 +4735,6 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[],struct TDICOMdata dc //for (int i = 1; i < nConvert; i++) // printf("%g ", intersliceDistance(dcmList[dcmSort[0].indx],dcmList[dcmSort[i].indx]) ); //printf("\n"); - isReorder = true; bool isInconsistenSliceDir = false; int slicePositionRepeats = 1; //how many times is first position repeated if (nConvert > 2) { @@ -4818,10 +4815,12 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[],struct TDICOMdata dc struct nifti_1_header hdrI; //double time = -1.0; if ((!opts.isOnlyBIDS) && (nConvert > 1)) { - int iStart = 1; - if (isReorder) iStart = 0; + //for (int i = 0; i < nConvert; i++) + // printMessage("%d\t%s\n", i, nameList->str[indx]); + //int iStart = 1; + //if (isReorder) iStart = 0; //for (int i = 1; i < nConvert; i++) { //<- works except where ensureSequentialSlicePositions() changes 1st slice - for (int i = iStart; i < nConvert; i++) { //stack additional images + for (int i = 0; i < nConvert; i++) { //stack additional images indx = dcmSort[i].indx; //double time2 = dcmList[dcmSort[i].indx].acquisitionTime; //if (time != time2) diff --git a/notarize.command b/notarize.command new file mode 100755 index 00000000..07b2ff06 --- /dev/null +++ b/notarize.command @@ -0,0 +1,82 @@ +#!/bin/bash + +basedir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Assumes ~/.bash_profile is set correctly, e.g. +# CODE_SIGN_SIGNATURE="Developer ID Application: John Doe" +# APPLE_ID_USER=doe@gmail.com +# DCM2NIIX_SPECIFIC_PASSWORD=bbzj-zowb-bzji-ynkl +# export APPLE_ID_USER DCM2NIIX_SPECIFIC_PASSWORD CODE_SIGN_SIGNATURE + +CODE_SIGN_SIGNATURE=$CODE_SIGN_SIGNATURE +APPLE_ID_USER=$APPLE_ID_USER +APP_SPECIFIC_PASSWORD=$DCM2NIIX_SPECIFIC_PASSWORD + +cd ${basedir} + +cd dcm2niix +mkdir build && cd build +cmake -DZLIB_IMPLEMENTATION=Cloudflare -DUSE_JPEGLS=ON -DUSE_OPENJPEG=ON .. +make + +cd bin + +# Clean up temporary files +rm -f dcm2niix_macOS.dmg +rm -f dcm2niix_macOS.tmp.dmg +rm -f upload_log_file.txt +rm -f request_log_file.txt +rm -f log_file.txt + +# https://stackoverflow.com/questions/2870992/automatic-exit-from-bash-shell-script-on-error +# terminate on error +set -e + +echo "\033[1;44mVerifying Info.plist\033[0m" +launchctl plist dcm2niix + +echo "\033[1;44mCode signing dcm2niix...\033[0m" +codesign -vvv --force --strict --options=runtime --timestamp -s "$CODE_SIGN_SIGNATURE" dcm2niix +codesign --verify --verbose --strict dcm2niix + +echo "\033[1;44mCreating disk image...\033[0m" + +hdiutil create -volname dcm2niix -srcfolder `pwd` -ov -format UDZO -layout SPUD -fs HFS+J dcm2niix_macOS.tmp.dmg +hdiutil convert dcm2niix_macOS.tmp.dmg -format UDZO -o dcm2niix_macOS.dmg + +# Notarizing with Apple... +echo "\033[1;44mUploading...\033[0m" +xcrun altool --notarize-app -t osx --file dcm2niix_macOS.dmg --primary-bundle-id com.mricro.dcm2niix -u $APPLE_ID_USER -p $APP_SPECIFIC_PASSWORD --output-format xml > upload_log_file.txt + +# WARNING: if there is a 'product-errors' key in upload_log_file.txt something went wrong +# we could parse it here and bail but not sure how to check for keys existing with PListBuddy +# /usr/libexec/PlistBuddy -c "Print :product-errors:0:message" upload_log_file.txt + +# now we need to query apple's server to the status of notarization +# when the "xcrun altool --notarize-app" command is finished the output plist +# will contain a notarization-upload->RequestUUID key which we can use to check status +echo "\033[1;44mChecking status...\033[0m" +sleep 20 +REQUEST_UUID=`/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" upload_log_file.txt` +while true; do + xcrun altool --notarization-info $REQUEST_UUID -u $APPLE_ID_USER -p $APP_SPECIFIC_PASSWORD --output-format xml > request_log_file.txt + # parse the request plist for the notarization-info->Status Code key which will + # be set to "success" if the package was notarized + STATUS=`/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" request_log_file.txt` + if [ "$STATUS" != "in progress" ]; then + break + fi + # echo $STATUS + echo "\033[1;35m$STATUS\033[0m" + sleep 10 +done + +# download the log file to view any issues +/usr/bin/curl -o log_file.txt `/usr/libexec/PlistBuddy -c "Print :notarization-info:LogFileURL" request_log_file.txt` + +# staple +echo "\033[1;44mStapling...\033[0m" +xcrun stapler staple dcm2niix_macOS.dmg +xcrun stapler validate dcm2niix_macOS.dmg + +open log_file.txt