Clean up some warnings.
This commit is contained in:
parent
a19567508e
commit
dba6a91ec1
25 changed files with 453 additions and 431 deletions
|
@ -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}")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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};
|
||||
};
|
||||
|
||||
|
|
|
@ -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
28
src/image/IImageWriter.h
Normal 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 };
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
};
|
216
src/image/png/BasicPngWriter.cpp
Normal file
216
src/image/png/BasicPngWriter.cpp
Normal 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();
|
||||
}
|
52
src/image/png/BasicPngWriter.h
Normal file
52
src/image/png/BasicPngWriter.h
Normal 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 };
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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>;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ private:
|
|||
|
||||
std::string mVersion {"1.7"};
|
||||
PdfXRefTablePtr mXRefTable;
|
||||
unsigned mXRefOffset{0};
|
||||
std::size_t mXRefOffset{0};
|
||||
PdfDocumentCatalogPtr mCatalog;
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue