Skip to content

Commit e3c7367

Browse files
committed
get in there
1 parent cbfee60 commit e3c7367

File tree

4 files changed

+238
-0
lines changed

4 files changed

+238
-0
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(ImageLoading)
3+
4+
set(CMAKE_CXX_STANDARD 11)
5+
6+
set(SOURCE_FILES main.cpp image.cpp image.h)
7+
add_executable(ImageLoading ${SOURCE_FILES})

image.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//
2+
// Created by Ole on 10.09.2017.
3+
//
4+
5+
#include "image.h"
6+
7+
unsigned char reversed(unsigned char value) {
8+
unsigned char t = value;
9+
for (int i = sizeof(value) * 8-1; i; i--)
10+
{
11+
value >>= 1;
12+
t <<= 1;
13+
t |= value & 1;
14+
}
15+
return t;
16+
}
17+
18+
Image::Image(const std::string& path) {
19+
init(path);
20+
}
21+
22+
void Image::init(const std::string& path) {
23+
std::ifstream stream(path, std::ifstream::in | std::ifstream::ate | std::ifstream::binary);
24+
auto size = (unsigned int) stream.tellg();
25+
if (!stream.good()) {
26+
LOG("FAILED TO OPEN FILE: " << path);
27+
size = 0;
28+
}
29+
stream.seekg(0, std::ifstream::beg);
30+
31+
unsigned char data[size];
32+
33+
unsigned int position = 0;
34+
char in;
35+
while (stream.get(in))
36+
data[position++] = (unsigned char) in;
37+
38+
loadChunks(data, size);
39+
formatIHDR();
40+
41+
stream.close();
42+
}
43+
44+
void Image::formatIHDR() {
45+
auto& data = chunks[0]->data;
46+
47+
format.width = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
48+
format.height = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | (data[7]);
49+
format.bitDepth = data[8];
50+
format.colorType = data[9];
51+
format.compressionMethod = data[10];
52+
format.filterMethod = data[11];
53+
format.interlaceMethod = data[12];
54+
}
55+
56+
std::vector<unsigned char> Image::extractCompressedPixelData(const Chunk& chunk) {
57+
std::vector<unsigned char> compressedData;
58+
compressedData.reserve(chunk.length);
59+
for(int i = 0; i < chunk.length; i++) {
60+
compressedData.push_back(chunk.data[i]);
61+
}
62+
return compressedData;
63+
}
64+
65+
void Image::loadChunks(const unsigned char* data, unsigned int size) {
66+
unsigned int offset = 8;
67+
while(offset < size) {
68+
chunks.push_back(loadChunk(data, offset));
69+
}
70+
}
71+
72+
Chunk* Image::loadChunk(const unsigned char* data, unsigned int& offset) {
73+
unsigned int chunkLength = (data[offset + 0] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | (data[offset + 3]);
74+
offset += 4;
75+
76+
char s[5];
77+
s[0] = data[offset + 0];
78+
s[1] = data[offset + 1];
79+
s[2] = data[offset + 2];
80+
s[3] = data[offset + 3];
81+
s[4] = 0;
82+
std::string chunkType(s);
83+
offset += 4;
84+
85+
std::vector<unsigned char> chunkData;
86+
chunkData.reserve(chunkLength);
87+
88+
for (int p = 0; p < chunkLength; p++) {
89+
chunkData.push_back(data[offset + p]);
90+
}
91+
offset += chunkLength;
92+
93+
unsigned int chunkCRC = (data[offset + 0] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | (data[offset + 3]);
94+
offset += 4;
95+
96+
return new Chunk(chunkLength, chunkType, chunkData, chunkCRC);
97+
}

image.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//
2+
// Created by Ole on 10.09.2017.
3+
//
4+
5+
#pragma once
6+
7+
#include <iostream>
8+
#include <fstream>
9+
#include <string>
10+
#include <vector>
11+
#include <utility>
12+
#include <bitset>
13+
14+
unsigned char reversed(unsigned char value);
15+
16+
#define LOG(x) (std::cout << x << std::endl)
17+
#define LOGB(x) (std::cout << (std::bitset<8>)reversed(x) << std::endl)
18+
19+
//unsigned int crc_table[256];
20+
//
21+
//void build_crc32() {
22+
// for (unsigned int n = 0; n < 256; n++) {
23+
// auto c = n;
24+
// for (unsigned int k = 0; k < 8; k++) {
25+
// if (c & 1)
26+
// c = (c >> 1) ^ 0xedb88320;
27+
// else
28+
// c = c >> 1;
29+
// }
30+
// crc_table[n] = c;
31+
// }
32+
//}
33+
//
34+
//void getCRC() {
35+
// LOG(crc_table[0]);
36+
//}
37+
38+
struct Chunk {
39+
unsigned int length;
40+
std::string type;
41+
std::vector<unsigned char> data;
42+
unsigned int crc;
43+
44+
Chunk(unsigned int length, std::string type, std::vector<unsigned char>& data, unsigned int crc)
45+
: length(length), type(std::move(type)), data(data), crc(crc) {}
46+
};
47+
48+
struct Format {
49+
unsigned int width;
50+
unsigned int height;
51+
char bitDepth;
52+
char colorType;
53+
char compressionMethod;
54+
char filterMethod;
55+
char interlaceMethod;
56+
57+
Format()
58+
: width(0),height(0),bitDepth(0),colorType(0),compressionMethod(0),filterMethod(0),interlaceMethod(0) {}
59+
};
60+
61+
class Image {
62+
public:
63+
std::vector<Chunk*> chunks;
64+
private:
65+
Format format;
66+
public:
67+
Image(const std::string& path);
68+
69+
void init(const std::string& path);
70+
71+
void formatIHDR();
72+
std::vector<unsigned char> extractCompressedPixelData(const Chunk& chunk);
73+
void loadChunks(const unsigned char* data, unsigned int size);
74+
75+
inline const Format& getFormat() const {
76+
return format;
77+
}
78+
private:
79+
Chunk* loadChunk(const unsigned char* data, unsigned int& offset);
80+
};
81+
82+

main.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
#include <cstring>
3+
#include "image.h"
4+
5+
int main() {
6+
{
7+
uint32_t i=0x01020304;
8+
char le[4]={4, 3, 2, 1};
9+
char be[4]={1, 2, 3, 4};
10+
if(memcmp(&i, le, 4)==0)
11+
puts("Little endian");
12+
else if(memcmp(&i, be, 4)==0)
13+
puts("Big endian");
14+
else
15+
puts("Mixed endian");
16+
}
17+
18+
Image image("smile.png");
19+
20+
Format format = image.getFormat();
21+
LOG("bit depth: " << (int) format.bitDepth);
22+
LOG("color type: " << (int) format.colorType);
23+
LOG("compression method: " << (int) format.compressionMethod);
24+
LOG("filter method: " << (int) format.filterMethod);
25+
LOG("interlace method: " << (int) format.interlaceMethod);
26+
LOG("");
27+
28+
int index = 0;
29+
while(image.chunks[++index]->type != "IDAT");
30+
Chunk pixelChunk = *image.chunks[index];
31+
LOG(pixelChunk.type);
32+
LOG(pixelChunk.length);
33+
LOG("");
34+
35+
std::vector<unsigned char> compressedData = image.extractCompressedPixelData(*image.chunks[index]);
36+
LOG("CMF:");
37+
LOGB(compressedData[0] + (unsigned char) (8 <<4));
38+
LOG("FLG:");
39+
LOGB(compressedData[1]); // 16-bit sum is 14415 % 31 == 0
40+
LOG("");
41+
LOGB(compressedData[2]);
42+
LOGB(compressedData[3]);
43+
LOGB(compressedData[4]);
44+
LOGB(compressedData[5]);
45+
LOGB(compressedData[6]);
46+
47+
48+
49+
50+
51+
return 0;
52+
}

0 commit comments

Comments
 (0)