View Raw SPL
/*****************************************************************************
* *
* READBMP.SPL Copyright (C) 1997-2002 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Reads a Microsoft .BMP bitmap file *
* *
* Revisions: 5 Dec 1997 RRR Creation *
* 20 May 1998 AMK Added 24-bit RGB bitmap support *
* 9 Jun 1998 RRR 24-bit RGB bitmaps via RGBIMAGE *
* 3 Jul 2002 RRR simple 32 bit support *
* *
*****************************************************************************/
#include
#if @HELP_READBMP
READBMP
Purpose: Reads a Microsoft .BMP bitmap file
Syntax: READBMP(filename)
filename - a string specifying a .BMP file
Returns: An array
Example:
READBMP("mandrill.bmp")
reads and displays the bitmap file "mandrill.bmp"
(image, cmap) = READBMP("mandrill.bmp")
reads the bitmap file into the variable image and copies
the colormap into the variable cmap.
Remarks:
READBMP currently supports only uncompressed .BMP files. If
the image is a 24 bit bitmap, it is automatically read as an
RGBIMAGE (i.e. 24 bits).
READBMP.SPL is based on LOADBMP.M (Copyright 1993) written by:
Ralph Sucher
Dept. of Communications Engineering
Technical University of Vienna
Gusshausstrasse 25/389
A-1040 Vienna
AUSTRIA
See Also:
Getrgb
Image24
Rgbimage
Writebmp
#endif
readbmp(bmpfile)
{
local status, fid, bftype;
local biSize, biWidth, biHeight, biPlanes, biBitCnt, nCol;
local biCompr, biSizeIm, biXPelsPerMeter;
local biYPelsPerMeter, biClrUsed, biClrImportant, MapLength;
local map, X, xx, i, ndata, data, isize, width3, block;
local Rvals, Gvals, Bvals;
if (argc != 1)
{
error("readbmp - BMP filename required");
}
if (strlen(strfind(".", bmpfile)) == 0)
{
bmpfile = strcat(bmpfile, ".bmp");
}
fid = fopen(bmpfile, "rb");
if (fid != TRUE)
{
error(sprintf("readbmp Cannot open %s .BMP file", bmpfile));
}
else fid = bmpfile;
// ------------------------------- BMP HEADER -------------------------------
// read file identifier
bfType = caststring(freadb(fid, byte, 2));
if (strcmp(bfType, "BM") != 0)
{
fclose(fid);
error(sprintf("readbmp - %s Not a valid .BMP file", bmpfile));
}
// read file length (bytes)
status = fseek(fid, 0, 2);
bfSize = ftell(fid);
status = fseek(fid, 6, 0);
// read bytes reserved for later extensions
dummy = freadb(fid, long, 1);
// read offset from beginning of file to first data byte
bfOffs = castint(freadb(fid, long, 1));
// ----------------------------- BMP INFO-BLOCK -----------------------------
// *** bitmap information header ***
// read length of bitmap information header
biSize = castint(freadb(fid, long, 1));
// read width of bitmap
biWidth = castint(freadb(fid, long, 1));
// read height of bitmap
biHeight = castint(freadb(fid, long, 1));
// read number of color planes
biPlanes = castint(freadb(fid, uint, 1));
// read number of bits per pixel
biBitCnt = castint(freadb(fid, uint, 1));
nCol = 2 ^ biBitCnt;
// read type of data compression
biCompr = castint(freadb(fid, long, 1));
if (biCompr != 0)
{
fclose(fid);
error("readbmp - currently only supports uncompressed .BMP files");
}
// read size of compressed image
biSizeIm = castint(freadb(fid, long, 1));
// read horizontal resolution (pixels/meter)
biXPelsPerMeter = castint(freadb(fid, long, 1));
// read vertical resolution (pixels/meter)
biYPelsPerMeter = castint(freadb(fid, long, 1));
// read number of used colors
biClrUsed = castint(freadb(fid, long, 1));
// read number of important colors
biClrImportant = castint(freadb(fid, long, 1));
// *** colormap ***
MapLength = int((bfOffs - 54) / 4);
if (MapLength != 0)
{
// read colormap
printf("%s - Reading colormap ...", bmpfile);
map = zeros(4, MapLength);
map[..] = freadb(fid, ubyte, MapLength * 4);
map = map[3..-1..1, ..]' / 255;
}
// ------------------------------ BITMAP DATA -------------------------------
ndata = castint(bfSize - bfOffs);
Width = (ndata * 8 / biBitCnt) / biHeight;
if (biBitCnt != 24)
{
X = zeros(Width, biHeight);
}
Xsize = Width * biHeight;
data = freadb(fid, UBYTE, ndata);
printf("%s - Data Read, Processing Image ...", bmpfile);
fclose(fid);
if (biBitCnt == 1)
{
xx = zeros(ndata, 1);
for (i = 1; i <= 8; i++)
{
X[i..8..Xsize] = fix((data - xx) / 2 ^ (8 - i));
xx = xx + X[i..8..Xsize] * 2 ^ (8 - i);
}
}
else if (biBitCnt == 4)
{
X[1..2..Xsize] = fix(data / 16);
X[2..2..Xsize] = round(data - X[1..2..Xsize] * 16);
}
else if (biBitCnt == 8)
{
if (length(data) != Xsize)
{
X[..] = extract(data, 1, Xsize);
}
else
{
X[..] = data;
}
if (biWidth != Width)
{
/* remove extraneous zero padding */
X = extract(X, 1, biWidth);
}
}
else if (biBitCnt == 24)
{
/* 24 bit support */
width3 = biWidth * 3;
isize = width3 * biHeight;
block = floor((length(data) - isize) / biHeight);
if (block)
{
/* remove 4 Byte alignment padding */
data = remove(data, width3 + block, width3 + 1, block);
}
/* extract individual RBG components */
Rvals = ravel(decimate(data, 3, 3) / 255, biWidth);
Gvals = ravel(decimate(data, 3, 2) / 255, biWidth);
Bvals = ravel(decimate(data, 3, 1) / 255, biWidth);
X = rgbimage(Rvals, Gvals, Bvals);
}
else if (biBitCnt == 32)
{
/* 32 bit support */
/* remove Byte alignment padding */
data = remove(data, 4, 4);
/* extract individual RBG components */
Rvals = ravel(decimate(data, 3, 3) / 255, biWidth);
Gvals = ravel(decimate(data, 3, 2) / 255, biWidth);
Bvals = ravel(decimate(data, 3, 1) / 255, biWidth);
X = rgbimage(Rvals, Gvals, Bvals);
}
else
{
error("readbmp - Not a valid .BMP file");
}
/* unity deltas for an image */
setdeltax(X, 1.0);
setdeltay(X, 1.0);
setxoffset(X, 0.0);
setyoffset(X, 0.0);
printf("%s - %dx%d %d Bit Image Completed", bmpfile, biWidth, biHeight, biBitcnt);
/* plot as image */
setplottype(X, 3);
setplotstyle(X, 0);
if (outargc == 0)
{
/* set colormap and display as image */
scales(0);
if (MapLength != 0)
{
setcolormap(map);
}
return(X);
}
else
{
if (MapLength != 0)
{
/* return image and colormap */
return(X, map);
}
else
{
/* just return image */
return(X);
}
}
}