home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
fortran
/
mslang
/
fort_bmp
/
bmpwrite.for
< prev
Wrap
Text File
|
1993-07-14
|
10KB
|
244 lines
subroutine bmpwrite(filename,biBitCount,ncol,nrow,nclr,rgb,data,
$ error)
implicit none
c****************************************************************************
c* *
c* (C) Copyright 1993 by Enlightened Solutions. All rights reserved. *
c* *
c* Enlightened Solutions *
c* 1503 Linda Rosa Avenue *
c* Los Angeles, CA 90041-2210 *
c* Phone: 213-255-3932 *
c* CIS ID: 70704,3067 *
c* *
c* This software is distributed free-of-charge, but is NOT released to *
c* the public domain. If you make changes to the code, please do so on a *
c* copy, and include the originals in any distribution, with copyright *
c* notices intact. *
c* *
c****************************************************************************
c This subroutine writes a Windows Bitmap v3.0 graphic file. Note that
c "v3.0" does not refer to Windows 3.0, but rather Bitmap 3.0, which is
c described in the file BMP30FMT.TXT. The files created by this routine are
c compatible with Windows 3.x. Compressed (RLE) bitmap formats are not
c supported. This subroutine has been compiled successfully under MS FORTRAN
c v5.1 and MS Powerstation FORTRAN (32 bit), although the Powerstation
c compiler will issue a warning that the [huge] attribute of the "data"
c array will be ignored, which is ok.
c The input arguments (and one output) are described below. The other
c bitmap header variables (as described in BMP30FMT.TXT) can remain set
c as they are for most work, but you could modify them if needed.
c
c filename - Character*(*), input. Name of the bitmap file to be created,
c including path if necessary. If the file already exists,
c "error" is set to .true., an informational message is
c displayed, and control is returned to the calling program.
c biBitCount - Integer*2, input. The number of bits/pixel of the "data"
c array. Valid values are 1,4,8, and 24 (representing maximum
c colors of 2,16,256, and 16.8 million, respectively).
c ncol - Integer*4, input. Number of pixels in the horizontal direction.
c nrow - Integer*4, input. Number of pixels in the vertical direction.
c nclr - Integer*4, input. Number of colors in palette.
c rgb - Byte(3,*), input. An array containing the red, green, and blue
c components of the color palette. The first color in the
c palette (corresponding to data with value=0) is specified by
c rgb(1,1), rgb(2,1), rgb(3,1), and so on through nclr colors.
c *EXCEPTION* It would be impractical to specify a 16.8 million color
c palette for a 24 bit image, therefore these images specify the colors
c directly by the data itself, i.e. the three bytes of data specify
c the red, green, and blue components of that particular pixel. In
c this case, "rgb" and "nclr" are ignored.
c data - [huge]byte(*), input. An array containing the data for the bitmap.
c "biBitCount" specifies how many bits/pixel. The array is one-dimen-
c sional here, but may be two (or more) dimensions in the calling
c program. The only requirement is that the data be contiguous
c starting at the first bit of the array. The first value of the
c array will correspond to the lower left pixel of the bitmap image.
c error - Logical*4, output. If an error occurred, this variable will be
c set to .true., an informational message will be displayed, and
c control will be returned to the calling program.
c Bitmap File-Header variables. See "BMP30FMT.TXT" for more info.
character*2 bfType
integer*4 bfSize,bfOffBits
integer*2 bfReserved1,bfReserved2
c Bitmap Info-Header variables. See "BMP30FMT.TXT" for more info.
integer*2 biPlanes,biBitCount
integer*4 biSize,biWidth,biHeight,biCompression,biSizeImage
integer*4 biXPelsPerMeter,biYPelsPerMeter,biClrUsed,biClrImportant
c RGBQuad variables. See "BMP30FMT.TXT" for more info.
byte rgb(3,*),rgbReserved
c Other passed and local variables.
byte data[huge](*),buffer(4)
integer*2 getlen,nbuf
integer*4 ncol_bytes,ncol,nrow,nclr,ioerr,iu,i,j,j0
logical*4 error,open,exist
character*(*) filename
data buffer /4*0/
c---------------------------------------------------------------------------
error = .false.
c Perform initial validity tests on formal arguments.
c Check for some non-sensical values of ncol and nrow.
if(ncol.le.0 .or. nrow.le.0) then
write(*,122) ncol,nrow
122 format(/,' BMPWRITE - Ncol and nrow must be > 0.',/,
$ ' Ncol = ',i8,/,
$ ' Nrow = ',i8,/)
error = .true.
return
endif
c Ensure biBitCount is valid.
if(biBitCount.ne.1 .and. biBitCount.ne.4 .and.
$ biBitCount.ne.8 .and. biBitCount.ne.24) then
write(*,222) biBitCount
222 format(/,' BMPWRITE - biBitCount must be 1,4,8, or 24.',/,
$ ' biBitCount = ',i8,/)
error = .true.
return
endif
c Ensure nclr is not too big, warn if too small. If 24 bit data, then
c nclr is ignored.
if(biBitCount.ne.24) then
if(nclr.gt.2**biBitCount) then
write(*,322) nclr,biBitCount,2**biBitCount
322 format(/,' BMPWRITE - Number of colors (nclr) too big for',/,
$ ' bits/pixel (biBitCount) specified.',/,
$ ' Nclr = ',i8,/,
$ ' biBitCount = ',i8,/,
$ ' Max colors allowed = ',i8,/)
error = .true.
return
else if(nclr.lt.2**biBitCount) then
write(*,422) biBitCount,nclr,2**biBitCount
422 format(/,' BMPWRITE - WARNING: Number of colors (nclr) is',/,
$ ' LESS than capacity of',i3,' bits/pixel data.',/,
$ ' Nclr = ',i8,/,
$ ' Max colors allowed = ',i8,/,
$ ' Continuing.',/)
endif
endif
c Make sure file doesn't already exist.
inquire(file=filename,exist=exist)
if(exist) then
write(*,522) filename(1:getlen(filename))
522 format(/,' BMPWRITE - ',a,' already exists.',/)
error = .true.
return
endif
c Find available unit # and open file.
iu = 0
open = .true.
do while(open)
iu = iu + 1
inquire(unit=iu,opened=open)
enddo
open(iu,file=filename,status='new',form='binary',iostat=ioerr,
$ err=98)
ncol_bytes = ncol*biBitCount/8
nbuf = mod(4 - mod(ncol_bytes,4),4)
bfType = 'BM'
if(biBitCount.ne.24) then
bfSize = 54 + nclr*4 + (ncol_bytes + nbuf)*nrow
bfOffBits = 54 + nclr*4
else
bfSize = 54 + (ncol_bytes + nbuf)*nrow
bfOffBits = 54
endif
bfReserved1 = 0
bfReserved2 = 0
c Write BitmapFileHeader
write(iu,iostat=ioerr,err=98) bfType,bfSize,bfReserved1,
$ bfReserved2,bfOffBits
biSize = 40
biWidth = ncol
biHeight = nrow
biPlanes = 1
biCompression = 0
biSizeImage = (ncol_bytes + nbuf)*nrow
biXPelsPerMeter = 0
biYPelsPerMeter = 0
biClrUsed = 0
biClrImportant = 0
c Write BitmapInfoHeader
write(iu,iostat=ioerr,err=98) biSize,biWidth,biHeight,biPlanes,
$ biBitCount,biCompression,
$ biSizeImage,biXPelsPerMeter,
$ biYPelsPerMeter,biClrUsed,
$ biClrImportant
c Write color table. Note that for 24 bit images, each three data
c bytes represent the red, green, and blue components, respectively.
if(biBitCount.ne.24) then
rgbReserved = 0
write(iu,iostat=ioerr,err=98)
$ ((rgb(j,i),j=3,1,-1),rgbReserved,i=1,nclr)
endif
c Write data. Note that the first pixel in array "data" will correspond
c to the lower left corner of the image.
c The different write statement for the nbuf.eq.0 case is only for
c speed reasons.
if(nbuf.ne.0) then
do 1 i = 1,nrow
j0 = (i - 1)*ncol_bytes + 1
write(iu,iostat=ioerr,err=98) (data(j),j=j0,j0+ncol_bytes-1),
$ (buffer(j),j=1,nbuf)
1 continue
else
write(iu,iostat=ioerr,err=98) (data(j),j=1,ncol_bytes*nrow)
endif
close(iu)
return
98 error = .true.
write(*,622) ioerr,filename(1:getlen(filename))
622 format(/,' BMPWRITE - Error # ',i5,' occurred while writing ',a,/)
close(iu)
return
end
c****************************************************************************
integer*2 function getlen(word)
integer*2 ic
character*(*) word
getlen = len(word) + 1
11 getlen = getlen - 1
if(getlen.eq.0) return
ic = ichar(word(getlen:getlen))
if(ic.eq.32 .or. ic.eq.0) go to 11
return
end