function [coords, code] = getchaincode(bw, N);
%
% CODE = GETCHAINCODE(BW, N)
%
% extracts chaincode of a binary image
%
% BW - binary image
% N  - connectivity (4 or 8 (default))
% CODE - chaincode
% COORDS - coordinates of border pixels
%

if nargin < 2, N = 8;
end

if N == 8,
   table = [0 -1; -1 -1; -1 0; -1 1; 0 1; 1 1; 1 0; 1 -1];
elseif N == 4,
   table = [0 -1; -1 0; 0 1; 1 0];
else
   error('connectivity can be either 8 or 4');
end

%add border to image
bwn = zeros(size(bw)+ [2 2]);
bwn(2:length(bwn(:,1))-1 , 2:length(bwn(1,:))-1) = bw;
bw = bwn;
clear bwn;

offset = N/2;		%offset for index calculation
height = size(bw,1);
width  = size(bw,2);
coords = [];
code = [];

%find the starting pixel - 'most upper/left'
c = 0;		%column
r = [];		%row
while isempty(r)
   c = c+1;
   r = find(bw(:,c));
end
if c == size(bw,2)
    error('could not find valid image'); 
end
   
r = r(1);           %if there is more than one pixel in a column, get the upper one
start = [r,c];	    %set the coordinates of the starting pixel
current = start;
count = 1;		    %perimeter length
index = 2;          % starting chaincode

while 1 == 1,		%loop until there are no more pixels
   %go clockwise from b to the first foreground pixel
    xy = current + table(index+1,:);
	while bw(xy(1),xy(2)) == 0          % 0 is background
      index = mod( index + 1, N );
      xy = current + table(index+1,:);
	end
   
    %coordinates of 
    coords = [coords;current];              %record coordinates
    code(count)	 = mod( index + offset, N);	%record chaincode
  	current = current + table(index+1,:);   %move to the next pixel
  	index = mod( code(count) + 1, N );      %index will equal current chaincode + 1
	if current == start,
   	    break;
    end
   
    count = count + 1;
end