function pixels = readcdib(filename)
%READCDIB Reads DIB image files from Cellomics devices.
% READCDIB(FILENAME) reads bitmapped image data from the specified file.
% Files from Cellomics High Content Screening systems may omit the file
% header information. This function ignores the missing header and
% returns the pixels data.
%
% Notes: This function uses TYPECAST to parse the files bytes, which
% means that it requires R14SP3. This was done because was it easier to
% prototype, but you could rather easily rework it to use a bunch of
% smaller FREAD commands.
%
% Also it's worth mentioning that because these are 16-bit images that
% don't span the full dynamic range of 16-bit data (0 to 65,355), the
% images will appear very dark without changing the CLim. You can do
% either of these:
%
% imshow(X, [])
%
% or
%
% imagesc(X)
% colormap(gray)
% Copyright 2009, The MathWorks, Inc.
% Get the data for the whole DIB.
fid = fopen(filename, 'r');
buffer = fread(fid, inf, 'uint8=>uint8');
fid = fclose(fid);
% Extract the header elements.
biSize = typecast(buffer(1:4), 'uint32');
biWidth = typecast(buffer(5:8), 'uint32');
biHeight = typecast(buffer(9:12), 'uint32');
biPlanes = typecast(buffer(13:14), 'uint16');
biBitCount = typecast(buffer(15:16), 'uint16');
biCompression = typecast(buffer(17:20), 'uint32');
biSizeImage = typecast(buffer(21:24), 'uint32');
biXPelsPerMeter = typecast(buffer(25:28), 'uint32');
biYPelsPerMeter = typecast(buffer(29:32), 'uint32');
biClrUsed = typecast(buffer(33:36), 'uint32');
biClrImportant = typecast(buffer(37:40), 'uint32');
% Convert the pixels.
startIdx = 1;
endIdx = biWidth * biHeight * double(biBitCount) / 8;
pixels = reshape(typecast(buffer(52 + (startIdx:endIdx)), 'uint16'), ...
[biWidth biHeight]);