function decode2(bar)

format short

% decode2(img): Decode barcode in image img

% Barcode 128c: four different run lengths, the relative widths are 1 2 3 4

[barh, barw] = size(bar);
slice = double(bar(round(barh/2),:));
sliceh = interp(slice,16);
thres = mean(sliceh);
sliceb = sliceh > thres;
runs = [];
m = 1;
for k=2:length(sliceb)
	if (sliceb(k)~=sliceb(m))
		runs = [runs k-m];
		m = k;
	end
end
color = sliceb(1);	% 0=black, 1=white
%figure(1),stem(runs);

codetab = [ ...
2 1 2 2 2 2;	% 00
2 2 2 1 2 2;
2 2 2 2 2 1;
1 2 1 2 2 3;
1 2 1 3 2 2;
1 3 1 2 2 2;
1 2 2 2 1 3;
1 2 2 3 1 2;
1 3 2 2 1 2;
2 2 1 2 1 3;
2 2 1 3 1 2;
2 3 1 2 1 2;
1 1 2 2 3 2;
1 2 2 1 3 2;
1 2 2 2 3 1;
1 1 3 2 2 2;
1 2 3 1 2 2;
1 2 3 2 2 1;
2 2 3 2 1 1;
2 2 1 1 3 2;
2 2 1 2 3 1;
2 1 3 2 1 2;
2 2 3 1 1 2;
3 1 2 1 3 1;
3 1 1 2 2 2;
3 2 1 1 2 2;
3 2 1 2 2 1;
3 1 2 2 1 2;
3 2 2 1 1 2;
3 2 2 2 1 1;
2 1 2 1 2 3;
2 1 2 3 2 1;
2 3 2 1 2 1;
1 1 1 3 2 3;
1 3 1 1 2 3;
1 3 1 3 2 1;
1 1 2 3 1 3;
1 3 2 1 1 3;
1 3 2 3 1 1;
2 1 1 3 1 3;
2 3 1 1 1 3;
2 3 1 3 1 1;
1 1 2 1 3 3;
1 1 2 3 3 1;
1 3 2 1 3 1;
1 1 3 1 2 3;
1 1 3 3 2 1;
1 3 3 1 2 1;
3 1 3 1 2 1;
2 1 1 3 3 1;
2 3 1 1 3 1;
2 1 3 1 1 3;
2 1 3 3 1 1;
2 1 3 1 3 1;
3 1 1 1 2 3;
3 1 1 3 2 1;
3 3 1 1 2 1;
3 1 2 1 1 3;
3 1 2 3 1 1;
3 3 2 1 1 1;
3 1 4 1 1 1;
2 2 1 4 1 1;
4 3 1 1 1 1;
1 1 1 2 2 4;
1 1 1 4 2 2;
1 2 1 1 2 4;
1 2 1 4 2 1;
1 4 1 1 2 2;
1 4 1 2 2 1;
1 1 2 2 1 4;
1 1 2 4 1 2;
1 2 2 1 1 4;
1 2 2 4 1 1;
1 4 2 1 1 2;
1 4 2 2 1 1;
2 4 1 2 1 1;
2 2 1 1 1 4;
4 1 3 1 1 1;
2 4 1 1 1 2;
1 3 4 1 1 1;
1 1 1 2 4 2;
1 2 1 1 4 2;
1 2 1 2 4 1;
1 1 4 2 1 2;
1 2 4 1 1 2;
1 2 4 2 1 1;
4 1 1 2 1 2;
4 2 1 1 1 2;
4 2 1 2 1 1;
2 1 2 1 4 1;
2 1 4 1 2 1;
4 1 2 1 2 1;
1 1 1 1 4 3;
1 1 1 3 4 1;
1 3 1 1 4 1;
1 1 4 1 1 3;
1 1 4 3 1 1;
4 1 1 1 1 3;
4 1 1 3 1 1;
1 1 3 1 4 1;		% 99
1 1 4 1 3 1;		% 100: code B
3 1 1 1 4 1;		% 101: code A
4 1 1 1 3 1;		% 102: FNC 1
2 1 1 4 1 2;		% 103: START code A
2 1 1 2 1 4;		% 104: START code B
2 1 1 2 3 2;		% 105: START code C
2 3 3 1 1 1 ];		% 106: STOP + 2
starta = 103;
startb = 104;
startc = 105;
stop = 106;

%color
detect = zeros(0,4);
for k=1:length(runs)-6
	if color==0
		[mse,est] = match2(runs(k:k+5),codetab(starta+1,:));
		detect = [detect; k mse est starta];
		[mse,est] = match2(runs(k:k+5),codetab(startb+1,:));
		detect = [detect; k mse est startb];
		[mse,est] = match2(runs(k:k+5),codetab(startc+1,:));
		detect = [detect; k mse est startc];
		[mse,est] = match2(runs(k:k+6),fliplr([codetab(stop+1,:) 2]));
		detect = [detect; k mse est stop];
	end
	color = 1-color;
end
detect = sortrows(detect, [2 1]);	% sort by smallest MSE first
%figure(2),stem(1./detect(:,2));

detect(1,:)
est = detect(1,3);	% Estimated width of the narrowest bar (module width?)
charset = detect(1,4);	% Charset code
estsum = est;
estnum = 1;

resultn = [];
results = [];
conf = zeros(0,4);
k = detect(1,1);
while k<=length(runs)-5
	codemse = zeros(0,3);
	for m=1:length(codetab)
		[cm,ce] = match2(runs(k:k+5),codetab(m,:));
		codemse = [codemse; m-1 cm ce];
	end
	codemse = sortrows(codemse, [2 1]);
%	figure(2),stem(1 ./ codemse(:,2));
%	pause
	
	code = codemse(1,1);
	resultn = [resultn code];
	conf = [conf; k code codemse(2,2)/codemse(1,2) codemse(1,3)];
	if code>=100
		results = [results sprintf('*', code)];
	else
		results = [results sprintf('%02i', code)];
	end
	if code==stop
		break
	end
	k = k+6;
end

%figure(3),stem(conf(:,4));
conf

%resultn

checksum = charset;
for k=2:length(resultn)-2
	checksum = mod((k-1)*resultn(k)+checksum,103);
end

if checksum ~= resultn(length(resultn)-1)
	warning('CHECKSUM ERROR')
else
	disp('Checksum OK');
end

results

if length(results)<55
	return
end
disp(sprintf('Versionumero     : %s', results(2)));
disp(sprintf('Saajan tilinumero: %s', results(3:16)));
disp(sprintf('Markat/eurot     : %s', results(17:22)));
disp(sprintf('Pennit/sentit    : %s', results(23:24)));
disp(sprintf('Viitenumero      : %s', results(25:44)));
disp(sprintf('Eräpäivä         : %s', results(45:50)));
disp(sprintf('Varalla          : %s', results(51:54)));
disp(sprintf('Tarkiste 1       : %s', results(55)));
