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
fb75351e
Commit
fb75351e
authored
May 11, 2019
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working on loci-compatible reader for camera files to use single-read
pass
parent
1338de2c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1128 additions
and
22 deletions
+1128
-22
.gitignore
.gitignore
+2
-1
pom.xml
pom.xml
+1
-1
EyesisTiff.java
src/main/java/EyesisTiff.java
+230
-16
JP46_Reader_camera.java
src/main/java/JP46_Reader_camera.java
+103
-4
LwirCamera.java
src/main/java/LwirCamera.java
+28
-0
ElphelMeta.java
src/main/java/com/elphel/imagej/readers/ElphelMeta.java
+308
-0
ElphelTiffReader.java
...main/java/com/elphel/imagej/readers/ElphelTiffReader.java
+250
-0
readers.txt
src/main/resources/readers.txt
+206
-0
No files found.
.gitignore
View file @
fb75351e
...
...
@@ -7,4 +7,5 @@ NC393I
attic
*.log
FOCUS-PSF*
src/main/resources/trained_model
\ No newline at end of file
src/main/resources/trained_model
bioformats
\ No newline at end of file
pom.xml
View file @
fb75351e
...
...
@@ -88,7 +88,7 @@
<dependency>
<groupId>
ome
</groupId>
<artifactId>
loci_tools
</artifactId>
<version>
5.
0
.0
</version>
<version>
5.
9
.0
</version>
</dependency>
</dependencies>
...
...
src/main/java/EyesisTiff.java
View file @
fb75351e
...
...
@@ -4,12 +4,12 @@
**
** Writes Tiff files suitable for Emblend, preserve ImageJ Info data
** Uses bioformat library
**
**
**
** Copyright (C) 2012 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
**
** EyesisTiff.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
...
...
@@ -31,24 +31,45 @@ 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.UnsupportedEncodingException
;
import
java.lang.reflect.Array
;
import
java.nio.ByteBuffer
;
import
java.nio.ByteOrder
;
import
java.util.Arrays
;
import
javax.imageio.ImageIO
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
//import org.apache.log4j.Logger;
import
ij.IJ
;
import
ij.ImagePlus
;
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
;
import
loci.formats.tiff.TiffParser
;
...
...
@@ -56,13 +77,206 @@ import loci.formats.tiff.TiffRational;
import
loci.formats.tiff.TiffSaver
;
public
class
EyesisTiff
{
// private static org.apache.log4j.Logger log= Logger.getLogger(EyesisTiff.class);
private
static
ClassList
<
IFormatReader
>
defaultClasses
;
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
ClassList
.
class
);
public
static
ClassList
<
IFormatReader
>
getCustomReaderClasses
()
{
defaultClasses
=
null
;
if
(
defaultClasses
==
null
)
{
try
{
defaultClasses
=
new
ClassList
<
IFormatReader
>(
EyesisTiff
.
class
.
getClassLoader
().
getResource
(
"readers.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.
}
catch
(
IOException
exc
)
{
defaultClasses
=
new
ClassList
<
IFormatReader
>(
IFormatReader
.
class
);
LOGGER
.
info
(
"Could not parse class list; using default classes"
,
exc
);
}
}
// ClassList<IFormatReader> dc = defaultClasses;
LOGGER
.
info
(
"Loaded "
+
defaultClasses
.
getClasses
().
length
+
" classes"
);
return
defaultClasses
;
}
// private static org.apache.log4j.Logger log= Logger.getLogger(EyesisTiff.class);
public
EyesisTiff
(){
// Please initialize the log4j system properly
}
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
);
// map input id string to input byte array
String
inId
=
"inBytes"
+
suffix
;
Location
.
mapFile
(
inId
,
new
ByteArrayHandle
(
inBytes
));
// 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
();
}
catch
(
DependencyException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
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
();
}
catch
(
ServiceException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
// final Class<? extends IFormatReader>[] defaultClasses =
// ImageReader.getDefaultReaderClasses().getClasses();
// final int currentHash = Arrays.hashCode(defaultClasses);
//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
ImageReader
reader
=
new
ImageReader
(
getCustomReaderClasses
());
// BaseTiffReader reader = new BaseTiffReader("Base_tiff_reader","tiff");
reader
.
setMetadataStore
(
omeMeta
);
try
{
reader
.
setId
(
inId
);
}
catch
(
FormatException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
// a lot of output for each unmatched format
//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
{
bytes
=
reader
.
openBytes
(
0
);
}
catch
(
FormatException
e1
)
{
LOGGER
.
warn
(
"Invalid image format, error "
+
e1
);
}
catch
(
IOException
e1
)
{
LOGGER
.
warn
(
"I/O error "
+
e1
);
}
if
(
bytes
!=
null
)
{
boolean
is_le
=
reader
.
isLittleEndian
();
int
bytes_per_pixel
=
(
bpp
+
7
)
/
9
;
float
[]
pixels
=
new
float
[
bytes
.
length
/
bytes_per_pixel
];
if
(
bytes_per_pixel
==
1
)
{
for
(
int
i
=
0
;
i
<
pixels
.
length
;
i
++)
{
pixels
[
i
]
=
((
bytes
[
i
]))
&
0xff
;
}
}
else
{
ByteBuffer
bb
=
ByteBuffer
.
wrap
(
bytes
);
if
(
is_le
)
{
bb
.
order
(
ByteOrder
.
LITTLE_ENDIAN
);
}
else
{
bb
.
order
(
ByteOrder
.
BIG_ENDIAN
);
}
for
(
int
i
=
0
;
i
<
pixels
.
length
;
i
++)
{
pixels
[
i
]
=
((
bb
.
getShort
()))
&
0xffff
;
}
}
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
}
// ImagePlus imp= makeArrays(pixels, width, height, title);
try
{
reader
.
close
();
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
return
imp
;
}
/*
* image width getSizeX()
image height getSizeY()
number of series per file getSeriesCount()
total number of images per series getImageCount()
number of slices in the current series getSizeZ()
number of timepoints in the current series getSizeT()
number of actual channels in the current series getSizeC()
number of channels per image getRGBChannelCount()
the ordering of the images within the current series getDimensionOrder()
whether each image is RGB isRGB()
whether the pixel bytes are in little-endian order isLittleEndian()
whether the channels in an image are interleaved isInterleaved()
the type of pixel data in this file getPixelType()
*/
public
void
savePNG_ARGB32
(
ImagePlus
imp
,
String
path
...
...
@@ -71,12 +285,12 @@ public class EyesisTiff {
int
height
=
imp
.
getHeight
();
int
[]
pixels
=
(
int
[])
imp
.
getProcessor
().
getPixels
();
System
.
out
.
println
(
"savePNG_ARGB32("
+
path
+
"): width="
+
width
+
", height="
+
height
+
" length="
+
pixels
.
length
);
DataBufferInt
buffer
=
new
DataBufferInt
(
pixels
,
pixels
.
length
);
int
[]
bandMasks
=
{
0xFF0000
,
0xFF00
,
0xFF
,
0xFF000000
};
// ARGB (yes, ARGB, as the masks are R, G, B, A always) order
WritableRaster
raster
=
Raster
.
createPackedRaster
(
buffer
,
width
,
height
,
width
,
bandMasks
,
null
);
ColorModel
cm
=
ColorModel
.
getRGBdefault
();
BufferedImage
bimage
=
new
BufferedImage
(
cm
,
raster
,
cm
.
isAlphaPremultiplied
(),
null
);
try
{
...
...
@@ -124,7 +338,7 @@ public class EyesisTiff {
int
IFDImageJByteCounts
=
0xc696
;
// was array {12( if no slices, roi, etc.), bytes in info}
int
IFDImageJInfo
=
0xc697
;
// ImageJ info, starting with magic IJIJinfo,
byte
[]
ImageJInfoMagic
={
73
,
74
,
73
,
74
,
105
,
110
,
102
,
111
,
0
,
0
,
0
,
1
};
byte
[]
ImageJInfoMagic
={
73
,
74
,
73
,
74
,
105
,
110
,
102
,
111
,
0
,
0
,
0
,
1
};
int
pixelsDenominator
=
1000
;
String
description
=(
imp
.
getProperty
(
"description"
)!=
null
)?((
String
)
imp
.
getProperty
(
"description"
)):
"Elphel Eyesis4pi"
;
...
...
@@ -152,7 +366,7 @@ public class EyesisTiff {
}
}
// for (int i = 0; i < imagePixels[3].length; i++){
// imagePixels[3][i] = 1.0f - imagePixels[3][i];
// imagePixels[3][i] = 1.0f - imagePixels[3][i];
// }
int
bw
;
byte
[]
bytes
;
...
...
@@ -221,7 +435,7 @@ public class EyesisTiff {
default
:
IJ
.
error
(
"saveTiffARGBFloat32"
,
"Unsupported output format mode ="
+
mode
);
return
;
}
}
// System.out.println("saveTiffARGBFloat32(): mode="+mode+" pixelType="+pixelType+" bw="+bw);
IFD
ifd
=
new
IFD
();
ifd
.
put
(
new
Integer
(
IFD
.
LITTLE_ENDIAN
),
new
Boolean
(
false
));
...
...
@@ -229,7 +443,7 @@ public class EyesisTiff {
ifd
.
put
(
new
Integer
(
IFD
.
IMAGE_WIDTH
),
imp
.
getWidth
());
ifd
.
put
(
new
Integer
(
IFD
.
IMAGE_LENGTH
),
imp
.
getHeight
());
ifd
.
put
(
new
Integer
(
IFD
.
SAMPLES_PER_PIXEL
),
4
);
ifd
.
putIFDValue
(
IFD
.
SOFTWARE
,
"Elphel Eyesis"
);
ifd
.
putIFDValue
(
IFD
.
SOFTWARE
,
"Elphel Eyesis"
);
ifd
.
putIFDValue
(
IFD
.
IMAGE_DESCRIPTION
,
description
);
// copy some other data?
ifd
.
putIFDValue
(
IFD
.
COMPRESSION
,
1
);
//TiffCompression.UNCOMPRESSED);
...
...
@@ -251,7 +465,7 @@ public class EyesisTiff {
if
(
imp
.
getProperty
(
"ImageFullLength"
)!=
null
){
ifd
.
putIFDValue
(
IFDImageFullLength
,
(
long
)
Integer
.
parseInt
((
String
)
imp
.
getProperty
(
"ImageFullLength"
)));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if
(
imageJTags
&&
(
imp
.
getProperty
(
"Info"
)!=
null
)
&&
(
imp
.
getProperty
(
"Info"
)
instanceof
String
)){
int
skipFirstBytes
=
2
;
String
info
=(
String
)
imp
.
getProperty
(
"Info"
);
...
...
@@ -269,7 +483,7 @@ public class EyesisTiff {
TiffSaver
tiffSaver
=
new
TiffSaver
(
path
);
tiffSaver
.
setWritingSequentially
(
true
);
tiffSaver
.
setLittleEndian
(
false
);
tiffSaver
.
writeHeader
();
tiffSaver
.
writeHeader
();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
// System.out.println("bytes.length="+bytes.length);
tiffSaver
.
writeImage
(
bytes
,
...
...
@@ -292,7 +506,7 @@ public class EyesisTiff {
int
IFDImageJByteCounts
=
0xc696
;
// was array {12( if no slices, roi, etc.), bytes in info}
int
IFDImageJInfo
=
0xc697
;
// ImageJ info, starting with magic IJIJinfo,
byte
[]
ImageJInfoMagic
={
73
,
74
,
73
,
74
,
105
,
110
,
102
,
111
,
0
,
0
,
0
,
1
};
byte
[]
ImageJInfoMagic
={
73
,
74
,
73
,
74
,
105
,
110
,
102
,
111
,
0
,
0
,
0
,
1
};
int
pixelsDenominator
=
1000
;
String
description
=(
imp
.
getProperty
(
"description"
)!=
null
)?((
String
)
imp
.
getProperty
(
"description"
)):
"Elphel Eyesis4pi"
;
...
...
@@ -311,7 +525,7 @@ public class EyesisTiff {
ifd
.
put
(
new
Integer
(
IFD
.
IMAGE_WIDTH
),
imp
.
getWidth
());
ifd
.
put
(
new
Integer
(
IFD
.
IMAGE_LENGTH
),
imp
.
getHeight
());
ifd
.
put
(
new
Integer
(
IFD
.
SAMPLES_PER_PIXEL
),
4
);
ifd
.
putIFDValue
(
IFD
.
SOFTWARE
,
"Elphel Eyesis"
);
ifd
.
putIFDValue
(
IFD
.
SOFTWARE
,
"Elphel Eyesis"
);
ifd
.
putIFDValue
(
IFD
.
IMAGE_DESCRIPTION
,
description
);
// copy some other data?
ifd
.
putIFDValue
(
IFD
.
COMPRESSION
,
1
);
//TiffCompression.UNCOMPRESSED);
...
...
@@ -334,7 +548,7 @@ public class EyesisTiff {
if
(
imp
.
getProperty
(
"ImageFullLength"
)!=
null
){
ifd
.
putIFDValue
(
IFDImageFullLength
,
(
long
)
Integer
.
parseInt
((
String
)
imp
.
getProperty
(
"ImageFullLength"
)));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if
(
imageJTags
&&
(
imp
.
getProperty
(
"Info"
)!=
null
)
&&
(
imp
.
getProperty
(
"Info"
)
instanceof
String
)){
int
skipFirstBytes
=
2
;
String
info
=(
String
)
imp
.
getProperty
(
"Info"
);
...
...
@@ -343,7 +557,7 @@ public class EyesisTiff {
int
index
=
0
;
for
(
int
i
=
0
;
i
<
ImageJInfoMagic
.
length
;
i
++)
bInfo
[
index
++]=
ImageJInfoMagic
[
i
];
for
(
int
i
=
skipFirstBytes
;
i
<
bInfoBody
.
length
;
i
++)
bInfo
[
index
++]=
bInfoBody
[
i
];
// first 2 bytes {-2, -1} ???
/*
/*
StringBuffer sb=new StringBuffer("bInfo: ");
for (int i=0;i<bInfo.length;i++) sb.append(bInfo[i]+" ");
System.out.println(sb.toString());
...
...
@@ -366,7 +580,7 @@ public class EyesisTiff {
TiffSaver
tiffSaver
=
new
TiffSaver
(
path
);
tiffSaver
.
setWritingSequentially
(
true
);
tiffSaver
.
setLittleEndian
(
false
);
tiffSaver
.
writeHeader
();
tiffSaver
.
writeHeader
();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
System
.
out
.
println
(
"bytes.length="
+
bytes
.
length
);
tiffSaver
.
writeImage
(
bytes
,
...
...
src/main/java/JP46_Reader_camera.java
View file @
fb75351e
...
...
@@ -39,9 +39,12 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.io.RandomAccessFile
;
import
java.io.StringReader
;
import
java.io.UnsupportedEncodingException
;
import
java.lang.reflect.Array
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.Properties
;
import
java.util.Set
;
...
...
@@ -66,10 +69,15 @@ import ij.gui.GUI;
import
ij.gui.GenericDialog
;
import
ij.io.FileInfo
;
import
ij.io.OpenDialog
;
import
ij.io.Opener
;
import
ij.plugin.frame.PlugInFrame
;
import
ij.process.ImageConverter
;
import
ij.process.ImageProcessor
;
import
ij.text.TextWindow
;
import
loci.common.RandomAccessInputStream
;
import
loci.formats.tiff.IFD
;
import
loci.formats.tiff.IFDList
;
import
loci.formats.tiff.TiffParser
;
...
...
@@ -1035,12 +1043,18 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
/* Modified from Opener.java */
ImagePlus
openJpegOrGif
(
String
dir
,
String
name
)
{
ImagePlus
imp
=
null
;
boolean
isTiff
=
false
;
Image
img
=
Toolkit
.
getDefaultToolkit
().
createImage
(
dir
+
name
);
if
(
img
!=
null
)
{
try
{
imp
=
new
ImagePlus
(
name
,
img
);
}
catch
(
IllegalStateException
e
)
{
return
null
;
// error loading image
//java.lang.IllegalStateException: Error loading image
// Try TIFF
Opener
opener
=
new
Opener
();
// Reads Tiff images
imp
=
opener
.
openImage
(
""
,
dir
+
name
);
if
(
imp
==
null
)
return
null
;
// error loading image
isTiff
=
true
;
}
if
(
imp
.
getType
()==
ImagePlus
.
COLOR_RGB
)
{
...
...
@@ -1049,15 +1063,100 @@ public class JP46_Reader_camera extends PlugInFrame implements ActionListener {
IJ
.
showStatus
(
"Converting to 32-bits"
);
new
ImageConverter
(
imp
).
convertToGray32
();
FileInfo
fi
=
new
FileInfo
();
fi
.
fileFormat
=
FileInfo
.
GIF_OR_JPG
;
FileInfo
fi
=
imp
.
getFileInfo
();
fi
.
fileName
=
name
;
fi
.
directory
=
dir
;
fi
.
fileFormat
=
isTiff
?
FileInfo
.
TIFF
:
FileInfo
.
GIF_OR_JPG
;
// even if set originally, it is lost after convertToGray32
imp
.
setFileInfo
(
fi
);
FileInfo
ofi
=
imp
.
getOriginalFileInfo
();
fi
=
imp
.
getFileInfo
();
// testing
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
);
if
(
imptiff
!=
null
)
{
imptiff
.
show
();
}
// IJ.error("TIFF Dumper", "File path not available or not TIFF file");
IJ
.
log
(
"\\Clear"
);
IJ
.
log
(
"PATH = "
+
path
);
try
{
dumpIFDs
(
path
);
}
catch
(
IOException
e
)
{
IJ
.
error
(
"Tiff Dumper"
,
""
+
e
);
}
Frame
log
=
WindowManager
.
getFrame
(
"Log"
);
if
(
log
!=
null
)
log
.
toFront
();
}
}
return
imp
;
}
public
static
void
dumpIFDs
(
String
path
)
throws
IOException
{
IJ
.
showStatus
(
"Parsing IFDs"
);
RandomAccessInputStream
in
=
new
RandomAccessInputStream
(
path
);
//TiffParser parser = new TiffParser(in);
TiffParser
parser
=
new
TiffParser
(
in
);
IFDList
ifdList
=
parser
.
getIFDs
();
IJ
.
showStatus
(
""
);
for
(
IFD
ifd
:
ifdList
)
{
for
(
Integer
key
:
ifd
.
keySet
())
{
int
k
=
key
.
intValue
();
String
name
=
IFD
.
getIFDTagName
(
k
)+
String
.
format
(
"(%d [0x%x])"
,
k
,
k
);
String
value
=
prettyValue
(
ifd
.
getIFDValue
(
k
),
0
);
IJ
.
log
(
name
+
" = "
+
value
);
}
}
in
.
close
();
}
private
static
String
prettyValue
(
Object
value
,
int
indent
)
{
if
(!
value
.
getClass
().
isArray
())
return
value
.
toString
()+
" ("
+
value
.
getClass
().
toString
()+
")"
;
char
[]
spaceChars
=
new
char
[
indent
];
Arrays
.
fill
(
spaceChars
,
' '
);
String
spaces
=
new
String
(
spaceChars
);
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"{\n"
);
for
(
int
i
=
0
;
i
<
Array
.
getLength
(
value
);
i
++)
{
sb
.
append
(
spaces
);
sb
.
append
(
" "
);
Object
component
=
Array
.
get
(
value
,
i
);
sb
.
append
(
prettyValue
(
component
,
indent
+
2
));
sb
.
append
(
"\n"
);
}
sb
.
append
(
spaces
);
sb
.
append
(
"}"
);
byte
[]
bstring
=
new
byte
[
Array
.
getLength
(
value
)];
for
(
int
i
=
0
;
i
<
bstring
.
length
;
i
++)
{
try
{
bstring
[
i
]=
(
byte
)
Integer
.
parseInt
(
Array
.
get
(
value
,
i
).
toString
());
}
catch
(
NumberFormatException
e
)
{
bstring
[
i
]
=
0
;
}
}
// String astring=new String((byte []) value);
String
astring
=
""
;
try
{
astring
=
new
String
(
bstring
,
"UTF-16"
);
}
catch
(
UnsupportedEncodingException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
sb
.
append
(
"\n\""
+
astring
+
"\""
);
return
sb
.
toString
();
}
@Override
public
void
setTitle
(
String
title
)
{
imageTitle
=
title
;
...
...
src/main/java/LwirCamera.java
0 → 100644
View file @
fb75351e
/**
**
** LwirCamera.java - Control/image acquisition for LWIR cameras
** (initially for Lepton 3.5 sensors, 103992 sesnor boards)
**
** Copyright (C) 2019 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** LwirCamera.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
public
class
LwirCamera
{
}
src/main/java/com/elphel/imagej/readers/ElphelMeta.java
0 → 100644
View file @
fb75351e
/**
** -----------------------------------------------------------------------------**
** ElphelTiffReader.java
**
** Parse Elphel MakerNote and other Exif fields for both Tiff and JP4
**
** Copyright (C) 2019 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** ElphelTiffReader.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package
com
.
elphel
.
imagej
.
readers
;
import
java.io.IOException
;
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
);
}
}
// 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
)
{
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
;
gammas
[
i
]=((
maker_note
[
i
+
4
]>>
16
)&
0xff
)/
100.0
;
gamma_scales
[
i
]=
maker_note
[
i
+
4
]
&
0xffff
;
property_table
.
put
(
"gains_"
+
i
,
String
.
format
(
"%f"
,
gains
[
i
]));
property_table
.
put
(
"blacks_"
+
i
,
String
.
format
(
"%f"
,
blacks
[
i
]));
property_table
.
put
(
"gammas_"
+
i
,
String
.
format
(
"%f"
,
gammas
[
i
]));
property_table
.
put
(
"gamma_scales_"
+
i
,
String
.
format
(
"%d"
,
gamma_scales
[
i
]));
}
if
(
maker_note
.
length
>=
14
)
{
COMPOSITE
=
((
maker_note
[
10
]
&
0xc0000000
)!=
0
);
if
(
COMPOSITE
)
{
HEIGHT1
=
maker_note
[
11
]
&
0xffff
;
BLANK1
=
(
maker_note
[
11
]>>
16
)
&
0xffff
;
HEIGHT2
=
maker_note
[
12
]
&
0xffff
;
BLANK2
=
(
maker_note
[
12
]>>
16
)
&
0xffff
;
HEIGHT3
=(
maker_note
[
9
]>>
16
)
-
HEIGHT1
-
BLANK1
-
HEIGHT2
-
BLANK2
;
FLIPH1
=
(((
maker_note
[
10
]
>>
24
)
&
1
)!=
0
);
// Same value as FLIP_H
FLIPV1
=
(((
maker_note
[
10
]
>>
25
)
&
1
)!=
0
);
// Same value as FLIP_V
FLIPH2
=
(((
maker_note
[
10
]
>>
26
)
&
1
)!=
0
);
FLIPV2
=
(((
maker_note
[
10
]
>>
27
)
&
1
)!=
0
);
FLIPH3
=
(((
maker_note
[
10
]
>>
28
)
&
1
)!=
0
);
FLIPV3
=
(((
maker_note
[
10
]
>>
29
)
&
1
)!=
0
);
}
PORTRAIT
=
(((
maker_note
[
13
]
>>
7
)
&
1
)!=
0
);
YTABLEFORC
=(((
maker_note
[
13
]
>>
15
)
&
1
)!=
0
);
QUALITY
=
(
maker_note
[
13
]
&
0x7f
);
CQUALITY
=
((
maker_note
[
13
]>>
8
)
&
0x7f
);
if
(
CQUALITY
==
0
)
CQUALITY
=
QUALITY
;
CORING_INDEX_Y
=
((
maker_note
[
13
]>>
16
)
&
0x7f
);
CORING_INDEX_C
=
((
maker_note
[
13
]>>
24
)
&
0x7f
);
if
(
CORING_INDEX_C
==
0
)
CORING_INDEX_C
=
CORING_INDEX_Y
;
}
if
(
maker_note
.
length
>=
12
)
{
WOI_LEFT
=
maker_note
[
8
]&
0xffff
;
WOI_WIDTH
=
maker_note
[
8
]>>
16
;
WOI_TOP
=
maker_note
[
9
]&
0xffff
;
WOI_HEIGHT
=
maker_note
[
9
]>>
16
;
FLIPH
=
maker_note
[
10
]
&
1
;
FLIPV
=
(
maker_note
[
10
]>>
1
)
&
1
;
BAYER_MODE
=(
maker_note
[
10
]>>
2
)
&
3
;
COLOR_MODE
=(
maker_note
[
10
]>>
4
)
&
0x0f
;
DCM_HOR
=
(
maker_note
[
10
]>>
8
)
&
0x0f
;
DCM_VERT
=
(
maker_note
[
10
]>>
12
)
&
0x0f
;
BIN_HOR
=
(
maker_note
[
10
]>>
16
)
&
0x0f
;
BIN_VERT
=
(
maker_note
[
10
]>>
20
)
&
0x0f
;
property_table
.
put
(
"WOI_LEFT"
,
String
.
format
(
"%d"
,
WOI_LEFT
));
property_table
.
put
(
"WOI_WIDTH"
,
String
.
format
(
"%d"
,
WOI_WIDTH
));
property_table
.
put
(
"WOI_TOP"
,
String
.
format
(
"%d"
,
WOI_TOP
));
property_table
.
put
(
"WOI_HEIGHT"
,
String
.
format
(
"%d"
,
WOI_HEIGHT
));
property_table
.
put
(
"FLIPH"
,
String
.
format
(
"%d"
,
FLIPH
));
property_table
.
put
(
"FLIPV"
,
String
.
format
(
"%d"
,
FLIPV
));
property_table
.
put
(
"BAYER_MODE"
,
String
.
format
(
"%d"
,
BAYER_MODE
));
property_table
.
put
(
"COLOR_MODE"
,((
COLOR_MODE
==
2
)?
"JP46"
:((
COLOR_MODE
==
5
)?
"JP4"
:((
COLOR_MODE
==
0
)?
"MONO"
:
"OTHER"
))));
property_table
.
put
(
"DCM_HOR"
,
String
.
format
(
"%d"
,
DCM_HOR
));
property_table
.
put
(
"DCM_VERT"
,
String
.
format
(
"%d"
,
DCM_VERT
));
property_table
.
put
(
"BIN_HOR"
,
String
.
format
(
"%d"
,
BIN_HOR
));
property_table
.
put
(
"BIN_VERT"
,
String
.
format
(
"%d"
,
BIN_VERT
));
}
if
(
maker_note
.
length
>=
14
)
{
property_table
.
put
(
"COMPOSITE"
,
String
.
format
(
"%d"
,
COMPOSITE
?
1
:
0
));
property_table
.
put
(
"ORIENTATION"
,(
PORTRAIT
?
"PORTRAIT"
:
"LANDSCAPE"
));
property_table
.
put
(
"ORIENTATION"
,(
YTABLEFORC
?
"1"
:
"0"
));
property_table
.
put
(
"QUALITY"
,
String
.
format
(
"%d"
,
QUALITY
));
//not full
property_table
.
put
(
"CORING_INDEX_Y"
,
String
.
format
(
"%d"
,
CORING_INDEX_Y
));
property_table
.
put
(
"CORING_INDEX_C"
,
String
.
format
(
"%d"
,
CORING_INDEX_C
));
}
if
(
maker_note
.
length
>=
16
)
{
long
[]
iTemps
={
(
maker_note
[
14
]>>
0
)
&
0xffff
,
(
maker_note
[
14
]>>
16
)
&
0xffff
,
(
maker_note
[
15
]>>
0
)
&
0xffff
,
(
maker_note
[
15
]>>
16
)
&
0xffff
};
for
(
i
=
0
;
i
<
iTemps
.
length
;
i
++)
if
(
iTemps
[
i
]!=
0xffff
){
double
temperature
=(
iTemps
[
i
]&
0xfff
)/
16.0
;
property_table
.
put
(
"TEMPERATURE_"
+
i
,
""
+
temperature
);
}
}
if
(
COMPOSITE
)
{
property_table
.
put
(
"HEIGHT1"
,
String
.
format
(
"%d"
,
HEIGHT1
));
property_table
.
put
(
"HEIGHT2"
,
String
.
format
(
"%d"
,
HEIGHT2
));
property_table
.
put
(
"HEIGHT3"
,
String
.
format
(
"%d"
,
HEIGHT3
));
property_table
.
put
(
"BLANK_ROWS1"
,
String
.
format
(
"%d"
,
BLANK1
));
property_table
.
put
(
"BLANK_ROWS2"
,
String
.
format
(
"%d"
,
BLANK2
));
property_table
.
put
(
"FLIPH1"
,
FLIPH1
?
"1"
:
"0"
);
property_table
.
put
(
"FLIPH2"
,
FLIPH2
?
"1"
:
"0"
);
property_table
.
put
(
"FLIPH3"
,
FLIPH3
?
"1"
:
"0"
);
property_table
.
put
(
"FLIPV1"
,
FLIPV1
?
"1"
:
"0"
);
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
(
FLIPV
!=
0
)
{
swapArrayElements
(
gains
,
1
,
3
);
swapArrayElements
(
gains
,
0
,
2
);
swapArrayElements
(
blacks
,
1
,
3
);
swapArrayElements
(
blacks
,
0
,
2
);
swapArrayElements
(
gammas
,
1
,
3
);
swapArrayElements
(
gammas
,
0
,
2
);
swapArrayElements
(
gamma_scales
,
1
,
3
);
swapArrayElements
(
gamma_scales
,
0
,
2
);
}
if
(
FLIPH
!=
0
)
{
swapArrayElements
(
gains
,
1
,
0
);
swapArrayElements
(
gains
,
3
,
2
);
swapArrayElements
(
blacks
,
1
,
0
);
swapArrayElements
(
blacks
,
3
,
2
);
swapArrayElements
(
gammas
,
1
,
0
);
swapArrayElements
(
gammas
,
3
,
2
);
swapArrayElements
(
gamma_scales
,
1
,
0
);
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
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
]));
}
// 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
)
{
double
tmp
=
arr
[
i
];
arr
[
i
]=
arr
[
j
];
arr
[
j
]=
tmp
;
}
void
swapArrayElements
(
long
[]
arr
,
int
i
,
int
j
)
{
long
tmp
=
arr
[
i
];
arr
[
i
]=
arr
[
j
];
arr
[
j
]=
tmp
;
}
/* 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
)
{
int
i
;
double
x
,
black256
,
k
;
int
[]
gtable
=
new
int
[
257
];
double
[]
rgtable
=
new
double
[
256
];
int
ig
;
black256
=
black
*
256.0
;
k
=
1.0
/(
256.0
-
black256
);
if
(
gamma
<
0.13
)
gamma
=
0.13
;
if
(
gamma
>
10.0
)
gamma
=
10.0
;
for
(
i
=
0
;
i
<
257
;
i
++)
{
x
=
k
*(
i
-
black256
);
if
(
x
<
0.0
)
x
=
0.0
;
ig
=
(
int
)
(
0.5
+
65535.0
*
Math
.
pow
(
x
,
gamma
));
ig
=(
ig
*
(
int
)
gamma_scale
)/
0x400
;
if
(
ig
>
0xffff
)
ig
=
0xffff
;
gtable
[
i
]=
ig
;
}
/* now gtable[] is the same as was used in the camera */
/* FPGA was using linear interpolation between elements of the gamma table, so now we'll reverse that process */
// double[] rgtable =new double[256];
int
indx
=
0
;
double
outValue
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
outValue
=
128
+(
i
<<
8
);
while
((
gtable
[
indx
+
1
]<
outValue
)
&&
(
indx
<
256
))
indx
++;
if
(
indx
>=
256
)
rgtable
[
i
]=
65535.0
/
256
;
else
if
(
gtable
[
indx
+
1
]==
gtable
[
indx
])
rgtable
[
i
]=
i
;
else
rgtable
[
i
]=
indx
+(
1.0
*(
outValue
-
gtable
[
indx
]))/(
gtable
[
indx
+
1
]
-
gtable
[
indx
]);
}
return
rgtable
;
}
}
src/main/java/com/elphel/imagej/readers/ElphelTiffReader.java
0 → 100644
View file @
fb75351e
/**
** -----------------------------------------------------------------------------**
** ElphelTiffReader.java
**
** loci.format compatible reader for Elphel 8/16 bpp monochrome Tiff files with
** MakerNote
**
**
** Copyright (C) 2019 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** ElphelTiffReader.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package
com
.
elphel
.
imagej
.
readers
;
import
java.io.IOException
;
import
java.util.Hashtable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
loci.formats.FormatException
;
import
loci.formats.in.MetadataLevel
;
import
loci.formats.in.TiffReader
;
import
loci.formats.meta.MetadataStore
;
/*
// non-IFD tags (for internal use)
public static final int LITTLE_ENDIAN = 0;
public static final int BIG_TIFF = 1;
public static final int REUSE = 3;
<MakerNote tag="0x927c" format="LONG" count="16" seq="26" dlen="64"/> 37500
package loci.formats.tiff;
IFD.java public static final int MAKER_NOTE = 37500;
* IFD data
{ 0=false, LITTLE_ENDIAN
1=false, BIG_TIFF
0x0100 256=160, ImageWidth
0x0101 257=120, ImageLength
0x0102 258= 16, BitsPerSample
0x0106 262= 1, PhotometricInterpretation
0x0129 297= [I@3d136141, PageNumber
0x8769 34665=242, ExifTag (A pointer to the Exif IFD.)
0x010e 270=[Ljava.lang.String;@640a5e9d, ImageDescription
0x010f 271=Elphel, Make
0xc62f 50735=00:0E:64:10:8F:15, CameraSerialNumber
0x0110 272=LEPTON35_15, Model
0x0111 273=557, StripOffsets
0x0131 305=https://git.elphel.com/Elphel/elphel393, Software
0x9211 37393=122, ImageNumber
0x0112 274=1, Orientation
0x0132 306=2019:05:06 14:41:51, DateTime
0x0115 277=1, SamplesPerPixel
0x0116 278=120, RowsPerStrip
0x0117 279=38400, StripByteCounts
0x00fe 254=0 NewSubfileType }
*/
public
class
ElphelTiffReader
extends
TiffReader
{
// BaseTiffReader {
// -- Constants --
public
static
final
String
ELPHEL_PROPERTY_PREFIX
=
"ELPHEL_"
;
/** Merge SubIFDs into the main IFD list. */
// protected transient boolean mergeSubIFDs = true; // false;
/** Logger for this class. */
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
ElphelTiffReader
.
class
);
// public static final String[] ELPHEL_TIFF_SUFFIXES =
// {"tif", "tiff"}; // , "tf2", "tf8", "btf"};
// public static final String[] COMPANION_SUFFIXES = {"xml", "txt"};
// public static final int IMAGEJ_TAG = 50839;
// -- Fields --
// private String companionFile;
// private String description;
// private String calibrationUnit;
// private Double physicalSizeZ;
// private Double timeIncrement;
// private Integer xOrigin, yOrigin;
// -- Constructor --
/** Constructs a new Tiff reader. */
public
ElphelTiffReader
()
{
super
();
// "Tagged Image File Format", ELPHEL_TIFF_SUFFIXES); // See if we can use TiffReader without its parent
mergeSubIFDs
=
true
;
// false;
LOGGER
.
info
(
"ElphelTiffReader(), after supper(), mergeSubIFDs = true;"
);
}
// -- IFormatReader API methods --
@Override
protected
void
initFile
(
java
.
lang
.
String
id
)
throws
FormatException
,
java
.
io
.
IOException
{
LOGGER
.
info
(
"Starting initFile() method"
);
super
.
initFile
(
id
);
LOGGER
.
info
(
"Ending initFile() method"
);
}
/* @see loci.formats.IFormatReader#getSeriesUsedFiles(boolean) */
@Override
public
String
[]
getSeriesUsedFiles
(
boolean
noPixels
)
{
return
super
.
getSeriesUsedFiles
(
noPixels
);
// if (noPixels) {
// return companionFile == null ? null : new String[] {companionFile};
// }
// if (companionFile != null) return new String[] {companionFile, currentId};
// return new String[] {currentId};
}
/* @see loci.formats.IFormatReader#close(boolean) */
@Override
public
void
close
(
boolean
fileOnly
)
throws
IOException
{
LOGGER
.
info
(
"close("
+
fileOnly
+
") before super"
);
super
.
close
(
fileOnly
);
LOGGER
.
info
(
"close("
+
fileOnly
+
") after super"
);
if
(!
fileOnly
)
{
// companionFile = null;
// description = null;
// calibrationUnit = null;
// physicalSizeZ = null;
// timeIncrement = null;
// xOrigin = null;
// yOrigin = null;
}
}
// -- Internal BaseTiffReader API methods --
/* @see BaseTiffReader#initStandardMetadata() */
@Override
protected
void
initStandardMetadata
()
throws
FormatException
,
IOException
{
LOGGER
.
info
(
"initStandardMetadata() - before super()"
);
super
.
initStandardMetadata
();
String
comment
=
ifds
.
get
(
0
).
getComment
();
// IMAGE_DESCRIPTION
LOGGER
.
info
(
"initStandardMetadata() - after super()"
);
ElphelMeta
elphelMeta
=
new
ElphelMeta
(
tiffParser
,
true
);
Hashtable
<
String
,
String
>
property_table
=
elphelMeta
.
getPropertyTable
();
LOGGER
.
info
(
"Created elphelMeta table, size="
+
property_table
.
size
());
for
(
String
key:
property_table
.
keySet
())
{
addGlobalMeta
(
ELPHEL_PROPERTY_PREFIX
+
key
,
property_table
.
get
(
key
));
}
MetadataLevel
level
=
getMetadataOptions
().
getMetadataLevel
();
if
(
level
!=
MetadataLevel
.
MINIMUM
)
{
Integer
[]
tags
=
ifds
.
get
(
0
).
keySet
().
toArray
(
new
Integer
[
0
]);
LOGGER
.
info
(
"initStandardMetadata() - got "
+
tags
.
length
+
" tags"
);
}
// check for ImageJ-style TIFF comment
boolean
ij
=
checkCommentImageJ
(
comment
);
// if (ij) parseCommentImageJ(comment);
/*
// check for MetaMorph-style TIFF comment
boolean metamorph = checkCommentMetamorph(comment);
if (metamorph && level != MetadataLevel.MINIMUM) {
parseCommentMetamorph(comment);
}
put("MetaMorph", metamorph ? "yes" : "no");
// check for other INI-style comment
if (!ij && !metamorph && level != MetadataLevel.MINIMUM) {
parseCommentGeneric(comment);
}
*/
// check for another file with the same name
/*
if (isGroupFiles()) {
Location currentFile = new Location(currentId).getAbsoluteFile();
String currentName = currentFile.getName();
Location directory = currentFile.getParentFile();
String[] files = directory.list(true);
if (files != null) {
for (String file : files) {
String name = file;
if (name.indexOf(".") != -1) {
name = name.substring(0, name.indexOf("."));
}
if (currentName.startsWith(name) &&
checkSuffix(name, COMPANION_SUFFIXES))
{
companionFile = new Location(directory, file).getAbsolutePath();
break;
}
}
}
}
*/
}
/* @see BaseTiffReader#initMetadataStore() */
@Override
protected
void
initMetadataStore
()
throws
FormatException
{
super
.
initMetadataStore
();
MetadataStore
store
=
makeFilterMetadata
();
// if (description != null) {
// store.setImageDescription(description, 0);
// }
populateMetadataStoreImageJ
(
store
);
}
// -- Helper methods --
// Convert to Elphel-specific parameters
/**
* Checks the original metadata table for ImageJ-specific information
* to propagate into the metadata store.
*/
private
void
populateMetadataStoreImageJ
(
MetadataStore
store
)
{
// TODO: Perhaps we should only populate the physical Z size if the unit is
// a known, physical quantity such as "micron" rather than "pixel".
// e.g.: if (calibrationUnit.equals("micron"))
/*
if (physicalSizeZ != null) {
double zDepth = physicalSizeZ.doubleValue();
if (zDepth < 0) zDepth = -zDepth;
store.setPixelsPhysicalSizeZ(new PositiveFloat(zDepth), 0);
}
if (timeIncrement != null) {
store.setPixelsTimeIncrement(timeIncrement, 0);
}
*/
}
//
private
boolean
checkCommentImageJ
(
String
comment
)
{
return
comment
!=
null
&&
comment
.
startsWith
(
"ImageJ="
);
}
}
src/main/resources/readers.txt
0 → 100644
View file @
fb75351e
# This document is a configuration file identifying all file format readers
# available to Bio-Formats, and the order in which they should be used.
# Please do not edit unless you know what you are doing, see
# https://docs.openmicroscopy.org/latest/bio-formats/developers/reader-guide.html
# Could not find loci.formats.in.URLReader
# Could not find loci.formats.in.SlideBook6Reader
# "loci.formats.in.MicroCTReader" is not valid.
# Could not find loci.formats.in.CV7000Reader
# Could not find loci.formats.in.KLBReader
# java.lang.ClassNotFoundException: loci.formats.in.SlideBook6Reader
# at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_201]
#Elphel readers
com.elphel.imagej.readers.ElphelTiffReader # extensions same as TiffReader
loci.formats.in.FilePatternReader # pattern
##loci.formats.in.URLReader[type=external] # urlreader # Could not find loci.formats.in.URLReader
# readers for compressed/archive files
loci.formats.in.ZipReader # zip
# javax.imageio readers
loci.formats.in.APNGReader # png [javax.imageio]
loci.formats.in.JPEGReader # jpg, jpeg [javax.imageio]
# external readers with unique file extensions
##loci.formats.in.SlideBook6Reader[type=external] # sld # Could not find loci.formats.in.SlideBook6Reader
loci.formats.in.ScreenReader[type=external] # .screen
# standalone readers with unique file extensions
loci.formats.in.PGMReader # pgm
loci.formats.in.FitsReader # fits
loci.formats.in.PCXReader # pcx
loci.formats.in.GIFReader # gif
loci.formats.in.BMPReader # bmp
loci.formats.in.IPLabReader # ipl
loci.formats.in.IvisionReader # ipm
loci.formats.in.DeltavisionReader # dv, r3d
loci.formats.in.MRCReader # mrc, st, ali
loci.formats.in.GatanReader # dm3
loci.formats.in.GatanDM2Reader # dm2
loci.formats.in.ImarisReader # ims
loci.formats.in.OpenlabRawReader # raw
loci.formats.in.OMEXMLReader # ome
loci.formats.in.LIFReader # lif
loci.formats.in.AVIReader # avi
loci.formats.in.PictReader # pict, pct
loci.formats.in.SDTReader # sdt
loci.formats.in.SPCReader # spc
loci.formats.in.EPSReader # eps, epsi
loci.formats.in.SlidebookReader # sld
loci.formats.in.AliconaReader # al3d
loci.formats.in.MNGReader # mng
loci.formats.in.KhorosReader # xv
loci.formats.in.VisitechReader # html, xys
loci.formats.in.LIMReader # lim
loci.formats.in.PSDReader # psd
loci.formats.in.InCellReader # xdce
loci.formats.in.L2DReader # l2d
loci.formats.in.FEIReader # img
loci.formats.in.NAFReader # naf
loci.formats.in.MINCReader # mnc
loci.formats.in.QTReader # mov
loci.formats.in.MRWReader # mrw
loci.formats.in.TillVisionReader # vws
loci.formats.in.ARFReader # arf
loci.formats.in.CellomicsReader # c01
loci.formats.in.LiFlimReader # fli
loci.formats.in.TargaReader # tga
loci.formats.in.OxfordInstrumentsReader # top
loci.formats.in.VGSAMReader # dti
loci.formats.in.HISReader # his
loci.formats.in.WATOPReader # wat
loci.formats.in.SeikoReader # xqd, xqf
loci.formats.in.TopometrixReader # tfr, ffr, zfr, zfp, 2fl
loci.formats.in.UBMReader # pr3
loci.formats.in.QuesantReader # afm
loci.formats.in.BioRadGelReader # 1sc
loci.formats.in.RHKReader # sm2, sm3
loci.formats.in.MolecularImagingReader # stp
loci.formats.in.CellWorxReader # pnl, htd
loci.formats.in.Ecat7Reader # v
loci.formats.in.VarianFDFReader # fdf
loci.formats.in.AIMReader # aim
loci.formats.in.InCell3000Reader # frm
loci.formats.in.SpiderReader # spi
loci.formats.in.VolocityReader # mvd2
loci.formats.in.ImagicReader # hed
loci.formats.in.HamamatsuVMSReader # vms
loci.formats.in.CellSensReader # vsi
loci.formats.in.INRReader # inr
loci.formats.in.KodakReader # bip
loci.formats.in.VolocityClippingReader # acff
loci.formats.in.ZeissCZIReader # czi
loci.formats.in.SIFReader # sif
loci.formats.in.NDPISReader # ndpis
loci.formats.in.PovrayReader # df3
loci.formats.in.IMODReader # mod
loci.formats.in.FakeReader # fake
loci.formats.in.AFIReader # afi
loci.formats.in.ImspectorReader # msr
loci.formats.in.BioRadSCNReader # scn
loci.formats.in.ZeissLMSReader # lms
loci.formats.in.PQBinReader # bin
loci.formats.in.FlowSightReader # cif
loci.formats.in.IM3Reader # im3
loci.formats.in.I2IReader # i2i
loci.formats.in.SPEReader # spe
loci.formats.in.OIRReader # oir
##loci.formats.in.KLBReader # klb # Could not find loci.formats.in.KLBReader
##loci.formats.in.MicroCTReader # vff # "loci.formats.in.MicroCTReader" is not valid.
# multi-extension messes
loci.formats.in.JEOLReader # dat, img, par
loci.formats.in.NiftiReader # hdr, img, nii, nii.gz
loci.formats.in.AnalyzeReader # hdr, img
loci.formats.in.APLReader # apl, mtb, tnb
loci.formats.in.NRRDReader # nrrd, nhdr, pic
loci.formats.in.ICSReader # ics, ids
loci.formats.in.PerkinElmerReader # rec, ano, csv, htm, tim, zpo, 2, 3, ...
loci.formats.in.AmiraReader # am, amiramesh, grey, hx, labels, ...
loci.formats.in.ScanrReader # dat, xml, tif
loci.formats.in.BDReader # exp, tif
loci.formats.in.UnisokuReader # dat, hdr
loci.formats.in.PDSReader # hdr, img
loci.formats.in.FujiReader # inf, img
loci.formats.in.OperettaReader # xml, tif, tiff
loci.formats.in.InveonReader # hdr, ct.img, cat, ...
loci.formats.in.CellVoyagerReader # xml, tif
loci.formats.in.ColumbusReader # xml, tif
##loci.formats.in.CV7000Reader # wpi # Could not find loci.formats.in.CV7000Reader
# standard PIC reader must go last (it accepts any PIC)
loci.formats.in.BioRadReader # pic
# readers requiring third-party libraries
loci.formats.in.FV1000Reader # oib, oif, various [POI]
loci.formats.in.ZeissZVIReader # zvi [POI]
loci.formats.in.IPWReader # ipw [POI]
loci.formats.in.JPEG2000Reader # jp2, j2k [JAI-ImageIO]
loci.formats.in.JPXReader # jpx [JAI-ImageIO]
loci.formats.in.ND2Reader # nd2, jp2 [JAI-ImageIO]
loci.formats.in.PCIReader # cxd [POI]
loci.formats.in.ImarisHDFReader # ims [NetCDF]
loci.formats.in.CellH5Reader # ch5 [JHDF]
loci.formats.in.WlzReader # wlz [JWlz]
loci.formats.in.VeecoReader # hdf [NetCDF]
# TIFF-based readers with unique file extensions
loci.formats.in.ZeissLSMReader # lsm, mdb [MDB Tools]
loci.formats.in.SEQReader # seq
loci.formats.in.GelReader # gel
loci.formats.in.ImarisTiffReader # ims
loci.formats.in.FlexReader # flex [LuraWave]
loci.formats.in.SVSReader # svs
loci.formats.in.ImaconReader # fff
loci.formats.in.LEOReader # sxm
loci.formats.in.JPKReader # jpk
loci.formats.in.NDPIReader # ndpi
loci.formats.in.PCORAWReader # pcoraw
# TIFF-based readers with slow isThisType
loci.formats.in.OMETiffReader # tif
loci.formats.in.PyramidTiffReader # tif, tiff
loci.formats.in.MIASReader # tif
loci.formats.in.TCSReader # xml, tif
loci.formats.in.LeicaReader # lei, tif
loci.formats.in.NikonReader # nef, tif
loci.formats.in.FluoviewReader # tif
loci.formats.in.PrairieReader # xml, cfg, tif
loci.formats.in.MetamorphReader # stk, tif, nd, scan
loci.formats.in.MicromanagerReader # txt, tif
loci.formats.in.ImprovisionTiffReader # tif
loci.formats.in.MetamorphTiffReader # tif
loci.formats.in.NikonTiffReader # tif
loci.formats.in.PhotoshopTiffReader # tif
loci.formats.in.FEITiffReader # tif
loci.formats.in.SimplePCITiffReader # tif
loci.formats.in.NikonElementsTiffReader # tif
loci.formats.in.TrestleReader # tif
loci.formats.in.SISReader # tif
loci.formats.in.DNGReader # cr2, crw, jpg, thm, wav, tif?
loci.formats.in.ZeissTIFFReader # tif
loci.formats.in.LeicaSCNReader # scn
loci.formats.in.VectraReader # tif, tiff, qptiff
loci.formats.in.SlidebookTiffReader # tiff
loci.formats.in.IonpathMIBITiffReader # tif, tiff
# standard TIFF reader must go last (it accepts any TIFF)
loci.formats.in.TiffDelegateReader # tif, tiff
# standard text reader must go last (it accepts any plaintext)
loci.formats.in.TextReader # txt, csv
# non-TIFF readers with slow isThisType
loci.formats.in.BurleighReader # img
loci.formats.in.OpenlabReader # liff
loci.formats.in.DicomReader # dcm, dicom
loci.formats.in.SMCameraReader # (no extension)
loci.formats.in.SBIGReader # (no extension)
loci.formats.in.HRDGDFReader # (no extension)
loci.formats.in.HitachiReader # txt, tif, jpg, bmp
loci.formats.in.BrukerReader # fid, acqp
loci.formats.in.CanonRawReader # cr2, crw, jpg, thm, wav
loci.formats.in.OBFReader # obf, msr
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment