Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
QcmpCompressionLibrary
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
BioinformaticDataCompression
QcmpCompressionLibrary
Commits
9a659ccb
Commit
9a659ccb
authored
4 years ago
by
Vojtech Moravec
Browse files
Options
Downloads
Patches
Plain Diff
Basic preparation for second version of QCMP file header.
parent
7a06c09a
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/main/java/cz/it4i/qcmp/fileformat/QCMPFileHeaderV1.java
+13
-25
13 additions, 25 deletions
src/main/java/cz/it4i/qcmp/fileformat/QCMPFileHeaderV1.java
src/main/java/cz/it4i/qcmp/fileformat/QCMPFileHeaderV2.java
+196
-0
196 additions, 0 deletions
src/main/java/cz/it4i/qcmp/fileformat/QCMPFileHeaderV2.java
with
209 additions
and
25 deletions
src/main/java/cz/it4i/qcmp/fileformat/QCMPFileHeaderV1.java
+
13
−
25
View file @
9a659ccb
...
...
@@ -44,7 +44,7 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
*/
@Override
public
boolean
validateHeader
()
{
if
(!
magicValue
.
equals
(
MAGIC_VALUE
))
if
(!
magicValue
.
equals
(
getMagicValue
()
))
return
false
;
if
(
bitsPerCodebookIndex
==
0
)
...
...
@@ -139,26 +139,10 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
builder
.
append
(
"Header is:\t\t invalid\n"
);
return
;
}
builder
.
append
(
"HeaderVersion\t\t: "
).
append
(
VERSION
).
append
(
'\n'
);
builder
.
append
(
"Magic value\t\t: "
).
append
(
magicValue
).
append
(
'\n'
);
builder
.
append
(
"Quantization type\t: "
);
switch
(
quantizationType
)
{
case
Scalar:
builder
.
append
(
"Scalar\n"
);
break
;
case
Vector1D:
builder
.
append
(
"Vector1D\n"
);
break
;
case
Vector2D:
builder
.
append
(
"Vector2D\n"
);
break
;
case
Vector3D:
builder
.
append
(
"Vector3D\n"
);
break
;
case
Invalid:
builder
.
append
(
"INVALID\n"
);
break
;
}
builder
.
append
(
"HeaderVersion\t\t: "
).
append
(
getHeaderVersion
()).
append
(
'\n'
);
builder
.
append
(
"Magic value\t\t: "
).
append
(
getMagicValue
()).
append
(
'\n'
);
builder
.
append
(
"Quantization type\t: "
).
append
(
quantizationType
).
append
(
'\n'
);
builder
.
append
(
"Bits per pixel\t\t: "
).
append
(
bitsPerCodebookIndex
).
append
(
'\n'
);
builder
.
append
(
"Codebook\t\t: "
).
append
(
codebookPerPlane
?
"one per plane\n"
:
"one for all\n"
);
...
...
@@ -176,6 +160,10 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
.
append
(
vectorSizeY
).
append
(
'x'
)
.
append
(
vectorSizeZ
).
append
(
'\n'
);
printFileSizeInfo
(
builder
,
inputFile
);
}
protected
void
printFileSizeInfo
(
final
StringBuilder
builder
,
final
String
inputFile
)
{
final
long
headerSize
=
getHeaderSize
();
final
long
fileSize
=
new
File
(
inputFile
).
length
();
final
long
dataSize
=
fileSize
-
headerSize
;
...
...
@@ -190,7 +178,7 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
builder
.
append
(
"Data size\t\t: "
);
Utils
.
prettyPrintFileSize
(
builder
,
dataSize
).
append
(
correctFileSize
?
"(correct)\n"
:
"(INVALID)\n"
);
final
long
pixelCount
=
imageSizeX
*
imageSizeY
*
imageSizeZ
;
final
long
pixelCount
=
(
long
)
imageSizeX
*
imageSizeY
*
imageSizeZ
;
final
long
uncompressedSize
=
2
*
pixelCount
;
// We assert 16 bit (2 byte) pixel.
final
double
compressionRatio
=
(
double
)
fileSize
/
(
double
)
uncompressedSize
;
builder
.
append
(
String
.
format
(
"Compression ratio\t: %.4f\n"
,
compressionRatio
));
...
...
@@ -201,7 +189,7 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
builder
.
append
(
"\n=== Input file is "
).
append
(
correctFileSize
?
"VALID"
:
"INVALID"
).
append
(
" ===\n"
);
}
pr
ivate
long
calculateDataSizeForSq
()
{
pr
otected
long
calculateDataSizeForSq
()
{
final
int
LONG_BYTES
=
8
;
// Quantization value count.
final
int
codebookSize
=
(
int
)
Math
.
pow
(
2
,
bitsPerCodebookIndex
);
...
...
@@ -218,7 +206,7 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
return
(
codebookDataSize
+
totalPlaneDataSize
);
}
pr
ivate
long
calculateDataSizeForVq
()
{
pr
otected
long
calculateDataSizeForVq
()
{
final
int
LONG_BYTES
=
8
;
// Vector count in codebook
final
int
codebookSize
=
(
int
)
Math
.
pow
(
2
,
bitsPerCodebookIndex
);
...
...
@@ -252,7 +240,7 @@ public class QCMPFileHeaderV1 implements IFileHeader, Cloneable {
@Override
public
String
getMagicValue
()
{
return
magicValue
;
return
MAGIC_VALUE
;
}
//endregion
...
...
This diff is collapsed.
Click to expand it.
src/main/java/cz/it4i/qcmp/fileformat/QCMPFileHeaderV2.java
0 → 100644
+
196
−
0
View file @
9a659ccb
package
cz.it4i.qcmp.fileformat
;
import
cz.it4i.qcmp.U16
;
import
cz.it4i.qcmp.compression.VQImageCompressor
;
import
java.io.DataInputStream
;
import
java.io.DataOutputStream
;
import
java.io.IOException
;
public
class
QCMPFileHeaderV2
extends
QCMPFileHeaderV1
{
//region Constants
private
static
final
int
VERSION
=
2
;
private
static
final
int
BASE_QCMP_HEADER_SIZE
=
50
;
public
static
final
String
MAGIC_VALUE
=
"QCMPFLV2"
;
//endregion
//region Header fields
private
int
channelCount
;
private
int
timepointCount
;
private
int
metadataSize
;
private
byte
[]
metadata
;
//endregion
//region IFileHeader implementation
/**
* Validate that all header values are in their valid range.
*
* @return True if this is valid QCMPFILE header.
*/
@Override
public
boolean
validateHeader
()
{
if
(!
super
.
validateHeader
())
return
false
;
if
(!
U16
.
isInRange
(
channelCount
))
return
false
;
if
(!
U16
.
isInRange
(
timepointCount
))
return
false
;
return
metadataSize
>=
0
;
}
@Override
public
void
writeToStream
(
final
DataOutputStream
outputStream
)
throws
IOException
{
// TODO
}
@Override
public
void
readFromStream
(
final
DataInputStream
inputStream
)
throws
IOException
{
// TODO
}
@Override
public
int
getHeaderVersion
()
{
return
VERSION
;
}
@Override
public
void
report
(
final
StringBuilder
builder
,
final
String
inputFile
)
{
if
(!
validateHeader
())
{
builder
.
append
(
"Header is:\t\t invalid\n"
);
return
;
}
builder
.
append
(
"HeaderVersion\t\t: "
).
append
(
getHeaderVersion
()).
append
(
'\n'
);
builder
.
append
(
"Magic value\t\t: "
).
append
(
getMagicValue
()).
append
(
'\n'
);
builder
.
append
(
"Quantization type\t: "
).
append
(
quantizationType
).
append
(
'\n'
);
builder
.
append
(
"Bits per pixel\t\t: "
).
append
(
bitsPerCodebookIndex
).
append
(
'\n'
);
builder
.
append
(
"Codebook\t\t: "
).
append
(
codebookPerPlane
?
"one per plane\n"
:
"one for all\n"
);
final
int
codebookSize
=
(
int
)
Math
.
pow
(
2
,
bitsPerCodebookIndex
);
builder
.
append
(
"Codebook size\t\t: "
).
append
(
codebookSize
).
append
(
'\n'
);
builder
.
append
(
"Image stack size\t: "
)
.
append
(
imageSizeX
).
append
(
'x'
)
.
append
(
imageSizeY
).
append
(
'x'
)
.
append
(
imageSizeZ
).
append
(
'x'
)
.
append
(
channelCount
).
append
(
'x'
)
.
append
(
timepointCount
).
append
(
" [XxYxZxCxT]"
).
append
(
'\n'
);
builder
.
append
(
"Quantization vector\t: "
)
.
append
(
vectorSizeX
).
append
(
'x'
)
.
append
(
vectorSizeY
).
append
(
'x'
)
.
append
(
vectorSizeZ
).
append
(
'\n'
);
builder
.
append
(
"MetadataSize\t: "
).
append
(
metadataSize
).
append
(
'\n'
);
printFileSizeInfo
(
builder
,
inputFile
);
}
@Override
protected
long
calculateDataSizeForSq
()
{
// TODO(Moravec): Fix this calculation. Size of the huffman tree will be added to chunk size.
final
int
LONG_BYTES
=
8
;
// Quantization value count.
final
int
codebookSize
=
(
int
)
Math
.
pow
(
2
,
bitsPerCodebookIndex
);
// Total codebook size in bytes. Also symbol frequencies for Huffman.
final
long
codebookDataSize
=
((
2
*
codebookSize
)
+
(
LONG_BYTES
*
codebookSize
))
*
(
codebookPerPlane
?
imageSizeZ
:
1
);
// Indices are encoded using huffman. Plane data size is written in the header.
long
totalPlaneDataSize
=
0
;
for
(
final
long
planeDataSize
:
planeDataSizes
)
{
totalPlaneDataSize
+=
planeDataSize
;
}
return
(
codebookDataSize
+
totalPlaneDataSize
);
}
@Override
protected
long
calculateDataSizeForVq
()
{
// TODO(Moravec): Fix this calculation. Size of the huffman tree will be added to chunk size.
final
int
LONG_BYTES
=
8
;
// Vector count in codebook
final
int
codebookSize
=
(
int
)
Math
.
pow
(
2
,
bitsPerCodebookIndex
);
// Single vector size in bytes.
final
int
vectorDataSize
=
2
*
vectorSizeX
*
vectorSizeY
*
vectorSizeZ
;
// Total codebook size in bytes.
final
long
codebookDataSize
=
((
codebookSize
*
vectorDataSize
)
+
(
codebookSize
*
LONG_BYTES
))
*
(
codebookPerPlane
?
imageSizeZ
:
1
);
// Indices are encoded using huffman. Plane data size is written in the header.
long
totalPlaneDataSize
=
0
;
for
(
final
long
planeDataSize
:
planeDataSizes
)
{
totalPlaneDataSize
+=
planeDataSize
;
}
return
(
codebookDataSize
+
totalPlaneDataSize
);
}
@Override
public
String
getMagicValue
()
{
return
MAGIC_VALUE
;
}
//endregion
//region Cloneable implementation
@Override
protected
Object
clone
()
throws
CloneNotSupportedException
{
return
super
.
clone
();
}
public
QCMPFileHeaderV2
copyOf
()
{
try
{
return
(
QCMPFileHeaderV2
)
this
.
clone
();
}
catch
(
final
CloneNotSupportedException
e
)
{
return
null
;
}
}
//endregion
//region Getters and Setters
public
int
getChannelCount
()
{
return
channelCount
;
}
public
void
setChannelCount
(
final
int
channelCount
)
{
this
.
channelCount
=
channelCount
;
}
public
int
getTimepointCount
()
{
return
timepointCount
;
}
public
void
setTimepointCount
(
final
int
timepointCount
)
{
this
.
timepointCount
=
timepointCount
;
}
public
int
getMetadataSize
()
{
return
metadataSize
;
}
public
void
setMetadataSize
(
final
int
metadataSize
)
{
this
.
metadataSize
=
metadataSize
;
}
public
byte
[]
getMetadata
()
{
return
metadata
;
}
public
void
setMetadata
(
final
byte
[]
metadata
)
{
this
.
metadata
=
metadata
;
}
public
long
getHeaderSize
()
{
final
int
chunkCount
=
(
quantizationType
!=
QuantizationType
.
Vector3D
)
?
imageSizeZ
:
VQImageCompressor
.
calculateVoxelLayerCount
(
imageSizeZ
,
vectorSizeZ
);
return
BASE_QCMP_HEADER_SIZE
+
metadataSize
+
(
chunkCount
*
4L
);
}
//endregion
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment