📄 vb_bmpinfo.m
字号:
function [info,msg] = VB_bmpinfo(filename, address)
% This function is exactly the same as the Mathworks IMBMPINFO.M
% file apart from the second input argument (i.e. 'address') and the
% lines of code with a comment: "Martin Dale"
% Martin Dale, July 2002
% Copyright 2002 All Rights Reserved.
% Version 1.00 9 June 2002
% This M-File should be placed in the \toolbox\matlab\iofun\ directory
% Contact Martin.Dale@Physics.org
info = [];
msg = '';
[fid,m] = fopen(filename, 'r', 'ieee-le'); % BMP files are little-endian
if (fid == -1)
info = [];
msg = m;
return;
end
filename = fopen(fid); % Get the full path name if not in pwd
d = dir(filename); % Read directory information
address=hex2dec(address); % "Martin Dale"
fseek(fid,address+12,'bof'); % "Martin Dale"
%
% Initialize universal structure fields to fix the order
%
info.Filename = filename;
info.FileModDate = d.date;
info.FileSize = d.bytes;
info.Format = 'bmp';
info.FormatVersion = [];
info.Width = [];
info.Height = [];
info.BitDepth = [];
info.ColorType = [];
info.FormatSignature = [];
%
% Initialize BMP-specific structure fields to fix the order
%
info.NumColormapEntries = [];
info.Colormap = [];
info.RedMask = [];
info.GreenMask = [];
info.BlueMask = [];
%
% First we must determine which variant of BMP we have.
% Use the algorithm from Encyclopedia of Graphics File Formats,
% 2ed, pp. 584-585
%
info.FormatSignature = char(fread(fid, 2, 'uint8')');
if (isempty(info.FormatSignature))
info = [];
msg = 'Empty file';
fclose(fid);
return;
end
if (strcmp(info.FormatSignature, 'BM'))
% We have a single-image BMP file. It may be
% a Windows or an OS/2 file.
info.FileSize = fread(fid, 1, 'uint32');
fseek(fid, 4, 'cof'); % skip 2 reserved 16-bit words
info.ImageDataOffset = fread(fid, 1, 'uint32')+address+12; %"Martin Dale"
info.BitmapHeaderSize = fread(fid, 1, 'uint32');
if (isempty(info.BitmapHeaderSize))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
compression = [];
switch info.BitmapHeaderSize
case 12
info.Width = fread(fid, 1, 'int16');
info.Height = fread(fid, 1, 'int16');
if (isempty(info.Width) | isempty(info.Height))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
if ((info.Width < 0) | (info.Height < 0))
info.FormatVersion = 'Version 1 (IBM OS/2 1.x)';
fseek(fid, -4, 'cof');
info.Width = fread(fid, 1, 'uint16');
info.Height = fread(fid, 1, 'uint16');
else
info.FormatVersion = 'Version 2 (Microsoft Windows 2.x)';
end
info.NumPlanes = fread(fid, 1, 'uint16');
info.BitDepth = fread(fid, 1, 'uint16');
case 40
info.Width = fread(fid, 1, 'uint32');
info.Height = fread(fid, 1, 'uint32');
info.NumPlanes = fread(fid, 1, 'uint16');
info.BitDepth = fread(fid, 1, 'uint16');
compression = fread(fid, 1, 'uint32');
if (isempty(compression))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
if (compression == 3)
info.FormatVersion = 'Version 3 (Microsoft Windows NT)'
else
info.FormatVersion = 'Version 3 (Microsoft Windows 3.x)';
end
case 108
info.FormatVersion = 'Version 4 (Microsoft Windows 95)';
compression = fread(fid, 1, 'uint32');
if (isempty(compression))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
otherwise
if ((info.HeaderSize > 12) & (info.HeaderSize <= 64))
info.FormatVersion = 'Version 2 (IBM OS/2 2.x)';
compression = fread(fid, 1, 'uint32');
if (isempty(compression))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
else
info = [];
msg = 'Corrupted header';
fclose(fid);
return;
end
end
if (~isempty(compression))
switch compression
case 0
info.CompressionType = 'none';
case 1
info.CompressionType = '8-bit RLE';
case 2
info.CompressionType = '4-bit RLE';
case 3
if (strcmp(info.FormatVersion, 'Version 3 (Microsoft Windows NT)'))
info.CompressionType = 'bitfields';
else
% OS/2 2.x
info.CompressionType = 'Huffman 1D';
end
case 4
% Only valid for OS/2 2.x
info.CompressionType = '24-bit RLE';
otherwise
info = [];
msg = 'Unrecognized compression type';
fclose(fid);
return;
end
else
info.CompressionType = 'none';
end
elseif (strcmp(info.FormatSignature, 'BA'))
info = [];
msg = 'Unsupported format; may be an OS/2 bitmap array';
fclose(fid);
return;
else
info = [];
msg = 'Not a BMP file';
fclose(fid);
return;
end
switch info.FormatVersion
case 'Version 1 (IBM OS/2 1.x)'
info.NumColormapEntries = (info.ImageDataOffset - ftell(fid))/3;
if (rem(info.NumColormapEntries, 1) ~= 0)
info = [];
msg = 'Corrupt file';
fclose(fid);
return;
end
if (info.NumColormapEntries > 0)
[map,count] = fread(fid, info.NumColormapEntries*3, 'uint8');
if (count ~= info.NumColormapEntries*3)
info = [];
msg = 'Truncated colormap data';
fclose(fid);
return;
end
map = reshape(map, 3, info.NumColormapEntries);
info.Colormap = double(flipud(map)')/255;
end
case 'Version 2 (Microsoft Windows 2.x)';
info.NumColormapEntries = (info.ImageDataOffset - ftell(fid))/3;
if (rem(info.NumColormapEntries, 1) ~= 0)
info = [];
msg = 'Corrupt file';
fclose(fid);
return;
end
if (info.NumColormapEntries > 0)
[map,count] = fread(fid, info.NumColormapEntries*3, 'uint8');
if (count ~= info.NumColormapEntries*3)
info = [];
msg = 'Truncated colormap data';
fclose(fid);
return;
end
map = reshape(map, 3, info.NumColormapEntries);
info.Colormap = double(flipud(map)')/255;
end
case 'Version 3 (Microsoft Windows 3.x)';
info.BitmapSize = fread(fid, 1, 'uint32');
info.HorzResolution = fread(fid, 1, 'int32');
info.VertResolution = fread(fid, 1, 'int32');
info.NumColorsUsed = fread(fid, 1, 'uint32');
info.NumImportantColors = fread(fid, 1, 'uint32');
info.NumColormapEntries = (info.ImageDataOffset - ftell(fid))/4;
if (rem(info.NumColormapEntries, 1) ~= 0)
info = [];
msg = 'Corrupt file';
fclose(fid);
return;
end
if (info.NumColormapEntries > 0)
[map,count] = fread(fid, info.NumColormapEntries*4, 'uint8');
if (count ~= info.NumColormapEntries*4)
info = [];
msg = 'Truncated colormap data';
fclose(fid);
return;
end
map = reshape(map, 4, info.NumColormapEntries);
info.Colormap = double(flipud(map(1:3,:))')/255;
end
case 'Version 3 (Microsoft Windows NT)'
info.BitmapSize = fread(fid, 1, 'uint32');
info.HorzResolution = fread(fid, 1, 'int32');
info.VertResolution = fread(fid, 1, 'int32');
info.NumColorsUsed = fread(fid, 1, 'uint32');
info.NumImportantColors = fread(fid, 1, 'uint32');
if (((info.BitDepth == 16) | (info.BitDepth == 32)) & ...
(~strcmp(info.CompressionType,'bitfields')))
info = [];
msg= 'BMP Version 3 (Microsoft Windows NT) file appears to be corrupt';
fclose(fid);
return;
end
if (strcmp(info.CompressionType, 'bitfields'))
info.NumColormapEntries = 0;
info.Colormap = [];
info.RedMask = fread(fid, 1, 'uint32');
info.GreenMask = fread(fid, 1, 'uint32');
info.BlueMask = fread(fid, 1, 'uint32');
else
info.NumColormapEntries = (info.ImageDataOffset - ftell(fid))/4;
if (rem(info.NumColormapEntries,1) ~= 0)
info = [];
msg= 'BMP Version 3 (Microsoft Windows NT) file appears to be corrupt';
fclose(fid);
return;
end
if (info.NumColormapEntries > 0)
[map,count] = fread(fid, info.NumColormapEntries*4, 'uint8');
if (count ~= info.NumColormapEntries*4)
info = [];
msg = 'Truncated colormap data';
fclose(fid);
return;
end
map = reshape(map, 4, info.NumColormapEntries);
info.Colormap = double(flipud(map(1:3,:))')/255;
end
end
case 'Version 4 (Microsoft Windows 95)';
info.BitmapSize = fread(fid, 1, 'uint32');
info.HorzResolution = fread(fid, 1, 'int32');
info.VertResolution = fread(fid, 1, 'int32');
info.NumColorsUsed = fread(fid, 1, 'uint32');
info.NumImportantColors = fread(fid, 1, 'uint32');
% Fields added for Version 4
info.RedMask = fread(fid, 1, 'uint32');
info.GreenMask = fread(fid, 1, 'uint32');
info.BlueMask = fread(fid, 1, 'uint32');
info.AlphaMask = fread(fid, 1, 'uint32');
info.ColorspaceType = fread(fid, 1, 'uint32');
info.RedX = fread(fid, 1, 'int32');
info.RedY = fread(fid, 1, 'int32');
info.RedZ = fread(fid, 1, 'int32');
info.GreenX = fread(fid, 1, 'int32');
info.GreenY = fread(fid, 1, 'int32');
info.GreenZ = fread(fid, 1, 'int32');
info.BlueX = fread(fid, 1, 'int32');
info.BlueY = fread(fid, 1, 'int32');
info.BlueZ = fread(fid, 1, 'int32');
info.GammaRed = fread(fid, 1, 'uint32');
info.GammaGreen = fread(fid, 1, 'uint32');
info.GammaBlue = fread(fid, 1, 'uint32');
if (((info.BitDepth == 16) | (info.BitDepth == 32)) & ...
(~strcmp(info.CompressionType,'bitfields')))
info = [];
msg= 'BMP Version 4 (Microsoft Windows 95) file appears to be corrupt';
fclose(fid);
return;
end
if (strcmp(info.CompressionType, 'bitfields'))
info.NumColormapEntries = 0;
info.Colormap = [];
else
info.NumColormapEntries = (info.ImageDataOffset - ftell(fid))/4;
if (rem(info.NumColormapEntries,1) ~= 0)
info = [];
msg= 'BMP Version 4 (Microsoft Windows 95) file appears to be corrupt';
fclose(fid);
return;
end
if (info.NumColormapEntries > 0)
[map,count] = fread(fid, info.NumColormapEntries*4, 'uint8');
if (count ~= info.NumColormapEntries*4)
info = [];
msg = 'Truncated colormap data';
fclose(fid);
return;
end
map = reshape(map, 4, info.NumColormapEntries);
info.Colormap = double(flipud(map(1:3,:))')/255;
end
end
case 'Version 2 (IBM OS/2 2.x)'
info.BitmapSize = fread(fid, 1, 'uint32');
info.HorzResolution = fread(fid, 1, 'uint32');
info.VertResolution = fread(fid, 1, 'uint32');
info.NumColorsUsed = fread(fid, 1, 'uint32');
info.NumImportantColors = fread(fid, 1, 'uint32');
units = fread(fid, 1, 'uint16');
if (isempty(units))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
if (units == 0)
info.Units = 'pixels/meter';
else
info.Units = 'unknown';
end
fseek(fid, 2, 'cof'); % skip 2-byte pad
info.Recording = fread(fid, 1, 'uint16');
halftoning = fread(fid, 1, 'uint16');
if (isempty(halftoning))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
switch halftoning
case 0
info.HalftoningAlgorithm = 'none';
case 1
info.HalftoningAlgorithm = 'error diffusion';
case 2
info.HalftoningAlgorithm = 'PANDA';
case 3
info.HalftoningAlgorithm = 'super-circle';
otherwise
info.HalftoningAlgorithm = 'unknown';
end
info.HalftoneField1 = fread(fid, 1, 'uint32');
info.HalftoneField2 = fread(fid, 1, 'uint32');
encoding = fread(fid, 1, 'uint32');
if (isempty(encoding))
info = [];
msg = 'Truncated header';
fclose(fid);
return;
end
if (encoding == 0)
info.ColorEncoding = 'RGB';
else
info.ColorEncoding = 'unknown';
end
info.ApplicationIdentifier = fread(fid, 1, 'uint32');
info.NumColormapEntries = (info.ImageDataOffset - ftell(fid))/4;
if (rem(info.NumColormapEntries,1) ~= 0)
info = [];
msg= 'BMP Version 2 (IBM OS/2 2.x) file appears to be corrupt';
fclose(fid);
return;
end
if (info.NumColormapEntries > 0)
map = fread(fid, info.NumColormapEntries*4, 'uint8');
map = reshape(map, 4, info.NumColormapEntries);
info.Colormap = double(flipud(map(1:3,:))')/255;
end
otherwise
info = [];
msg = 'Problem identifying format version';
fclose(fid);
return;
end
fclose(fid);
if (isempty(info.NumColormapEntries))
info.NumColormapEntries = 0;
end
if (info.NumColormapEntries > 0)
info.ColorType = 'indexed';
else
if (info.BitDepth <= 8)
info.ColorType = 'grayscale';
else
info.ColorType = 'truecolor';
end
end
%
% Other validity checks
%
if ((info.Width < 0) | (info.Height < 0))
info = [];
msg = 'Corrupt BMP file: bad image dimensions';
return;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -