Files
school/semester_5/racunalniska_vecpredstavnost/vaja_2/src/decompressor.cpp

120 lines
2.4 KiB
C++

#
#include <vector>
#include <cmath>
#include <iostream>
#include "decompressor.h"
#include "BitReader.h"
int Decompressor::decode(int g)
{
int v = 0;
for (int i = 0; i < g; i++)
{
bool bit = reader.readBit();
v |= bit << i;
}
return v;
}
void Decompressor::DEIC(std::vector<int> &C, int L, int H)
{
if (H - L <= 1)
return;
if (C[L] == C[H])
{
for (size_t i = L + 1; i < H; i++)
{
C[i] = C[L];
}
}
else
{
int M = (L + H) / 2;
int G = std::ceil(std::log2(C[H] - C[L] + 1));
C[M] = C[L] + decode(G);
if (L < M)
DEIC(C, L, M);
if (M < H)
DEIC(C, M, H);
}
}
std::vector<unsigned char> Decompressor::predictInvers(std::vector<int> &E, int width, int hight)
{
std::vector<unsigned char> matrix1(width * hight, 0);
matrix1[0] = E[0];
for (size_t i = 1; i < width; i++)
{
matrix1[i] = matrix1[i - 1] - E[i];
}
for (size_t i = 1; i < hight; i++)
{
matrix1[i * width] = matrix1[(i - 1) * width] - E[i * width];
}
for (size_t i = 1; i < hight; i++)
{
for (size_t j = 1; j < width; j++)
{
if (matrix1[(i - 1) * width + j - 1] >= std::max(matrix1[i * width + j - 1], matrix1[(i - 1) * width + j]))
{
matrix1[i * width + j] = std::min(matrix1[i * width + j - 1], matrix1[(i - 1) * width + j]) - E[i * width + j];
}
else if (matrix1[(i - 1) * width + j - 1] <= std::min(matrix1[i * width + j - 1], matrix1[(i - 1) * width + j]))
{
matrix1[i * width + j] = std::max(matrix1[i * width + j - 1], matrix1[(i - 1) * width + j]) - E[i * width + j];
}
else
{
matrix1[i * width + j] = matrix1[i * width + j - 1] + matrix1[(i - 1) * width + j] - matrix1[(i - 1) * width + j - 1] - E[i * width + j];
}
}
}
return matrix1;
}
std::vector<unsigned char> Decompressor::decompress()
{
int hight = reader.readShort();
int first = reader.readByte();
int last = reader.readInt();
int size = reader.readInt();
int width = size / hight;
std::vector<int> C(size, 0);
C[0] = first;
C[size - 1] = last;
DEIC(C, 0, size - 1);
std::vector<int> N(size, 0);
N[0] = C[0];
for (size_t i = 1; i < size; i++)
{
N[i] = C[i] - C[i - 1];
}
std::vector<int> E(size, 0);
E[0] = N[0];
for (size_t i = 1; i < size; i++)
{
if (N[i] % 2 == 0)
{
E[i] = N[i] / 2;
}
else
{
E[i] = -((N[i] + 1) / 2);
}
}
return predictInvers(E, width, hight);
}