% *****************************************************************
% Chaoticka mapa
% Stagl Lubos
%
% obraz_new = zmeneny obraz chaos mapou
% Qfaktor, kvatizacni faktor u jpeg komprese, diky tomu velka odolnost 
% alfa = hodnota jenz se bude vkladat do puvodnich dat
% *************************************************************************
function [obraz_IIBPC] = vloz_vodoznak(obraz_new,vodoznak_cesta,Qfaktor,alfa,stred)

Blok = 8;

[m,n]=size(obraz_new);

vodoznak = imread(vodoznak_cesta);
[yv,xv]=size(vodoznak);

RR = zeros(m,n/2);
RC = zeros(m,n/2);

for j=1:m
    cnt = 0;
    for k=1:n/2
            RC(j,k) = obraz_new(j,k+cnt);
            RR(j,k) = obraz_new(j,k+cnt+1);
            cnt = cnt + 1;
    end 
end

% *************************************************************************
% vytvoreni transformacni matice o velikosti B (8*8)

T=dctmtx(Blok);

%transformace do dct po blocich 8*8
RC_dct = blkproc(RC,[Blok Blok],'P1*x*P2',T,T');
RR_dct = blkproc(RR,[Blok Blok],'P1*x*P2',T,T');

% *************************************************************************
% kvantizace Q - faktor >50 zmenseni koef. <50 zvetseni 

QTable =   [16   11   10   16   24   40    51    61         
            12   12   14   19   26   58    60    55
            14   13   16   24   40   57    69    56
            14   17   22   29   51   87    80    62
            18   22   37   56   68   109   103   77
            24   35   55   64   81   104   113   92
            49   64   78   87   103  121   120   101
            72   92   95   98   112  100   103   99];   % kvantizacni jpeg matice

% *************************************************************************
% vypocet Qtable podle Q faktoru
       
if Qfaktor <= 50
    QTable = QTable.*50/Qfaktor;
else
    QTable = QTable.*(2-0.02*Qfaktor);
end

fun = @(x) x./QTable;                        % x=RR_dct, ktere pak vola blkproc

QA = blkproc(RC_dct,[Blok Blok],fun);
QB = blkproc(RR_dct,[Blok Blok],fun);        % samotna kvantizace

% *************************************************************************
% vkladani vodoznaku 
% je mozne vodoznak svou velikosti vlozit do obrazu?

[yqb,xqb]=size(QB);

save('QA.mat');
save('QB.mat');

suma=0;
jednicky=1;
nuly=1;

for j=0:(yqb/Blok-1)
    for k=0:(xqb/Blok-1)

        matQB = QB(j*Blok+1:j*Blok+Blok,k*Blok+1:k*Blok+Blok);
        matQA = QA(j*Blok+1:j*Blok+Blok,k*Blok+1:k*Blok+Blok);

        matQB(1,1) = 0;                                     % snulovani stredni hodnoty
        
        plus = find((matQB) > stred);                       % {+} > nez stred, indexy
        minus = find((matQB) < -stred);                     % {-} < nez stred, indexy
                     
        for y=1:size(plus,1)
            suma = suma + 1;
              if suma <(yv*xv)+1                                              % delej jen do rozmeru vodoznaku
                 if vodoznak(suma) == 1
                        if matQA(plus(y)) > 0
                           matQA(plus(y)) = matQA(plus(y)) + abs(alfa*matQB(plus(y)));        % v jejich navrhu je to matice E
                           jednicky = jednicky+1;                                                  % pocet jednicek
                        else
                           matQA(plus(y)) = matQA(plus(y)) - abs(alfa*matQB(plus(y)));        % v jejich navrhu je to matice E
                           jednicky = jednicky+1;                                                  % pocet jednicek
                        end                           
                 else  
                        nuly = nuly + 1;
                  end
             end
        end
            
        for y=1:size(minus,1)
            suma = suma + 1;
              if suma <(yv*xv)+1                                                                   % delej jen do rozmeru vodoznaku
                 if vodoznak(suma) == 1
                     if matQA(minus(y)) >= 0
                        matQA(minus(y)) = matQA(minus(y)) + abs(alfa*matQB(minus(y)));        % v jejich navrhu je to matice E
                        jednicky = jednicky + 1;                                                     % pocet jednicek
                     else
                        matQA(minus(y)) = matQA(minus(y)) - abs(alfa*matQB(minus(y)));             % v jejich navrhu je to matice E
                        jednicky = jednicky + 1;                                                     % pocet jednicek                       
                     end
                 else  
                        nuly = nuly + 1;
                        
                 end               
               end
        end
        QA(j*Blok+1:j*Blok+Blok,k*Blok+1:k*Blok+Blok) = matQA;
    end   
end

jednicky
nuly
suma

% *************************************************************************
% po vkladani vodoznaku nutno QA vynasobit kvantizacni matici

fun = @(x) x.*QTable;                           % x=RR_dct, ktere pak vola blkproc
MA = blkproc(QA,[Blok Blok],fun);

RC_IDCT = blkproc(MA,[Blok Blok],'P1*x*P2',T',T);     % zpetna dct transformace po blocich B*B

RC_IDCT = ceil(RC_IDCT);

% *************************************************************************
% IIBPC  - inverze, registr a kontejner ABABAB

for j=1:m
    cnt = 0;
    for k=1:n/2
            obraz_IIBPC(j,k+cnt) = RC_IDCT(j,k);
            obraz_IIBPC(j,k+cnt+1) = RR(j,k); 
            cnt = cnt + 1;
    end 
end

% figure(4)
% title('Zpetne prehozeni po vlozeni vodoznaku');
% colormap('Gray')
% imagesc(obraz_IIBPC)                 % reference registr A
