This is easy if you use rawconvert and GNU Octave/Matlab. First use rawconvert to transform .crw files into something easier to read:
rawconvert -10to16 -w=3336 -h=2480 -noshift filename.crw filename.raw
Then add a PGM header:
echo -ne "P5\n#Bayer Raw\n3336 2480\n65535\n" > myraw.pgm
cat filename.raw >> myraw.pgm
Then use the following .m file in Octave (probably works in Matlab too with little to no modification). This example is specific to my A590. If you have a different camera your width, height, and Bayer color filter array arrangement will be different. You can find this info in camera.h. Adding a header is not necessary, but if you don't you'll have to hard code your specific width and height into the .m file.
function I = bayer_raw_read(fname)
fid = fopen(fname,'r');
if (fid == -1)
I = -1;
else
magicnum = fgetl(fid);
if strcmp(magicnum, 'P5') %binary PBM
hline2 = fgetl(fid); %second line of header
if (hline2(1) == '#')
size = sscanf(fgetl(fid),'%d %d');
else %no comment in header
size = sscanf(hline2,'%d %d');
endif
w = size(1);
h = size(2);
maxcolor = sscanf(fgetl(fid),'%d');
bpp = log2(maxcolor+1);
prec = ['uint' num2str(bpp)];
% a row of the source image becomes a column vector of matrix R
[R, count] = fread(fid , [w, h], prec);
R = R.'; % transpose to give R the same orientation as source image
%colormap(gray(2^16));
%imagesc(R)
Mr = repmat([0 0; 1 0], h/2, w/2);
Mg = repmat([1 0; 0 1], h/2, w/2);
Mb = repmat([0 1; 0 0], h/2, w/2);
I(:,:,1) = R.*Mr;
I(:,:,2) = R.*Mg;
I(:,:,3) = R.*Mb;
%gmap = gray(2^16).*repmat([0 1 0], 2^16, 1);
%colormap(gmap);
%imagesc(R.*Mg)
else %magic number is invalid
I = -1;
endif
fclose(fid);
endif
endfunction