function [signal_in, signal_kvant, signal_out, signal_kvant_out,  psnr, psnr_ok,psnr_kvant] = signal_dequanting2D_impl(image, ridkost, rozmer, original_picture, baze, wavelet, hloubka_decom, pocet_hladin)
global rozdeleni;       
global delta;
global M;
global N;

disp(strcat('image: ', image));
disp(['Ridkost: ' num2str(ridkost)]);
disp(['Rozmer: ' num2str(rozmer)]);

disp(strcat('Obrazek: ', original_picture));
disp(strcat('Baze: ', baze));
disp(strcat('Wavelet: ', wavelet));
disp(['Hloubka Dekompozice: ' num2str(hloubka_decom)]);
disp(['Pocet kvant.hladin: ' num2str(pocet_hladin)]);



J = hloubka_decom;
k = ridkost;
L = rozmer;

%% devise of picture
velikost_deleni = 16;
switch  L < velikost_deleni 
    case true
        velikost_deleni = L;
        m_ = 1;
        n_ = 1;
    case false
        m_ = M/velikost_deleni;
        n_ = N/velikost_deleni;
  
end

 %% Base
 
switch baze
    case 'DCT'
    U = dctmtx(velikost_deleni)';           %baze po zpracovavani obrazu
    U_or = dctmtx(L)';                      %baze po vytvoreni orig. obrazu
     
    case 'DWT'
    [Lo_D,Hi_D,Lo_R,Hi_R] = w_filters(wavelet); 
     U = dwtmatrix(Lo_D,Hi_D,J,velikost_deleni)';           %baze po zpracovavani obrazu
    U_or = dwtmatrix(Lo_D,Hi_D,J,L)';                       %baze po vytvoreni orig. obrazu
   
    
end



%% Original_signal
switch image
    case 'nahodny'
        N = L;
        M = L;
        S = N*N;
        
        x_signal = zeros(S, 1);
        perm = randperm(S); %random positions of nonzeros
        indexes = perm(1:k);
        x_signal(indexes) = randi(255,k,1);    %2*rand(k1,1)-1; %vector of coordinates contains random values from [-1,1] at nonzero positions
        
        koef = reshape(x_signal,M,N);

        original_picture_n = U_or' * koef * U_or; 
                 
        signal_in = original_picture_n(:);
    
    case 'real'
    
            switch size(size(imread(original_picture)),2)
    
                case 3
     
                original_picture_n = im2double(rgb2gray(imread(original_picture)));

                case 2
                 original_picture_n = im2double(imread(original_picture));
            end

            original_picture_n = imresize(original_picture_n,[64,64]);

            M = size(original_picture_n,1);   % size of picture M x N 
            N = size(original_picture_n,2);
 
            signal_in = original_picture_n(:);
end


max_in = max(signal_in);
min_in = min(signal_in);


%% Quantized_signal

delta = (max_in-min_in+0.1)/(pocet_hladin-2);         %sirka hladin
rozdeleni = (min_in-(delta/2)-0.1:delta:max_in+(delta/2));

% quantisation of signal
signal_kvant_v = signal_in;
for i = 1:N*N
    for j = 1:pocet_hladin
         if signal_kvant_v(i) < rozdeleni(j)+(delta/2) && signal_kvant_v(i)>= rozdeleni(j)-(delta/2)
            signal_kvant_v(i) = rozdeleni(j);
        end
    end
end


signal_kvant = reshape(signal_kvant_v,M,N);


%% PSNR
signal_in    = double(signal_in);
signal_kvant_v = double(signal_kvant_v);
absD = abs(signal_in-signal_kvant_v);
moc    = absD.^2;
mse  = sum(moc(:))/numel(signal_in);
psnr_ok = 10*log10((max(signal_in)-min(signal_in))^2/mse);



%% Dictionary
 A = kron(U',U');

%% Dequantisation
%tic;
signal_out = zeros(M,N);
for i = 1:m_
    for j = 1:n_
        
        m_dilci = ((i-1)*velikost_deleni + 1):i*velikost_deleni;
        n_dilci = ((j-1)*velikost_deleni + 1):j*velikost_deleni;
        
        part_of_picture = signal_kvant(m_dilci,n_dilci);
        y = part_of_picture(:);
        
K = velikost_deleni*velikost_deleni; 

f = (ones([1 2*K]));      

s = (delta/2)-y;
t = (delta/2)+y;
b = [s t];
b = b(:);

lb = zeros(2*K,1);      %hledane hodnoty jsou kladne

A_ = [A -A; -A A];

w = linprog(f,A_,b,[],[],lb);   %l1-minimization by linear programming 

uv = reshape(w,K,2);
u = uv(:, 1);
v = uv(:, 2);
sparse_coord_lin = v-u;        
signal_out_v = A*sparse_coord_lin;                      %reconstructed sparse vector of coordinates        

signal_out(m_dilci,n_dilci) = reshape(signal_out_v,velikost_deleni,velikost_deleni);

    end
        
end
disp('konec');
%toc;
%% PSNR
signal_in    = double(signal_in);
signal_out = double(signal_out(:));
absD = abs(signal_in-signal_out);
moc    = absD.^2;
mse  = sum(moc(:))/numel(signal_in);
psnr = 10*log10((max(signal_in)-min(signal_in))^2/mse);


%% quant_original vs. quant_recontr.

% quantisation of signal
signal_kvant_out = signal_out;
for i = 1:N*N
    for j = 1:pocet_hladin
        
         if  signal_kvant_out(i) < rozdeleni(j)+(delta/2) && signal_kvant_out(i)>= rozdeleni(j)-(delta/2)
             signal_kvant_out(i) = rozdeleni(j);
        
        end
    end
end


%% PSNR_kvant
%max_out = max(abs(signal_kvant));
signal_kvant    = double(signal_kvant(:));
signal_kvant_out = double(signal_kvant_out(:));
absD = abs(signal_kvant-signal_kvant_out);
moc    = absD.^2;
mse  = sum(moc(:))/numel(signal_kvant);
psnr_kvant = 10*log10((max(signal_kvant)-min(signal_kvant))^2/mse);





