+// g++ -std=c++11 -O4 -msse2 -msse3 -msse4 -fopenmp -O3 test_mat2.cpp -o test_mat2 -I /home/couturie/tools/armadillo-6.200.5/include/ -lc -lm -lpthread -lgfortran -DMAX_STACK_ALLOC=2048 -Wall -m64 -DF_INTERFACE_GFORT -fPIC -DSMP_SERVER -DNO_WARMUP -DMAX_CPU_NUMBER=8 -DNO_AFFINITY -UCOMPLEX -DDOUBLE -I/home/couturie/tools/openblas/include -I/home/couturie/Downloads/OpenBLAS-0.2.15/ /home/couturie/tools/openblas/lib/libopenblas_haswellp-r0.2.15.a
+
+
+
+#include <armadillo>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <iostream>
+#include <iterator> // std::ostream_iterator
+#include <fstream>
+#include <vector>
+#include <iostream> // std::cout, std::fixed
+#include <iomanip>
+#include <math.h>
+
+using namespace arma;
+using namespace std;
+int key_size=256;
+
+
+ const int mm=251;
+
+typedef unsigned char byte;
+
+
+template<typename T>
+T mod(T a, int n)
+{
+ return a - floor(a/n)*n;
+}
+
+inline int positive_modulo(int i, int n) {
+ return (i % n + n) % n;
+}
+
+void Bezout(int rkm2,int rkm1,int *res,int ukm1=0,int vkm1=1,int ukm2=1,int vkm2=0){
+/*r(k-4)=r(k-3)*q(k-2)+r(k-2) <=> r(k-2)=a*u(k-2)+b*v(k-2)
+
+
+r(k-3)=r(k-2)*q(k-1)+r(k-1) <=> r(k-1)=a*u(k-1)+b*v(k-1)
+
+r(k-2)=r(k-1)*q(k)+r(k) <=> r(k)=a*u(k)+b*v(k) avec u(k)=u(k-2)-qk*u(k-1) et v(k)=v(k-2)-qk*v(k-1)*/
+
+ int rk=rkm2%rkm1;
+ int qk=(rkm2-rk)/rkm1;
+ if(rk==0) {
+ cout<<rkm1<<" = a*"<<ukm1<<"+b*"<<vkm1<<std::endl;
+ *res=ukm1;
+ }
+ else
+ Bezout(rkm1,rk,res,ukm2-qk*ukm1,vkm2-qk*vkm1,ukm1,vkm1);
+ return;
+}
+
+
+void saveFile(Row<byte> data, const char *fileName,long size_file=0) {
+ byte* vec=(byte*)data.memptr();
+// cout<<"vec "<<d2.size()<<endl;
+ FILE* pFile = fopen (fileName, "wb");
+ if(size_file==0)
+ size_file=data.size();
+
+ fwrite (vec , sizeof(byte), size_file, pFile);
+ fclose (pFile);
+
+
+/* vector<uint8_t> v =conv_to< vector<uint8_t> >::from(data);
+ ofstream outfile(fileName, ios::out | ofstream::binary);
+
+ copy(v.begin(), v.end(), ostream_iterator<uint8_t>(outfile));
+ outfile.close();
+*/
+
+}
+
+Row<byte> readFile( const char *fileName) {
+ /*ifstream stream(fileName, ios::in | ios::binary | ios::ate);
+ int sizeFile=stream.tellg();
+ stream.seekg(0, ios::beg);
+ vector<uint8_t> vec((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
+ Row<byte> d2(vec);
+ */
+
+
+ FILE* pFile = fopen (fileName, "rb");
+ fseek(pFile, 0L, SEEK_END);
+ int sz = ftell(pFile);
+ rewind(pFile);
+ byte* vec=new byte[sz];
+ fread (vec , sizeof(byte), sz, pFile);
+ fclose (pFile);
+
+
+ Row<byte> d2(vec,sz);
+ delete vec;
+
+
+ cout<<"vec ici"<<d2.size()<<endl;
+ return d2;
+}
+
+
+
+vector<uint8_t>
+convert_vec256_to_vec250(vector<uint8_t> vec256){
+
+
+ int num_val_greater = std::count_if(vec256.begin(), vec256.end(), [](int i){return i>=mm;});
+ vector<uint8_t> vec250;
+ vec250.reserve(vec256.size()+num_val_greater);
+ // cout<<"ICI "<<vec250.size()<<" "<<vec256.size()+num_val_greater<<endl;
+
+ int l=0;
+ for (int i=0; i<vec256.size(); i++) {
+ if(vec256[i]>=mm-1) {
+ vec250.push_back(mm-1);
+ vec250.push_back(vec256[i]-mm+1);
+ //vec250[l++]=(mm-1);
+
+ //vec250[l++]=vec256[i]-mm+1;
+ }
+ else {
+ vec250.push_back(vec256[i]);
+ //vec250[l++]=vec256[i];
+ }
+ }
+ //cout<<"ICI "<<vec250.size()<<endl;
+ return vec250;
+
+
+}
+
+vector<uint8_t>
+convert_vec250_to_vec256(vector<uint8_t> vec250){
+
+
+ vector<uint8_t> vec256;
+ vec256.reserve(vec250.size());
+
+ for (int i=0; i<vec250.size(); i++) {
+ if(vec250[i]==mm-1) {
+ vec256.push_back(vec250[++i]+mm-1);
+ }
+ else {
+ vec256.push_back(vec250[i]);
+ }
+ }
+
+// cout<<"ICI 2 "<<vec256.size()<<endl;
+ return vec256;
+}
+
+
+
+
+
+Mat<byte> readFullFile(int n, int k, long& sizeFile, int &lc) {
+
+// ifstream stream("lena.png", ios::in | ios::binary | ios::ate);
+ ifstream stream("/home/couturie/Downloads/CARCARIASS.zip", ios::in | ios::binary | ios::ate);
+// ifstream stream("lena_small2.png", ios::in | ios::binary | ios::ate);
+ sizeFile=stream.tellg();
+ cout<<sizeFile<<endl;
+ stream.seekg(0, ios::beg);
+
+
+ uint8_t mysize[8];
+
+
+ long tmpSize=sizeFile;
+ for(int i=0;i<8;i++) {
+ uint8_t t=tmpSize;
+// cout<<(int)t<<endl;
+ mysize[i]=t;
+ tmpSize>>=8;
+ }
+
+ cout<<"rebuild"<<endl;
+ long res=0;
+ for(int i=8-1;i>=0;i--) {
+ res<<=8;
+ res+=mysize[i];
+ }
+
+ cout<<(long)res<<endl;
+
+
+
+ vector<uint8_t> contents((istreambuf_iterator<char>(stream)), istreambuf_iterator<char>());
+ cout<<"res contents "<<contents.size()<<endl;
+ cout<<"add size of file"<<endl;
+// for(int i=0;i<8;i++)
+// contents.insert(i,mysize[i]);
+ contents.insert (contents.begin(), mysize, mysize+8);
+ cout<<"res contents "<<contents.size()<<endl;
+ vector<uint8_t> contents2=convert_vec256_to_vec250(contents);
+ cout<<"res contents2 "<<contents2.size()<<endl;
+
+
+
+/*
+ cout<<"AFTER"<<endl;
+for (auto i = contents2.begin(); i != contents2.end(); ++i)
+ std::cout << (int)*i << ' ';
+cout<<endl;
+*/
+
+// vector<uint8_t> contents3=convert_vec250_to_vec256(contents2);
+
+ /*cout<<"LAST"<<endl;
+for (auto i = contents3.begin(); i != contents3.end(); ++i)
+ cout << (int)*i << ' ';
+cout<<endl;
+
+
+if (std::equal(contents.begin(), contents.begin() + contents.size(), contents3.begin()))
+ cout << "success" << endl;
+ */
+
+lc=ceil(contents2.size()/k);
+ cout<<lc<<endl;
+ Mat<byte> matData(&contents2[0],1,contents2.size());
+
+
+/* Row<byte> test(&contents[0],contents.size());
+ cout<<"test "<<size(test)<<endl;
+ saveFile(test, "lena3.png");
+*/
+
+ cout << "file size: " << contents2.size() << endl;
+
+ matData.reshape(k,lc);
+ cout<<matData.n_rows<<" "<<matData.n_cols<<endl;
+ return matData;
+}
+
+
+
+
+int main( int argc, char *argv[] ) {
+
+
+
+ int full=0;
+
+ int n=8;
+ int k=4;
+ int Tb=64;
+ int l=10;//399*Tb;
+
+
+
+
+
+
+
+
+ int lc;
+ long sizeFile;
+ Mat<byte> S;
+ S=readFullFile(n,k,sizeFile,lc);
+
+
+
+ arma_rng::set_seed(time(NULL));
+ //S=randi<Mat<byte>>(k,100000000);
+
+ cout<<"S "<<size(S)<<endl;
+ S=mod(S,mm);
+
+ Mat<byte> G= randi<Mat<byte>>(n,k);
+ cout<<"G "<<size(G)<<endl;
+
+
+ Mat<int> C=conv_to<Mat<int>>::from(G)*conv_to<Mat<int>>::from(S);
+ C=mod(C,mm);
+ cout<<"C "<<size(C)<<endl;
+
+ Mat<byte> C2=conv_to<Mat<byte>>::from(C);
+
+
+ //write files
+ for(int i=0;i<n;i++) {
+ stringstream ss;
+ ss <<"lena_"<<i<<".png";
+ string str = ss.str();
+ saveFile(C2.row(i), str.c_str());
+ }
+
+
+ cout<<"tatat"<<endl;
+ Mat<byte> C3;
+
+ //read k files among n
+ for(int i=0;i<k;i++) {
+ stringstream ss;
+ ss <<"lena_"<<i<<".png";
+ string str = ss.str();
+
+ Row<byte> d2=readFile(str.c_str());
+ C3.insert_rows(i,d2);
+ }
+
+
+
+
+
+// Mat<int> Cs=C.rows(0,k-1);
+ Mat<int> Cs=conv_to<Mat<int>>::from(C3);
+
+ cout<<size(Cs)<<" "<<size(C3)<<endl;
+
+
+
+ Mat<int> Gs2=conv_to<Mat<int>>::from(G).rows(0,k-1);
+ mat Gs=conv_to<mat>::from(Gs2);
+
+ cout<<"tot"<<endl;
+ cout<<Gs<<endl;
+
+ double determinant2=det(Gs);
+ int determinant=remainder(determinant2,mm);
+ determinant=positive_modulo(determinant,mm);
+
+ int r;
+ Bezout(determinant,mm,&r);
+
+
+ cout<<determinant<<" "<<mm<<" "<<r<<endl;
+
+ mat Gsi=round(inv(Gs)*det(Gs)*r);
+ Gsi=mod(Gsi,mm);
+ Gsi=mod(Gsi,mm);
+
+ cout<<Gsi<<endl;
+
+ mat temp=Gsi*Cs;
+ mat SS2=mod(temp,mm);
+ Mat<byte> S2=conv_to<Mat<byte>>::from(SS2);
+ S2=mod(S2,mm);
+// cout<<S2<<endl;
+// cout<<"max"<<endl;
+// cout<<max(S2-S,1)<<endl;
+
+
+
+
+ S2.reshape(1,S2.n_rows*S2.n_cols);
+
+
+ vector<uint8_t> res =conv_to< vector<uint8_t> >::from(S2.row(0));
+ cout<<"res size "<<res.size()<<endl;
+ vector<uint8_t> res2=convert_vec250_to_vec256(res);
+ cout<<"res2 size "<<res2.size()<<endl;
+
+ cout<<"get size"<<endl;
+ uint8_t mysize[8];
+
+ for(int i=0;i<8;i++) {
+ mysize[i]=res2.front();
+ res2.erase(res2.begin());
+ }
+
+ for(int i=0;i<8;i++)
+ cout<<(int)mysize[i]<<endl;
+
+ cout<<"rebuild size"<<endl;
+ long size_file=0;
+ for(int i=8-1;i>=0;i--) {
+ size_file<<=8;
+ size_file+=mysize[i];
+ }
+
+ cout<<"size file "<<(long)size_file<<endl;
+ saveFile(res2, "lena2.png",size_file);
+
+
+
+
+}