📄 bmp.c
字号:
}
}
else
seWriteRegByte(REG_DISPLAY_MODE, seReadRegByte(REG_DISPLAY_MODE) & ~ROTATE90_MODE_BIT);
ShowBMP(fname, 0, 0);
DisplayBlank(FALSE);
seGetResolution(&nWidth, &nHeight);
if (kbhit() && (getch() == ESC))
exit(1);
return SUCCEED;
}
/*---------------------------------------------GetBMPInfo( )------*/
void GetBMPInfo(char *fname, unsigned *width, unsigned *height, unsigned *BitsPerPixel)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER inf;
int ff;
if( (ff = open(fname,O_RDONLY | O_BINARY)) == -1 )
{
printf("\nERROR: Failed to open BMP file:'%s'\n", fname);
PrintUsage();
close(ff);
exit(1);
}
read(ff,&bfh,sizeof(BITMAPFILEHEADER));
if( bfh.bfType != BFT_BMAP )
{
printf("\nERROR: '%s' is not a valid bitmap file.\n",fname);
close(ff);
exit(1);
}
read(ff,&inf,sizeof(BITMAPINFOHEADER));
*BitsPerPixel = inf.biBitCount;
*width = (unsigned) inf.biWidth;
*height = (unsigned) inf.biHeight;
close(ff);
}
/*---------------------------------------------ShowBMP( )------*/
unsigned ShowBMP(char *fname, unsigned DstX, unsigned DstY)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER inf;
RGBQUAD rgbQ;
int ff, i;
unsigned BitsPerPixel, DesiredBitsPerPixel;
unsigned ImgWidth, ImgHeight;
unsigned nWidth, nHeight;
int tmp;
unsigned BytesPerScanline;
BYTE *pLut;
unsigned VirtualWidth, VirtualHeight;
BYTE LUT[256*3];
if( (ff = open(fname,O_RDONLY | O_BINARY)) == -1 )
{
printf("\nERROR: Failed to open BMP file:'%s'\n", fname);
PrintUsage();
close(ff);
return FAIL;
}
read(ff,&bfh,sizeof(BITMAPFILEHEADER));
if( bfh.bfType != BFT_BMAP )
{
printf("\nERROR: '%s' is not a valid bitmap file.\n",fname);
close(ff);
return FAIL;
}
read(ff,&inf,sizeof(BITMAPINFOHEADER));
BitsPerPixel = inf.biBitCount;
ImgWidth = (unsigned) inf.biWidth;
ImgHeight = (unsigned) inf.biHeight;
if (inf.biCompression)
gbImgCompress = TRUE;
else
gbImgCompress = FALSE;
if (VerboseMode)
{
printf("Image Size: %d x %d x %d bits-per-pixel\n",
ImgWidth, ImgHeight, BitsPerPixel);
printf("Compression: ");
if (gbImgCompress)
printf("YES\n");
else
printf("NO\n");
}
/*
** Turn off display by blanking display
*/
seDisplayBlank(TRUE);
if (BitsPerPixel == 24)
DesiredBitsPerPixel = 16;
else
DesiredBitsPerPixel = BitsPerPixel;
seGetResolution( &nWidth, &nHeight );
if (ImgHeight > nHeight)
VirtualHeight = ImgHeight;
else
VirtualHeight = nHeight;
seDisplayBlank(TRUE);
seGetResolution(&VirtualWidth, &VirtualHeight);
BytesPerScanline = seGetBytesPerScanline();
if (BitsPerPixel >= 15)
tmp = 16;
else
tmp = BitsPerPixel;
VirtualWidth = (unsigned) (BytesPerScanline * 8L / tmp);
if (BitsPerPixel <= 8) /* no DAC for 16 Bpp */
{
/* Init LUT entries */
pLut = &LUT[0];
for ( i=0; i<pow(2,(double)BitsPerPixel); i++ )
{
read(ff,&rgbQ,sizeof(RGBQUAD));
*pLut++ = rgbQ.rgbRed;
*pLut++ = rgbQ.rgbGreen;
*pLut++ = rgbQ.rgbBlue;
}
}
if ( gbImgCompress == FALSE )
ShowUncompressed( ff, DstX, DstY, ImgHeight, ImgWidth, VirtualWidth, VirtualHeight, nWidth, BitsPerPixel );
else
ShowCompressed( ff, DstX, DstY, ImgHeight, ImgWidth, VirtualWidth, VirtualHeight, nWidth, BitsPerPixel );
if (BitsPerPixel <= 8) /* no DAC for 16 Bpp */
WriteLut( GetActiveSurfaceNumber(), LUT, (int) pow(2, (double) BitsPerPixel) );
/*
** Turn on display by turning off display blanking
*/
seDisplayBlank(FALSE);
close(ff);
return SUCCEED;
}
/*---------------------------------------------LineBlt( )------*/
//
// Because VirtualWidth is always 1024 in SwivelView 90/270 modes, it is necessary
// to determine how wide the display is with PhysicalWidth. PhysicalWidth, for a panel
// of 640x480 in SwivelView 90/270, is 480 pixels wide.
//
void LineBlt( BYTE far *pImgBuf, unsigned ImgWidth, unsigned DstX, unsigned DstY, unsigned VirtualWidth, unsigned PhysicalWidth, unsigned Bpp, DWORD DispLinearAddr )
{
DWORD DstAddr;
unsigned regDisplayMode;
DWORD Count;
DWORD Mask;
DWORD val;
DWORD *dwImgBuf;
/* adjust ImgWidth */
if ( ImgWidth > (PhysicalWidth-DstX) )
{
ImgWidth = PhysicalWidth-DstX;
}
regDisplayMode = seReadRegByte(REG_DISPLAY_MODE);
DstAddr = DispLinearAddr - seGetLinearDisplayAddress();
if (DstAddr > seGetInstalledMemorySize())
DstAddr = 0;
DstAddr += ((DWORD)DstY*(DWORD)VirtualWidth + DstX) * Bpp / 8;
if (DstAddr < 0x200000)
{
dwImgBuf = (DWORD *) pImgBuf;
Count = ImgWidth * Bpp;
Mask = (1 << (Count & 31)) - 1;
Count >>= 5;
do
{
seWriteDisplayDwords(DstAddr, *dwImgBuf++, 1);
DstAddr += sizeof (long);
--Count;
} while (Count);
val = seReadDisplayDword(DstAddr);
seWriteDisplayDwords(DstAddr, (*dwImgBuf & Mask) | (val & ~Mask), 1);
}
}
/*---------------------------------------------seLineBlt( )------*/
void seLineBlt( BYTE far *pImgBuf, unsigned ImgWidth, unsigned DstX, unsigned DstY, unsigned VirtualWidth, unsigned PhysicalWidth, unsigned Bpp )
{
switch (DisplaySurfaceCombination)
{
default:
case SURFACE_LCD0:
seSetLcdAsActiveSurface();
LineBlt(pImgBuf, ImgWidth, DstX, DstY, VirtualWidth, PhysicalWidth, Bpp, seGetSurfaceLinearAddress());
break;
case SURFACE_CRTTV0:
seSetCrtAsActiveSurface();
LineBlt(pImgBuf, ImgWidth, DstX, DstY, VirtualWidth, PhysicalWidth, Bpp, seGetSurfaceLinearAddress());
break;
case SURFACE_LCD0_CRTTV1:
if (GetActiveSurfaceNumber() == 0)
seSetLcdAsActiveSurface();
else if (GetActiveSurfaceNumber() == 1)
seSetCrtAsActiveSurface();
LineBlt(pImgBuf, ImgWidth, DstX, DstY, VirtualWidth, PhysicalWidth, Bpp, seGetSurfaceLinearAddress());
break;
}
}
/*-----------------------------------------------------------------------*/
/* we only support RLE_8 & RLE_4 format */
/*-----------------------------------------------------------------------*/
unsigned ShowCompressed( int ff, unsigned DstX, unsigned DstY, unsigned ImgH, unsigned ImgW, unsigned VirtualW, unsigned VirtualH, unsigned PhysicalWidth, unsigned Bpp )
{
unsigned LineCount=0;
unsigned LineWidth=0;
unsigned ColumnCount=0;
unsigned Val, Y, tmp, tmp1, i;
unsigned PreReadLine=0;
BYTE far * pTmp;
BYTE far *pImgBuf;
unsigned DesiredBpp;
int forever = TRUE;
#if defined(INTEL_W32) || defined(__GNUC__)
pImgBuf = (BYTE far*) malloc( 256+ImgW*Bpp/8 );
#else
pImgBuf = (BYTE far*) _fmalloc( 256+ImgW*Bpp/8 );
#endif
/* pImgBuf = (BYTE far*) _fmalloc( 2048 ); */
if( pImgBuf == NULL )
{
printf("\n no memory...");
close(ff);
free(pImgBuf);
return FAIL;
}
/*printf("pImgBuf:%lx, ff:%d, DstX:%d, DstY:%d ImgH:%d, ImgW:%d\n",pImgBuf, ff, DstX, DstY, ImgH, ImgW);
**printf("VW:%d, VH:%d, Bpp:%d\n",VirtualW, VirtualH, Bpp );
**getch();
*/
pTmp = pImgBuf;
Y=ImgH+DstY-1;
/* adjust ImgH */
if ( ImgH > (VirtualH-DstY) )
{
/* read from the image file, decode it if necessary,
** forward file pointer by (DstY+VirtualH-ImgH) lines
*/
PreReadLine = DstY+ImgH-VirtualH;
ImgH = VirtualH-DstY;
}
DesiredBpp = Bpp;
while (forever)
{
read( ff, &Val, 2 ); /* read in a word */
/* printf("Val:%04x\n",Val);*/
switch ( Val )
{
case 0x0100: /* end of bmp */
if ( LineCount >= PreReadLine )
{
Translate( pImgBuf, LineWidth, Bpp );
seLineBlt( pImgBuf, LineWidth, DstX+ColumnCount, Y-LineCount, VirtualW, PhysicalWidth, DesiredBpp );
}
free(pImgBuf);
return SUCCEED;
case 0x0000: /* end of a line */
if ( LineCount >= PreReadLine )
{
Translate( pImgBuf, LineWidth, Bpp );
seLineBlt( pImgBuf, LineWidth, DstX+ColumnCount, Y-LineCount, VirtualW, PhysicalWidth, DesiredBpp );
}
LineCount++;
LineWidth = 0;
ColumnCount = 0;
pTmp = pImgBuf;
break;
case 0x0200: /* delta mode, jump right & down */
if ( LineCount >= PreReadLine )
{
Translate( pImgBuf, LineWidth, Bpp );
seLineBlt( pImgBuf, LineWidth, DstX+ColumnCount, Y-LineCount, VirtualW, PhysicalWidth, DesiredBpp );
}
read( ff, &tmp, 2 ); /* read in the next word */
ColumnCount += (tmp&0xff) + LineWidth;
LineCount += (tmp&0xff00)>>8;
LineWidth = 0;
pTmp = pImgBuf;
break;
default:
if ( !(Val&0xff) )
{
/* absolute mode */
tmp = ( ((Val&0xff00)>>8) * Bpp +4 ) /8;
read( ff, pTmp, (tmp+1)&0xfffe ); /* read in more bytes, WORD aligned */
pTmp += tmp;
LineWidth += tmp*8/Bpp;
}
else
{
/* encode mode */
tmp = ((Val & 0xff) * Bpp +4)/8; /* # of bytes to repeat */
tmp1 = (Val& 0xff00)>>8; /* value of the byte */
for ( i=0; i<tmp; i++ )
{
*pTmp = (BYTE)tmp1;
pTmp++;
}
LineWidth += tmp*8/Bpp;
}
break;
}
}
/*
** Avoid compiler warning in Win32: unreachable code
*/
#ifndef INTEL_W32
return FAIL;
#endif
}
/*-----------------------------------------------------------------------*/
unsigned ShowUncompressed( int ff, unsigned DstX, unsigned DstY, unsigned ImgH, unsigned ImgW, unsigned VirtualW, unsigned VirtualH, unsigned PhysicalWidth, unsigned Bpp )
{
unsigned Count, Y;
#ifdef INTEL_DOS
BYTE far *pImgBuf;
#else
BYTE *pImgBuf;
#endif
unsigned DesiredBpp;
#if defined(INTEL_W32) || defined(__GNUC__)
pImgBuf = (BYTE *) malloc( 256+ImgW*Bpp/8 );
#else
pImgBuf = (BYTE far *) _fmalloc( 256+ImgW*Bpp/8 );
#endif
if( pImgBuf == NULL )
{
printf("\n no memory...");
close(ff);
free(pImgBuf);
return FAIL;
}
/* adjust ImgH */
if ( ImgH > (VirtualH-DstY) )
{
/*
** read from the image file, decode it if necessary,
** forward file pointer by (DstY+VirtualH-ImgH) lines
*/
for ( Y=DstY+ImgH-VirtualH; Y!=0; Y--)
read ( ff, pImgBuf, (unsigned)((ImgW*Bpp/8+3)&0xfffc) );
ImgH = VirtualH-DstY;
}
DesiredBpp = Bpp;
if (DesiredBpp == 24)
DesiredBpp = 16;
for( Y=ImgH+DstY; Y!=DstY; Y-- )
{
/* Read a line from the image file, decode RLE if required to pImgBuf */
/* line break if find word 0x0000 or 0x0200. */
Count = (unsigned)((ImgW*Bpp/8+3)&0xfffc);
read ( ff, pImgBuf, Count);
Translate( pImgBuf, Count, Bpp );
/* Blt a line to the virtual screen */
seLineBlt( pImgBuf, ImgW, DstX, Y-1, VirtualW, PhysicalWidth, DesiredBpp );
}
free(pImgBuf);
return SUCCEED;
}
/*--------------------------------------------------------------------
* Function:
* Translate 24 Bpp image to 16 bpp image.
*--------------------------------------------------------------------*/
void Translate( BYTE far *pImgBuf, unsigned LineWidth, unsigned Bpp )
{
BYTE far *pTmp1;
WORD far *pTmp2;
unsigned b, g, r, i;
if ( Bpp==24 )
{
/*
** Truncate the 24bpp color to 16bpp color.
** Only the most significant bits of the colors are saved.
*/
pTmp1 = pImgBuf;
pTmp2 = (WORD *)pImgBuf;
for ( i=0; i<LineWidth/3; i++ )
{
b = (*pTmp1++) >>3;
g = (*pTmp1++) <<3 & 0x07e0;
r = (*pTmp1++) <<8 & 0xf800;
*pTmp2++ = (WORD) (b|g|r);
}
}
}
/*------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -