1 // Copyright 2008 Dolphin Emulator Project 2 // Licensed under GPLv2+ 3 // Refer to the license.txt file included. 4 5 // WARNING Code not big-endian safe. 6 7 // To create new compressed BLOBs, use CompressFileToBlob. 8 9 // File format 10 // * Header 11 // * [Block Pointers interleaved with block hashes (hash of decompressed data)] 12 // * [Data] 13 14 #pragma once 15 16 #include <memory> 17 #include <string> 18 #include <vector> 19 20 #include "Common/CommonTypes.h" 21 #include "Common/File.h" 22 #include "DiscIO/Blob.h" 23 24 namespace DiscIO 25 { 26 static constexpr u32 GCZ_MAGIC = 0xB10BC001; 27 28 // GCZ file structure: 29 // BlobHeader 30 // u64 offsetsToBlocks[n], top bit specifies whether the block is compressed, or not. 31 // compressed data 32 33 // Blocks that won't compress to less than 97% of the original size are stored as-is. 34 struct CompressedBlobHeader // 32 bytes 35 { 36 u32 magic_cookie; // 0xB10BB10B 37 u32 sub_type; // GC image, whatever 38 u64 compressed_data_size; 39 u64 data_size; 40 u32 block_size; 41 u32 num_blocks; 42 }; 43 44 class CompressedBlobReader : public SectorReader 45 { 46 public: 47 static std::unique_ptr<CompressedBlobReader> Create(File::IOFile file, 48 const std::string& filename); 49 ~CompressedBlobReader(); 50 GetHeader()51 const CompressedBlobHeader& GetHeader() const { return m_header; } 52 GetBlobType()53 BlobType GetBlobType() const override { return BlobType::GCZ; } 54 GetRawSize()55 u64 GetRawSize() const override { return m_file_size; } GetDataSize()56 u64 GetDataSize() const override { return m_header.data_size; } IsDataSizeAccurate()57 bool IsDataSizeAccurate() const override { return true; } 58 GetBlockSize()59 u64 GetBlockSize() const override { return m_header.block_size; } HasFastRandomAccessInBlock()60 bool HasFastRandomAccessInBlock() const override { return false; } GetCompressionMethod()61 std::string GetCompressionMethod() const override { return "Deflate"; } 62 63 u64 GetBlockCompressedSize(u64 block_num) const; 64 bool GetBlock(u64 block_num, u8* out_ptr) override; 65 66 private: 67 CompressedBlobReader(File::IOFile file, const std::string& filename); 68 69 CompressedBlobHeader m_header; 70 std::vector<u64> m_block_pointers; 71 std::vector<u32> m_hashes; 72 int m_data_offset; 73 File::IOFile m_file; 74 u64 m_file_size; 75 std::vector<u8> m_zlib_buffer; 76 std::string m_file_name; 77 }; 78 79 } // namespace DiscIO 80