Skip to content
Snippets Groups Projects
Commit c38dc14e authored by theazgra's avatar theazgra
Browse files

Proof of concept simplest image extraction.

parent 48e66eb2
Branches
No related tags found
No related merge requests found
Showing with 62140 additions and 26 deletions
This diff is collapsed.
......@@ -15,6 +15,9 @@ if(Boost_FOUND)
target_link_libraries(czi-parser ${Boost_LIBRARIES})
endif()
find_package (Threads)
target_link_libraries (czi-parser ${CMAKE_THREAD_LIBS_INIT})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
......@@ -46,6 +46,12 @@ long BinaryStream::get_size() const
return this->fileSize;
}
long BinaryStream::get_position()
{
assert(this->isOpen);
return (long)(this->fileStream.tellg());
}
void BinaryStream::move_to(const long position)
{
assert(this->isOpen);
......
......@@ -25,6 +25,8 @@ public:
void close_stream();
// Get size of opened file.
long get_size() const;
// Get current position in stream.
long get_position();
// Advance file stream to requested position.
void move_to(const long position);
// Move file stream to beginning.
......
#include "czi_file.h"
#include <sstream>
#include "utilities/vector_utilities.h"
bool CziFile::is_master_file() const
{
......@@ -131,7 +129,7 @@ const char *dimension_type_str(const Dimension d)
}
}
void CziFile::report() const
void CziFile::report(bool verbose) const
{
printf("Loaded CZI FILE: %s\n", fileName.c_str());
......@@ -162,17 +160,33 @@ void CziFile::report() const
printf("%-25s %15s\n", "PyramidType", pyramid_type_str(subBlockDirectory.entries[entry].pyramidType));
printf("%-25s %15i\n", "DimensionCount", subBlockDirectory.entries[entry].dimensionCount);
for (size_t dim = 0; dim < subBlockDirectory.entries[entry].dimensionCount; dim++)
if (verbose)
{
printf("-------SubBlock %i dimension %i-------\n", (int)entry, (int)dim);
printf("%-25s %15s\n", "Dimension", dimension_type_str(subBlockDirectory.entries[entry].dimensions[dim].dimension));
printf("%-25s %15i\n", "Start", subBlockDirectory.entries[entry].dimensions[dim].start);
printf("%-25s %15i\n", "Size", subBlockDirectory.entries[entry].dimensions[dim].size);
printf("%-25s %15i\n", "StoredSize", subBlockDirectory.entries[entry].dimensions[dim].storedSize);
for (size_t dim = 0; dim < subBlockDirectory.entries[entry].dimensionCount; dim++)
{
printf("-------SubBlock %i dimension %i-------\n", (int)entry, (int)dim);
printf("%-25s %15s\n", "Dimension", dimension_type_str(subBlockDirectory.entries[entry].dimensions[dim].dimension));
printf("%-25s %15i\n", "Start", subBlockDirectory.entries[entry].dimensions[dim].start);
printf("%-25s %15i\n", "Size", subBlockDirectory.entries[entry].dimensions[dim].size);
printf("%-25s %15i\n", "StoredSize", subBlockDirectory.entries[entry].dimensions[dim].storedSize);
}
}
printf("-----------------------------------------\n");
}
printf("======================================\n");
}
void CziFile::extract_images(const std::string &baseName) const
{
BinaryStream cziStream(fileName);
int imageIndex = 0;
for (const DirectoryEntryDV &entry : subBlockDirectory.entries)
{
assert(entry.width > 0 && entry.height > 0);
auto imageBytes = cziStream.move_and_consume_bytes(entry.subBlock.dataLocation, entry.subBlock.dataSize);
std::string imageFileName = baseName + std::to_string(imageIndex++) + ".bpm";
create_image_file(imageFileName.c_str(), imageBytes, entry.pixelType, entry.width, entry.height);
}
}
#pragma once
#include "czi_parts/segments.h"
#include "utilities/vector_utilities.h"
#include "binary_stream.h"
#include "image_writer.h"
//TODO: Handle multi-file scenarios.
struct CziFile
{
// Path to loaded czi file.
std::string fileName;
FileHeaderSegment header;
MetadataSegment metadata;
SubBlockDirectory subBlockDirectory;
bool is_master_file() const;
void report() const;
void report(bool verbose) const;
void extract_images(const std::string &baseName) const;
};
#include "czi_file.cpp"
\ No newline at end of file
......@@ -115,6 +115,7 @@ SubBlockDirectory CziParser::parse_subblock_directory(BinaryStream &cziStream, c
DirectoryEntryDV CziParser::parse_subblock_directory_entry(BinaryStream &cziStream)
{
DirectoryEntryDV result = {};
result.schemaType = cziStream.consume_bytes(2);
assert(result.schemaType.size() == 2 && result.schemaType[0] == 'D' && result.schemaType[1] == 'V');
......@@ -134,7 +135,12 @@ DirectoryEntryDV CziParser::parse_subblock_directory_entry(BinaryStream &cziStre
for (size_t dim = 0; dim < result.dimensionCount; dim++)
{
result.dimensions.push_back(parse_dimension_entry(cziStream));
auto dimEntry = parse_dimension_entry(cziStream);
result.dimensions.push_back(dimEntry);
if (dimEntry.dimension == Dimension::X)
result.width = dimEntry.size;
if (dimEntry.dimension == Dimension::Y)
result.height = dimEntry.size;
}
result.entrySize = 32 + (result.dimensionCount * DimensionEntryDV1Size);
......@@ -177,13 +183,15 @@ SubBlockSegment CziParser::parse_subblock(BinaryStream &cziStream, const long po
int distance = entrySize + fillSize;
cziStream.move_by(distance);
auto metadataBytes = cziStream.consume_bytes(result.metadataSize);
// Metadata bytes
auto metadataBytes = cziStream.consume_bytes(result.metadataSize);
result.metadataString = utf8bytes_to_string(metadataBytes);
//printf("%s\n", result.metadataString.c_str());
// Data bytes
// For now we won't read image into memory, we will just save its location in file.
result.dataLocation = cziStream.get_position();
// Attachments bytes
return result;
......
......@@ -27,4 +27,8 @@ struct DirectoryEntryDV
SubBlockSegment subBlock;
// Size of this directory entry.
int entrySize;
// Width of an image.
int width = -1;
// height of an image.
int height = -1;
};
......@@ -13,4 +13,6 @@ struct SubBlockSegment
int directoryEntryIndex;
// XML metadata string.
std::string metadataString;
// Location of image data in CZI file.
long dataLocation;
};
#define cimg_display 0
#include "CImg.h"
#include "pixel_structures.h"
// struct RgbPixel
// {
// byte R;
// byte G;
// byte B;
// RgbPixel()
// {
// R = 0;
// G = 0;
// B = 0;
// }
// RgbPixel(byte r, byte g, byte b)
// {
// R = r;
// G = g;
// B = b;
// }
// RgbPixel(byte value)
// {
// R = value;
// G = value;
// B = value;
// }
// };
inline void set_pixel(cimg_library::CImg<byte> &img, const uint &row, const uint &col, const Bgr24Pixel &bgr)
{
img(col, row, 0) = bgr.r;
img(col, row, 1) = bgr.g;
img(col, row, 2) = bgr.b;
}
inline void set_pixel(cimg_library::CImg<byte> &img, const uint &row, const uint &col, const byte &px)
{
img(col, row, 0) = px;
}
inline Bgr24Pixel get_pixel(cimg_library::CImg<byte> &img, const uint &row, const uint &col)
{
Bgr24Pixel rgb;
rgb.r = img(col, row, 0);
rgb.g = img(col, row, 1);
rgb.b = img(col, row, 2);
return rgb;
}
cimg_library::CImg<byte> create_grayscale_image(const uint width, const uint height)
{
cimg_library::CImg<byte> image(width, height, 1, 1);
image.fill(0);
return image;
}
cimg_library::CImg<byte> create_color_image(const uint width, const uint height)
{
cimg_library::CImg<byte> image(width, height, 1, 3);
image.fill(0);
return image;
}
\ No newline at end of file
#pragma once
#include <fstream>
#include "czi_parts/pixel_type.h"
#include "pixel_structures.h"
#include "image.cpp"
void create_image_file(const char *fileName, const std::vector<byte> &bytes, const PixelType pixelType, const int width, const int height)
{
cimg_library::CImg<byte> img = create_color_image((uint)width, (uint)height);
// Hard-Coded for uncompressed Bgr24 pixel.
size_t current = 0;
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
Bgr24Pixel px = {};
px.b = bytes[current++];
px.g = bytes[current++];
px.r = bytes[current++];
set_pixel(img, row, col, px);
}
}
//set_pixel()
img.save_bmp(fileName);
}
\ No newline at end of file
#include "czi_parser.h"
#include "pixel_structures.h"
int main(int argc, char **argv)
{
std::string cziFile;
......@@ -8,6 +8,8 @@ int main(int argc, char **argv)
CziParser parser;
auto parseResult = parser.parse_czi_file(cziFile);
parseResult.report();
parseResult.extract_images("extracted");
parseResult.report(false);
return 0;
}
}
\ No newline at end of file
#pragma once
#include "custom_types.h"
typedef byte Gray8Pixel;
typedef short Gray16Pixel;
typedef float Gray32FloatPixel;
// struct BasePixel
// {
// virtual const char *data() = 0;
// virtual const int data_size() = 0;
// };
template <typename PixelValueType>
struct BasePixel
struct Gray8Pixel
{
virtual std::vector<PixelValueType> get_value() = 0;
byte value;
};
struct Bgr24Pixel // : BasePixel<byte>
struct Gray16Pixel
{
short value;
};
struct Gray32FloatPixel
{
float value;
};
struct Bgr24Pixel
{
byte b;
byte g;
......@@ -58,5 +69,12 @@ struct Bgr192ComplexFloatPixel
float rRealPart;
};
typedef long Gray32Pixel;
typedef double Gray64Pixel;
\ No newline at end of file
struct Gray32Pixel
{
long value;
};
struct Gray64Pixel
{
double value;
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment