% <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
% Funkce na ziskani hladiny pro vkladani vodoznaku
%
% function [s]=najdi_prvky_z_hladiny(obraz,hladina,zobraz_prvky)
%
% Vstupni parametry obraz a hladina do ktere vkladame
% dale hodnota true or false zobraz prvky
% Vystupni je dana matice hodnot z dane hladiny
% <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

function [hlad_po, hlad_vodoz, Obr_upr, w, NCC] = Patchwork_dekoder(obraz,vodoznak,hladina,klic,cislo_klice,velke)

 puvod_obraz = obraz;

% %jednoduchy utok 
% imwrite(uint8(vodoznak),'jpeg_n.jpg','jpg','Quality',velke); 
% vodoznak=imread('jpeg_n.jpg','jpg'); 

[file_v,cesta_v] = uigetfile('*.jpg', 'Nacteni obrazu pro vodoznaceni');        % *.* nacteni vsech souboru *.bmp
  if file_v == 0
      warning_2;
  else
      vodoznak = (imread(fullfile(cesta_v,file_v)));                                  % info 0 - 255 o kazdem bodu obrazu  
  end

Y = size(obraz,2);                                    % x
X = size(obraz,1);                                    % y  
velikost = X*Y;

A = size(vodoznak,2);                                    % x
B = size(vodoznak,1);                                    % y  

% nacteni souboru po utoku
% pokud je obraz mensi doplnime chybejici cast nulama
if (A < Y) || (B < X)
  H = zeros(X,Y,'uint8');
    for k=1:A
        for l=1:B      
            H(l,k) = H(l,k) + vodoznak(l,k); 
        end
    end
    vodoz = H;
end


% <<<<<<< 8 bitovych rovin, kazda do vlastni matice 1-8 >>>>>     

load OH                                                         % nacteni originalni hladiny z obrazku
hlad_po = OH;

[hlad_vodoz]=najdi_prvky_z_hladiny(vodoznak,hladina,velke);
hlad_vodoz = uint8(hlad_vodoz./255);                            % abym vratili zpet na puvodni hodnoty pred upravou na zobrazeni

% ********** Vytazeni vodoznaku ************

if (cislo_klice <=3)                                            % vodoznaky 1-3
    for m=1:Y
        for n=1:X
            Obr_upr(n,m) = bitxor(hlad_vodoz(n,m),klic(n,m));
        end
    end
    
    % >>>>>>>>>>>>>>>>>> NCC vytazeneho vodoznaku s puvodnim vodoznakem >>>>>>>>>>>>>>>>>>>>>>>>> 

        vod = double(Obr_upr);
        vytazeny_vodoznak = double(OH);
        citatel = sum(sum(vod.*vytazeny_vodoznak));
        jmenovatel = sum(sum(vod.^2));
        NCC = citatel/jmenovatel;
   
else

load Vodoznak                                                   % vodoznak è. 4
[vy,vx] = size(Vodoznak);                                       % velikost vodoznaku

    for a=1:vy;                                                  % vytazeni vodoznaku z obrazu
        for b=1:vx;
            V1(a,b)= hlad_vodoz(a,b);          
            V2(a,b)= hlad_vodoz(PO_sirka-vy+a,b);
            V3(a,b)= hlad_vodoz(a,PO_vyska-vx+b);
            V4(a,b)= hlad_vodoz(PO_sirka-vy+a,PO_vyska-vx+b);
        end
    end

% >>>>>>>>>>>>>>>>>> NCC vytazeneho vodoznaku s puvodnim vodoznakem >>>>>>>>>>>>>>>>>>>>>>>>>
% pokud by se ze stringu dala zavolat promenna usnadnilo by to vypocty
% najde nejlepsi shodu a pote preda jako vysledek zpet

  vod = double(Vodoznak);
  
     for d = 1:4
            switch d
               case 1
                vytazeny_vodoznak = double(V1);
               case 2
                vytazeny_vodoznak = double(V2);
               case 3
                vytazeny_vodoznak = double(V3);
               case 4
                vytazeny_vodoznak = double(V4);
            end
        citatel = sum(sum(vod.*vytazeny_vodoznak));
        jmenovatel = sum(sum(vod.^2));
        NCC(d) = citatel/jmenovatel;      
     end
    
     maximum = max(NCC);                % najdu nejlepsi shodu vodoznaku
     
   for d = 1:4
    if maximum == NCC(d)
            switch d
               case 1
                Obr_upr = V1;
                NC = NCC(d);
               case 2
                Obr_upr = V2;
                NC = NCC(d);
               case 3
                Obr_upr = V3;
                NC = NCC(d);
                case 4
                Obr_upr = V4;
                NC = NCC(d);
            end
     end
   end
 NCC = NC;                      % pokud bude vice stejnych, bylo potreba ulozit do jine promenne aby se neprepsalo NCC
end

%**************************************************************************
if velke == 1
    
figure(254);
imshow(uint8(hlad_po.*255));                                            % puvodni obraz
title('Puvodni obraz z dane hladiny pred dekodovanim','Fontsize',12,'color','blue');

figure(253);
imshow(uint8(hlad_vodoz.*255));                                         % puvodni obraz
title('Obraz po vlozeni vodoznaku do dane hladiny','Fontsize',12,'color','blue');

figure(252);
imshow(uint8(Obr_upr.*255));                                          % puvodni obraz
title('Ziskany obraz po zpetnem vodoznaceni','Fontsize',12,'color','blue');

figure(251);
imshow(uint8(V1.*255));                                            % puvodni obraz
title('V1','Fontsize',12,'color','blue');

figure(250);
imshow(uint8(V2.*255));                                            % puvodni obraz
title('V2','Fontsize',12,'color','blue');

figure(249);
imshow(uint8(V3.*255));                                            % puvodni obraz
title('V3','Fontsize',12,'color','blue');

figure(248);
imshow(uint8(V4.*255));                                            % puvodni obraz
title('V4','Fontsize',12,'color','blue');
end
% >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

figure;
colormap('Gray');                 % zobrazeni vodoznaku po utoku
image(Obr_upr.*255);

if NCC > 0.75
    w='Vlozeny vodoznak vytazen';
 else
    w='Vlozeny vodoznak nenalezen';
end

end