For the past 2 months, I've been implementing a png/deflate decoder, (for various reasons but mainly for learning purposes) but only returns the correct expected data in some cases.
Here in this table, I've gathered some details of the files (and the files themselves) that I've been using for the program in case you want to check them out:
State | Image | Block type | Lz77 obtained (if fail) | Header info (Block type 2 only) |
---|---|---|---|---|
Works | Color checker pattern | 2 | HLIT: 29, HDIST: 23, HCLEN: 14, Header cls: {0,3,3,3,3,4,0,4,0,3,0,4,0,4,0,4,0,4} | |
Works | A grid with grayscale pixels | 1 | ||
Doesn't work | 10x10 noise image | 2 | 0 0 0 1 2 257 4 0 3 1 4 0 5 6 7 8 0 9 10 11 0 12 0 3 0 13 14 1 15 0 1 16 17 258 -fails here [ 9 11 ] -Program attempts to read 36 symbols backwards on a 33 sized list | HLIT: 2, HDIST: 13, HCLEN: 12, Header cls: {2,4,4,4,0,2,0,4,0,5,0,5,0,4,0,3} |
Doesn't work | ![]() |
1 | 1 255 255 255 0 260 0 1 1 261 6 0 0 0 183 262 8 3 2 261 5 1 270 0 0 272 0 9 6 51 255 176 266 0 -fails here [ 26 141 ] -Program attempts to read 8334 symbols backwards on a 34 sized list | |
Returns malformed data | Some random colors | 2 | Possibly some data was malformed | HLIT: 4, HDIST: 10, HCLEN: 14, Header cls: {0,4,3,3,0,0,0,3,0,4,0,3,0,2,0,4,0,4} |
Here is a snippet (or a MRE) of how I implemented deflate (The program needs the image path as a parameter; I tried my best to get it working with the fewest lines of code):
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
//Quick table for ll distinction
uint16_t qtfld[5][2] = {
{269,1},{273,2},
{277,3},{281,4},
{285,5}
};
//Quick table for distance distinction
uint8_t qtfdd[13][2] = {
{6,1},{8,2},{9,3},
{12,4},{14,5},{16,6},
{18,7},{20,8},{22,9},
{24,10},{26,11},{28,12},
{30,13}
};
uint32_t FlipEndian(
uint32_t value,
uint32_t SToFlip
){
if(SToFlip==0){return 0;}
else{
uint32_t reversed = 0;
for(uint32_t w = 0; w <= SToFlip; w++){
uint32_t lshift = 0;
uint32_t rshift = 0;
lshift = value<<(31-w);
rshift = lshift>>31;
reversed = (rshift<<((SToFlip-1)-w)) | reversed;
}
return reversed;
}
}
uint16_t** GenCodes(
uint16_t* cl_table,
uint16_t* symbol_table,
uint32_t both_tables_size
){
//Finaltable
uint32_t sizecodes = both_tables_size * sizeof(uint16_t*);
uint16_t** codes = (uint16_t**)malloc(sizecodes);
for(uint32_t i=0; i<both_tables_size; i++){
codes[i] = (uint16_t*)malloc(3*sizeof(uint16_t));
}
//List for the sorting and frequency obtaining of the cl codes
uint32_t size = both_tables_size*sizeof(uint16_t);
int16_t* used_cls = (int16_t*)malloc(size);
for(uint32_t i=0; i<both_tables_size; i++){
used_cls[i] = -1;
}
//The aforementioned sorted cl table
uint32_t cl_amount = 15*sizeof(uint16_t*);
uint16_t** sorted_cl_frequencies = (uint16_t**)malloc(cl_amount);
for(uint32_t c=0; c<15; c++){
sorted_cl_frequencies[c] = (uint16_t*)malloc(2*sizeof(uint16_t));
}
for(uint32_t i=0; i<both_tables_size; i++){
uint16_t min_cl = 15;
uint8_t cl_usage = 0;
for(uint32_t j=0; j<both_tables_size; j++){
uint16_t current_cl = cl_table[i];
for(uint32_t k=0; k<both_tables_size; k++){
if(current_cl == used_cls[k]){
cl_usage = 1;
break;
}
}
if(cl_usage==0){
if(current_cl<min_cl){min_cl = current_cl;}
}
}
if(cl_usage==0){
uint32_t cl_counter = 0;
for(uint32_t a=0; a<both_tables_size; a++){
if(cl_table[a]==min_cl){cl_counter++;}
}
sorted_cl_frequencies[min_cl][0] = min_cl;
sorted_cl_frequencies[min_cl][1] = cl_counter;
used_cls[i] = min_cl;
}
}
//Huffman code algorithm
uint16_t code = 0;
for(uint32_t i = 1; i <= 15; i++) {
if(i<15){
uint16_t prevfreq = sorted_cl_frequencies[i-1][1];
uint16_t prevcl = sorted_cl_frequencies[i][0];
code = (code + prevfreq) << 1;
uint16_t aum = 0;
for(uint32_t j = 0;j<both_tables_size;j++){
if(prevcl==cl_table[j]){
codes[j][0] = symbol_table[j];
codes[j][1] = cl_table[j];
codes[j][2] = FlipEndian(code+aum,cl_table[j]);
aum+=1;
}
}
}
}
for(uint8_t i=0; i<15; i++){
free(sorted_cl_frequencies[i]);
}
free(used_cls);
free(sorted_cl_frequencies);
return codes;
}
//OverallSlicedDataGathering
uint16_t OSDG(
uint8_t* list,
uint32_t* biotl, //bitindexonthelist
uint8_t sogd //sizeofgivendata
){
uint32_t currentbyte = (uint32_t)floor((*biotl/8));
uint32_t landingbyte = (uint32_t)floor((((*biotl-1)+sogd)/8));
uint16_t final_data = 0;
if(landingbyte>currentbyte){
if(landingbyte>(currentbyte+1)){
uint8_t bocb = 8-(*biotl%8);//bitsoncurrentbyte
uint8_t slice1 = list[currentbyte]>>(8-bocb);
uint8_t bonb = sogd-bocb;//bitsonnextbyte
uint8_t slice2 = list[landingbyte] << (8-bonb);
slice2 = slice2>>(8-bonb);
uint16_t walls = 0;
uint8_t middleslice = list[currentbyte+1];
walls = (slice2<<(bocb+8)) | (middleslice<<bocb) | slice1;
final_data = walls;
}
else{
uint8_t bocb = 8-(*biotl%8);//bitsoncurrentbyte
uint8_t slice1 = list[currentbyte]>>(8-bocb);
uint8_t bonb = sogd-bocb;//bitsonnextbyte
uint8_t slice2 = list[landingbyte] << (8-bonb);
slice2 = slice2>>(8-bonb);
uint16_t walls = 0;
walls = (slice2<<(bocb)) | slice1;
final_data = walls;
}
}
else{
//alongpartsifthereis
uint8_t apiti = (*biotl%8)+sogd;
//ShapedData
uint8_t sd = list[currentbyte] << (8-apiti);
sd = sd >> (8-sogd);
final_data = (uint16_t)sd;
}
*biotl += sogd;
return final_data;
}
uint16_t* Obtain_CL_From_Bistream(
uint16_t encoded_cls,
uint16_t** codes,
uint32_t size_of_codes,
uint32_t* bit_index,
uint8_t* idat_pointer
){
uint32_t size = sizeof(uint16_t)*encoded_cls;
uint16_t* finaltable = (uint16_t*)malloc(size);
//skippedllsymbols
int16_t sls = -1;
for(uint16_t i=0; i<encoded_cls; i++){
if(i>sls){
for(uint32_t j=0; j<size_of_codes; j++){
uint16_t cc = codes[j][2]; //currentcode
uint16_t ccl = codes[j][1]; //currentcodelength
uint16_t ccs = codes[j][0]; //currentcodesymbol
//retrievedsymbolcodefrombitstream
uint8_t rscfb = OSDG(idat_pointer,bit_index,ccl);
*bit_index-= ccl;
if(rscfb==cc){
*bit_index += ccl;
//amountofsymbols
uint16_t aos = 0;
if(ccs==16){
uint8_t ntb = OSDG(idat_pointer,bit_index,2);
aos = (ntb+3);
//previoussymbol
uint16_t ps = (uint16_t)(finaltable[i-1]);
for(uint16_t x=0 ;x<=aos; x++){
finaltable[i+x] = ps;
}
}
else if(ccs==17){
//nextthreebits
uint8_t ntrb = OSDG(idat_pointer,bit_index,3);
aos = (ntrb+3);
for(uint16_t x=0; x<=aos; x++){
finaltable[i+x] = (uint16_t)(0);
}
}
else if(ccs==18){
//nextsevenbits
uint8_t nsb = OSDG(idat_pointer,bit_index,7);
aos = (nsb+11);
for(uint16_t x=0; x<=aos; x++){
finaltable[i+x] = (uint16_t)(0);
}
}
else{
aos = 1;
finaltable[i] = (uint16_t)(ccs);
}
sls += aos;
break;
}
}
}
}
return finaltable;
}
uint16_t* Uncompressed(
uint32_t* bit_index,
uint8_t* idat_pointer,
uint32_t arbitrary_size
){
*bit_index += 5;
uint16_t len1 = idat_pointer[(uint32_t)floor((*bit_index/8))];
uint16_t len2 = idat_pointer[(uint32_t)floor((*bit_index/8))+1];
uint16_t LEN = (len1<<8)|(len2);
*bit_index += 16;
uint16_t nlen1 = idat_pointer[(uint32_t)floor((*bit_index/8))];
uint16_t nlen2 = idat_pointer[(uint32_t)floor((*bit_index/8))+1];
uint16_t NLEN = ~((nlen1<<8)|(nlen2));
*bit_index += 16;
uint32_t size = arbitrary_size*(sizeof(uint16_t));
uint16_t* data = (uint16_t*)malloc(size);
for(uint32_t i = 0; i<arbitrary_size; i++){
data[i] = 0;
}
if(LEN==NLEN){
for(uint32_t i = 0; i<arbitrary_size; i++){
data[i] = OSDG(idat_pointer,bit_index,8);
}
}
return data;
}
uint16_t* Static(
uint32_t* bit_index,
uint8_t* idat_pointer,
uint32_t arbitrary_size
){
uint32_t size = arbitrary_size*(sizeof(uint16_t));
uint16_t* data = (uint16_t*)malloc(size);
uint8_t EOT_found=0;
for(uint32_t i=0; i<arbitrary_size; i++){
if(EOT_found){break;}
uint8_t ignore=0;
//newobtainedfixedvaluefrombitstream
int16_t nofvfb = (int16_t)OSDG(idat_pointer,bit_index,8);
nofvfb = FlipEndian(nofvfb,8);
*bit_index-=8;
if((nofvfb-48)<=143 && (nofvfb-48)>=0){
*bit_index+=8;
data[i] = (nofvfb-48);
ignore=1;
}
nofvfb = (int16_t)OSDG(idat_pointer,bit_index,9);
nofvfb = FlipEndian(nofvfb,9);
*bit_index-=9;
if((nofvfb-256)<=255 && (nofvfb-256)>=144){
if(ignore==0){
data[i] = (nofvfb-256);
*bit_index+=9;
ignore=1;
}
}
nofvfb = (int16_t)OSDG(idat_pointer,bit_index,7);
nofvfb = FlipEndian(nofvfb,7);
*bit_index-=7;
if((nofvfb+256)<=279 && (nofvfb+256)>=256){
if(ignore==0){
*bit_index+=7;
if((nofvfb+256)!=256){
data[i] = (nofvfb+256);
ignore=1;
if((nofvfb+256)>264 && (nofvfb+256)<285){
for(uint32_t j=0;j<5;j++){
if((nofvfb+256)<qtfld[j][0]){
i+=1;
//readoffsetbitsoflength
uint8_t robol = (uint8_t)OSDG(idat_pointer,bit_index,qtfld[j][1]);
data[i] = robol;
break;
}
}
}
i+=1;
//distancereturnedvaluebybits
uint8_t drvbb = (uint8_t)OSDG(idat_pointer,bit_index,5);
drvbb = FlipEndian(drvbb,5);
data[i] = drvbb;
if(drvbb>3){
for(uint32_t k=0;k<13;k++){
if(drvbb<qtfdd[k][0]){
i+=1;
//readoffsetbitsofdistance
uint8_t robod = (uint8_t)OSDG(idat_pointer,bit_index,qtfdd[k][1]);
data[i] = robod;
break;
}
}
}
}
else{
data[i] = (nofvfb+256);
ignore=1;
EOT_found=1;
}
}
}
nofvfb = (int16_t)OSDG(idat_pointer,bit_index,8);
nofvfb = FlipEndian(nofvfb,8);
*bit_index-=8;
if((nofvfb+88)<=287 && (nofvfb+88)>=280){
if(ignore==0){
*bit_index+=8;
data[i] = (nofvfb+88);
ignore=1;
if((nofvfb+88)>264 && (nofvfb+88)<285){
for(uint32_t j=0;j<5;j++){
if((nofvfb+88)<qtfld[j][0]){
i+=1;
//readoffsetbitsoflength
uint8_t robol = (uint8_t)OSDG(idat_pointer,bit_index,qtfld[j][1]);
data[i] = robol;
break;
}
}
}
i+=1;
//distancereturnedvaluebybits
uint8_t drvbb = (uint8_t)OSDG(idat_pointer,bit_index,5);
drvbb = FlipEndian(drvbb,5);
data[i] = drvbb;
if(drvbb>3){
for(uint32_t k=0;k<13;k++){
if(drvbb<qtfdd[k][0]){
i+=1;
//readoffsetbitsofdistance
uint8_t robod = (uint8_t)OSDG(idat_pointer,bit_index,qtfdd[k][1]);
data[i] = robod;
break;
}
}
}
}
}
}
return data;
}
uint16_t* Dynamic(
uint32_t* bit_index,
uint8_t* idat_pointer,
uint32_t arbitrary_size
){
uint8_t HLIT = (uint8_t)OSDG(idat_pointer,bit_index,5);
printf("\nHLIT: %d",HLIT);
uint8_t HDIST = (uint8_t)OSDG(idat_pointer,bit_index,5);
printf("\nHDIST: %d",HDIST);
uint8_t HCLEN = (uint8_t)OSDG(idat_pointer,bit_index,4);
printf("\nHCLEN: %d",HCLEN);
uint16_t newcl_clorder[19] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
//List of CLs
uint16_t* CL_cl_lengths = (uint16_t*)malloc(sizeof(uint16_t)*(HCLEN + 4));
printf("\nHeader cls\n");
uint8_t not_zero_cls_counter = 0;
for(uint32_t i = 0; i < (HCLEN + 4); i++){
uint8_t CL_cl = (uint8_t)OSDG(idat_pointer,bit_index,3);
CL_cl_lengths[newcl_clorder[i]] = CL_cl;
printf("%d,",CL_cl_lengths[newcl_clorder[i]]);
if(CL_cl!=0){
not_zero_cls_counter++;
}
}
uint32_t size = sizeof(uint16_t)*not_zero_cls_counter;
//sorted header cl symbols
uint16_t* shcs = (uint16_t*)malloc(size);
//sorted header cl cl
uint16_t* shcc = (uint16_t*)malloc(size);
int8_t* used_cls = (int8_t*)malloc(sizeof(int8_t)*not_zero_cls_counter);
for(uint8_t i=0; i<not_zero_cls_counter; i++){used_cls[i]=-1;}
for(uint8_t i=0; i<not_zero_cls_counter; i++){
uint8_t smallestsymbol = 18;
uint8_t smallestsymbol_index = 2;
for(uint8_t j=0; j<(HCLEN + 4); j++){
uint8_t used_cls_usage = 0;
uint16_t newavailablesymbol = newcl_clorder[j];
for(uint8_t k=0; k<not_zero_cls_counter; k++){
if(newavailablesymbol==used_cls[k]){
used_cls_usage = 1;
break;
}
}
if(used_cls_usage==0){
uint8_t newsymbcl = CL_cl_lengths[newcl_clorder[j]];
if(newavailablesymbol<smallestsymbol && newsymbcl != 0){
smallestsymbol = newavailablesymbol;
smallestsymbol_index = j;
}
}
}
shcs[i] = newcl_clorder[smallestsymbol_index];
shcc[i] = CL_cl_lengths[newcl_clorder[smallestsymbol_index]];
used_cls[i] = newcl_clorder[smallestsymbol_index];
}
uint16_t** header_cl_symbols = GenCodes(shcc,shcs,not_zero_cls_counter);
///////////Obtainingofllcodes
uint16_t* zeroed_ll_cls = Obtain_CL_From_Bistream(
(257+HLIT),header_cl_symbols,
not_zero_cls_counter,
bit_index,idat_pointer
);
uint16_t* ll_cl = (uint16_t*)malloc(sizeof(uint16_t)*288);
uint16_t* ll_symbols = (uint16_t*)malloc(sizeof(uint16_t)*288);
//finalsizeofnotzeroedlls
uint32_t fsonzl = 0;
uint32_t ll_omitter = 0;
for(uint32_t i=0; i<(257+HLIT);i++){
if(zeroed_ll_cls[i]!=0){
ll_cl[i-ll_omitter] = zeroed_ll_cls[i];
ll_symbols[i-ll_omitter]=i;
fsonzl+=1;
}
else{ll_omitter+=1;}
}
uint16_t** ll_codes = GenCodes(ll_cl,ll_symbols,fsonzl);
printf("\nLL generated codes:");
for(uint32_t l=0; l<fsonzl; l++){
printf("\nsymbol: %d, ",ll_codes[l][0]);
printf("cl: %d, ",ll_codes[l][1]);
printf("code: %d",ll_codes[l][2]);
}
///////////Obtainingofdistcodes
uint16_t* zeroed_dist_cls = Obtain_CL_From_Bistream(
(HDIST+1),header_cl_symbols,
not_zero_cls_counter,
bit_index,idat_pointer
);
uint16_t* dist_cl = (uint16_t*)malloc(sizeof(uint16_t)*32);
uint16_t* dist_symbols = (uint16_t*)malloc(sizeof(uint16_t)*32);
//finalsizeofnotzeroeddist
uint32_t fsonzd = 0;
uint32_t dist_omitter = 0;
for(uint32_t i=0; i<(HDIST+1);i++){
if(zeroed_dist_cls[i]!=0){
dist_cl[i-dist_omitter] = zeroed_dist_cls[i];
dist_symbols[i-dist_omitter] = i;
fsonzd+=1;
}
else{dist_omitter+=1;}
}
uint16_t** dist_codes = GenCodes(dist_cl,dist_symbols,fsonzd);
printf("\nDistance generated codes:");
for(uint32_t d=0; d<fsonzd; d++){
printf("\nsymbol: %d, ",dist_codes[d][0]);
printf("cl: %d, ",dist_codes[d][1]);
printf("code: %d",dist_codes[d][2]);
}
///////////bitstreamdecryption
uint32_t bsize = arbitrary_size*(sizeof(uint16_t));
uint16_t* data = (uint16_t*)malloc(bsize);
for(uint32_t i=0; i<arbitrary_size; i++){data[i]=0;}
int ofsfld = -1;
uint8_t megabreak = 0;
for(int i=0; i<arbitrary_size; i++){
if(megabreak==1){break;}
if(i>ofsfld){
for(uint16_t j=0; j<=fsonzl; j++){
uint16_t cc = ll_codes[j][2]; //currentcode
uint16_t ccl = ll_codes[j][1]; //currentcodelength
uint16_t ccs = ll_codes[j][0]; //currentcodesymbol
//retrievedllsymbolcodefrombistream
uint16_t rlscfb = OSDG(idat_pointer,bit_index,ccl);
*bit_index -= ccl;
if(rlscfb==cc){
*bit_index += ccl;
data[i] = ccs;
ofsfld+=1;
if(ccs==256){megabreak=1;break;}
if(ccs>256){
uint8_t aum = 0;
if(ccs>264 && ccs!=285){
for(uint8_t t=0; t<5; t++){
if(ccs<qtfld[t][0]){
//readoffset
data[(i+1)] = OSDG(idat_pointer,bit_index,qtfld[t][1]);
aum=1;
ofsfld+=1;
break;
}
}
}
for(uint32_t k=0; k<=fsonzd; k++){
uint16_t dcc = dist_codes[k][2]; //distancecc
uint16_t dccl = dist_codes[k][1]; //distanceccl
uint16_t dccs = dist_codes[k][0]; //distanceccs
//retrieveddistancesymbolcodefrombistream
uint8_t rdscfb = OSDG(idat_pointer,bit_index,dccl);
*bit_index -= dccl;
if(rdscfb==dcc){
*bit_index += dccl;
ofsfld += 1;
data[(i+(1+aum))] = dccs;
if(dccs>3){
for(uint8_t e=0; e<13; e++){
if(dccs<qtfdd[e][0]){
//readoffset
data[(i+(2+aum))] = OSDG(idat_pointer,bit_index,qtfdd[e][1]);
ofsfld += 1;
break;
}
}
}
break;
}
}
}
break;
}
}
}
}
for(uint8_t i=0; i<not_zero_cls_counter; i++){
free(header_cl_symbols[i]);
}
free(header_cl_symbols);
free(CL_cl_lengths);
free(shcs);
free(shcc);
free(used_cls);
free(ll_symbols);
free(ll_cl);
for(uint8_t i=0; i<fsonzl; i++){
free(ll_codes[i]);
}
free(ll_codes);
free(dist_symbols);
free(dist_cl);
for(uint8_t i=0; i<fsonzd; i++){
free(dist_codes[i]);
}
free(dist_codes);
return data;
}
uint16_t lengthAr[29][2] = {
{257,3}, {258,4},
{259,5}, {260,6},
{261,7}, {262,8},
{263,9}, {264,10},
{265,11}, {266,13},
{267,15}, {268,17},
{269,19}, {270,23},
{271,27}, {272,31},
{273,35}, {274,43},
{275,51}, {276,59},
{277,67}, {278,83},
{279,99}, {280,115},
{281,131}, {282,163},
{283,195}, {284,227},
{285,258}
};
uint16_t distanceAr[30][2] = {
{0,1}, {1,2},
{2,3}, {3,4},
{4,5}, {5,7},
{6,9}, {7,13},
{8,17}, {9,25},
{10,33}, {11,49},
{12,65}, {13,97},
{14,129}, {15,193},
{16,257}, {17,385},
{18,513}, {19,769},
{20,1025}, {21,1537},
{22,2049}, {23,3073},
{24,4097}, {25,6145},
{26,8193}, {27,12289},
{28,16385}, {29,24577}
};
uint8_t* Lz77(
uint16_t* lz77_pointer,
uint32_t arbitrary_size
){
//currentindexfordecrypteddata
uint32_t cifdd = 0;
uint8_t* data = (uint8_t*)malloc(arbitrary_size*sizeof(uint8_t));
//lengtharraysizeonvariable
uint16_t lason = (uint16_t)floor((sizeof(lengthAr)/sizeof(lengthAr[0])));
//distancearraysizeonvariable
uint16_t dason = (uint16_t)floor((sizeof(distanceAr)/sizeof(distanceAr[0])));
uint8_t megabreak = 0;
for(uint32_t i=0; i<arbitrary_size; i++){
printf("\ndata at %d: %d",i,lz77_pointer[i]);
if(lz77_pointer[i]==256 || megabreak==1){break;}
if(lz77_pointer[i]>256){
uint32_t rs = 0; //repeatsize
int dtg = 0; //distancetogo
for(uint16_t j=0; j<lason; j++){
if(lz77_pointer[i]==lengthAr[j][0]){
i+=1;
//offsetbitslength
uint16_t obl = 0;
if(lengthAr[j][0]>264 && lengthAr[j][0] != 285){
obl = lz77_pointer[i];
i+=1;
}
rs = (lengthAr[j][1])+obl;
for(uint16_t k=0; k<dason; k++){
if(lz77_pointer[i]==distanceAr[k][0]){
uint16_t obd = 0;
if(distanceAr[k][0]>3){
i+=1;
obd = lz77_pointer[i];
}
dtg = (distanceAr[k][1])+obd;
break;
}
}
break;
}
}
printf("\nLength: %d",rs);
printf("\nDistance: %d",dtg);
int backpos = cifdd-dtg;
if(backpos<0){
printf("\nERROR: Reading negative indexes");
break;
}
for(uint32_t s=0; s<rs; s++){
data[cifdd+s] = data[backpos+s];
}
cifdd+=rs;
}
else{
data[cifdd] = lz77_pointer[i];
cifdd += 1;
}
}
return data;
}
int main(
int nop, //numberofparameters
char** pl //parameterlist
){
uint8_t png[32768];
FILE* fp;
fp = fopen(pl[1],"r");
fread(png,sizeof(uint8_t),32768,fp);
fclose(fp);
uint32_t idatsize = 0;
uint8_t* idatpointer = NULL;
for(uint32_t i=8; i<32768; i++){
uint32_t chunksize = (png[i]<<24)|(png[i+1]<<16)|(png[i+2]<<8)|(png[i+3]);
i += 4;
if(png[i]==73 && png[i+1]==68 && png[i+2]==65 && png[i+3]==84){
idatpointer = (uint8_t*)malloc((chunksize-6)*sizeof(uint8_t));
}
i += 4;
if(idatpointer!=NULL){
for(uint32_t j=0;j<chunksize-4;j++){
idatpointer[j] = png[(i+2)+j];
}
break;
}
i += chunksize;
i += 3;
}
uint32_t imgx = (png[16]<<24)|(png[17]<<16)|(png[18]<<8)|(png[19]);
uint32_t imgy = (png[20]<<24)|(png[21]<<16)|(png[22]<<8)|(png[23]);
uint32_t colortype = png[25];
uint8_t samples_per_pixel = 0;
if(colortype==0){samples_per_pixel=1;}
else if(colortype==2){samples_per_pixel=3;}
else if(colortype==3){samples_per_pixel=1;}
else if(colortype==4){samples_per_pixel=2;}
else if(colortype==6){samples_per_pixel=4;}
uint32_t bit = 0;
uint8_t islastbit = (uint8_t)OSDG(idatpointer,&bit,1);
uint8_t btype = (uint8_t)OSDG(idatpointer,&bit,2);
printf("\nbtype: %d",btype);
uint16_t* lz77_pointer = NULL;
uint32_t arbitrary_size = (((imgx*imgy)*samples_per_pixel)+imgy)+idatsize;
if(btype==0){lz77_pointer = Uncompressed(&bit,idatpointer,arbitrary_size);}
else if(btype==1){lz77_pointer = Static(&bit,idatpointer,arbitrary_size);}
else if(btype==2){lz77_pointer = Dynamic(&bit,idatpointer,arbitrary_size);}
printf("\nLzz7 symbols: ");
for(uint32_t i = 0; i<arbitrary_size; i++){
printf("%d ",lz77_pointer[i]);
}
uint8_t* deencryped_data = Lz77(lz77_pointer,arbitrary_size);
printf("\nDecompressed data: ");
for(uint32_t i = 0; i<arbitrary_size; i++){
printf("%d ",deencryped_data[i]);
}
int8_t c = getchar();
free(deencryped_data);
return 0;
}