Add png reader

This commit is contained in:
jmsgrogan 2022-08-01 14:00:40 +01:00
parent ed925afabf
commit 4fce4fc614
7 changed files with 201 additions and 3 deletions

View file

@ -6,6 +6,7 @@ list(APPEND image_HEADERS
list(APPEND image_LIB_INCLUDES
Image.cpp
PngWriter.cpp
PngReader.cpp
)
add_library(image SHARED ${image_LIB_INCLUDES} ${image_HEADERS})
@ -18,4 +19,4 @@ set_target_properties( image PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
find_package(PNG REQUIRED)
target_link_libraries( image PUBLIC PNG::PNG core)
set_property(TARGET image PROPERTY FOLDER src)
set_property(TARGET image PROPERTY FOLDER src)

View file

@ -7,6 +7,11 @@ Image::Image(unsigned width, unsigned height)
}
Image::~Image()
{
}
void Image::Initialize()
{
mData = std::vector<unsigned char>(GetBytesPerRow()*mHeight, 0);

View file

@ -11,6 +11,7 @@ class Image
public:
Image(unsigned width, unsigned height);
~Image();
static std::unique_ptr<Image> Create(unsigned width, unsigned height);
unsigned GetBytesPerRow() const;

129
src/image/PngReader.cpp Normal file
View file

@ -0,0 +1,129 @@
#include "PngReader.h"
#include "BinaryStream.h"
#include "Image.h"
#include <iostream>
PngReader::~PngReader()
{
}
void PngReader::setPath(const std::string& path)
{
mPath = path;
}
bool PngReader::checkSignature()
{
const int highBitCheck = 0x89;
const auto firstPos = mFile->GetInHandle()->get();
if (firstPos != highBitCheck)
{
return false;
}
std::string fileType;
BinaryStream::getNextString(mFile->GetInHandle(), fileType, 3);
if (fileType != "PNG")
{
return false;
}
std::vector<char> sequence{13, 10, 26, 10};
for (auto c : sequence)
{
if (mFile->GetInHandle()->get() != c)
{
return false;
}
}
mCurrentOffset += 8;
return true;
}
bool PngReader::readChunk()
{
unsigned length = *BinaryStream::getNextDWord(mFile->GetInHandle());
std::string chunkType;
BinaryStream::getNextString(mFile->GetInHandle(), chunkType, 4);
mCurrentOffset += 8;
std::cout << "Got chunk with type: " << chunkType << " and length: " << length << std::endl;
bool lastChunk = false;
if (chunkType == "IHDR")
{
parseHeader();
}
else if(chunkType == "IEND")
{
lastChunk = true;
}
else
{
for(unsigned idx=0;idx<length;idx++)
{
mFile->GetInHandle()->get();
}
}
unsigned crcCheck = *BinaryStream::getNextDWord(mFile->GetInHandle());
mCurrentOffset += 4;
return !lastChunk;
}
void PngReader::parseHeader()
{
mIHDRChunk.width = *BinaryStream::getNextDWord(mFile->GetInHandle());
mIHDRChunk.height = *BinaryStream::getNextDWord(mFile->GetInHandle());
mIHDRChunk.bitDepth = mFile->GetInHandle()->get();
mIHDRChunk.colorType = mFile->GetInHandle()->get();
mIHDRChunk.compressionMethod = mFile->GetInHandle()->get();
mIHDRChunk.filterMethod = mFile->GetInHandle()->get();
mIHDRChunk.interlaceMethod = mFile->GetInHandle()->get();
mCurrentOffset += 13;
logHeader();
}
void PngReader::logHeader()
{
std::stringstream sstr;
sstr << "IHDR\n";
sstr << "width: " << mIHDRChunk.width << "\n";
sstr << "height: " << mIHDRChunk.height << "\n";
sstr << "bitDepth: " << (int)mIHDRChunk.bitDepth << "\n";
sstr << "colorType: " << (int)mIHDRChunk.colorType << "\n";
sstr << "compressionMethod: " << (int)mIHDRChunk.compressionMethod << "\n";
sstr << "filterMethod: " << (int)mIHDRChunk.filterMethod << "\n";
sstr << "interlaceMethod: " << (int)mIHDRChunk.interlaceMethod << "\n";
sstr << "************\n";
std::cout << sstr.str() << std::endl;
}
std::unique_ptr<Image> PngReader::read()
{
auto image = std::make_unique<Image>(5, 5);
mFile = std::make_unique<File>(mPath);
mFile->Open(true);
if (!checkSignature())
{
std::cout << "Signature check failed" << std::endl;
return image;
}
while(readChunk())
{
}
return std::move(image);
}

45
src/image/PngReader.h Normal file
View file

@ -0,0 +1,45 @@
#pragma once
#include <string>
#include <memory>
#include <vector>
#include "File.h"
class Image;
class PngReader
{
public:
~PngReader();
void setPath(const std::string& path);
std::unique_ptr<Image> read();
private:
struct IHDRChunk
{
unsigned width{0};
unsigned height{0};
char bitDepth{0};
char colorType{0};
char compressionMethod{0};
char filterMethod{0};
char interlaceMethod{0};
};
bool readChunk();
void parseHeader();
void logHeader();
bool checkSignature();
unsigned mCurrentOffset{0};
IHDRChunk mIHDRChunk;
std::unique_ptr<Image> mWorkingImage;
std::unique_ptr<File> mFile;
std::string mPath;
};

View file

@ -16,7 +16,8 @@ list(APPEND TestFiles
graphics/TestOpenGlRendering.cpp
graphics/TestRasterizer.cpp
ipc/TestDbus.cpp
image/TestPngWriter.cpp
image/TestPngReader.cpp
image/TestPngWriter.cpp
network/TestNetworkManagerClient.cpp
network/TestNetworkManagerServer.cpp
publishing/TestPdfWriter.cpp
@ -34,6 +35,7 @@ list(APPEND TestNames
TestOpenGlRendering
TestRasterizer
TestDbus
TestPngReader
TestPngWriter
TestNetworkManagerClient
TestNetworkManagerServer
@ -55,4 +57,4 @@ endforeach()
add_executable(test_runner test_runner.cpp)
target_link_libraries(test_runner PUBLIC core fonts network database geometry audio graphics web client)
target_link_libraries(test_runner PUBLIC core fonts network database geometry audio graphics web client)

View file

@ -0,0 +1,15 @@
#include "PngReader.h"
#include "Image.h"
#include <iostream>
int main()
{
const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test.png";
PngReader reader;
reader.setPath(path);
auto image = reader.read();
return 0;
}