Exemple #1
0
// Liest Dateiheader und Farbtabelle im DIBformat ein 
HBITMAP CBildObjekt :: ReadDIBitmapInfo (unsigned int fh) 
{
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
unsigned int iNumColors = 0;
HBITMAP hBI = NULL;		// Farbtabelle - HANDLE
BITMAPINFOHEADER *lpBI = NULL;
RGBQUAD *lpRGB;			// Farbtabelle 
ULONG dwOffset;         // Dateiposition

	if (fh == -1) return NULL;      // ungültiges Dateihandle

// Dateiheader (BITMAPFILEHEADER) lesen
	dwOffset = _llseek (fh, 0L, SEEK_CUR);
	if (_hread (fh, &bf, sizeof(bf)) != sizeof(bf))
		return NULL;

// Not a DIB ? 
	if (!ISDIB (bf.bfType))
		return NULL;

// BitMapHeader (BITMAPINFOHEADER) lesen
	if (_hread (fh, &bi, sizeof(bi)) != sizeof(bi))
		return NULL;	// not a DIB

	iNumColors = DIBNumColors ((BITMAPINFOHEADER *)&bi);
	if (bi.biSize != sizeof(BITMAPINFOHEADER))	
		return NULL;	// falsches Datenformat

// Defaultgrößen setzen 
	if (bi.biSizeImage == 0)
		bi.biSizeImage = WIDTHBYTES ((ULONG)bi.biWidth * bi.biBitCount)
						*bi.biHeight;
	if (bi.biClrUsed == 0)
		bi.biClrUsed = iNumColors;

// Speicher für BitMap und Farbtabelle anfordern 
	hBI = (HBITMAP)GlobalAlloc (GHND, (ULONG)bi.biSize + iNumColors * sizeof(RGBQUAD));
	if (!hBI) return NULL;

	lpBI = (BITMAPINFOHEADER *)GlobalLock (hBI);
	*lpBI = bi;
	lpRGB = (RGBQUAD *)((char *)lpBI + bi.biSize);

// Farbtabelle einlesen 
	if (iNumColors)
		_hread (fh, lpRGB, iNumColors * sizeof(RGBQUAD));

// an Anfang der BitMap positionieren 
	if (bf.bfOffBits != 0)
		_llseek (fh, dwOffset + bf.bfOffBits, SEEK_SET);

	m_dim = CSize(bi.biWidth, bi.biHeight);

// Speicher wieder freigeben 
	GlobalUnlock (hBI);

return hBI;
}
Exemple #2
0
//************************************************************************
BOOL CDib::LoadFromFile(LPCSTR lpFileName, BOOL fDecodeRLE)
//************************************************************************
{
	FNAME szExpFileName;
	if ( !FindContent( (LPSTR)lpFileName, szExpFileName ) )
		return(FALSE);

	HFILE fh;
	OFSTRUCT of;
	if ( (fh = OpenFile(szExpFileName, &of, OF_READ)) < 0 )
		return(FALSE);
			
	if ( !(ReadBitmapInfo(fh)) )
		return FALSE;

	// Can we get enough memory to hold the DIB bits
	DWORD dwBits;
	if ( !(m_lp = AllocX( dwBits = GetSizeImage(), GMEM_ZEROINIT )) )
		{
		_lclose(fh);
		return( FALSE );
		}

	// read in the bits
	_hread( fh, m_lp, dwBits );
	_lclose( fh );

	return(CheckDecodeRLE(fDecodeRLE));
}
Exemple #3
0
/* internal function, reads lzheader
 * returns BADINHANDLE for non filedescriptors
 * return 0 for file not compressed using LZ
 * return UNKNOWNALG for unknown algorithm
 * returns lzfileheader in *head
 */
static INT read_header(HFILE fd,struct lzfileheader *head)
{
	BYTE	buf[LZ_HEADER_LEN];

	if (_llseek(fd,0,SEEK_SET)==-1)
		return LZERROR_BADINHANDLE;

	/* We can't directly read the lzfileheader struct due to
	 * structure element alignment
	 */
	if (_hread(fd,buf,LZ_HEADER_LEN)<LZ_HEADER_LEN)
		return 0;
	memcpy(head->magic,buf,LZ_MAGIC_LEN);
	memcpy(&(head->compressiontype),buf+LZ_MAGIC_LEN,1);
	memcpy(&(head->lastchar),buf+LZ_MAGIC_LEN+1,1);

	/* FIXME: consider endianess on non-intel architectures */
	memcpy(&(head->reallength),buf+LZ_MAGIC_LEN+2,4);

	if (memcmp(head->magic,LZMagic,LZ_MAGIC_LEN))
		return 0;
	if (head->compressiontype!='A')
		return LZERROR_UNKNOWNALG;
	return 1;
}
Exemple #4
0
BOOL My__hread()
{
	HFILE hFile=NULL;
	LPVOID lpBuffer=NULL;
	long lBytes=NULL;
	long returnVal_Real = NULL;
	long returnVal_Intercepted = NULL;

	DWORD error_Real = 0;
	DWORD error_Intercepted = 0;
	disableInterception();
	returnVal_Real = _hread (hFile,lpBuffer,lBytes);
	error_Real = GetLastError();
	enableInterception();
	returnVal_Intercepted = _hread (hFile,lpBuffer,lBytes);
	error_Intercepted = GetLastError();
	return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted));
}
Exemple #5
0
LPVOID LoadFile(LPCTSTR szFile, DWORD * pFileLength)
{
    LPVOID pFile;
    HANDLE hFile;
    HANDLE h;
    DWORD  FileLength;

#ifdef WIN32
    hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if (hFile == INVALID_HANDLE_VALUE)
        return 0;

    FileLength = (LONG)GetFileSize(hFile, NULL);

    if (pFileLength)
       *pFileLength = FileLength ;

    h = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    CloseHandle(hFile);

    if (h == INVALID_HANDLE_VALUE)
        return 0;

    pFile = MapViewOfFile(h, FILE_MAP_READ, 0, 0, 0);
    CloseHandle(h);

    if (pFile == NULL)
        return 0;
#else
    hFile = (HANDLE)_lopen(szFile, OF_READ);

    if (hFile == (HANDLE)-1)
        return 0;

    FileLength = _llseek((int)hFile, 0, SEEK_END);
    _llseek((int)hFile, 0, SEEK_SET);

    pFile = GlobalAllocPtr(GHND, FileLength);

    if (pFile && _hread((int)hFile, pFile, FileLength) != FileLength)
    {
        GlobalFreePtr(pFile);
        pFile = NULL;
    }
    _lclose((int)hFile);
#endif
    return pFile;
}
Exemple #6
0
static int
_lzget(struct lzstate *lzs,BYTE *b) {
	if (lzs->getcur<lzs->getlen) {
		*b		= lzs->get[lzs->getcur++];
		return		1;
	} else {
		int ret = _hread(lzs->realfd,lzs->get,GETLEN);
		if (ret==HFILE_ERROR)
			return HFILE_ERROR;
		if (ret==0)
			return 0;
		lzs->getlen	= ret;
		lzs->getcur	= 1;
		*b		= *(lzs->get);
		return 1;
	}
}
Exemple #7
0
// Einlesen der DIB in den Speicher 
HBITMAP CBildObjekt :: ReadDIB (unsigned fh) 
{
ULONG dwBits;   // Größe der DIB
ULONG dwLen;
HBITMAP h;
BITMAPINFOHEADER bi;
BITMAPINFOHEADER *lpbi;

// Benoetigten Speicherplatz berechnen 
	DIBInfo (&bi);
	dwBits = bi.biSizeImage;
	dwLen = bi.biSize + (ULONG)(DIBNumColors(&bi)*sizeof(RGBQUAD));
					// PaletteSize (&bi);

// Vergrößern des Speicherplatzes für gesamte Bitmap
	h = (HBITMAP)GlobalReAlloc (m_hDIB, dwLen + dwBits, GHND);
	if (!h) {
	/* gesamten Speicher freigeben */
		GlobalFree (m_hDIB);
		m_hDIB = NULL;
		return NULL;
	} 

// DIB-Bits einlesen
	lpbi = (BITMAPINFOHEADER *)GlobalLock (h);
	if ((DWORD)_hread (fh, (char *)lpbi + dwLen, dwBits) != dwBits) {
	// LeseFehler
		GlobalUnlock (h);
		GlobalFree (h);
		GlobalFree (m_hDIB);  // bisher angeforderten Speicher freigeben
		m_hDIB = NULL;
		return NULL;
	}
	GlobalUnlock (h);

return h;
}
Exemple #8
0
static tsize_t 
_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
{
  return (_hread(fd, buf, size));
}
Exemple #9
0
//***********************************************************************
LRESULT MMIOJunkRead(MMIOINFO *pInfo, LPBYTE lpBuf, long lSize)
//***********************************************************************
{
	HFILE hFile = pInfo->adwInfo[0];
	CHNKTIP *pChnkTip;

	// Make sure these are set to the default in case no
	// data is found
	nCurPlayerZ = 0;
	nCurNumWalls = 0;
	nCurNumEnemy = 0;

#ifdef DEBUG_READ
char debug[80];
wsprintf(debug, "--- Read %ld, at %ld\n", lSize, pInfo->lDiskOffset);
OutputDebugString(debug);
#endif

#ifdef DEBUG_DATA3D
int lDebOffset = pInfo->lDiskOffset;
#endif

	// Read the buffer
	long lNum = _hread(hFile, lpBuf, lSize);
	if (lNum != HFILE_ERROR)
	{
		pInfo->lDiskOffset += lNum;		
		pChnkTip = (CHNKTIP *)lpBuf;

		// Is this the index?
		if (lSize > 1000000)
		{
			g_pIndex = (AVIINDEXENTRY *)lpBuf;
			g_dwNumIdx = lSize / sizeof(AVIINDEXENTRY);

			//for(int i=0; i<20; i++)
			//{

			//wsprintf(debug, "%d) %c%c%c%c off=%ld size=%ld\n", i,
			//									   (BYTE)g_pIndex[i].ckid,
			//									   (BYTE)(DWORD)(g_pIndex[i].ckid >> 8),
			//									   (BYTE)(DWORD)(g_pIndex[i].ckid >> 16),
			//									   (BYTE)(DWORD)(g_pIndex[i].ckid >> 24),
			//									   (long)g_pIndex[i].dwChunkOffset,
			//									   (long)g_pIndex[i].dwChunkLength);
			//OutputDebugString(debug);
			//}
		}

//#define mmioFOURCC( ch0, ch1, ch2, ch3 )				\
//		( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |	\
//		( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )

		//if (g_pIndex)
		//{
		//	wsprintf(debug, "%c%c%c%c off=%ld size=%ld\n", (BYTE)g_pIndex->ckid,
		//										   (BYTE)(DWORD)(g_pIndex->ckid >> 8),
		//										   (BYTE)(DWORD)(g_pIndex->ckid >> 16),
		//										   (BYTE)(DWORD)(g_pIndex->ckid >> 24),
		//										   (long)g_pIndex->dwChunkLength);
		//	OutputDebugString(debug);
		//}
//typedef struct {
//    DWORD  ckid;
//    DWORD  dwFlags;
//    DWORD  dwChunkOffset;
//    DWORD  dwChunkLength;
//} AVIINDEXENTRY;
		// Is this a wave chunk?
		if (pChnkTip->ckid == FOURCC_WB)
		{
			//wsprintf(debug, "wave size = %ld, frame %ld\n", pChnkTip->cksize, lFrameCount++);
			//OutputDebugString(debug);
		}

		// Not a wave chunk, but there may be wave data in this chunk...let's find out
		else
		{
			//wsprintf(debug, "%c%c%c%c\n", *lpBuf, *(lpBuf+1), *(lpBuf+2), *(lpBuf+3));
			//OutputDebugString(debug);

			// Is this a video chunk?
			if (pChnkTip->ckid == FOURCC_DC)
			{
				
				// Offset to wave buffer (make sure even byte aligned)
				long lOffset = ((pChnkTip->cksize + sizeof(CHNKTIP)) + 1) & 0xfffffffe;
#ifdef DEBUG_DATA3D
lDebOffset += lOffset;
#endif

				// Set pointer to possible wave data
				lpBuf = lpBuf + lOffset;

				pChnkTip = (CHNKTIP *)lpBuf;

				// Is this a wave chunk?
				if (pChnkTip->ckid == FOURCC_WB)
				{
					//wsprintf(debug, "wave size = %ld, frame %ld\n", pChnkTip->cksize, lFrameCount++);
					//OutputDebugString(debug);

					// Offset to junk data
					lOffset = ((pChnkTip->cksize + sizeof(CHNKTIP)) + 1) & 0xfffffffe;

#ifdef DEBUG_DATA3D
lDebOffset += lOffset;
#endif
					// Set pointer to possible junk data
					lpBuf = lpBuf + lOffset;
					pChnkTip = (CHNKTIP *)lpBuf;

					if (pChnkTip->ckid == FOURCC_JK)
					{
						lpBuf += 8;
						char cTag = *lpBuf;
				
						// If 3d data in this junk
						if (cTag == '3')
						{
							int i;

#ifdef DEBUG_DATA3D
{
char debug[80];
lDebOffset += 8;
wsprintf(debug,"--- 3d data offset=%ld ---\n", lDebOffset);
OutputDebugString(debug);
}
#endif
							// Get Command code
							lpBuf += sizeof(cTag);
							nCurCommand = *((int *)lpBuf);

							// Get current player z position
							lpBuf += sizeof(nCurCommand);
							nCurPlayerZ = *((int *)lpBuf);

							// Get the number of walls
							lpBuf += sizeof(nCurPlayerZ);
							nCurNumWalls = *((int *)lpBuf);
							if (nCurNumWalls > nMaxWalls || nCurNumWalls < 0)
							{
#ifdef _DEBUG
								char debug[81];
								wsprintf(debug,"ERROR!!! Too many walls (%d)!\n", nCurNumWalls);
								OutputDebugString(debug);
#endif
								// Bad data, so we need to make it safe and bail
								goto GotBadDataNeedToBail;
							}
							assert(nCurNumWalls <= nMaxWalls);
							
							// Get the y (ground) position
							lpBuf += sizeof(nCurNumWalls);
							yCurGround = *((int *)lpBuf);

#ifdef DEBUG_DATA3D
{
char debug[80];
wsprintf(debug,"nCurPlayerZ=%d,nCurNumWalls=%d,yCurGround=%d\n", nCurPlayerZ, nCurNumWalls, yCurGround);
OutputDebugString(debug);
}
#endif
							// Get the walls (if any)
							lpBuf += sizeof(yCurGround);
							for (i=0; i<nCurNumWalls; i++)
							{
								memcpy( &CurWalls[i], lpBuf, sizeof(SWALL));
								lpBuf += sizeof(SWALL);
							}

							// Get the number of enemies
							nCurNumEnemy = *((int *)lpBuf);
							if (nCurNumEnemy >= nMaxEnemies || nCurNumEnemy < 0)
							{
#ifdef _DEBUG
								char debug[81];
								wsprintf(debug,"ERROR!!! Too many enemies (%d)!\n", nCurNumEnemy);
								OutputDebugString(debug);
								//DebugBreak();
#endif
								goto GotBadDataNeedToBail;
							}
							assert(nCurNumEnemy < nMaxEnemies);

#ifdef DEBUG_DATA3D
{
char debug[80];
wsprintf(debug,"nCurNumEnemy=%d\n", nCurNumEnemy);
OutputDebugString(debug);
}
#endif
							// Get the enemies (if any)
							lpBuf += sizeof(nCurNumEnemy);
							for (i=0; i<nCurNumEnemy; i++)
							{
								memcpy( &CurEnemy[i], lpBuf, sizeof(SENEMY));
								lpBuf += sizeof(SENEMY);
							}

							//wsprintf(debug, "3D Data!\n");
							//OutputDebugString(debug);
						}
					}
				}				
			}
			else
			{
				//char szChunk[5];
				//lstrcpyn(szChunk, (char *)pChnkTip, 4);
				//szChunk[4] = NULL;
				//wsprintf(debug, "chunk? = %s, frame %ld\n", szChunk, lFrameCount++);
				//OutputDebugString(debug);
			}
		}
	}
	return lNum;

GotBadDataNeedToBail:

	nCurNumWalls = 0;
	yCurGround = 0;
	nCurNumEnemy = 0;

	return lNum;

}
Exemple #10
0
/***********************************************************************
 *           LZRead   (KERNEL32.@)
 */
INT WINAPI LZRead( HFILE fd, LPSTR vbuf, INT toread )
{
	int	howmuch;
	BYTE	b,*buf;
	struct	lzstate	*lzs;

	buf=(LPBYTE)vbuf;
	DPRINT("(%d,%p,%d)\n",fd,buf,toread);
	howmuch=toread;
	if (!(lzs = GET_LZ_STATE(fd))) return _hread(fd,buf,toread);

/* The decompressor itself is in a define, cause we need it twice
 * in this function. (the decompressed byte will be in b)
 */
#define DECOMPRESS_ONE_BYTE 						\
		if (lzs->stringlen) {					\
			b		= lzs->table[lzs->stringpos];	\
			lzs->stringpos	= (lzs->stringpos+1)&0xFFF;	\
			lzs->stringlen--;				\
		} else {						\
			if (!(lzs->bytetype&0x100)) {			\
				if (1!=GET(lzs,b)) 			\
					return toread-howmuch;		\
				lzs->bytetype = b|0xFF00;		\
			}						\
			if (lzs->bytetype & 1) {			\
				if (1!=GET(lzs,b))			\
					return toread-howmuch;		\
			} else {					\
				BYTE	b1,b2;				\
									\
				if (1!=GET(lzs,b1))			\
					return toread-howmuch;		\
				if (1!=GET(lzs,b2))			\
					return toread-howmuch;		\
				/* Format:				\
				 * b1 b2				\
				 * AB CD 				\
				 * where CAB is the stringoffset in the table\
				 * and D+3 is the len of the string	\
				 */					\
				lzs->stringpos	= b1|((b2&0xf0)<<4);	\
				lzs->stringlen	= (b2&0xf)+2; 		\
				/* 3, but we use a  byte already below ... */\
				b		= lzs->table[lzs->stringpos];\
				lzs->stringpos	= (lzs->stringpos+1)&0xFFF;\
			}						\
			lzs->bytetype>>=1;				\
		}							\
		/* store b in table */					\
		lzs->table[lzs->curtabent++]= b;			\
		lzs->curtabent	&= 0xFFF;				\
		lzs->realcurrent++;

	/* if someone has seeked, we have to bring the decompressor
	 * to that position
	 */
	if (lzs->realcurrent!=lzs->realwanted) {
		/* if the wanted position is before the current position
		 * I see no easy way to unroll ... We have to restart at
		 * the beginning. *sigh*
		 */
		if (lzs->realcurrent>lzs->realwanted) {
			/* flush decompressor state */
			_llseek(lzs->realfd,LZ_HEADER_LEN,SEEK_SET);
			GET_FLUSH(lzs);
			lzs->realcurrent= 0;
			lzs->bytetype	= 0;
			lzs->stringlen	= 0;
			memset(lzs->table,' ',LZ_TABLE_SIZE);
			lzs->curtabent	= 0xFF0;
		}
		while (lzs->realcurrent<lzs->realwanted) {
			DECOMPRESS_ONE_BYTE;
		}
	}

	while (howmuch) {
		DECOMPRESS_ONE_BYTE;
		lzs->realwanted++;
		*buf++		= b;
		howmuch--;
	}
	return 	toread;
#undef DECOMPRESS_ONE_BYTE
}
Exemple #11
0
BOOL CDDB::ConstructDDBFromFile(		// build a CDDB object from a DIB in a file
	LPCSTR lpszFileName,						// name of file containing DIB data
	HDC hDC,										// device context to use for call to CreateDIBitmap()
	BOOL fUseDIBPalette,						// flag indicating if DIB bitmap should be used for conversion
	HPALETTE hPalette)
{
	/*
	// Attempt to open the file and read in the BITMAPFILEHEADER structure.
	*/
		
	OFSTRUCT of;
	HFILE hfDIB;
		
	if ((hfDIB = OpenFile(lpszFileName, &of, OF_READ|OF_SHARE_DENY_WRITE)) != HFILE_ERROR)
	{
		BITMAPFILEHEADER BitmapFileHeader;
			
		if (_lread(hfDIB, &BitmapFileHeader, sizeof(BitmapFileHeader)) == sizeof(BitmapFileHeader))
		{
			/*
			// Validate the header.
			*/
				
			if (BitmapFileHeader.bfType == 0x4d42)
			{
				/*
				// Read in the rest of the file.
				*/
					
				HGLOBAL hDIB;
				long dwDIBSize;
					
				dwDIBSize = BitmapFileHeader.bfSize-sizeof(BitmapFileHeader);
					
				if ((hDIB = GlobalAlloc(GMEM_MOVEABLE, dwDIBSize)) != NULL)
				{
					LPBITMAPINFOHEADER lpHeader;
			
					if ((lpHeader = (LPBITMAPINFOHEADER)GlobalLock(hDIB)) != NULL)
					{
						if (_hread(hfDIB, lpHeader, dwDIBSize) == dwDIBSize)
						{
							/*
							// Validate the header size.
							*/
								
							if (lpHeader->biSize == sizeof(BITMAPINFOHEADER))
							{
								/*
								// Create the DDB.
								*/
									
								ConstructDDB(			// construct a DDB from the DIB data
									lpHeader,				// pointer to BITMAPINFOHEADER structure
									hDC,						// device context to use for call to CreateDIBitmap()
									fUseDIBPalette,		// flag indicating if DIB bitmap should be used for conversion
									hPalette);
							}
						}
							
						GlobalUnlock(hDIB);
						lpHeader = NULL;
					}
						
					GlobalFree(hDIB);
					hDIB = NULL;
				}
			}
		}
			
		_lclose(hfDIB);
		hfDIB = HFILE_ERROR;
	}
	
	return IsValid();
}
Exemple #12
0
BOOL LoadSoundData( HWND hwndParent, SOUND_DATA *psd, LPSTR szFile )
{
  int i, n, f_tag, f_channels, f_bits_per_sample;
  long f_len, f_sample_rate, data_offset, data_size;
  HFILE fh;
  BYTE huge *pData;
  CHAR szBuf[256];

  fh = _lopen( szFile, READ );

  if ( fh == HFILE_ERROR )
  {
    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Unable to open %s",
            (LPSTR)szFile );

    return FALSE;
  }

  _fmemset( szBuf, 0, sizeof(szBuf) );

  if ( _lread( fh, szBuf, sizeof(szBuf) ) < 4 )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Error reading sound file header for %s",
            (LPSTR)szFile );

    return FALSE;
  }

  i = 0;
  n = 0;

  while( i < sizeof(szBuf) - 4 )
  {
    if ( _fstrnicmp( &szBuf[i], "RIFF", 4 ) == 0 )
    {
      n = 1;
      i += 8;
    }
    else if ( _fstrnicmp( &szBuf[i], "WAVE", 4 ) == 0 )
    {
      if ( n < 1 )
      {
        break;
      }

      n = 2;
      i += 4;
    }
    else if ( _fstrnicmp( &szBuf[i], "fmt", 3 ) == 0 )
    {
      if ( n < 2 )
      {
        break;
      }

      f_len = *((long *)(&szBuf[i+4]));
      f_tag = *((int *)(&szBuf[i+8]));
      f_channels = *((int *)(&szBuf[i+10]));
      f_sample_rate = *((long *)(&szBuf[i+12]));
      f_bits_per_sample = *((int *)(&szBuf[i+22]));

      n = 3;
      i += (int)f_len + 8;
    }
    else if ( _fstrnicmp( &szBuf[i], "data", 4 ) == 0 )
    {
      data_offset = (long)(i + 8);
      data_size = *((long *)(&szBuf[i+4]));
      n = 4;
      break;
    }
    else
    {
      ++i;
    }
  }

  if ( n != 4 )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Unable to find sound data in %s",
            (LPSTR)szFile );

    return FALSE;
  }

  if ( f_tag != 1 )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Data in %s is not in PCM format.",
            (LPSTR)szFile );

    return FALSE;
  }

  if ( f_channels != 1 )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Data in %s is not single channel (mono).",
            (LPSTR)szFile );

    return FALSE;
  }

  if ( f_sample_rate < 22000 || f_sample_rate > 22100 )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Data in %s was recorded at %ldHz (22050Hz required).",
            (LPSTR)szFile, f_sample_rate );

    return FALSE;
  }

  if ( f_bits_per_sample != 8 )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Data in %s is not 8 bit data.",
            (LPSTR)szFile );

    return FALSE;
  }

  if ( data_size == 0L )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Data in %s has zero length.",
            (LPSTR)szFile );

    return FALSE;
  }

  pData = (BYTE huge *)GlobalAllocPtr( GPTR, (DWORD)data_size );

  if ( pData == NULL )
  {
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Out of memory reading sound file %s",
            (LPSTR)szFile );

    return FALSE;
  }

  _llseek( fh, data_offset, SEEK_SET );

  if ( _hread( fh, pData, data_size ) != data_size )
  {
    GlobalFreePtr( pData );
    _lclose(fh);

    MsgBox( hwndParent,
            MB_ICONEXCLAMATION,
            "Error reading sound file for %s",
            (LPSTR)szFile );

    return FALSE;
  }

  _lclose(fh);

  psd->length = data_size;
  psd->data = pData;

#if 0

  //
  // Convert from unsigned 8 bit data to signed 8 bit data.
  //

  while( data_size > 0L )
  {
    *pData++ -= 128;
    --data_size;
  }

#endif

  return TRUE;
  
} // LoadSoundData