Skip to content

Instantly share code, notes, and snippets.

@bitsgalore
Last active October 13, 2017 11:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bitsgalore/c636c095f99184b974c6f289f4c037f2 to your computer and use it in GitHub Desktop.
Save bitsgalore/c636c095f99184b974c6f289f4c037f2 to your computer and use it in GitHub Desktop.
Test script: convert TIFFs to JP2 according to KB specifications
#!/bin/bash
# Convert uncompressed TIFF images to JP2, using KB specs for lossless
# preservation masters and lossy access copies using Kakadu.
#
# Script automatically chooses the appropriate bitrate values depending
# on the number of samples per pixel (works for both RGB and grayscale
# images, provided that the number of bits per sample equals 8)
#
# Dependencies:
#
# - Kakadu demo binaries (kdu_compress)
# - Exiftool (needed for metadata extraction from TIFF)
# - sed (needed to process XMP sidecar files)
# - Jpylyzer
#
# Display usage message if command line does not contain expected
# number of arguments
if [ "$#" -ne 3 ] ; then
echo "Usage: toJP2.sh dirIn dirMaster dirAccess" >&2
exit 1
fi
# Input and output directories
dirIn="$1"
dirMaster="$2"
dirAccess="$3"
if ! [ -d "$dirIn" ] ; then
echo "input directory does not exist" >&2
exit 1
fi
if ! [ -d "$dirMaster" ] ; then
mkdir $dirMaster
fi
if ! [ -d "$dirAccess" ] ; then
mkdir $dirAccess
fi
# Location of Kakadu binaries
kduPath=~/kakadu
# Add Kakadu path to LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$kduPath
# Codestream comment strings for master and access images
cCommentMaster="KB_MASTER_LOSSLESS_01/01/2015"
cCommentAccess="KB_ACCESS_LOSSY_01/01/2015"
# Files to store stdout/stderr output
fstdout="stdout.txt"
fstderr="stderr.txt"
# Delete stdout and stderr files if they exist already
if [ -f $fstdout ] ; then
rm $fstdout
fi
if [ -f $fstderr ] ; then
rm $fstderr
fi
while IFS= read -d $'\0' -r file ; do
# File basename
bName=$(basename -s .TIF "$file")
# Output name
outName=$bName.jp2
# Name for temporary XMP sidecar file
xmpName=$bName.xmp
# Full output paths
outMaster="$dirMaster/$outName"
outAccess="$dirAccess/$outName"
# Extract metadata from TIFF with Exiftool and write to XMP sidecar
exiftool "$file" -o "$xmpName" >>$fstdout 2>>$fstderr
# Insert string "xml "at start of sidecar file so Kakadu knows to use XML box
sed -i "1s/^/xml /" "$xmpName"
# Get SamplesPerPixel value
samplesPerPixel=$(exiftool -s -s -s -SamplesPerPixel "$file")
# Determine bitrate values, depending on samplesPerPixel value
# Since bitrate = (BPP/CompressionRatio)
if [ $samplesPerPixel -eq 3 ] ; then
bitratesMaster="-,4.8,2.4,1.2,0.6,0.3,0.15,0.075,0.0375,0.01875,0.009375"
bitratesAccess="1.2,0.6,0.3,0.15,0.075,0.0375,0.01875,0.009375"
fi
if [ $samplesPerPixel -eq 1 ] ; then
bitratesMaster="-,1.6,0.8,0.4,0.2,0.1,0.05,0.025,0.0125,0.00625,0.003125"
bitratesAccess="0.4,0.2,0.1,0.05,0.025,0.0125,0.00625,0.003125"
fi
# Construct Kakadu command lines (lossless master, lossy access copy)
cmdlineMaster="$kduPath/kdu_compress -i "$file"
-o "$outMaster"
Creversible=yes
Clevels=5
Corder=RPCL
Stiles={1024,1024}
Cblk={64,64}
Cprecincts={256,256},{256,256},{128,128}
Clayers=11
-rate $bitratesMaster
Cuse_sop=yes
Cuse_eph=yes
Cmodes=SEGMARK
-jp2_box "$xmpName"
-com "$cCommentMaster""
cmdlineAccess="$kduPath/kdu_compress -i "$file"
-o "$outAccess"
Creversible=no
Clevels=5
Corder=RPCL
Stiles={1024,1024}
Cblk={64,64}
Cprecincts={256,256},{256,256},{128,128}
Clayers=8
-rate $bitratesAccess
Cuse_sop=yes
Cuse_eph=yes
Cmodes=SEGMARK
-jp2_box "$xmpName"
-com "$cCommentAccess""
# Convert to JP2 (lossless master, lossy access copy)
$cmdlineMaster >>$fstdout 2>>$fstderr
$cmdlineAccess >>$fstdout 2>>$fstderr
# Remove XMP sidecar file
rm $xmpName
done < <(find $dirIn -type f -name "*.TIF" -print0)
# Run jpylyzer on master and access JP2s
jpylyzer -w "$dirMaster"/*.jp2 > master.xml
jpylyzer -w "$dirAccess"/*.jp2 > access.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment