campo-sirio/cb5/r4bit.c

326 lines
7.2 KiB
C
Raw Normal View History

/* r4bit.c (c)Copyright Sequiter Software Inc., 1991-1994. All rights reserved. */
#include "d4all.h"
#ifdef S4WINDOWS
#define ABS(x) ((x<0)?-1*(x):x)
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')
#define BYTES_PER_READ 32767
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD) (lpbi)) == sizeof (BITMAPINFOHEADER))
DWORD PASCAL kwrite ( int, VOID FAR *, DWORD );
WORD S4FUNCTION DIBNumColors (LPSTR lpbi)
{
WORD wBitCount;
/* If this is a Windows style DIB, the number of colors in the */
/* color table can be less than the number of bits per pixel */
/* allows for (i.e. lpbi->biClrUsed can be set to some value). */
/* If this is the case, return the appropriate value. */
if (IS_WIN30_DIB (lpbi))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
if (dwClrUsed)
return (WORD) dwClrUsed;
}
/* Calculate the number of colors in the color table based on */
/* the number of bits per pixel for the DIB. */
if (IS_WIN30_DIB (lpbi))
wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER) lpbi)->bcBitCount;
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
WORD S4FUNCTION PaletteSize (LPSTR lpbi)
{
if (IS_WIN30_DIB (lpbi))
return (DIBNumColors (lpbi) * sizeof (RGBQUAD));
else
return (DIBNumColors (lpbi) * sizeof (RGBTRIPLE));
}
LPSTR S4FUNCTION FindDIBBits (LPSTR lpbi)
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
}
HANDLE S4FUNCTION GetDIB ( LPSTR fname, CODE4 *code_base )
{
int hFile;
OFSTRUCT ofs;
HANDLE hDIB;
char fname2[14];
FILE4 file;
u4name_piece( fname2, sizeof(fname2), fname, 0, 1 );
SetCursor(LoadCursor(NULL, IDC_WAIT));
if( file4open( &file, code_base, fname2, 1 ) == 0 )
{
file4close( &file );
if ((hFile = OpenFile (fname2, &ofs, OF_READ)) != -1)
{
hDIB = ReadDIBFile (hFile);
_lclose (hFile);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return hDIB;
}
}
else
e4set( code_base, 0 );
if ((hFile = OpenFile (fname, &ofs, OF_READ)) != -1)
{
hDIB = ReadDIBFile (hFile);
_lclose (hFile);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return hDIB;
}
SetCursor(LoadCursor(NULL, IDC_ARROW));
return NULL;
}
/*************************************************************************
Function: MyRead (int, LPSTR, DWORD)
Purpose: Routine to read files greater than 64K in size.
Returns: TRUE if successful.
FALSE if an error occurs.
Comments:
History: Date Reason
6/1/91 Created
*************************************************************************/
BOOL MyRead (int hFile, LPSTR lpBuffer, DWORD dwSize)
{
#ifndef S4WIN32
char huge *lpInBuf = (char huge *) lpBuffer;
#else
char *lpInBuf = (char *) lpBuffer;
#endif
int nBytes;
while (dwSize)
{
nBytes = (int) (dwSize > (DWORD) BYTES_PER_READ ? BYTES_PER_READ :
LOWORD (dwSize));
if (_lread (hFile, (LPSTR) lpInBuf, nBytes) != (WORD) nBytes)
return FALSE;
dwSize -= nBytes;
lpInBuf += nBytes;
}
return TRUE;
}
/*************************************************************************
Function: ReadDIBFile (int)
Purpose: Reads in the specified DIB file into a global chunk of
memory.
Returns: A handle to a dib (hDIB) if successful.
NULL if an error occurs.
Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything
from the end of the BITMAPFILEHEADER structure on is
returned in the global memory handle.
History: Date Author Reason
6/1/91 Created
6/27/91 Removed PM bitmap conversion routines.
6/31/91 Removed logic which overallocated memory
(to account for bad display drivers).
11/08/91 Again removed logic which overallocated
memory (it had creeped back in!)
*************************************************************************/
HANDLE S4FUNCTION ReadDIBFile (int hFile)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HANDLE hDIB;
LPSTR pDIB;
/* get length of DIB in bytes for use when reading */
dwBitsSize = filelength (hFile);
/* Go read the DIB file header and check if it's valid. */
if ((_lread (hFile, (LPSTR) &bmfHeader, sizeof (bmfHeader)) != sizeof (bmfHeader)) ||
(bmfHeader.bfType != DIB_HEADER_MARKER))
{
/* DIBError (ERR_NOT_DIB); */
return NULL;
}
/* Allocate memory for DIB */
hDIB = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize - sizeof(BITMAPFILEHEADER));
if (hDIB == 0)
{
/* DIBError (ERR_MEMORY); */
return NULL;
}
pDIB = GlobalLock (hDIB);
/* Go read the bits. */
if (!MyRead (hFile, pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)))
{
GlobalUnlock (hDIB);
GlobalFree (hDIB);
return NULL;
}
GlobalUnlock (hDIB);
return hDIB;
}
/****************************************************************************
FUNCTION : lwrite(int fh, VOID FAR *pv, DWORD ul)
PURPOSE : Writes data in steps of 32k till all the data is written.
RETURNS : 0 - If write did not proceed correctly.
number of bytes written otherwise.
****************************************************************************/
DWORD PASCAL kwrite (int fh, VOID FAR *pv, DWORD ul)
{
DWORD ulT = ul;
#ifndef S4WIN32
BYTE huge *hp = (unsigned char huge *)pv;
#else
BYTE *hp = pv;
#endif
while (ul > BYTES_PER_READ)
{
if (_lwrite(fh, (LPSTR)hp, (WORD)BYTES_PER_READ) != BYTES_PER_READ)
return 0;
ul -= BYTES_PER_READ;
hp += BYTES_PER_READ;
}
if (_lwrite(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
return 0;
return ulT;
}
/****************************************************************************
FUNCTION : WriteDIB(LPSTR szFile,HANDLE hdib)
PURPOSE : Write a global handle in CF_DIB format to a file.
RETURNS : TRUE - if successful.
FALSE - otherwise
****************************************************************************/
BOOL S4FUNCTION WriteDIB (LPSTR szFile, HANDLE hdib)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
int fh;
OFSTRUCT of;
if (!hdib)
return FALSE;
fh = OpenFile (szFile, &of, OF_CREATE|OF_READWRITE);
if (fh == -1)
return FALSE;
lpbi = (LPBITMAPINFOHEADER)GlobalLock (hdib);
/* Fill in the fields of the file header */
hdr.bfType = DIB_HEADER_MARKER;
hdr.bfSize = GlobalSize (hdib) + sizeof (BITMAPFILEHEADER);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpbi->biSize +
PaletteSize((LPSTR)lpbi);
/* Write the file header */
if (!_lwrite (fh, (LPSTR)&hdr, sizeof (BITMAPFILEHEADER)))
{
GlobalUnlock (hdib);
_lclose (fh);
return FALSE;
}
/* Write the DIB header and the bits */
if (!kwrite (fh, (LPSTR)lpbi, GlobalSize (hdib)))
{
GlobalUnlock (hdib);
_lclose (fh);
return FALSE;
}
GlobalUnlock (hdib);
_lclose (fh);
return TRUE;
}
#endif