Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
2397e946
Commit
2397e946
authored
May 13, 2019
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More on JP4+Tiff reading with bioformatrs.
parent
fb75351e
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
945 additions
and
187 deletions
+945
-187
.gitignore
.gitignore
+2
-1
pom.xml
pom.xml
+2
-1
EyesisTiff.java
src/main/java/EyesisTiff.java
+104
-72
JP46_Reader_camera.java
src/main/java/JP46_Reader_camera.java
+72
-7
ElphelJp4Reader.java
src/main/java/com/elphel/imagej/readers/ElphelJp4Reader.java
+299
-0
ElphelMeta.java
src/main/java/com/elphel/imagej/readers/ElphelMeta.java
+89
-101
ElphelTiffReader.java
...main/java/com/elphel/imagej/readers/ElphelTiffReader.java
+135
-5
ImagejJp4Tiff.java
src/main/java/com/elphel/imagej/readers/ImagejJp4Tiff.java
+235
-0
readers1.txt
src/main/resources/readers1.txt
+7
-0
No files found.
.gitignore
View file @
2397e946
...
...
@@ -8,4 +8,5 @@ attic
*.log
FOCUS-PSF*
src/main/resources/trained_model
bioformats
\ No newline at end of file
bioformats*.*
metadata*.*
pom.xml
View file @
2397e946
...
...
@@ -88,7 +88,8 @@
<dependency>
<groupId>
ome
</groupId>
<artifactId>
loci_tools
</artifactId>
<version>
5.9.0
</version>
<version>
6.1.0-SNAPSHOT
</version>
<type>
java-source
</type>
</dependency>
</dependencies>
...
...
src/main/java/EyesisTiff.java
View file @
2397e946
...
...
@@ -31,21 +31,32 @@ import java.awt.image.ColorModel;
import
java.awt.image.DataBufferInt
;
import
java.awt.image.Raster
;
import
java.awt.image.WritableRaster
;
import
java.io.DataInputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.StringReader
;
import
java.io.UnsupportedEncodingException
;
import
java.lang.reflect.Array
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.util.Arrays
;
import
java.util.Hashtable
;
import
java.util.Iterator
;
import
java.util.Properties
;
import
java.util.Set
;
import
javax.imageio.ImageIO
;
import
javax.xml.parsers.DocumentBuilder
;
import
javax.xml.parsers.DocumentBuilderFactory
;
import
javax.xml.parsers.ParserConfigurationException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.w3c.dom.Document
;
import
org.w3c.dom.NodeList
;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
com.elphel.imagej.readers.ElphelTiffReader
;
//import org.apache.log4j.Logger;
...
...
@@ -55,20 +66,15 @@ import ij.WindowManager;
import
ij.io.FileInfo
;
import
ij.process.FloatProcessor
;
import
ij.process.ImageProcessor
;
import
loci.common.ByteArrayHandle
;
import
loci.common.Location
;
import
loci.common.RandomAccessInputStream
;
import
loci.common.services.DependencyException
;
import
loci.common.services.ServiceException
;
import
loci.common.services.ServiceFactory
;
import
loci.formats.ClassList
;
import
loci.formats.CoreMetadata
;
import
loci.formats.FormatException
;
import
loci.formats.IFormatReader
;
import
loci.formats.ImageReader
;
//import loci.formats.in.TiffReader;
import
loci.formats.meta.IMetadata
;
import
loci.formats.meta.MetadataStore
;
import
loci.formats.services.OMEXMLService
;
import
loci.formats.tiff.IFD
;
import
loci.formats.tiff.IFDList
;
...
...
@@ -86,6 +92,7 @@ public class EyesisTiff {
defaultClasses
=
new
ClassList
<
IFormatReader
>(
EyesisTiff
.
class
.
getClassLoader
().
getResource
(
"readers.txt"
).
getFile
(),
// @param file Configuration file containing the list of classes.
// EyesisTiff.class.getClassLoader().getResource("readers1.txt").getFile(), // @param file Configuration file containing the list of classes.
IFormatReader
.
class
,
// @param base Base class to which all classes are assignable.
null
);
// @param location Class indicating which package to search for the file.
}
...
...
@@ -109,43 +116,14 @@ public class EyesisTiff {
}
public
ImagePlus
readTiff
(
String
path
)
{
// TiffReader tiffReader = new TiffReader();
// tiffReader.initFile(path);
// read in entire file
// TODO: add option to get URL
//https://docs.openmicroscopy.org/bio-formats/5.9.2/developers/in-memory.html
System
.
out
.
println
(
"Reading file into memory from disk: "
+
path
);
File
inputFile
=
new
File
(
path
);
int
fileSize
=
(
int
)
inputFile
.
length
();
DataInputStream
in
=
null
;
try
{
in
=
new
DataInputStream
(
new
FileInputStream
(
inputFile
));
}
catch
(
FileNotFoundException
e
)
{
System
.
out
.
println
(
"File not found: "
+
path
);
}
byte
[]
inBytes
=
new
byte
[
fileSize
];
try
{
in
.
readFully
(
inBytes
);
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
System
.
out
.
println
(
fileSize
+
" bytes read."
);
// determine input file suffix
String
fileName
=
inputFile
.
getName
();
int
dot
=
fileName
.
lastIndexOf
(
"."
);
String
suffix
=
dot
<
0
?
""
:
fileName
.
substring
(
dot
);
return
readTiff
(
path
,
"STD_"
);
// null);
}
public
ImagePlus
readTiff
(
String
path
,
String
std
)
{
// std - include non-elphel properties with prefix std
// map input id string to input byte array
String
inId
=
"inBytes"
+
suffix
;
Location
.
mapFile
(
inId
,
new
ByteArrayHandle
(
inBytes
));
String
inId
=
null
;
inId
=
path
;
// read data from byte array using ImageReader
System
.
out
.
println
();
System
.
out
.
println
(
"Reading image data from memory..."
);
//
ServiceFactory
factory
=
null
;
try
{
factory
=
new
ServiceFactory
();
...
...
@@ -153,13 +131,15 @@ public class EyesisTiff {
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
OMEXMLService
service
=
null
;
OMEXMLService
service
=
null
;
try
{
service
=
factory
.
getInstance
(
OMEXMLService
.
class
);
}
catch
(
DependencyException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
IMetadata
omeMeta
=
null
;
try
{
omeMeta
=
service
.
createOMEXMLMetadata
();
...
...
@@ -174,8 +154,13 @@ public class EyesisTiff {
//https://www.javatips.net/api/libbio-formats-java-master/components/scifio/src/loci/formats/in/BaseTiffReader.java
//https://docs.openmicroscopy.org/bio-formats/5.7.2/developers/reader-guide.html
//https://docs.openmicroscopy.org/bio-formats/5.9.2/developers/java-library.html#file-reading-and-performance
//defaultClasses = new ClassList<IFormatReader>(IFormatReader.class);
// ClassList<IFormatReader> cl0 = getCustomReaderClasses(); // new ClassList<IFormatReader>(IFormatReader.class);
ClassList
<
IFormatReader
>
classList
=
new
ClassList
<
IFormatReader
>(
IFormatReader
.
class
);
classList
.
addClass
(
com
.
elphel
.
imagej
.
readers
.
ElphelTiffReader
.
class
);
ImageReader
reader
=
new
ImageReader
(
getCustomReaderClasses
());
//
BaseTiffReader reader = new BaseTiffReader("Base_tiff_reader","tiff"
);
//
ImageReader reader = new ImageReader(classList
);
reader
.
setMetadataStore
(
omeMeta
);
try
{
reader
.
setId
(
inId
);
...
...
@@ -187,32 +172,10 @@ public class EyesisTiff {
//e.printStackTrace();
}
/* read-end */
int
seriesCount
=
reader
.
getSeriesCount
();
int
imageCount
=
reader
.
getImageCount
();
int
sizeX
=
reader
.
getSizeX
();
int
sizeY
=
reader
.
getSizeY
();
int
sizeZ
=
reader
.
getSizeZ
();
int
sizeC
=
reader
.
getSizeC
();
int
sizeT
=
reader
.
getSizeT
();
int
bpp
=
reader
.
getBitsPerPixel
();
int
pixelType
=
reader
.
getPixelType
();
java
.
util
.
List
<
CoreMetadata
>
cmd
=
reader
.
getCoreMetadataList
();
java
.
util
.
Hashtable
<
java
.
lang
.
String
,
java
.
lang
.
Object
>
gmd
=
reader
.
getGlobalMetadata
();
MetadataStore
mtds
=
reader
.
getMetadataStore
();
IFormatReader
ifr
=
reader
.
getReader
();
IFormatReader
[]
ifrs
=
reader
.
getReaders
();
// all available readers?
// output some details
System
.
out
.
println
(
"Series count: "
+
seriesCount
);
System
.
out
.
println
(
"First series:"
);
System
.
out
.
println
(
"\tImage count = "
+
imageCount
);
System
.
out
.
println
(
"\tSizeX = "
+
sizeX
);
System
.
out
.
println
(
"\tSizeY = "
+
sizeY
);
System
.
out
.
println
(
"\tSizeZ = "
+
sizeZ
);
System
.
out
.
println
(
"\tSizeC = "
+
sizeC
);
System
.
out
.
println
(
"\tSizeT = "
+
sizeT
);
System
.
out
.
println
(
"\tbppT = "
+
bpp
);
System
.
out
.
println
(
"\treader = "
+
ifr
.
toString
());
System
.
out
.
println
(
"\tpixelType = "
+
pixelType
);
// 3
byte
[]
bytes
=
null
;
ImagePlus
imp
=
null
;
try
{
...
...
@@ -245,11 +208,26 @@ public class EyesisTiff {
ImageProcessor
ip
=
new
FloatProcessor
(
reader
.
getSizeX
(),
reader
.
getSizeY
());
ip
.
setPixels
(
pixels
);
ip
.
resetMinAndMax
();
// imp = new ImagePlus(fileName, ip); // original jp46 reader had full path as title
imp
=
new
ImagePlus
(
path
,
ip
);
// original jp46 reader had full path as title
Hashtable
<
String
,
Object
>
meta_hash
=
reader
.
getGlobalMetadata
();
String
prefix
=
ElphelTiffReader
.
ELPHEL_PROPERTY_PREFIX
;
String
imageName
=
path
;
String
imageNameKey
=
prefix
+
ElphelTiffReader
.
CONTENT_FILENAME
;
if
(
meta_hash
.
containsKey
(
imageNameKey
))
{
imageName
=
meta_hash
.
get
(
imageNameKey
).
toString
();
}
imp
=
new
ImagePlus
(
imageName
,
ip
);
// original jp46 reader had full path as title
// first - save all as properties, later - only ELPHEL_*
for
(
String
key:
meta_hash
.
keySet
())
{
if
(
key
.
startsWith
(
prefix
))
{
imp
.
setProperty
(
key
.
substring
(
prefix
.
length
()),
meta_hash
.
get
(
key
).
toString
());
}
else
if
(
std
!=
null
)
{
imp
.
setProperty
(
std
+(
key
.
replace
(
" "
,
"_"
)),
meta_hash
.
get
(
key
).
toString
());
}
}
encodeProperiesToInfo
(
imp
);
}
// ImagePlus imp= makeArrays(pixels, width, height, title);
try
{
reader
.
close
();
}
catch
(
IOException
e
)
{
...
...
@@ -662,4 +640,58 @@ the type of pixel data in this file getPixelType()
return
sb
.
toString
();
}
// copied from JP46_Reader_camera.java
public
ImagePlus
encodeProperiesToInfo
(
ImagePlus
imp
){
String
info
=
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><properties>"
;
Set
<
Object
>
jp4_set
;
Properties
jp4_prop
;
Iterator
<
Object
>
itr
;
String
str
;
jp4_prop
=
imp
.
getProperties
();
if
(
jp4_prop
!=
null
)
{
jp4_set
=
jp4_prop
.
keySet
();
itr
=
jp4_set
.
iterator
();
while
(
itr
.
hasNext
())
{
str
=
(
String
)
itr
.
next
();
// if (!str.equals("Info")) info+="<"+str+">\""+jp4_prop.getProperty(str)+"\"</"+str+">";
if
(!
str
.
equals
(
"Info"
))
info
+=
"<"
+
str
+
">"
+
jp4_prop
.
getProperty
(
str
)+
"</"
+
str
+
">"
;
}
}
info
+=
"</properties>\n"
;
imp
.
setProperty
(
"Info"
,
info
);
return
imp
;
}
public
boolean
decodeProperiesFromInfo
(
ImagePlus
imp
){
if
(
imp
.
getProperty
(
"Info"
)==
null
)
return
false
;
String
xml
=
(
String
)
imp
.
getProperty
(
"Info"
);
DocumentBuilder
db
=
null
;
try
{
db
=
DocumentBuilderFactory
.
newInstance
().
newDocumentBuilder
();
}
catch
(
ParserConfigurationException
e
)
{
return
false
;
}
InputSource
is
=
new
InputSource
();
is
.
setCharacterStream
(
new
StringReader
(
xml
));
Document
doc
=
null
;
try
{
doc
=
db
.
parse
(
is
);
}
catch
(
SAXException
e
)
{
return
false
;
}
catch
(
IOException
e
)
{
return
false
;
}
NodeList
allNodes
=
doc
.
getDocumentElement
().
getElementsByTagName
(
"*"
);
for
(
int
i
=
0
;
i
<
allNodes
.
getLength
();
i
++)
{
String
name
=
allNodes
.
item
(
i
).
getNodeName
();
String
value
=
allNodes
.
item
(
i
).
getFirstChild
().
getNodeValue
();
imp
.
setProperty
(
name
,
value
);
}
return
true
;
}
}
src/main/java/JP46_Reader_camera.java
View file @
2397e946
...
...
@@ -59,6 +59,8 @@ import org.w3c.dom.NodeList;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
com.elphel.imagej.readers.ImagejJp4Tiff
;
import
ij.IJ
;
import
ij.ImageJ
;
import
ij.ImagePlus
;
...
...
@@ -75,6 +77,7 @@ import ij.process.ImageConverter;
import
ij.process.ImageProcessor
;
import
ij.text.TextWindow
;
import
loci.common.RandomAccessInputStream
;
import
loci.formats.FormatException
;
import
loci.formats.tiff.IFD
;
import
loci.formats.tiff.IFDList
;
import
loci.formats.tiff.TiffParser
;
...
...
@@ -96,7 +99,7 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
static
File
dir
;
public
String
camera_url
=
"http://192.168.0.
236:8081
/"
;
public
String
camera_url
=
"http://192.168.0.
36:2323
/"
;
public
String
camera_img
=
"bimg"
;
public
String
camera_img_new
=
"towp/wait/bimg"
;
// will always wait for the next image (repetitive acquisitions get new images)
public
String
camera_jp46settings
=
""
;
...
...
@@ -322,6 +325,10 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
if
(
demux
)
showImage
=
false
;
double
[]
xtraExif
=
new
double
[
1
];
// ExposureTime
double
[]
lla
=
null
;
imp
=
openJpegOrGif
(
directory
,
fileName
);
imp
.
show
();
if
(
imp
!=
null
)
return
imp
;
try
{
imp
=
openJpegOrGif
(
directory
,
fileName
);
if
(
imp
==
null
)
{
...
...
@@ -390,7 +397,35 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
String
arg
,
boolean
scale
,
ImagePlus
imp_src
,
boolean
showImage
)
{
boolean
showImage
)
{
// ImagePlus imptiff = (new EyesisTiff()).readTiff(url);
ImagePlus
imptiff
=
null
;
try
{
imptiff
=
(
new
ImagejJp4Tiff
()).
readTiffJp4
(
url
);
}
catch
(
IOException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
}
catch
(
FormatException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
}
if
(
imptiff
!=
null
)
{
imptiff
.
show
();
if
(
imptiff
.
getType
()==
ImagePlus
.
COLOR_RGB
)
{
checkGrayJpegTo32Bits
(
imptiff
);
}
IJ
.
showStatus
(
"Converting to 32-bits"
);
new
ImageConverter
(
imptiff
).
convertToGray32
();
FileInfo
fi
=
imptiff
.
getFileInfo
();
// fi.fileName = name;
// fi.directory = dir;
fi
.
fileFormat
=
FileInfo
.
TIFF
;
imptiff
.
setFileInfo
(
fi
);
return
imptiff
;
}
long
[]
ElphelMakerNote
=
null
;
ImagePlus
imp
=
null
;
boolean
reuse_imp
=
false
;
...
...
@@ -399,14 +434,14 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
double
[]
xtraExif
=
new
double
[
1
];
// ExposureTime
// System.out.println("imp_src is "+((imp_src!=null)?"not ":"")+"null");
// System.out.println("imp_src is "+((imp_src!=null)?"not ":"")+"null");
try
{
imp
=
openJpegOrGifUsingURL
(
url
);
if
(
imp
==
null
)
{
IJ
.
showMessage
(
"JP46 Reader Error"
,
"Could not open the URL: "
+
url
+
" as JPEG/JP46"
);
}
else
{
if
((
imp_src
==
null
)
&&
showImage
)
{
// System.out.println("show() 1");
// System.out.println("show() 1");
imp
.
show
();
/* Shows before re-ordering*/
}
/// get rid of the "/towp/wait" if any - there is a chance to re-read the same image
...
...
@@ -429,7 +464,7 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
if
(
reuse_imp
)
{
imp
=
imp_src
;
}
else
if
((
imp_src
!=
null
)
&&
showImage
)
{
/* tried to reuse, but wrong size */
// System.out.println("show() 2");
// System.out.println("show() 2");
imp
.
show
();
/* never did that before */
}
if
((
xtraExif
!=
null
)
&&
!
Double
.
isNaN
(
xtraExif
[
0
])){
...
...
@@ -1042,6 +1077,35 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
/* Modified from Opener.java */
ImagePlus
openJpegOrGif
(
String
dir
,
String
name
)
{
// Testing new readers
ImagePlus
imptiff
=
null
;
// imptiff = (new EyesisTiff()).readTiff(dir+name);
try
{
imptiff
=
(
new
ImagejJp4Tiff
()).
readTiffJp4
(
dir
+
name
);
}
catch
(
IOException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
}
catch
(
FormatException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
}
if
(
imptiff
!=
null
)
{
imptiff
.
show
();
if
(
imptiff
.
getType
()==
ImagePlus
.
COLOR_RGB
)
{
checkGrayJpegTo32Bits
(
imptiff
);
}
IJ
.
showStatus
(
"Converting to 32-bits"
);
new
ImageConverter
(
imptiff
).
convertToGray32
();
FileInfo
fi
=
imptiff
.
getFileInfo
();
fi
.
fileName
=
name
;
fi
.
directory
=
dir
;
fi
.
fileFormat
=
FileInfo
.
TIFF
;
imptiff
.
setFileInfo
(
fi
);
return
imptiff
;
}
ImagePlus
imp
=
null
;
boolean
isTiff
=
false
;
Image
img
=
Toolkit
.
getDefaultToolkit
().
createImage
(
dir
+
name
);
...
...
@@ -1073,8 +1137,8 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
fi
=
imp
.
getFileInfo
();
// testing
if
((
ofi
!=
null
)
&&
(
ofi
.
directory
!=
null
)
&&
(
ofi
.
fileFormat
==
FileInfo
.
TIFF
))
{
/*
if ((ofi!=null) && (ofi.directory!=null) && (ofi.fileFormat ==
FileInfo.TIFF)) {
String path = ofi.directory + ofi.fileName;
EyesisTiff ET = new EyesisTiff();
ImagePlus imptiff = ET.readTiff(path);
...
...
@@ -1093,6 +1157,7 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
Frame log = WindowManager.getFrame("Log");
if (log!=null) log.toFront();
}
*/
}
...
...
src/main/java/com/elphel/imagej/readers/ElphelJp4Reader.java
0 → 100644
View file @
2397e946
This diff is collapsed.
Click to expand it.
src/main/java/com/elphel/imagej/readers/ElphelMeta.java
View file @
2397e946
...
...
@@ -29,74 +29,59 @@ import java.util.Hashtable;
//import ij.IJ;
import
loci.formats.FormatException
;
import
loci.formats.tiff.IFD
;
import
loci.formats.tiff.IFDList
;
import
loci.formats.tiff.TiffParser
;
import
loci.formats.tiff.TiffRational
;
public
class
ElphelMeta
{
private
Hashtable
<
String
,
String
>
property_table
=
null
;
public
ElphelMeta
(
TiffParser
tiffParser
,
boolean
scale
)
throws
FormatException
,
IOException
{
IFDList
exifIFDs
=
tiffParser
.
getExifIFDs
();
property_table
=
new
Hashtable
<
String
,
String
>
();
long
[]
maker_note
=
null
;
if
(
exifIFDs
.
size
()
>
0
)
{
IFD
exifIFD
=
exifIFDs
.
get
(
0
);
tiffParser
.
fillInIFD
(
exifIFD
);
if
(
exifIFD
.
containsKey
(
IFD
.
MAKER_NOTE
))
{
maker_note
=
(
long
[])
exifIFD
.
get
(
IFD
.
MAKER_NOTE
);
}
if
(
exifIFD
.
containsKey
(
IFD
.
EXPOSURE_TIME
))
{
Object
exp
=
exifIFD
.
get
(
IFD
.
EXPOSURE_TIME
);
if
(
exp
instanceof
TiffRational
)
{
TiffRational
texp
=
(
TiffRational
)
exp
;
double
d
=
1.0
*
texp
.
getNumerator
()/
texp
.
getDenominator
();
property_table
.
put
(
"EXPOSURE"
,
String
.
format
(
"%f"
,
d
));
}
}
if
(
exifIFD
.
containsKey
(
IFD
.
DATE_TIME_ORIGINAL
))
{
String
dt
=
exifIFD
.
get
(
IFD
.
DATE_TIME_ORIGINAL
).
toString
();
if
(
exifIFD
.
containsKey
(
IFD
.
SUB_SEC_TIME_ORIGINAL
))
{
dt
+=
"."
+
exifIFD
.
get
(
IFD
.
SUB_SEC_TIME_ORIGINAL
).
toString
();
}
property_table
.
put
(
"DATE_TIME"
,
dt
);
}
// private Hashtable<String, String> property_table = null;
public
static
Hashtable
<
String
,
String
>
getMeta
(
Hashtable
<
String
,
String
>
property_table
,
long
[]
maker_note
,
double
exposure
,
String
date_time
,
boolean
scale
)
throws
FormatException
,
IOException
{
if
(
property_table
==
null
)
{
property_table
=
new
Hashtable
<
String
,
String
>
();
}
// copied from JP4_Reader_cam
// Add GPS tags when there will be images to experiment (or while reimplementing JP4 reader)
double
[]
gains
=
new
double
[
4
];
double
[]
blacks
=
new
double
[
4
];
double
[]
blacks256
=
new
double
[
4
];
double
[]
gammas
=
new
double
[
4
];
long
[]
gamma_scales
=
new
long
[
4
];
/* now not used, was scale _after_ gamma is applied, 0x400(default) corresponds to 1.0 */
int
i
;
double
[][]
rgammas
=
new
double
[
4
][];
double
min_gain
;
long
WOI_LEFT
,
WOI_WIDTH
,
WOI_TOP
,
WOI_HEIGHT
,
BAYER_MODE
,
DCM_HOR
,
DCM_VERT
,
BIN_HOR
,
BIN_VERT
;
long
COLOR_MODE
=
0
;
long
FLIPH
=
0
;
long
FLIPV
=
0
;
long
HEIGHT1
=
0
;
long
HEIGHT2
=
0
;
long
HEIGHT3
=
0
;
long
BLANK1
=
0
;
long
BLANK2
=
0
;
boolean
FLIPH1
=
false
;
boolean
FLIPV1
=
false
;
boolean
FLIPH2
=
false
;
boolean
FLIPV2
=
false
;
boolean
FLIPH3
=
false
;
boolean
FLIPV3
=
false
;
boolean
COMPOSITE
=
false
;
boolean
PORTRAIT
=
false
;
boolean
YTABLEFORC
=
false
;
long
QUALITY
=
0
;
long
CQUALITY
=
0
;
long
CORING_INDEX_Y
=
0
;
long
CORING_INDEX_C
=
0
;
double
[]
satValue
={
255.0
,
255.0
,
255.0
,
255.0
};
if
(
maker_note
!=
null
)
{
if
(!
Double
.
isNaN
(
exposure
))
{
property_table
.
put
(
"EXPOSURE"
,
String
.
format
(
"%f"
,
exposure
));
}
if
(
date_time
==
null
)
{
property_table
.
put
(
"DATE_TIME"
,
date_time
);
}
if
(
maker_note
!=
null
)
{
// copied from JP4_Reader_cam
// Add GPS tags when there will be images to experiment (or while reimplementing JP4 reader)
double
[]
gains
=
new
double
[
4
];
double
[]
blacks
=
new
double
[
4
];
double
[]
blacks256
=
new
double
[
4
];
double
[]
gammas
=
new
double
[
4
];
long
[]
gamma_scales
=
new
long
[
4
];
/* now not used, was scale _after_ gamma is applied, 0x400(default) corresponds to 1.0 */
int
i
;
double
[][]
rgammas
=
new
double
[
4
][];
double
min_gain
;
long
WOI_LEFT
,
WOI_WIDTH
,
WOI_TOP
,
WOI_HEIGHT
,
BAYER_MODE
,
DCM_HOR
,
DCM_VERT
,
BIN_HOR
,
BIN_VERT
;
long
COLOR_MODE
=
0
;
long
FLIPH
=
0
;
long
FLIPV
=
0
;
long
HEIGHT1
=
0
;
long
HEIGHT2
=
0
;
long
HEIGHT3
=
0
;
long
BLANK1
=
0
;
long
BLANK2
=
0
;
boolean
FLIPH1
=
false
;
boolean
FLIPV1
=
false
;
boolean
FLIPH2
=
false
;
boolean
FLIPV2
=
false
;
boolean
FLIPH3
=
false
;
boolean
FLIPV3
=
false
;
boolean
COMPOSITE
=
false
;
boolean
PORTRAIT
=
false
;
boolean
YTABLEFORC
=
false
;
long
QUALITY
=
0
;
long
CQUALITY
=
0
;
long
CORING_INDEX_Y
=
0
;
long
CORING_INDEX_C
=
0
;
double
[]
satValue
={
255.0
,
255.0
,
255.0
,
255.0
};
for
(
i
=
0
;
i
<
4
;
i
++)
{
/* r,g,gb,b */
gains
[
i
]=
maker_note
[
i
]/
65536.0
;
blacks
[
i
]=(
maker_note
[
i
+
4
]>>
24
)/
256.0
;
...
...
@@ -193,7 +178,7 @@ public class ElphelMeta {
property_table
.
put
(
"FLIPV2"
,
FLIPV2
?
"1"
:
"0"
);
property_table
.
put
(
"FLIPV3"
,
FLIPV3
?
"1"
:
"0"
);
}
// If there are FLIPH, FLIPV - swap gains, gammas, blacks accordingly. later the images will be also flipped
// If there are FLIPH, FLIPV - swap gains, gammas, blacks accordingly. later the images will be also flipped
if
(
FLIPV
!=
0
)
{
swapArrayElements
(
gains
,
1
,
3
);
swapArrayElements
(
gains
,
0
,
2
);
...
...
@@ -215,54 +200,57 @@ public class ElphelMeta {
swapArrayElements
(
gamma_scales
,
3
,
2
);
}
for
(
i
=
0
;
i
<
4
;
i
++)
rgammas
[
i
]=
elphel_gamma_calc
(
gammas
[
i
],
blacks
[
i
],
gamma_scales
[
i
]);
}
else
{
return
;
// No MakerNote, return with nothing done
}
/**adjusting gains to have the result picture in the range 0..256 */
min_gain
=
2.0
*
gains
[
0
];
for
(
i
=
0
;
i
<
4
;
i
++)
{
if
(
min_gain
>
gains
[
i
]*(
1.0
-
blacks
[
i
]))
min_gain
=
gains
[
i
]*(
1.0
-
blacks
[
i
]);
}
property_table
.
put
(
"GAIN"
,
String
.
format
(
"%f"
,
min_gain
));
// common gain
/**adjusting gains to have the result picture in the range 0..256 */
min_gain
=
2.0
*
gains
[
0
];
for
(
i
=
0
;
i
<
4
;
i
++)
{
if
(
min_gain
>
gains
[
i
]*(
1.0
-
blacks
[
i
]))
min_gain
=
gains
[
i
]*(
1.0
-
blacks
[
i
]);
}
property_table
.
put
(
"GAIN"
,
String
.
format
(
"%f"
,
min_gain
));
// common gain
for
(
i
=
0
;
i
<
4
;
i
++)
gains
[
i
]/=
min_gain
;
for
(
i
=
0
;
i
<
4
;
i
++)
blacks256
[
i
]=
256.0
*
blacks
[
i
];
for
(
i
=
0
;
i
<
4
;
i
++)
gains
[
i
]/=
min_gain
;
for
(
i
=
0
;
i
<
4
;
i
++)
blacks256
[
i
]=
256.0
*
blacks
[
i
];
for
(
i
=
0
;
i
<
4
;
i
++)
{
if
(
maker_note
!=
null
)
{
if
(
scale
)
satValue
[
i
]=((
rgammas
[
i
][
255
])-
blacks256
[
i
])/
gains
[
i
];
else
satValue
[
i
]=((
rgammas
[
i
][
255
])-
blacks256
[
i
]);
}
else
satValue
[
i
]=
255.0
;
property_table
.
put
(
"saturation_"
+
i
,
String
.
format
(
"%f"
,
satValue
[
i
]));
for
(
i
=
0
;
i
<
4
;
i
++)
{
if
(
maker_note
!=
null
)
{
if
(
scale
)
satValue
[
i
]=((
rgammas
[
i
][
255
])-
blacks256
[
i
])/
gains
[
i
];
else
satValue
[
i
]=((
rgammas
[
i
][
255
])-
blacks256
[
i
]);
}
else
satValue
[
i
]=
255.0
;
property_table
.
put
(
"saturation_"
+
i
,
String
.
format
(
"%f"
,
satValue
[
i
]));
}
// swap satValue to match FLIPH,FLIPV again
if
(
FLIPV
!=
0
)
{
swapArrayElements
(
satValue
,
1
,
3
);
swapArrayElements
(
satValue
,
0
,
2
);
}
if
(
FLIPH
!=
0
)
{
swapArrayElements
(
satValue
,
1
,
0
);
swapArrayElements
(
satValue
,
3
,
2
);
}
for
(
i
=
0
;
i
<
4
;
i
++)
{
property_table
.
put
(
"saturation_"
+
i
,
String
.
format
(
"%f"
,
satValue
[
i
]));
}
}
// swap satValue to match FLIPH,FLIPV again
if
(
FLIPV
!=
0
)
{
swapArrayElements
(
satValue
,
1
,
3
);
swapArrayElements
(
satValue
,
0
,
2
);
}
if
(
FLIPH
!=
0
)
{
swapArrayElements
(
satValue
,
1
,
0
);
swapArrayElements
(
satValue
,
3
,
2
);
}
for
(
i
=
0
;
i
<
4
;
i
++)
{
property_table
.
put
(
"saturation_"
+
i
,
String
.
format
(
"%f"
,
satValue
[
i
]));
}
}
public
Hashtable
<
String
,
String
>
getPropertyTable
(){
return
property_table
;
}
// -- Helper methods --
void
swapArrayElements
(
double
[]
arr
,
int
i
,
int
j
)
{
// public Hashtable<String, String> getPropertyTable(){
// return property_table;
// }
// -- Helper methods --
static
void
swapArrayElements
(
double
[]
arr
,
int
i
,
int
j
)
{
double
tmp
=
arr
[
i
];
arr
[
i
]=
arr
[
j
];
arr
[
j
]=
tmp
;
}
void
swapArrayElements
(
long
[]
arr
,
int
i
,
int
j
)
{
static
void
swapArrayElements
(
long
[]
arr
,
int
i
,
int
j
)
{
long
tmp
=
arr
[
i
];
arr
[
i
]=
arr
[
j
];
arr
[
j
]=
tmp
;
...
...
@@ -270,7 +258,7 @@ public class ElphelMeta {
/* reverses gamma calculations in the camera
returns double[] table , in the range 0.0..255.996
*/
double
[]
elphel_gamma_calc
(
double
gamma
,
double
black
,
long
gamma_scale
)
{
static
double
[]
elphel_gamma_calc
(
double
gamma
,
double
black
,
long
gamma_scale
)
{
int
i
;
double
x
,
black256
,
k
;
int
[]
gtable
=
new
int
[
257
];
...
...
src/main/java/com/elphel/imagej/readers/ElphelTiffReader.java
View file @
2397e946
...
...
@@ -27,15 +27,25 @@
*/
package
com
.
elphel
.
imagej
.
readers
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.util.Hashtable
;
import
org.apache.commons.compress.utils.IOUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
loci.common.ByteArrayHandle
;
import
loci.common.Location
;
import
loci.formats.FormatException
;
import
loci.formats.in.MetadataLevel
;
import
loci.formats.in.TiffReader
;
import
loci.formats.meta.MetadataStore
;
import
loci.formats.tiff.IFD
;
import
loci.formats.tiff.IFDList
;
import
loci.formats.tiff.TiffRational
;
/*
// non-IFD tags (for internal use)
...
...
@@ -72,7 +82,9 @@ IFD.java public static final int MAKER_NOTE = 37500;
public
class
ElphelTiffReader
extends
TiffReader
{
// BaseTiffReader {
// -- Constants --
public
static
final
String
ELPHEL_PROPERTY_PREFIX
=
"ELPHEL_"
;
public
static
final
String
CONTENT_FILENAME
=
"CONTENT_FILENAME"
;
/** Merge SubIFDs into the main IFD list. */
// protected transient boolean mergeSubIFDs = true; // false;
...
...
@@ -89,7 +101,10 @@ public class ElphelTiffReader extends TiffReader{ // BaseTiffReader {
// public static final int IMAGEJ_TAG = 50839;
// -- Fields --
// private String inId = null; // to close Location.mapFile