Added processing for headers and the first chunck. Some infs are still missing tho

This commit is contained in:
2022-09-15 17:49:43 +02:00
parent 36a8664b76
commit e6c1329f2d
2 changed files with 138 additions and 6 deletions

View File

@@ -25,7 +25,14 @@ namespace TEST_DecodePng
if (Directory.Exists(imageFolderPath))
{
lsbFiles.Enabled = true;
string[] files = Directory.GetFiles(imageFolderPath,"*png");
string[] files = Directory.GetFiles(imageFolderPath,"*.png");
foreach (string file in files)
{
lsbFiles.Items.Add(Path.GetFileName(file));
}
//TO REMOVE, ONLY HERE FOR DEBUGGING
files = Directory.GetFiles(imageFolderPath, "*.jpg");
foreach (string file in files)
{
lsbFiles.Items.Add(Path.GetFileName(file));

View File

@@ -1,25 +1,150 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TEST_DecodePng
{
internal class PngDecoder
{
const int PNG_SIGNATURE_LENGTH = 8;
readonly byte[] EXPECTED_PNG_SIGNATURE = new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 };
const int CHUNCK_SIZE_FIELD_LENGTH = 4;
const int CHUNCK_TYPE_FIELD_LENGTH = 4;
const string FIRST_CHUNK_TYPE = "IHDR";
const int IMAGE_WIDTH_FIELD_SIZE = 4;
const int IMAGE_HEIGHT_FIELD_SIZE = 4;
public Stopwatch chrono;
public PngDecoder()
{
//Empty
chrono = new Stopwatch();
//I start and stop the chronometer so all the methods can just use the Restart method.
chrono.Start(); chrono.Stop();
}
public Bitmap Decode(string filename)
{
Byte[] content = File.ReadAllBytes(filename);
int pngSignatureLength = 8;
//TO REMOVE !!
return new Bitmap(100,100);
//Timing Stuff
chrono.Reset();
chrono.Start();
//Timing Stuff
byte[] content = File.ReadAllBytes(filename);
int cursor = 0;
byte[] pngSignature = new byte[PNG_SIGNATURE_LENGTH];
for (int i = 0; i < PNG_SIGNATURE_LENGTH; i++)
{
pngSignature[i] = content[cursor];
cursor++;
}
//Checks if the file has a valid png signature
if (!compareByteArrays(EXPECTED_PNG_SIGNATURE, pngSignature))
return null;
//We are now sure that we are working with a png file and we will then read chuncks
byte[] chunckLength = new byte[CHUNCK_SIZE_FIELD_LENGTH];
for (int i = 0; i < CHUNCK_SIZE_FIELD_LENGTH; i++)
{
chunckLength[i] = content[cursor];
cursor++;
}
byte[] chunckType = new byte[CHUNCK_TYPE_FIELD_LENGTH];
for (int i = 0; i < CHUNCK_TYPE_FIELD_LENGTH; i++)
{
chunckType[i] = content[cursor];
cursor++;
}
//The first chunck MUST be a IHDR chunck so we need to check if that is the case
string ckType = System.Text.Encoding.UTF8.GetString(chunckType);
//If the first chunck is not the IHDR that means that we should not continue to decompress it
if (ckType != FIRST_CHUNK_TYPE)
return null;
//As it is the first chunck, his structure is a little bit different
int imageWidth, imageHeight, bitDepth, colorType, compressionMethod, filterMethod, interfaceMethod;
byte[] btaImageWidth = new byte[IMAGE_WIDTH_FIELD_SIZE];
byte[] btaImageHeight = new byte[IMAGE_HEIGHT_FIELD_SIZE];
for (int i = 0; i < IMAGE_WIDTH_FIELD_SIZE; i++)
{
btaImageWidth[i] = content[cursor];
cursor++;
}
for (int i = 0; i < IMAGE_HEIGHT_FIELD_SIZE; i++)
{
btaImageHeight[i] = content[cursor];
cursor++;
}
//Those are in little endien notation so we need to reverse it
Array.Reverse(btaImageWidth);
Array.Reverse(btaImageHeight);
imageWidth = BitConverter.ToInt32(btaImageWidth,0);
imageHeight = BitConverter.ToInt32(btaImageHeight,0);
cursor++;
bitDepth = Convert.ToInt32(content[cursor]);
cursor++;
colorType = Convert.ToInt32(content[cursor]);
cursor++;
compressionMethod = Convert.ToInt32(content[cursor]);
cursor++;
filterMethod = Convert.ToInt32(content[cursor]);
cursor++;
interfaceMethod = Convert.ToInt32(content[cursor]);
MessageBox.Show("Image width: " + imageWidth +
Environment.NewLine + "Image height: " + imageHeight +
Environment.NewLine + "byte depth : " + bitDepth +
Environment.NewLine + "color type : " + colorType +
Environment.NewLine + "compression method : " + compressionMethod +
Environment.NewLine + "filter method : " + filterMethod +
Environment.NewLine + "interface method : " + interfaceMethod
);
//Timing Stuff
chrono.Stop();
//Timing Stuff
//TO REMOVE
return new Bitmap(100, 100);
}
public byte[] ReadChunck()
{
//Must always return two values in the array or null
//TO REMOVE
return new byte[] { 0, 0 };
}
public bool compareByteArrays(byte[] firstArray, byte[] secondArray)
{
if (firstArray.Length != secondArray.Length)
return false;
bool result = true;
for (int i = 0; i < firstArray.Length; i++)
{
if (firstArray[0] != secondArray[0])
result = false;
}
return result;
}
}