Clean up some warnings.

This commit is contained in:
jmsgrogan 2023-01-16 11:56:46 +00:00
parent a19567508e
commit dba6a91ec1
25 changed files with 453 additions and 431 deletions

View file

@ -5,6 +5,8 @@ project(NotesTK)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
set_property( GLOBAL PROPERTY USE_FOLDERS ON)
set (CMAKE_MODULE_PATH infra/cmake)
@ -12,7 +14,9 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if(FALSE)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
elseif(FALSE)
set(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
set(GCC_COVERAGE_LINK_FLAGS "-lgcov")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")

View file

@ -28,11 +28,11 @@ AudioSamplePtr AudioSynth::getSineWave(double freq, unsigned duration) const
const double tick_duration = 1.0/sample_rate;
const double pi_2 = 2.0 * M_PI;
const short max_short = std::numeric_limits<short>::max();
constexpr short max_short = std::numeric_limits<short>::max();
for(unsigned idx=0; idx<num_samples; idx++)
{
const auto t = double(idx)*tick_duration;
data[idx] = max_short*std::sin(pi_2*freq*t);
data[idx] = max_short*static_cast<short>(std::sin(pi_2*freq*t));
}
sample->setChannelData(data, 0);
return sample;

View file

@ -32,13 +32,13 @@ bool AudioWriter::write(const AudioSamplePtr& sample)
auto handle = outfile.getOutHandle();
const auto sample_rate = sample->getSampleRate();
const auto num_channels = sample->getNumChannels();
const auto num_channels = static_cast<unsigned>(sample->getNumChannels());
const auto bytes_per_sample = sample->getBitDepth() / 8;
unsigned byte_rate = sample_rate*num_channels*bytes_per_sample;
handle->write("RIFF", 4);
auto data = sample->getChannelData(0);
const auto num_samples = data.size();
const auto num_samples = static_cast<unsigned>(data.size());
unsigned content_size = 36 + bytes_per_sample* num_samples*num_channels;
BinaryStream::write<int>(handle, content_size);
@ -56,7 +56,7 @@ bool AudioWriter::write(const AudioSamplePtr& sample)
/* write data subchunk */
handle->write("data", 4);
BinaryStream::write<int>(handle, bytes_per_sample* num_samples*num_channels); // bits/sample
BinaryStream::write<int>(handle, static_cast<int>(bytes_per_sample* num_samples*num_channels)); // bits/sample
handle->write(reinterpret_cast<const char*>(&data[0]), data.size()*sizeof(short));

View file

@ -25,15 +25,15 @@ void HuffmanCodeLengthTable::buildCompressedLengthSequence()
const auto count = entry.second;
if (count < 3)
{
for(unsigned idx=0; idx<count; idx++)
for(std::size_t idx=0; idx<count; idx++)
{
mCompressedLengthSequence.push_back({length, 0});
}
}
else if (length == 0)
{
unsigned num_big = count / 138;
for(unsigned idx=0; idx<num_big; idx++)
std::size_t num_big = count / 138;
for(std::size_t idx=0; idx<num_big; idx++)
{
mCompressedLengthSequence.push_back({18, 127});
}
@ -48,7 +48,7 @@ void HuffmanCodeLengthTable::buildCompressedLengthSequence()
}
else
{
for(unsigned idx=0; idx<remainder_big; idx++)
for(std::size_t idx=0; idx<remainder_big; idx++)
{
mCompressedLengthSequence.push_back({0, 0});
}
@ -58,7 +58,7 @@ void HuffmanCodeLengthTable::buildCompressedLengthSequence()
{
mCompressedLengthSequence.push_back({length, 0});
auto num_blocks_of_six = (count-1)/6;
for(unsigned idx=0; idx<num_blocks_of_six; idx++)
for(std::size_t idx=0; idx<num_blocks_of_six; idx++)
{
mCompressedLengthSequence.push_back({16, 3});
}
@ -69,7 +69,7 @@ void HuffmanCodeLengthTable::buildCompressedLengthSequence()
}
else
{
for(unsigned idx=0; idx<remaining_counts; idx++)
for(std::size_t idx=0; idx<remaining_counts; idx++)
{
mCompressedLengthSequence.push_back({length, 0});
}
@ -77,7 +77,7 @@ void HuffmanCodeLengthTable::buildCompressedLengthSequence()
}
}
mCompressedLengthCounts = std::vector<unsigned>(19, 0);
mCompressedLengthCounts = std::vector<std::size_t>(19, 0);
for (const auto& entry : mCompressedLengthSequence)
{
mCompressedLengthCounts[entry.first]++;
@ -89,7 +89,7 @@ const std::vector<HuffmanCodeLengthTable::CompressedSequenceEntry>& HuffmanCodeL
return mCompressedLengthSequence;
}
const std::vector<unsigned> HuffmanCodeLengthTable::getCompressedLengthCounts() const
const std::vector<std::size_t> HuffmanCodeLengthTable::getCompressedLengthCounts() const
{
return mCompressedLengthCounts;
}
@ -106,7 +106,7 @@ bool HuffmanCodeLengthTable::readNextSymbol(unsigned& result, BitStream* stream)
return false;
}
unsigned working_index{0};
std::size_t working_index{0};
auto length = getCodeLength(working_index);
auto delta = length;
@ -188,7 +188,7 @@ void HuffmanCodeLengthTable::buildPrefixCodes()
const auto code = next_code[length];
next_code[length]++;
auto prefix_code = PrefixCode(code, length);
mTree.addCodeLengthEntry(length, {PrefixCode(code, length), idx});
mTree.addCodeLengthEntry(length, {PrefixCode(code, length), static_cast<unsigned>(idx)});
mCodes.push_back(prefix_code);
}
}
@ -206,7 +206,7 @@ std::string HuffmanCodeLengthTable::dumpPrefixCodes() const
return mTree.dump();
}
unsigned HuffmanCodeLengthTable::mapToDeflateIndex(unsigned index) const
std::size_t HuffmanCodeLengthTable::mapToDeflateIndex(std::size_t index) const
{
if (index>= DEFLATE_PERMUTATION_SIZE)
{
@ -240,7 +240,7 @@ void HuffmanCodeLengthTable::setInputLengthSequence(const std::vector<unsigned c
if (targetDeflate)
{
mInputLengthSequence = std::vector<unsigned char>(DEFLATE_PERMUTATION_SIZE, 0);
for(unsigned idx=0; idx<sequence.size(); idx++)
for(std::size_t idx=0; idx<sequence.size(); idx++)
{
mInputLengthSequence[mapToDeflateIndex(idx)] = sequence[idx];
//std::cout << "Got code length for " << mapToDeflateIndex(idx) << " of " << static_cast<unsigned>(sequence[idx]) << std::endl;

View file

@ -28,13 +28,13 @@ public:
using CompressedSequenceEntry = std::pair<unsigned, unsigned>;
const std::vector<CompressedSequenceEntry>& getCompressedLengthSequence() const;
const std::vector<unsigned> getCompressedLengthCounts() const;
const std::vector<std::size_t> getCompressedLengthCounts() const;
std::size_t getNumCodeLengths() const;
unsigned getCodeLength(std::size_t treeIndex) const;
unsigned mapToDeflateIndex(unsigned index) const;
std::size_t mapToDeflateIndex(std::size_t index) const;
void setInputLengthSequence(const std::vector<unsigned char>& sequence, bool targetDeflate = true);
@ -49,7 +49,7 @@ private:
std::vector<PrefixCode> mCodes;
std::vector<CompressedSequenceEntry> mCompressedLengthSequence;
std::vector<unsigned> mCompressedLengthCounts;
std::vector<std::size_t> mCompressedLengthCounts;
static constexpr unsigned DEFLATE_PERMUTATION_SIZE{19};
static constexpr unsigned DEFLATE_PERMUTATION[DEFLATE_PERMUTATION_SIZE]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};

View file

@ -1,6 +1,6 @@
#include "Color.h"
Color::Color(unsigned r, unsigned g, unsigned b, double a)
Color::Color(unsigned char r, unsigned char g, unsigned char b, double a)
: mR(r),
mG(g),
mB(b),
@ -9,26 +9,7 @@ Color::Color(unsigned r, unsigned g, unsigned b, double a)
}
Color::Color(Name name)
{
if (name == Name::WHITE)
{
Color(255, 255, 255);
}
else
{
Color(255, 255, 255);
}
}
std::shared_ptr<Color> Color::CreateShared(unsigned r, unsigned g, unsigned b,
double a )
{
return std::make_shared<Color>(r, g, b, a);
}
std::unique_ptr<Color> Color::Create(unsigned r, unsigned g, unsigned b,
double a )
std::unique_ptr<Color> Color::Create(unsigned char r, unsigned char g, unsigned char b, double a )
{
return std::make_unique<Color>(r, g, b, a);
}
@ -38,17 +19,17 @@ std::unique_ptr<Color> Color::Create(const Color& color)
return std::make_unique<Color>(color);
}
unsigned Color::getR() const
unsigned char Color::getR() const
{
return mR;
}
unsigned Color::getG() const
unsigned char Color::getG() const
{
return mG;
}
unsigned Color::getB() const
unsigned char Color::getB() const
{
return mB;
}
@ -57,3 +38,13 @@ double Color::getAlpha() const
{
return mAlpha;
}
std::vector<double> Color::getAsVectorDouble() const
{
return { mR / 255.0, mG / 255.0, mB / 255.0, mAlpha };
}
uint32_t Color::getAsUInt32() const
{
return static_cast<uint32_t>(mB + (mG << 8) + (mR << 16));
}

View file

@ -2,30 +2,24 @@
#include <memory>
#include <vector>
#include <cstdint>
class Color
{
public:
Color(unsigned char r = 0, unsigned char g = 0, unsigned char b = 0, double a = 1.0);
enum class Name
{
WHITE
};
Color(unsigned r = 0, unsigned g = 0, unsigned b = 0, double a = 1.0);
Color(Name name);
static std::shared_ptr<Color> CreateShared(unsigned r, unsigned g, unsigned b, double a = 1.0);
static std::unique_ptr<Color> Create(unsigned r, unsigned g, unsigned b, double a = 1.0);
static std::unique_ptr<Color> Create(unsigned char r, unsigned char g, unsigned char b, double a = 1.0);
static std::unique_ptr<Color> Create(const Color& color);
unsigned getR() const;
unsigned getG() const;
unsigned getB() const;
unsigned char getR() const;
unsigned char getG() const;
unsigned char getB() const;
double getAlpha() const;
std::vector<double> getAsVectorDouble() const;
uint32_t getAsUInt32() const;
bool operator==(const Color& rhs) const
{
return (mR == rhs.mR)
@ -39,25 +33,10 @@ public:
return !operator==(rhs);
}
std::vector<double> getAsVectorDouble() const
{
return {mR/255.0, mG/255.0, mB/255.0, mAlpha};
}
uint32_t getAsUInt32() const
{
return mB + (mG<<8) + (mR<<16);
}
static Color White()
{
return { 255, 255, 255, 1 };
}
private:
unsigned mR{0};
unsigned mG{0};
unsigned mB{0};
unsigned char mR{0};
unsigned char mG{0};
unsigned char mB{0};
double mAlpha{0.0};
};

View file

@ -4,9 +4,11 @@ set(platform_LIB_INCLUDES)
list(APPEND image_HEADERS
Image.h
IImageWriter.h
PlatformImage.h
PlatformImageWriter.h
png/PngWriter.h
png/BasicPngWriter.h
png/PngReader.h
)
@ -14,6 +16,7 @@ list(APPEND image_LIB_INCLUDES
Image.cpp
ImageBitStream.cpp
PlatformImage.cpp
png/BasicPngWriter.cpp
png/PngWriter.cpp
png/PngReader.cpp
png/PngHeader.cpp

28
src/image/IImageWriter.h Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include <filesystem>
using Path = std::filesystem::path;
class Image;
class IImageWriter
{
public:
enum class ImgFormat
{
PNG,
UNKNOWN
};
IImageWriter(ImgFormat format)
: mFormat(format)
{
};
virtual void write(const Path& path, Image* image) = 0;
protected:
ImgFormat mFormat{ ImgFormat::UNKNOWN };
};

View file

@ -1,18 +1,13 @@
#pragma once
#include <filesystem>
#include "IImageWriter.h"
using Path = std::filesystem::path;
class Image;
class PlatformImageWriter
class PlatformImageWriter : public IImageWriter
{
public:
enum class ImgFormat
PlatformImageWriter(ImgFormat format)
: IImageWriter(format)
{
PNG
};
virtual void write(const Path& path, Image* image, ImgFormat format = ImgFormat::PNG) = 0;
}
};

View file

@ -0,0 +1,216 @@
#include "BasicPngWriter.h"
#include "Image.h"
#include "File.h"
#include "BufferBitStream.h"
#include "OutputBitStream.h"
#include "ImageBitStream.h"
#include "StringUtils.h"
#include "PngFilter.h"
#include "Lz77Encoder.h"
#include "ZlibEncoder.h"
#include "HuffmanEncoder.h"
#include "CyclicRedundancyChecker.h"
#include "ByteUtils.h"
#include <iostream>
BasicPngWriter::BasicPngWriter()
: IImageWriter(ImgFormat::PNG)
{
}
BasicPngWriter::~BasicPngWriter()
{
}
std::unique_ptr<BasicPngWriter> BasicPngWriter::Create()
{
return std::make_unique<BasicPngWriter>();
}
void BasicPngWriter::setCompressionMethod(Deflate::CompressionMethod method)
{
mCompressionMethod = method;
}
void BasicPngWriter::setPngInfo(const PngInfo& info)
{
mPngInfoUserSet = true;
mPngInfo = info;
}
void BasicPngWriter::writeSignature()
{
mOutStream->writeByte(mPngHeader.getHighBitCheck());
mOutStream->writeBytes(StringUtils::toBytes(mPngHeader.getFileName()));
mOutStream->writeBytes(mPngHeader.getSignature());
}
void BasicPngWriter::writeHeader()
{
writeSignature();
if (!mPngInfoUserSet)
{
if (mWorkingImage->getNumChannels() == 1)
{
mPngInfo.mColorType = PngInfo::ColorType::GREYSCALE;
}
else if (mWorkingImage->getNumChannels() == 2)
{
mPngInfo.mColorType = PngInfo::ColorType::GREYSCALE_ALPHA;
}
else if (mWorkingImage->getNumChannels() == 3)
{
mPngInfo.mColorType = PngInfo::ColorType::RGB;
}
else if (mWorkingImage->getNumChannels() == 4)
{
mPngInfo.mColorType = PngInfo::ColorType::RGB_ALPHA;
}
}
mPngHeader.setPngInfo(mPngInfo);
mPngHeader.setImageData(mWorkingImage->getWidth(), mWorkingImage->getHeight(), mWorkingImage->getBitDepth());
auto length = mPngHeader.getLength();
mOutStream->write(length);
mOutStream->writeBytes(StringUtils::toBytes(mPngHeader.getChunkName()));
mPngHeader.updateData();
mOutStream->writeBytes(mPngHeader.getData());
auto crc = mPngHeader.getCrc();
//std::cout << mPngHeader.toString() << "*********" << std::endl;
mOutStream->write(crc);
}
void BasicPngWriter::writeEndChunk()
{
//std::cout << "Start writing end chunk" << std::endl;
unsigned length{ 0 };
mOutStream->write(length);
mOutStream->writeBytes(StringUtils::toBytes("IEND"));
std::vector<unsigned char> char_data = StringUtils::toBytes("IEND");
CyclicRedundancyChecker crc_check;
for (auto c : char_data)
{
crc_check.addValue(c);
}
auto crc = crc_check.getChecksum();
mOutStream->write(crc);
//std::cout << "Writing end chunk" << std::endl;
}
void BasicPngWriter::writeDataChunks(const BufferBitStream& buffer)
{
auto num_bytes = buffer.getBuffer().size();
std::size_t max_bytes{ 32000 };
auto num_dat_chunks = num_bytes / max_bytes + 1;
std::size_t offset = 0;
for (std::size_t idx = 0; idx < num_dat_chunks; idx++)
{
auto length = max_bytes;
if (idx == num_dat_chunks - 1)
{
length = num_bytes - num_dat_chunks * num_bytes;
}
//std::cout << "Writing idat length " << num_bytes << std::endl;
mOutStream->write(static_cast<uint32_t>(num_bytes));
std::vector<unsigned char> char_data = StringUtils::toBytes("IDAT");
mOutStream->writeBytes(char_data);
CyclicRedundancyChecker crc_check;
for (auto c : char_data)
{
crc_check.addValue(c);
}
for (unsigned jdx = 0; jdx < num_bytes; jdx++)
{
auto val = buffer.getBuffer()[idx * max_bytes + jdx];
mOutStream->writeByte(val);
crc_check.addValue(val);
}
auto crc = crc_check.getChecksum();
//std::cout << "Writing idat crc" << crc << std::endl;
mOutStream->write(crc);
//std::cout << "Finished Writing idat crc" << crc << std::endl;
}
}
void BasicPngWriter::write(const Path& path, Image* image)
{
std::unique_ptr<File> out_file;
if (path.empty())
{
out_file = std::make_unique<File>(path);
out_file->open(File::AccessMode::Write);
mOutStream = std::make_unique<OutputBitStream>(out_file->getOutHandle());
}
else
{
mOutStream = std::make_unique<BufferBitStream>();
}
mWorkingImage = image;
auto image_bit_stream = std::make_unique<ImageBitStream>(image);
auto raw_image_stream = image_bit_stream.get();
mInStream = std::move(image_bit_stream);
writeHeader();
auto filter_out_stream = std::make_unique<BufferBitStream>();
PngFilter filter(raw_image_stream, filter_out_stream.get());
filter.encode();
filter_out_stream->resetOffsets();
std::unique_ptr<BufferBitStream> lz77_out_stream;
if (mCompressionMethod == Deflate::CompressionMethod::NONE)
{
lz77_out_stream = std::move(filter_out_stream);
}
else
{
lz77_out_stream = std::make_unique<BufferBitStream>();
Lz77Encoder lz77_encoder(filter_out_stream.get(), lz77_out_stream.get());
if (mCompressionMethod == Deflate::CompressionMethod::FIXED_HUFFMAN)
{
auto huffman_encoder = std::make_unique<HuffmanEncoder>();
huffman_encoder->setUseFixedCode(true);
lz77_encoder.setPrefixCodeGenerator(std::move(huffman_encoder));
}
lz77_encoder.encode();
lz77_out_stream->resetOffsets();
}
BufferBitStream zlib_out_stream;
ZlibEncoder zlib_encoder(lz77_out_stream.get(), &zlib_out_stream);
zlib_encoder.setDeflateCompressionMethod(mCompressionMethod);
zlib_encoder.encode();
zlib_out_stream.resetOffsets();
writeDataChunks(zlib_out_stream);
writeEndChunk();
}

View file

@ -0,0 +1,52 @@
#pragma once
#include "IImageWriter.h"
#include "PngHeader.h"
#include "Image.h"
#include "DeflateElements.h"
#include <memory>
#include <string>
#include <filesystem>
using Path = std::filesystem::path;
class BitStream;
class BufferBitStream;
class BasicPngWriter : public IImageWriter
{
public:
BasicPngWriter();
~BasicPngWriter();
static std::unique_ptr<BasicPngWriter> Create();
void setCompressionMethod(Deflate::CompressionMethod method);
void setPngInfo(const PngInfo& info);
void write(const Path& path, Image* image) override;
private:
void writeSignature();
void writeHeader();
void writeDataChunks(const BufferBitStream& buffer);
void writeEndChunk();
//void writeIDatChunk();
Image* mWorkingImage{ nullptr };
std::unique_ptr<BitStream> mInStream;
std::unique_ptr<BitStream> mOutStream;
unsigned mPngInfoUserSet{ false };
PngInfo mPngInfo;
PngHeader mPngHeader;
Deflate::CompressionMethod mCompressionMethod{ Deflate::CompressionMethod::DYNAMIC_HUFFMAN };
};

View file

@ -1,29 +1,19 @@
#include "PngWriter.h"
#include "Image.h"
#include "File.h"
#include "BufferBitStream.h"
#include "OutputBitStream.h"
#include "ImageBitStream.h"
#include "StringUtils.h"
#include "PngFilter.h"
#include "Lz77Encoder.h"
#include "ZlibEncoder.h"
#include "HuffmanEncoder.h"
#include "CyclicRedundancyChecker.h"
#include "ByteUtils.h"
#ifdef _WIN32
#include "Win32WicImageWriter.h"
#else
#include "BasicPngWriter.h"
#endif
#include <iostream>
PngWriter::PngWriter()
: IImageWriter(ImgFormat::PNG)
{
#ifdef _WIN32
mWriterImpl = std::make_unique<Win32WicImageWriter>(mFormat);
#else
mWriterImpl = std::make_unique<BasicPngWriter>(mFormat);
#endif
}
PngWriter::~PngWriter()
@ -36,209 +26,7 @@ std::unique_ptr<PngWriter> PngWriter::Create()
return std::make_unique<PngWriter>();
}
void PngWriter::setCompressionMethod(Deflate::CompressionMethod method)
void PngWriter::write(const Path& path, Image* image)
{
mCompressionMethod = method;
}
void PngWriter::setPath(const Path& path)
{
mPath = path;
}
void PngWriter::setPngInfo(const PngInfo& info)
{
mPngInfoUserSet = true;
mPngInfo = info;
}
void PngWriter::writeSignature()
{
mOutStream->writeByte(mPngHeader.getHighBitCheck());
mOutStream->writeBytes(StringUtils::toBytes(mPngHeader.getFileName()));
mOutStream->writeBytes(mPngHeader.getSignature());
}
void PngWriter::writeHeader()
{
writeSignature();
if (!mPngInfoUserSet)
{
if (mWorkingImage->getNumChannels() == 1)
{
mPngInfo.mColorType = PngInfo::ColorType::GREYSCALE;
}
else if (mWorkingImage->getNumChannels() == 2)
{
mPngInfo.mColorType = PngInfo::ColorType::GREYSCALE_ALPHA;
}
else if (mWorkingImage->getNumChannels() == 3)
{
mPngInfo.mColorType = PngInfo::ColorType::RGB;
}
else if (mWorkingImage->getNumChannels() == 4)
{
mPngInfo.mColorType = PngInfo::ColorType::RGB_ALPHA;
}
}
mPngHeader.setPngInfo(mPngInfo);
mPngHeader.setImageData(mWorkingImage->getWidth(), mWorkingImage->getHeight(), mWorkingImage->getBitDepth());
auto length = mPngHeader.getLength();
mOutStream->write(length);
mOutStream->writeBytes(StringUtils::toBytes(mPngHeader.getChunkName()));
mPngHeader.updateData();
mOutStream->writeBytes(mPngHeader.getData());
auto crc = mPngHeader.getCrc();
//std::cout << mPngHeader.toString() << "*********" << std::endl;
mOutStream->write(crc);
}
void PngWriter::writeEndChunk()
{
//std::cout << "Start writing end chunk" << std::endl;
unsigned length{0};
mOutStream->write(length);
mOutStream->writeBytes(StringUtils::toBytes("IEND"));
std::vector<unsigned char> char_data = StringUtils::toBytes("IEND");
CyclicRedundancyChecker crc_check;
for (auto c : char_data)
{
crc_check.addValue(c);
}
auto crc = crc_check.getChecksum();
mOutStream->write(crc);
//std::cout << "Writing end chunk" << std::endl;
}
void PngWriter::writeDataChunks(const BufferBitStream& buffer)
{
auto num_bytes = buffer.getBuffer().size();
auto max_bytes{32000};
auto num_dat_chunks = num_bytes/max_bytes + 1;
std::size_t offset = 0;
for(std::size_t idx=0;idx<num_dat_chunks;idx++)
{
auto length = max_bytes;
if (idx == num_dat_chunks - 1)
{
length = num_bytes - num_dat_chunks*num_bytes;
}
//std::cout << "Writing idat length " << num_bytes << std::endl;
mOutStream->write(num_bytes);
std::vector<unsigned char> char_data = StringUtils::toBytes("IDAT");
mOutStream->writeBytes(char_data);
CyclicRedundancyChecker crc_check;
for (auto c : char_data)
{
crc_check.addValue(c);
}
for(unsigned jdx=0; jdx<num_bytes; jdx++)
{
auto val = buffer.getBuffer()[idx*max_bytes + jdx];
mOutStream->writeByte(val);
crc_check.addValue(val);
}
auto crc = crc_check.getChecksum();
//std::cout << "Writing idat crc" << crc << std::endl;
mOutStream->write(crc);
//std::cout << "Finished Writing idat crc" << crc << std::endl;
}
}
void PngWriter::writePlatform(Image* image)
{
mPlatformWriter = std::make_unique<Win32WicImageWriter>();
mPlatformWriter->write(mPath, image, PlatformImageWriter::ImgFormat::PNG);
}
void PngWriter::write(Image* image)
{
if (image->getPlatformImage())
{
writePlatform(image);
return;
}
if (!mPath.empty())
{
mWorkingFile = std::make_unique<File>(mPath);
mWorkingFile->open(File::AccessMode::Write);
mOutStream = std::make_unique<OutputBitStream>(mWorkingFile->getOutHandle());
}
else
{
mOutStream = std::make_unique<BufferBitStream>();
}
mWorkingImage = image;
auto image_bit_stream = std::make_unique<ImageBitStream>(image);
auto raw_image_stream = image_bit_stream.get();
mInStream = std::move(image_bit_stream);
writeHeader();
auto filter_out_stream = std::make_unique<BufferBitStream>();
PngFilter filter(raw_image_stream, filter_out_stream.get());
filter.encode();
filter_out_stream->resetOffsets();
std::unique_ptr<BufferBitStream> lz77_out_stream;
if (mCompressionMethod == Deflate::CompressionMethod::NONE)
{
lz77_out_stream = std::move(filter_out_stream);
}
else
{
lz77_out_stream = std::make_unique<BufferBitStream>();
Lz77Encoder lz77_encoder(filter_out_stream.get(), lz77_out_stream.get());
if (mCompressionMethod == Deflate::CompressionMethod::FIXED_HUFFMAN)
{
auto huffman_encoder = std::make_unique<HuffmanEncoder>();
huffman_encoder->setUseFixedCode(true);
lz77_encoder.setPrefixCodeGenerator(std::move(huffman_encoder));
}
lz77_encoder.encode();
lz77_out_stream->resetOffsets();
}
BufferBitStream zlib_out_stream;
ZlibEncoder zlib_encoder(lz77_out_stream.get(), &zlib_out_stream);
zlib_encoder.setDeflateCompressionMethod(mCompressionMethod);
zlib_encoder.encode();
zlib_out_stream.resetOffsets();
writeDataChunks(zlib_out_stream);
writeEndChunk();
if (mWorkingFile)
{
mWorkingFile->close();
}
}
void PngWriter::write(const std::unique_ptr<Image>& image)
{
write(image.get());
mWriterImpl->write(path, image);
}

View file

@ -1,21 +1,12 @@
#pragma once
#include "PngHeader.h"
#include "Image.h"
#include "DeflateElements.h"
#include "PlatformImageWriter.h"
#include "IImageWriter.h"
#include <memory>
#include <string>
#include <filesystem>
using Path = std::filesystem::path;
class BitStream;
class BufferBitStream;
class File;
class PngWriter
class PngWriter : public IImageWriter
{
public:
PngWriter();
@ -23,40 +14,10 @@ public:
static std::unique_ptr<PngWriter> Create();
void setCompressionMethod(Deflate::CompressionMethod method);
void setPath(const Path& path);
void setPngInfo(const PngInfo& info);
void write(const std::unique_ptr<Image>& image);
void write(Image* image);
void write(const Path& path, Image* image) override;
private:
void writePlatform(Image* image);
void writeSignature();
void writeHeader();
void writeDataChunks(const BufferBitStream& buffer);
void writeEndChunk();
//void writeIDatChunk();
Path mPath;
Image* mWorkingImage{nullptr};
std::unique_ptr<BitStream> mInStream;
std::unique_ptr<BitStream> mOutStream;
std::unique_ptr<File> mWorkingFile;
unsigned mPngInfoUserSet{false};
PngInfo mPngInfo;
PngHeader mPngHeader;
Deflate::CompressionMethod mCompressionMethod{Deflate::CompressionMethod::DYNAMIC_HUFFMAN};
std::unique_ptr<PlatformImageWriter> mPlatformWriter;
std::unique_ptr<IImageWriter> mWriterImpl;
};
using PngWriterPtr = std::unique_ptr<PngWriter>;

View file

@ -8,7 +8,13 @@
#include <wincodec.h>
#include <wrl.h>
void Win32WicImageWriter::write(const Path& path, Image* image, ImgFormat format )
Win32WicImageWriter::Win32WicImageWriter(ImgFormat format)
: PlatformImageWriter(format)
{
}
void Win32WicImageWriter::write(const Path& path, Image* image)
{
Win32WicInterface wic_interface;
@ -18,21 +24,21 @@ void Win32WicImageWriter::write(const Path& path, Image* image, ImgFormat format
hr = pStream->InitializeFromFilename(path.wstring().c_str(), GENERIC_WRITE);
Microsoft::WRL::ComPtr<IWICBitmapEncoder> pEncoder;
hr = wic_interface.getFactory()->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder);
hr = wic_interface.getFactory()->CreateEncoder(GUID_ContainerFormatPng, nullptr, &pEncoder);
hr = pEncoder->Initialize(pStream.Get(), WICBitmapEncoderNoCache);
Microsoft::WRL::ComPtr<IWICBitmapFrameEncode> pFrameEncode;
hr = pEncoder->CreateNewFrame(&pFrameEncode, NULL);
hr = pEncoder->CreateNewFrame(&pFrameEncode, nullptr);
hr = pFrameEncode->Initialize(NULL);
hr = pFrameEncode->Initialize(nullptr);
hr = pFrameEncode->SetSize(image->getWidth(), image->getHeight());
WICPixelFormatGUID out_format = GUID_WICPixelFormatDontCare;
hr = pFrameEncode->SetPixelFormat(&out_format);
hr = pFrameEncode->WriteSource(dynamic_cast<Win32WicImage*>(image->getPlatformImage())->getBitmap(), NULL);
hr = pFrameEncode->WriteSource(dynamic_cast<Win32WicImage*>(image->getPlatformImage())->getBitmap(), nullptr);
hr = pFrameEncode->Commit();

View file

@ -5,5 +5,7 @@
class Win32WicImageWriter : public PlatformImageWriter
{
public:
void write(const Path& path, Image* image, ImgFormat format = ImgFormat::PNG) override;
Win32WicImageWriter(ImgFormat format);
void write(const Path& path, Image* image) override;
};

View file

@ -6,8 +6,8 @@
#include <memory>
using EdgeIds = std::vector<std::pair<unsigned, unsigned> >;
using FaceIds = std::vector<std::vector<unsigned> >;
using EdgeIds = std::vector<std::pair<std::size_t, std::size_t> >;
using FaceIds = std::vector<std::vector<std::size_t> >;
using VecPoints = std::vector<Point>;
class MeshBuilder

View file

@ -32,14 +32,14 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRectangleAsTriMesh()
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
}
std::unique_ptr<TriMesh> MeshPrimitives::buildCircleAsTriMesh(unsigned numSegments)
std::unique_ptr<TriMesh> MeshPrimitives::buildCircleAsTriMesh(std::size_t numSegments)
{
VecPoints locations(numSegments + 1);
locations[0] = {0, 0};
const double delta_theta = (2.0*M_PI)/double(numSegments);
double theta = 0.0;
for(unsigned idx=1; idx<=numSegments; idx++)
for(std::size_t idx=1; idx<=numSegments; idx++)
{
const double x = sin(theta);
const double y = cos(theta);
@ -49,7 +49,7 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildCircleAsTriMesh(unsigned numSegmen
}
EdgeIds edge_ids(2*numSegments);
for(unsigned idx=0; idx<numSegments; idx++)
for(std::size_t idx=0; idx<numSegments; idx++)
{
edge_ids[idx] = {0, idx+1};
@ -62,7 +62,7 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildCircleAsTriMesh(unsigned numSegmen
}
FaceIds face_ids(numSegments);
for(unsigned idx=0; idx<numSegments; idx++)
for(std::size_t idx=0; idx<numSegments; idx++)
{
auto top_edge_inner = idx + 1;
if (top_edge_inner == numSegments)
@ -76,7 +76,7 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildCircleAsTriMesh(unsigned numSegmen
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
}
std::unique_ptr<LineMesh> MeshPrimitives::buildCircleAsLineMesh(unsigned numSegments)
std::unique_ptr<LineMesh> MeshPrimitives::buildCircleAsLineMesh(std::size_t numSegments)
{
VecPoints locations(numSegments);
const double delta_theta = (2.0*M_PI)/double(numSegments);
@ -101,10 +101,10 @@ std::unique_ptr<LineMesh> MeshPrimitives::buildCircleAsLineMesh(unsigned numSegm
return MeshBuilder::buildLineMesh(locations, edge_ids);
}
std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio, unsigned num_segments)
std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio, std::size_t num_segments)
{
unsigned num_fans = 4;
unsigned num_nodes_per_fan = num_segments + 2;
std::size_t num_fans = 4;
std::size_t num_nodes_per_fan = num_segments + 2;
VecPoints locations(num_fans * num_nodes_per_fan);
double rect_start_x = radius;
@ -115,8 +115,8 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double r
double running_theta = 0;
locations[0] = {rect_end_x, radius};
unsigned offset = 1;
for (unsigned idx=0; idx<=num_segments; idx++)
std::size_t offset = 1;
for (std::size_t idx=0; idx<=num_segments; idx++)
{
locations[offset + idx] = {rect_end_x + radius*sin(running_theta), radius*(1.0 - cos(running_theta))};
running_theta += delta_theta;
@ -126,7 +126,7 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double r
locations[offset] = {rect_end_x, rect_end_y};
offset++;
running_theta = 0;
for (unsigned idx=0; idx<=num_segments;idx++)
for (std::size_t idx=0; idx<=num_segments;idx++)
{
locations[offset + idx] = {rect_end_x + radius*cos(running_theta), rect_end_y + radius*sin(running_theta)};
running_theta += delta_theta;
@ -136,7 +136,7 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double r
locations[offset] = {rect_start_x, rect_end_y};
offset ++;
running_theta = 0;
for (unsigned idx=0; idx<=num_segments;idx++)
for (std::size_t idx=0; idx<=num_segments;idx++)
{
locations[offset + idx] = {rect_start_x - radius*sin(running_theta), rect_end_y + radius*cos(running_theta)};
running_theta += delta_theta;
@ -146,37 +146,37 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildRoundedRectangleAsTriMesh(double r
locations[offset] = {rect_start_x, radius};
offset++;
running_theta = 0;
for (unsigned idx=0; idx<=num_segments;idx++)
for (std::size_t idx=0; idx<=num_segments;idx++)
{
locations[offset + idx] = {rect_start_x - radius*cos(running_theta), radius *(1 - sin(running_theta))};
running_theta += delta_theta;
}
unsigned num_edges_per_fan = 2*num_segments + 1;
unsigned num_inner_rect_edges = 3*num_fans;
std::size_t num_edges_per_fan = 2*num_segments + 1;
std::size_t num_inner_rect_edges = 3*num_fans;
EdgeIds edge_ids(num_edges_per_fan*num_fans + num_inner_rect_edges + 1);
// Fan edges
for (unsigned jdx=0; jdx< num_fans; jdx++)
for (std::size_t jdx=0; jdx< num_fans; jdx++)
{
unsigned node_offset = jdx*num_nodes_per_fan;
unsigned edge_offset = jdx*num_edges_per_fan;
std::size_t node_offset = jdx*num_nodes_per_fan;
std::size_t edge_offset = jdx*num_edges_per_fan;
// Inner edges
for(unsigned idx=0; idx<=num_segments; idx++)
for(std::size_t idx=0; idx<=num_segments; idx++)
{
edge_ids[edge_offset + idx] = {node_offset, node_offset + idx + 1};
}
// Outer edges
for(unsigned idx=0; idx<num_segments; idx++)
for(std::size_t idx=0; idx<num_segments; idx++)
{
edge_ids[edge_offset + num_segments + 1 + idx] = {node_offset + idx + 1, node_offset + idx + 2};
}
}
// Inner rect edges
unsigned edge_offset = num_edges_per_fan*num_fans;
std::size_t edge_offset = num_edges_per_fan*num_fans;
return nullptr;
}
@ -199,7 +199,7 @@ std::unique_ptr<LineMesh> MeshPrimitives::buildRectangleAsLineMesh()
return MeshBuilder::buildLineMesh(locations, edge_ids);
}
std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(unsigned numX, unsigned numY)
std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(std::size_t numX, std::size_t numY)
{
double delta_x = 1.0/double(numX);
double delta_y = 1.0/double(numY);
@ -207,9 +207,9 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(unsigned num
VecPoints locations (4 * numX * numY);
double offset_x = delta_x/2.0;
double offset_y = delta_y/2.0;
for (unsigned idx=0; idx<numY; idx++)
for (std::size_t idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
for(std::size_t jdx=0; jdx<numX; jdx++)
{
auto locX0 = offset_x - delta_x/2.0;
auto locX1 = offset_x + delta_x/2.0;
@ -229,11 +229,11 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(unsigned num
}
EdgeIds edge_ids(5 * numX * numY);
for (unsigned idx=0; idx<numY; idx++)
for (std::size_t idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
for(std::size_t jdx=0; jdx<numX; jdx++)
{
unsigned node_offset = 4 * (jdx + numX * idx);
std::size_t node_offset = 4 * (jdx + numX * idx);
auto id_offset = 5* (jdx + numX*idx);
edge_ids[id_offset] = {node_offset, node_offset + 1};
edge_ids[id_offset + 1] = {node_offset + 1, node_offset + 2};
@ -244,12 +244,12 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(unsigned num
}
FaceIds face_ids(2 *numX * numY);
for (unsigned idx=0; idx<numY; idx++)
for (std::size_t idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
for(std::size_t jdx=0; jdx<numX; jdx++)
{
unsigned edge_offset = 5 * (jdx + numX * idx);
unsigned face_offset = 2 * (jdx + numX * idx);
std::size_t edge_offset = 5 * (jdx + numX * idx);
std::size_t face_offset = 2 * (jdx + numX * idx);
face_ids[face_offset] = {edge_offset, edge_offset + 1, edge_offset + 4};
face_ids[face_offset + 1] = {edge_offset + 4, edge_offset + 2, edge_offset + 3};
}
@ -258,7 +258,7 @@ std::unique_ptr<TriMesh> MeshPrimitives::buildExplodedGridAsTriMesh(unsigned num
return MeshBuilder::buildTriMesh(locations, edge_ids, face_ids);
}
std::unique_ptr<LineMesh> MeshPrimitives::buildExplodedGridAsLineMesh(unsigned numX, unsigned numY)
std::unique_ptr<LineMesh> MeshPrimitives::buildExplodedGridAsLineMesh(std::size_t numX, std::size_t numY)
{
double delta_x = 1.0/double(numX);
double delta_y = 1.0/double(numY);
@ -266,9 +266,9 @@ std::unique_ptr<LineMesh> MeshPrimitives::buildExplodedGridAsLineMesh(unsigned n
VecPoints locations (4 * numX * numY);
double offset_x = delta_x/2.0;
double offset_y = delta_y/2.0;
for (unsigned idx=0; idx<numY; idx++)
for (std::size_t idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
for(std::size_t jdx=0; jdx<numX; jdx++)
{
auto locX0 = offset_x - delta_x/2.0;
auto locX1 = offset_x + delta_x/2.0;
@ -288,11 +288,11 @@ std::unique_ptr<LineMesh> MeshPrimitives::buildExplodedGridAsLineMesh(unsigned n
}
EdgeIds edge_ids(4 * numX * numY);
for (unsigned idx=0; idx<numY; idx++)
for (std::size_t idx=0; idx<numY; idx++)
{
for(unsigned jdx=0; jdx<numX; jdx++)
for(std::size_t jdx=0; jdx<numX; jdx++)
{
unsigned node_offset = 4 * (jdx + numX * idx);
std::size_t node_offset = 4 * (jdx + numX * idx);
auto id_offset = 4* (jdx + numX*idx);
edge_ids[id_offset] = {node_offset, node_offset + 1};
edge_ids[id_offset + 1] = {node_offset + 1, node_offset + 2};

View file

@ -6,17 +6,17 @@
class MeshPrimitives
{
public:
static std::unique_ptr<TriMesh> buildCircleAsTriMesh(unsigned numSegments = 24);
static std::unique_ptr<TriMesh> buildCircleAsTriMesh(std::size_t numSegments = 24);
static std::unique_ptr<LineMesh> buildCircleAsLineMesh(unsigned numSegments = 24);
static std::unique_ptr<LineMesh> buildCircleAsLineMesh(std::size_t numSegments = 24);
static std::unique_ptr<TriMesh> buildRectangleAsTriMesh();
static std::unique_ptr<LineMesh> buildRectangleAsLineMesh();
static std::unique_ptr<TriMesh> buildExplodedGridAsTriMesh(unsigned numX, unsigned numY);
static std::unique_ptr<TriMesh> buildExplodedGridAsTriMesh(std::size_t numX, std::size_t numY);
static std::unique_ptr<LineMesh> buildExplodedGridAsLineMesh(unsigned numX, unsigned numY);
static std::unique_ptr<LineMesh> buildExplodedGridAsLineMesh(std::size_t numX, std::size_t numY);
static std::unique_ptr<TriMesh> buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio = 1.0, unsigned num_segments = 4);
static std::unique_ptr<TriMesh> buildRoundedRectangleAsTriMesh(double radius, double aspect_ratio = 1.0, std::size_t num_segments = 4);
};

View file

@ -35,7 +35,7 @@ private:
std::string mVersion {"1.7"};
PdfXRefTablePtr mXRefTable;
unsigned mXRefOffset{0};
std::size_t mXRefOffset{0};
PdfDocumentCatalogPtr mCatalog;
};

View file

@ -16,8 +16,8 @@ std::string PdfXRefTable::toString()
content += "\n";
for (const auto& record : section.mRecords)
{
auto offsetString = StringUtils::toPaddedString(10, record.mOffsetBytes);
auto generationString = StringUtils::toPaddedString(5, record.mGenerationNumber);
auto offsetString = StringUtils::toPaddedString(10, static_cast<unsigned>(record.mOffsetBytes));
auto generationString = StringUtils::toPaddedString(5, static_cast<unsigned>(record.mGenerationNumber));
auto freeString = record.mIsFree ? "f" : "n";
content += offsetString + " " + generationString + " " + freeString + "\n";
@ -27,7 +27,7 @@ std::string PdfXRefTable::toString()
return content;
}
unsigned PdfXRefTable::getNextOffset()
std::size_t PdfXRefTable::getNextOffset()
{
auto lastNumRecords = mSections[mSections.size() - 1].mRecords.size();
if (lastNumRecords > 0)
@ -45,7 +45,7 @@ unsigned PdfXRefTable::getNextOffset()
}
}
void PdfXRefTable::addRecord(unsigned numBytes, unsigned generation, unsigned isFree)
void PdfXRefTable::addRecord(std::size_t numBytes, std::size_t generation, unsigned isFree)
{
XRefRecord record;
@ -56,9 +56,9 @@ void PdfXRefTable::addRecord(unsigned numBytes, unsigned generation, unsigned is
mLastAddedBytes = numBytes;
}
unsigned PdfXRefTable::getNumEntries()
std::size_t PdfXRefTable::getNumEntries()
{
unsigned count = 0;
std::size_t count = 0;
for (const auto& section : mSections)
{
count += section.mRecords.size();

View file

@ -6,14 +6,14 @@
struct XRefRecord
{
unsigned mOffsetBytes{0};
unsigned mGenerationNumber{0};
std::size_t mOffsetBytes{0};
std::size_t mGenerationNumber{0};
bool mIsFree{false};
};
struct TableSubSection
{
unsigned mStartIndex{0};
std::size_t mStartIndex{0};
std::vector<XRefRecord> mRecords;
};
@ -22,14 +22,14 @@ class PdfXRefTable
public:
PdfXRefTable();
void addRecord(unsigned numBytes, unsigned generation, unsigned isFree);
void addRecord(std::size_t numBytes, std::size_t generation, unsigned isFree);
unsigned getNextOffset();
std::size_t getNextOffset();
unsigned getNumEntries();
std::size_t getNumEntries();
std::string toString();
private:
unsigned mLastAddedBytes{0};
std::size_t mLastAddedBytes{0};
std::vector<TableSubSection> mSections;
};

View file

@ -76,9 +76,9 @@ void DirectX2dIntegration::wrapBuffer(ID3D12Resource* renderTarget)
mDxInterface->get11On12Device()->CreateWrappedResource(renderTarget, &d3d11Flags,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT, IID_PPV_ARGS(&mWrappedBackBuffers[mWrappedBackBuffers.size()-1]));
float dpiX{ 0.0 };
float dpiY{ 0.0 };
mDx2dInterface->getFactory()->GetDesktopDpi(&dpiX, &dpiY);
float dpiX{ 96.0 };
float dpiY{ 96.0 };
//mDx2dInterface->getFactory()->GetDesktopDpi(&dpiX, &dpiY);
const auto pixel_format = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED);
const auto bitmap_props = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, pixel_format, dpiX, dpiY);

View file

@ -30,9 +30,8 @@ TEST_CASE(TestCompressedPng, "image")
image->getGridT<unsigned char>()->setData(data);
PngWriter writer;
writer.setPath(TestUtils::getTestOutputDir() / "test_compressed.png");
writer.setCompressionMethod(Deflate::CompressionMethod::NONE);
writer.write(image);
//writer.setCompressionMethod(Deflate::CompressionMethod::NONE);
writer.write(TestUtils::getTestOutputDir() / "test_compressed.png", image.get());
return;
File test_file(TestUtils::getTestOutputDir() / "test_compressed.png");
@ -64,9 +63,8 @@ TEST_CASE(TestFixedPng, "image")
image->getGridT<unsigned char>()->setData(data);
PngWriter writer;
writer.setPath(TestUtils::getTestOutputDir() / "test_fixed.png");
writer.setCompressionMethod(Deflate::CompressionMethod::FIXED_HUFFMAN);
writer.write(image);
//writer.setCompressionMethod(Deflate::CompressionMethod::FIXED_HUFFMAN);
writer.write(TestUtils::getTestOutputDir() / "test_fixed.png", image.get());
//return;
File test_file(TestUtils::getTestOutputDir() / "test_fixed.png");
@ -94,8 +92,8 @@ TEST_CASE(TestDynamicCompressedPng, "image")
image->getGridT<unsigned char>()->setData(data);
PngWriter writer;
writer.setPath(TestUtils::getTestOutputDir() / "test_dynamic.png");
writer.write(image);
//writer.setPath(TestUtils::getTestOutputDir() / "test_dynamic.png");
writer.write(TestUtils::getTestOutputDir() / "test_dynamic.png", image.get());
//return;
File test_file(TestUtils::getTestOutputDir() / "test_dynamic.png");

View file

@ -37,8 +37,7 @@ public:
auto image = mSurface->getImage();
PngWriter writer;
writer.setPath(path);
writer.write(image);
writer.write(path, image);
}
void writeSvg(const Path& path)