diff --git a/src/image/CMakeLists.txt b/src/image/CMakeLists.txt index f138c91..01381c9 100644 --- a/src/image/CMakeLists.txt +++ b/src/image/CMakeLists.txt @@ -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) \ No newline at end of file +set_property(TARGET image PROPERTY FOLDER src) diff --git a/src/image/Image.cpp b/src/image/Image.cpp index ed84269..bbf6616 100644 --- a/src/image/Image.cpp +++ b/src/image/Image.cpp @@ -7,6 +7,11 @@ Image::Image(unsigned width, unsigned height) } +Image::~Image() +{ + +} + void Image::Initialize() { mData = std::vector(GetBytesPerRow()*mHeight, 0); diff --git a/src/image/Image.h b/src/image/Image.h index 20ed550..cbda8e4 100644 --- a/src/image/Image.h +++ b/src/image/Image.h @@ -11,6 +11,7 @@ class Image public: Image(unsigned width, unsigned height); + ~Image(); static std::unique_ptr Create(unsigned width, unsigned height); unsigned GetBytesPerRow() const; diff --git a/src/image/PngReader.cpp b/src/image/PngReader.cpp new file mode 100644 index 0000000..122a783 --- /dev/null +++ b/src/image/PngReader.cpp @@ -0,0 +1,129 @@ +#include "PngReader.h" +#include "BinaryStream.h" + +#include "Image.h" + +#include + +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 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;idxGetInHandle()->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 PngReader::read() +{ + auto image = std::make_unique(5, 5); + + mFile = std::make_unique(mPath); + mFile->Open(true); + + if (!checkSignature()) + { + std::cout << "Signature check failed" << std::endl; + return image; + } + + while(readChunk()) + { + + } + + return std::move(image); +} diff --git a/src/image/PngReader.h b/src/image/PngReader.h new file mode 100644 index 0000000..12f0b84 --- /dev/null +++ b/src/image/PngReader.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +#include "File.h" + +class Image; + +class PngReader +{ +public: + ~PngReader(); + void setPath(const std::string& path); + + std::unique_ptr 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 mWorkingImage; + std::unique_ptr mFile; + std::string mPath; +}; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index edc4187..bdc6fb5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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) \ No newline at end of file +target_link_libraries(test_runner PUBLIC core fonts network database geometry audio graphics web client) diff --git a/test/image/TestPngReader.cpp b/test/image/TestPngReader.cpp new file mode 100644 index 0000000..ce3d865 --- /dev/null +++ b/test/image/TestPngReader.cpp @@ -0,0 +1,15 @@ +#include "PngReader.h" + +#include "Image.h" +#include + +int main() +{ + const auto path = "/home/jmsgrogan/code/MediaTool-build/bin/test.png"; + + PngReader reader; + reader.setPath(path); + auto image = reader.read(); + + return 0; +}