Skip to content
Snippets Groups Projects
czi_file.cpp 7.61 KiB
Newer Older
  • Learn to ignore specific revisions
  • theazgra's avatar
    theazgra committed
    #include "czi_file.h"
    
    
    bool CziFile::is_master_file() const
    
    theazgra's avatar
    theazgra committed
    {
    
        return ((header.filePart == 0) && (header.fileGuid == header.masterFileGuid));
    
    theazgra's avatar
    theazgra committed
    }
    
    
    void print_segment_header(const SegmentHeader &segmentHeader)
    {
        printf("---------SegmentHeader---------\n");
        printf("%-25s %15s\n", "SID", segmentHeader.sId.c_str());
        printf("%-25s %15li\n", "AllocatedSize", segmentHeader.allocatedSize);
        printf("%-25s %15li\n", "UsedSize", segmentHeader.usedSize);
        printf("-------------------------------\n");
    }
    
    
    const char *pixel_type_str(const PixelType px)
    {
    
        switch (px)
        {
        case PixelType::Gray8:
            return "Gray8";
        case PixelType::Gray16:
            return "Gray16";
        case PixelType::Gray32Float:
            return "Gray32Float";
        case PixelType::Bgr24:
            return "Bgr24";
        case PixelType::Bgr48:
            return "Bgr48";
        case PixelType::Bgr96Float:
            return "Bgr96Float";
        case PixelType::Bgra32:
            return "Bgra32";
        case PixelType::Gray64ComplexFloat:
            return "Gray64ComplexFloat";
        case PixelType::Bgr192ComplexFloat:
            return "Bgr192ComplexFloat";
        case PixelType::Gray32:
            return "Gray32";
        case PixelType::Gray64:
            return "Gray64";
        default:
            assert("Bad pixel type." && false);
            break;
        }
    }
    
    const char *pyramid_type_str(const PyramidType pt)
    {
        switch (pt)
        {
        case PyramidType::None:
            return "None";
        case PyramidType::SingleSubBlock:
            return "SingleSubBlock";
        case PyramidType::MultiSubBlock:
            return "MultiSubBlock";
            break;
        default:
        {
            assert("Bad pyramid type." && false);
            break;
        }
        }
    }
    
    const char *compression_type_str(const CompressionType ct)
    {
        switch (ct)
        {
        case CompressionType::Uncompressed:
            return "Uncompressed";
        case CompressionType::LZW:
            return "LZW";
        case CompressionType::JpgFile:
            return "JpgFile";
        case CompressionType::JpegXrFile:
            return "JpegXrFile";
        case CompressionType::Camera:
            return "Camera";
        case CompressionType::System:
            return "System";
            break;
        default:
        {
            assert("Bad compression type." && false);
            break;
        }
        }
    }
    
    const char *dimension_type_str(const Dimension d)
    {
        switch (d)
        {
        case Dimension::X:
    
        case Dimension::Y:
    
        case Dimension::C:
    
            return "C (channels)";
    
        case Dimension::Z:
    
            return "Z (Z-slices)";
    
        case Dimension::T:
    
            return "T (timestamps)";
    
        case Dimension::R:
    
            return "R (rotation)";
    
        case Dimension::S:
    
        case Dimension::I:
    
            return "I (illumination)";
    
        case Dimension::B:
    
            return "B (block index)";
    
        case Dimension::M:
    
        case Dimension::H:
    
        case Dimension::V:
    
    
            break;
        default:
        {
            assert("Bad dimension type." && false);
            break;
        }
        }
    }
    
    theazgra's avatar
    theazgra committed
    void CziFile::report_verbose() const
    
    theazgra's avatar
    theazgra committed
    {
    
    theazgra's avatar
    theazgra committed
        report();
    
    
        printf("==========SubBlock directory==========\n");
        print_segment_header(subBlockDirectory.header);
        printf("%-25s %15i\n", "EntryCount", subBlockDirectory.entryCount);
    
        for (size_t entry = 0; entry < subBlockDirectory.entryCount; entry++)
        {
            printf("-------SubBlock directory entry %i-------\n", (int)entry);
            printf("%-25s %15s\n", "PixelType", pixel_type_str(subBlockDirectory.entries[entry].pixelType));
            printf("%-25s %15li\n", "FilePosition", subBlockDirectory.entries[entry].filePosition);
            printf("%-25s %15i\n", "FilePart", subBlockDirectory.entries[entry].filePart);
            printf("%-25s %15s\n", "Compression", compression_type_str(subBlockDirectory.entries[entry].compression));
            printf("%-25s %15s\n", "PyramidType", pyramid_type_str(subBlockDirectory.entries[entry].pyramidType));
            printf("%-25s %15i\n", "DimensionCount", subBlockDirectory.entries[entry].dimensionCount);
    
    
    theazgra's avatar
    theazgra committed
            for (size_t dim = 0; dim < subBlockDirectory.entries[entry].dimensionCount; dim++)
    
    theazgra's avatar
    theazgra committed
                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");
    
    std::string byte_array_str(const std::vector<byte> &bytes)
    {
        std::string result = "";
    
        for (size_t i = 0; i < bytes.size(); i++)
        {
            result.append(std::to_string(bytes[i]));
            if (i % 4 == 0 && i != bytes.size() - 1)
                result.append("-");
        }
        return result;
    }
    
    
    theazgra's avatar
    theazgra committed
    void CziFile::report() const
    
    {
        printf("Loaded CZI FILE: %s\n", fileName.c_str());
    
    
    theazgra's avatar
    theazgra committed
        printf("==========Summary report==========\n");
    
        print_segment_header(header.header);
        printf("%-25s %13i.%i\n", "FileVersion", header.fileVersion.major, header.fileVersion.minor);
    
        printf("%-25s %15i\n", "FilePart", header.filePart);
    
        printf("%-25s %30s\n", "MasterGUID", byte_array_str(header.masterFileGuid).c_str());
        printf("%-25s %30s\n", "FileGUID", byte_array_str(header.masterFileGuid).c_str());
    
        //TODO: Replace with GUID print.
        printf("%-25s %15i\n", "GUIDs are matching", are_same_vectors(header.masterFileGuid, header.fileGuid));
        printf("%-25s %15i\n", "UpdatePending", header.updatePending);
        printf("%-25s %15li\n", "SubblockDirPosition", header.subBlockDirectoryPosition);
        printf("%-25s %15li\n", "MetadataPosition", header.metadataPosition);
        printf("%-25s %15li\n", "AttachmentDirPosition", header.attachmentDirectoryPosition);
        printf("%-25s %15i\n", "SubBlockCount", subBlockDirectory.entryCount);
    
    theazgra's avatar
    theazgra committed
    
        if (subBlockDirectory.entryCount > 0)
            printf("%-25s %15i\n", "DimensionCount", subBlockDirectory.entries[0].dimensionCount);
    
        printf("%-25s %15i\n", "AttachmentCount", attachmentDirectory.entryCount);
    
        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);
        }
    }
    
    
    void CziFile::dump_image_data(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 binaryFileName = baseName + std::to_string(imageIndex++) + ".bin";
    
            std::ofstream binaryStream(binaryFileName, std::ios::binary | std::ios::out);
            assert(binaryStream.is_open());
            binaryStream.write(reinterpret_cast<const char *>(imageBytes.data()), imageBytes.size());
            printf("Wrote %s\n", binaryFileName.c_str());
        }
    }