Example #1
0
//--------------------------------------------------------------------------//
//--------------------------------------------------------------------------//
void CAGSymImage::LoadDIB(const BITMAPINFOHEADER* pHdr, const BYTE* pBits)
{
	Free();

	if (pHdr->biCompression == BI_RGB && (pHdr->biBitCount == 1 || pHdr->biBitCount == 4 || pHdr->biBitCount == 8 || pHdr->biBitCount == 24))
	{
		BITMAPINFOHEADER bi;
		bi = *pHdr;
		bi.biCompression = BI_RGB;

		if (!bi.biSizeImage)
			bi.biSizeImage = DibSizeImage(&bi);
		if (!bi.biClrUsed)
			bi.biClrUsed = DibNumColors(&bi);

		if (m_pDIB = (BITMAPINFOHEADER*)malloc(DibSize(&bi)))
		{
			*m_pDIB = bi;

			if (bi.biClrUsed)
				memcpy((void*)DibColors(m_pDIB), (void*)DibColors(pHdr), DibPaletteSize(pHdr));

			BYTE* pNewBits = (BYTE*)DibPtr(m_pDIB);
			const BYTE* pSrcBits;
			if (pBits)
				pSrcBits = pBits;
			else
				pSrcBits = (BYTE*)(DibColors(pHdr) + bi.biClrUsed);

			memcpy(pNewBits, pSrcBits, bi.biSizeImage);
		}
	}
}
Example #2
0
BOOL StartScan(DWORD *pdwLineSize)
{
	/*
	*	Preload our image into memory
	*/
	char szModulePath[_MAX_PATH];
	char szCompletePath[_MAX_PATH];
	char szFileLocation[_MAX_PATH];
	char szDriveName[_MAX_DRIVE];

	VERIFY(GetModuleFileName(hDSInst, szModulePath, _MAX_PATH));
	_splitpath(szModulePath, szDriveName, szFileLocation, NULL, NULL);
	wsprintf(szCompletePath, "%s%s", szDriveName, szFileLocation);

	_giRowsCopied = 0;
	_gpHeader = NULL;
	_gpImageData = NULL;
	_gpCurrentLine = NULL;
	_gdwLineSize = 0l;

	if(_ghDIB)
	{
		GlobalFree(_ghDIB);
		_ghDIB = NULL;
	}

	if(GetCurrentXResolution()==100.0F)
	{
		/*
		*	Easy, this is the format of our originals
		*/
		if(GetCurrentPixelType()==TWPT_GRAY)
		{
			strcat(szCompletePath, "twaingray.bmp");
			_ghDIB = OpenDIB(szCompletePath);
		}
		else if(GetCurrentPixelType()==TWPT_RGB)
		{
			strcat(szCompletePath, "twainrgb.bmp");
			_ghDIB = OpenDIB(szCompletePath);
		}
		else
		{
			strcat(szCompletePath, "twainbw.bmp");
			_ghDIB = OpenDIB(szCompletePath);
		}

		_gpHeader = (BITMAPINFOHEADER*)GlobalLock(_ghDIB);
		if(_gpHeader)
		{
			_gpImageData = ((BYTE*)_gpHeader) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * DibNumColors(_gpHeader);
			_gdwLineSize = ((_gpHeader->biWidth * _gpHeader->biBitCount+31)/32)*4;
			_gpCurrentLine = _gpImageData + (_gdwLineSize * (_gpHeader->biHeight-1));
			*pdwLineSize = _gdwLineSize;
		}
	}
	return _ghDIB?TRUE:FALSE;
}
Example #3
0
WORD PaletteSize (VOID FAR * pv)
{
	
	LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)pv;
	WORD NumColors = DibNumColors(lpbi);
	if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
		return (WORD)(NumColors * sizeof(RGBTRIPLE));
	else
		return (WORD)(NumColors * sizeof(RGBQUAD));
}
Example #4
0
BOOL W32CheckDibColorIndices(LPBITMAPINFOHEADER lpbmi)
{
    WORD i, nColors;
    LPWORD lpw = (LPWORD)DibColors(lpbmi);

    nColors = DibNumColors(lpbmi);
    if (lpbmi->biClrImportant) {
        nColors = min(nColors, (WORD)lpbmi->biClrImportant);
    }
    
    for (i = 0; i < nColors; ++i) {
        if (*lpw++ != i) {
            return FALSE;
        }
    }

    LOGDEBUG(LOG_ALWAYS, ("\nUndocumented Dib.Drv behaviour used\n"));

    return TRUE;
}
Example #5
0
HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi)
{
	LOGPALETTE *pPal;
	HPALETTE hpal = NULL;
	WORD nNumColors;
	BYTE red;
	BYTE green;
	BYTE blue;
	WORD i;
	RGBQUAD FAR *pRgb;
	if (!lpbi)
		return NULL;
	
	if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
		return NULL;
	/* Get a pointer to the color table and the number of colors in it */
	pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
	nNumColors = DibNumColors(lpbi);
	
	if (nNumColors)
	{
		/* Allocate for the logical palette structure */
		pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
		if (!pPal)
			return NULL;
		pPal->palNumEntries = nNumColors;
		pPal->palVersion = 0x300;
		/* 
		Fill in the palette entries from the DIB color table and create a logical color palette.
		*/
		for (i = 0; i < nNumColors; i++)
		{
			pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
			pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
			pPal->palPalEntry[i].peBlue  = pRgb[i].rgbBlue;
			pPal->palPalEntry[i].peFlags = (BYTE)0;
		}
		hpal = CreatePalette(pPal);
		LocalFree((HANDLE)pPal);
	}
	else if (lpbi->biBitCount == 24)
	{
		/* 
		A 24 bitcount DIB has no color table entries so, set the number of to the maximum value (256).
		*/
		nNumColors = 256;
		pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
		if (!pPal)
			return NULL;
		pPal->palNumEntries = nNumColors;
		pPal->palVersion = 0x300;
		red = green = blue = 0;
		for (i = 0; i < pPal->palNumEntries; i++)
		{
			pPal->palPalEntry[i].peRed = red;
			pPal->palPalEntry[i].peGreen = green;
			pPal->palPalEntry[i].peBlue  = blue;
			pPal->palPalEntry[i].peFlags = (BYTE)0;
			if (!(red += 32))
				if (!(green += 32))
					blue += 64;
		}
		hpal = CreatePalette(pPal);
		LocalFree((HANDLE)pPal);
	}
	return hpal;
}
Example #6
0
BOOL CDib::Open(HWND hWnd, const char *pFileName, BOOL bOpenFromFile)
{
	/*
	UINT fuLoad;

	if(bOpenFromFile==TRUE)
		fuLoad = LR_CREATEDIBSECTION|LR_LOADFROMFILE|LR_DEFAULTSIZE;
	else
		fuLoad = (bOpenFromFile?LR_CREATEDIBSECTION:0)|LR_LOADFROMFILE|LR_DEFAULTSIZE;
	*/
	m_hBitmap=(HBITMAP)::LoadImage(
		bOpenFromFile? NULL : (HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),
		pFileName,
		IMAGE_BITMAP,
		0,0,
		//fuLoad);
		LR_CREATEDIBSECTION|(bOpenFromFile?LR_LOADFROMFILE:0)|LR_DEFAULTSIZE);
	if(m_hBitmap==NULL){
//		SetErrors(CMERR_CANT_OPEN_FILE,pFileName);
		return FALSE;
	}

	BITMAP bm;
	BITMAPINFOHEADER bi;
	LPBITMAPINFOHEADER lpbi;	// 24bit라서 팔레트 정보가 없을 것이므로 필요없으나... 확장을 위해

	GetObject(m_hBitmap,sizeof(BITMAP),&bm);

	if(bm.bmHeight>=0)m_bTopDown=FALSE;
	else m_bTopDown=TRUE;

    bi.biSize				= sizeof(BITMAPINFOHEADER);
    bi.biWidth				= bm.bmWidth;
    bi.biHeight				= bm.bmHeight;
    bi.biPlanes				= 1;
    //bi.biBitCount           = bm.bmPlanes * bm.bmBitsPixel;
	bi.biBitCount			= 24;			// 8bit 도 24bit로 읽어낸다. 따라서 Pal 정보가 없다.
    bi.biCompression		= BI_RGB;
    bi.biSizeImage			= 0;
    bi.biXPelsPerMeter		= 0;
    bi.biYPelsPerMeter		= 0;
    bi.biClrUsed			= 0;
    bi.biClrImportant		= 0;

// 팔레트 개수
#define DibNumColors(lpbi)	((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
								? (WORD)(1 << (int)(lpbi)->biBitCount) \
								: (WORD)(lpbi)->biClrUsed)

	// BITMAPINFO( BITMAPINFOHEADER+PAL ) 의 크기
	DWORD nLen  = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD);

	lpbi=(LPBITMAPINFOHEADER)new char[nLen];

	*lpbi=bi;

	HDC hDC=GetDC(hWnd);
	GetDIBits(hDC,m_hBitmap,0,bi.biHeight,NULL,(LPBITMAPINFO)lpbi,DIB_RGB_COLORS);
	ReleaseDC(hWnd,hDC);

	bi=*lpbi;

	// 드라이버가 biSizeImage를 채우지 않는 경우
	if(bi.biSizeImage==0){
		bi.biSizeImage=(DWORD)WIDTHBYTES(bm.bmWidth*bi.biBitCount)*bm.bmHeight;
		if(bi.biCompression!=BI_RGB)
			bi.biSizeImage=(bi.biSizeImage*3)/2;
	}

	delete[] lpbi;

	nLen=bi.biSize+DibNumColors(&bi)*sizeof(RGBQUAD)+bi.biSizeImage;

	//lpbi=(LPBITMAPINFOHEADER)new char[nLen];
	m_pBitmapData=new BYTE[nLen];

	if(m_pBitmapData==NULL){
		//_RPT0(_CRT_WARN,"Memory Allocation Error");
//		SetError(CMERR_OUT_OF_MEMORY);
		return FALSE;
	}

	*(LPBITMAPINFOHEADER)m_pBitmapData=bi;

	hDC=GetDC(hWnd);
	GetDIBits(hDC,m_hBitmap,0,bi.biHeight,DibPtr((LPBITMAPINFOHEADER)m_pBitmapData),(LPBITMAPINFO)m_pBitmapData,DIB_RGB_COLORS);
	ReleaseDC(hWnd,hDC);
	
	return TRUE;
}
Example #7
0
PDIB DibReadBitmapInfo(int fh)
{
    DWORD     off;
    HANDLE    hbi = NULL;
    int       size;
    int       i;
    int       nNumColors;

    RGBQUAD FAR       *pRgb;
    BITMAPINFOHEADER   bi;
    BITMAPCOREHEADER   bc;
    BITMAPFILEHEADER   bf;
    PDIB               pdib;

    if (fh == -1)
        return NULL;

    off = lseek(fh,0L,SEEK_CUR);

    if (sizeof(bf) != read(fh,(LPSTR)&bf,sizeof(bf)))
        return FALSE;

    /*
     *  do we have a RC HEADER?
     */
    if (bf.bfType != BFT_BITMAP)
    {
        bf.bfOffBits = 0L;
        lseek(fh,off,SEEK_SET);
    }

    if (sizeof(bi) != read(fh,(LPSTR)&bi,sizeof(bi)))
        return FALSE;

    /*
     *  what type of bitmap info is this?
     */
    switch (size = (int)bi.biSize)
    {
    default:
    case sizeof(BITMAPINFOHEADER):
       break;
       
    case sizeof(BITMAPCOREHEADER):
       bc = *(BITMAPCOREHEADER*)&bi;
       bi.biSize               = sizeof(BITMAPINFOHEADER);
       bi.biWidth              = (DWORD)bc.bcWidth;
       bi.biHeight             = (DWORD)bc.bcHeight;
       bi.biPlanes             =  (UINT)bc.bcPlanes;
       bi.biBitCount           =  (UINT)bc.bcBitCount;
       bi.biCompression        = BI_RGB;
       bi.biSizeImage          = 0;
       bi.biXPelsPerMeter      = 0;
       bi.biYPelsPerMeter      = 0;
       bi.biClrUsed            = 0;
       bi.biClrImportant       = 0;
       
       lseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
       
       break;
    }
    
    nNumColors = DibNumColors(&bi);
    
    if (bi.biSizeImage == 0)
        bi.biSizeImage = DibSizeImage(&bi);

    if (bi.biClrUsed == 0)
        bi.biClrUsed = DibNumColors(&bi);

    pdib = (PDIB) malloc((LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));

    if (!pdib)
        return NULL;

    *pdib = bi;

    pRgb = DibColors(pdib);

    if (nNumColors == 0)
    {
       printf("Bitmap has no palette (24 bit)\n", NUM_COLORS, nNumColors);
       return NULL;
    }

    if (nNumColors != NUM_COLORS)
    {
       printf("Expecting %d color bitmap; found %d colors\n", NUM_COLORS, nNumColors);
       return NULL;
    }
       
    if (size == sizeof(BITMAPCOREHEADER))
    {
       /*
        * convert a old color table (3 byte entries) to a new
        * color table (4 byte entries)
        */
       read(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
       
       for (i=nNumColors-1; i>=0; i--)
       {
          RGBQUAD rgb;
          
          rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
          rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
          rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
          rgb.rgbReserved = (BYTE)0;
          
          pRgb[i] = rgb;
       }
    }
    else
    {
       read(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
    }

    if (bf.bfOffBits != 0L)
        lseek(fh,off + bf.bfOffBits,SEEK_SET);

    return pdib;
}
Example #8
0
HDIB DibConvert (HDIB hdibSrc, int iBitCountDst)
{
     HDIB         hdibDst ;
     HPALETTE     hPalette ;
     int          i, x, y, cx, cy, iBitCountSrc, cColors ;
     PALETTEENTRY pe ;
     RGBQUAD      rgb ;
     WORD         wNumEntries ;

     cx = DibWidth (hdibSrc) ;
     cy = DibHeight (hdibSrc) ;
     iBitCountSrc = DibBitCount (hdibSrc) ;

     if (iBitCountSrc == iBitCountDst)
          return NULL ;

          // DIB with color table to DIB with larger color table:

     if ((iBitCountSrc < iBitCountDst) && (iBitCountDst <= 8))
     {
          cColors = DibNumColors (hdibSrc) ;
          hdibDst = DibCreate (cx, cy, iBitCountDst, cColors) ;

          for (i = 0 ; i < cColors ; i++)
          {
               DibGetColor (hdibSrc, i, &rgb) ;
               DibSetColor (hdibDst, i, &rgb) ;
          }

          for (x = 0 ; x < cx ; x++)
          for (y = 0 ; y < cy ; y++)
          {
               DibSetPixel (hdibDst, x, y, DibGetPixel (hdibSrc, x, y)) ;
          }
     }
          // Any DIB to DIB with no color table

     else if (iBitCountDst >= 16)
     {
          hdibDst = DibCreate (cx, cy, iBitCountDst, 0) ;

          for (x = 0 ; x < cx ; x++)
          for (y = 0 ; y < cy ; y++)
          {
               DibGetPixelColor (hdibSrc, x, y, &rgb) ;
               DibSetPixelColor (hdibDst, x, y, &rgb) ;
          }
     }
          // DIB with no color table to 8-bit DIB

     else if (iBitCountSrc >= 16 && iBitCountDst == 8)
     {
          hPalette = DibPalMedianCut (hdibSrc, 6) ;

          GetObject (hPalette, sizeof (WORD), &wNumEntries) ;

          hdibDst = DibCreate (cx, cy, 8, wNumEntries) ;
          
          for (i = 0 ; i < (int) wNumEntries ; i++)
          {
               GetPaletteEntries (hPalette, i, 1, &pe) ;

               rgb.rgbRed   = pe.peRed ;
               rgb.rgbGreen = pe.peGreen ;
               rgb.rgbBlue  = pe.peBlue ;
               rgb.rgbReserved = 0 ;

               DibSetColor (hdibDst, i, &rgb) ;
          }

          for (x = 0 ; x < cx ; x++)
          for (y = 0 ; y < cy ; y++)
          {
               DibGetPixelColor (hdibSrc, x, y, &rgb) ;

               DibSetPixel (hdibDst, x, y,
                    GetNearestPaletteIndex (hPalette, 
                         RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ;
          }
          DeleteObject (hPalette) ;
     }
          // Any DIB to monochrome DIB

     else if (iBitCountDst == 1)
     {
          hdibDst = DibCreate (cx, cy, 1, 0) ;
          hPalette = DibPalUniformGrays (2) ;

          for (i = 0 ; i < 2 ; i++)
          {
               GetPaletteEntries (hPalette, i, 1, &pe) ;

               rgb.rgbRed   = pe.peRed ;
               rgb.rgbGreen = pe.peGreen ;
               rgb.rgbBlue  = pe.peBlue ;
               rgb.rgbReserved = 0 ;

               DibSetColor (hdibDst, i, &rgb) ;
          }

          for (x = 0 ; x < cx ; x++)
          for (y = 0 ; y < cy ; y++)
          {
               DibGetPixelColor (hdibSrc, x, y, &rgb) ;

               DibSetPixel (hdibDst, x, y,
                    GetNearestPaletteIndex (hPalette, 
                         RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ;
          }
          DeleteObject (hPalette) ;
     }
          // All non-monochrome DIBs to 4-bit DIB

     else if (iBitCountSrc >= 8 && iBitCountDst == 4)
     {
          hdibDst = DibCreate (cx, cy, 4, 0) ;
          hPalette = DibPalVga () ;

          for (i = 0 ; i < 16 ; i++)
          {
               GetPaletteEntries (hPalette, i, 1, &pe) ;

               rgb.rgbRed   = pe.peRed ;
               rgb.rgbGreen = pe.peGreen ;
               rgb.rgbBlue  = pe.peBlue ;
               rgb.rgbReserved = 0 ;

               DibSetColor (hdibDst, i, &rgb) ;
          }

          for (x = 0 ; x < cx ; x++)
          for (y = 0 ; y < cy ; y++)
          {
               DibGetPixelColor (hdibSrc, x, y, &rgb) ;

               DibSetPixel (hdibDst, x, y,
                    GetNearestPaletteIndex (hPalette, 
                         RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ;
          }
          DeleteObject (hPalette) ;
     }
          // Should not be necessary

     else
          hdibDst = NULL ;

     return hdibDst ;
}
bool CxImageBMP::Decode(CxFile * hFile)
{
	if (hFile == NULL) return false;

	BITMAPFILEHEADER   bf;
	DWORD off = hFile->Tell(); //<CSC>
  try {
    if (hFile->Read(&bf,min(14,sizeof(bf)),1)==0) throw "Not a BMP";
    if (bf.bfType != BFT_BITMAP) { //do we have a RC HEADER?
        bf.bfOffBits = 0L;
        hFile->Seek(off,SEEK_SET);
    }

	if (!DibReadBitmapInfo(hFile,&head)) throw "Error reading BMP info";
	DWORD dwCompression=head.biCompression;
	DWORD dwBitCount=head.biBitCount; //preserve for BI_BITFIELDS compression <Thomas Ernst>
	bool bIsOldBmp = head.biSize == sizeof(BITMAPCOREHEADER);
	head.biSize = sizeof(BITMAPINFOHEADER);

	bool bTopDownDib = head.biHeight<0; //<Flanders> check if it's a top-down bitmap
	if (bTopDownDib) head.biHeight=-head.biHeight;

	if (!Create(head.biWidth,head.biHeight,head.biBitCount,CXIMAGE_FORMAT_BMP))
		throw "Can't allocate memory";

	info.xDPI = (long) floor(head.biXPelsPerMeter * 254.0 / 10000.0 + 0.5);
	info.yDPI = (long) floor(head.biYPelsPerMeter * 254.0 / 10000.0 + 0.5);

	if (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding

    RGBQUAD *pRgb = GetPalette();
    if (pRgb){
        if (bIsOldBmp){
             // convert a old color table (3 byte entries) to a new
             // color table (4 byte entries)
            hFile->Read((void*)pRgb,DibNumColors(&head) * sizeof(RGBTRIPLE),1);
            for (int i=DibNumColors(&head)-1; i>=0; i--){
                pRgb[i].rgbRed      = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
                pRgb[i].rgbBlue     = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
                pRgb[i].rgbGreen    = ((RGBTRIPLE *)pRgb)[i].rgbtGreen;
                pRgb[i].rgbReserved = (BYTE)0;
            }
        } else {
            hFile->Read((void*)pRgb,DibNumColors(&head) * sizeof(RGBQUAD),1);
			//force rgbReserved=0, to avoid problems with some WinXp bitmaps
			for (unsigned int i=0; i<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
        }
    }

	if (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding

	switch (dwBitCount) {
		case 32 :
			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
			if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
				long imagesize=4*head.biHeight*head.biWidth;
				BYTE* buff32=(BYTE*)malloc(imagesize);
				if (buff32){
					hFile->Read(buff32, imagesize,1); // read in the pixels
					Bitfield2RGB(buff32,0,0,0,32);
					free(buff32);
				} else throw "can't allocate memory";
			} else throw "unknown compression";
			break;
		case 24 :
			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
			if (dwCompression == BI_RGB){
				hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
			} else throw "unknown compression";
			break;
		case 16 :
		{
			DWORD bfmask[3];
			if (dwCompression == BI_BITFIELDS)
			{
				hFile->Read(bfmask, 12, 1);
			} else {
				bfmask[0]=0x7C00; bfmask[1]=0x3E0; bfmask[2]=0x1F; //RGB555
			}
			// bf.bfOffBits required after the bitfield mask <Cui Ying Jie>
			if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
			// read in the pixels
			hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1);
			// transform into RGB
			Bitfield2RGB(info.pImage,(WORD)bfmask[0],(WORD)bfmask[1],(WORD)bfmask[2],16);
			break;
		}
		case 8 :
		case 4 :
		case 1 :
		if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
		switch (dwCompression) {
			case BI_RGB :
				hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
				break;
			case BI_RLE4 :
			{
				BYTE status_byte = 0;
				BYTE second_byte = 0;
				int scanline = 0;
				int bits = 0;
				BOOL low_nibble = FALSE;
				CImageIterator iter(this);

				for (BOOL bContinue = TRUE; bContinue;) {
					hFile->Read(&status_byte, sizeof(BYTE), 1);
					switch (status_byte) {
						case RLE_COMMAND :
							hFile->Read(&status_byte, sizeof(BYTE), 1);
							switch (status_byte) {
								case RLE_ENDOFLINE :
									bits = 0;
									scanline++;
									low_nibble = FALSE;
									break;
								case RLE_ENDOFBITMAP :
									bContinue=FALSE;
									break;
								case RLE_DELTA :
								{
									// read the delta values
									BYTE delta_x;
									BYTE delta_y;
									hFile->Read(&delta_x, sizeof(BYTE), 1);
									hFile->Read(&delta_y, sizeof(BYTE), 1);
									// apply them
									bits       += delta_x / 2;
									scanline   += delta_y;
									break;
								}
								default :
									hFile->Read(&second_byte, sizeof(BYTE), 1);
									BYTE *sline = iter.GetRow(scanline);
									for (int i = 0; i < status_byte; i++) {
										if (low_nibble) {
											if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
												*(sline + bits) |=  second_byte & 0x0F;
											}
											if (i != status_byte - 1)
												hFile->Read(&second_byte, sizeof(BYTE), 1);
											bits++;
										} else {
											if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
												*(sline + bits) = (BYTE)(second_byte & 0xF0);
											}
										}
										low_nibble = !low_nibble;
									}
									if (((status_byte / 2) & 1 )== 1)
										hFile->Read(&second_byte, sizeof(BYTE), 1);												
									break;
							};
							break;
						default :
						{
							BYTE *sline = iter.GetRow(scanline);
							hFile->Read(&second_byte, sizeof(BYTE), 1);
							for (unsigned i = 0; i < status_byte; i++) {
								if (low_nibble) {
									if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
										*(sline + bits) |= second_byte & 0x0F;
									}
									bits++;
								} else {
									if ((DWORD)(sline+bits) < (DWORD)(info.pImage+head.biSizeImage)){
										*(sline + bits) = (BYTE)(second_byte & 0xF0);
									}
								}				
								low_nibble = !low_nibble;
							}
						}
						break;
					};
				}
				break;
			}
			case BI_RLE8 :
			{
				BYTE status_byte = 0;
				BYTE second_byte = 0;
				int scanline = 0;
				int bits = 0;
				CImageIterator iter(this);

				for (BOOL bContinue = TRUE; bContinue; ) {
					hFile->Read(&status_byte, sizeof(BYTE), 1);
					switch (status_byte) {
						case RLE_COMMAND :
							hFile->Read(&status_byte, sizeof(BYTE), 1);
							switch (status_byte) {
								case RLE_ENDOFLINE :
									bits = 0;
									scanline++;
									break;
								case RLE_ENDOFBITMAP :
									bContinue=FALSE;
									break;
								case RLE_DELTA :
								{
									// read the delta values
									BYTE delta_x;
									BYTE delta_y;
									hFile->Read(&delta_x, sizeof(BYTE), 1);
									hFile->Read(&delta_y, sizeof(BYTE), 1);
									// apply them
									bits     += delta_x;
									scanline += delta_y;
									break;
								}
								default :
									hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(BYTE) * status_byte, 1);
									// align run length to even number of bytes 
									if ((status_byte & 1) == 1)
										hFile->Read(&second_byte, sizeof(BYTE), 1);												
									bits += status_byte;													
									break;								
							};
							break;
						default :
							BYTE *sline = iter.GetRow(scanline);
							hFile->Read(&second_byte, sizeof(BYTE), 1);
							for (unsigned i = 0; i < status_byte; i++) {
								*(sline + bits) = second_byte;
								bits++;					
							}
							break;
					};
				}
				break;
			}
			default :								
				throw "compression type not supported";
		}
	}

	if (bTopDownDib) Flip(); //<Flanders>

  } catch (char *message) {
	strncpy(info.szLastError,message,255);
	return false;
  }
    return true;
}
Example #10
0
HX_RESULT
CHXDIBits::GetDIBits(HDC		hDC,
		     HBITMAP		hBM,
		     UCHAR*&		pBits,
		     BITMAPINFOHEADER*&	pHeader)
{
    HX_RESULT		hr = HXR_OK;
    WORD		wBits = 0;
    DWORD   		dwLen = 0;
    BITMAP		bm;
    BITMAPINFOHEADER	bi;
    LPBITMAPINFOHEADER	lpbi = NULL;

    pBits = NULL;
    pHeader = NULL;

    if (!hDC || !hBM)
    {
	hr = HXR_FAILED;
	goto cleanup;
    }

    GetObject(hBM, sizeof(bm), &bm);

    wBits = (WORD)(bm.bmPlanes * bm.bmBitsPixel);

    bi.biSize		= sizeof(BITMAPINFOHEADER);
    bi.biWidth		= bm.bmWidth;
    bi.biHeight		= bm.bmHeight;
    bi.biPlanes		= 1;
    bi.biBitCount	= wBits;
    bi.biCompression	= BI_RGB;
    bi.biSizeImage	= WIDTHBYTES(bm.bmWidth * wBits) * bm.bmHeight;
    bi.biXPelsPerMeter	= 0;
    bi.biYPelsPerMeter  = 0;
    bi.biClrUsed	= 0;
    bi.biClrImportant	= 0;

    dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;

    if (!m_hDIB)
    {
	m_hDIB = GlobalAlloc(GMEM_MOVEABLE, dwLen);
    }
    else if (m_hDIB && (GlobalSize(m_hDIB) != dwLen))
    {
	GlobalFree(m_hDIB);
	m_hDIB = GlobalAlloc(GMEM_MOVEABLE, dwLen);
    }

    lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);

    if (!lpbi)
    {
	// This is bad, it's not clear how callers of this class can
	// really handle a failure case. So, we need to make sure that
	// all our callers do handle this correctly.
	HX_ASSERT(lpbi);
	hr = HXR_FAILED;
	goto cleanup;
    }

    *lpbi = bi;

    ::GetDIBits(hDC,
	      hBM,
	      0,
	      (WORD)bi.biHeight,
	      DibPtr(lpbi),
	      (LPBITMAPINFO)lpbi,
	      DIB_RGB_COLORS);

    bi = *lpbi;

    lpbi->biClrUsed = DibNumColors(lpbi);

    pBits = (UCHAR*)DibPtr(lpbi);
    pHeader = lpbi;

    GlobalUnlock(m_hDIB);

cleanup:

    return hr;
}
Example #11
0
HDC W32HandleDibDrv (PVPVOID vpbmi16)
{
    HDC             hdcMem = NULL;
    HBITMAP         hbm = NULL;
    PVOID           pvBits, pvIntelBits;
    STACKBMI32      bmi32;
    LPBITMAPINFO    lpbmi32;
    DWORD           dwClrUsed,nSize,nAlignmentSpace;
    PBITMAPINFOHEADER16 pbmi16;
    INT             nbmiSize,nBytesWritten;
    HANDLE          hfile=NULL,hsec=NULL;
    ULONG           RetVal,OriginalSelLimit,SelectorLimit,OriginalFlags;
    PARM16          Parm16;
    CHAR            pchTempFile[MAX_PATH];
    BOOL            bRet = FALSE;
    PVPVOID         vpBase16 = (PVPVOID) ((ULONG) vpbmi16 & 0xffff0000);

    if ((hdcMem = W32FindAndLockDibInfo((USHORT)HIWORD(vpbmi16))) != (HDC)NULL) {
        return hdcMem;
    }

    // First create a memory device context compatible to
    // the app's current screen
    if ((hdcMem = CreateCompatibleDC (NULL)) == NULL) {
        LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv CreateCompatibleDC failed\n"));
        return NULL;
    }

    // Copy bmi16 to bmi32. DIB.DRV only supports DIB_RGB_COLORS
    lpbmi32 = CopyBMI16ToBMI32(
                     vpbmi16,
                     (LPBITMAPINFO)&bmi32,
                     (WORD) DIB_RGB_COLORS);

    // this hack for Director 4.0 does essentially what WFW does
    // if this bitmap is 0 sized, just return an hDC for something simple
    if(bmi32.bmiHeader.biSizeImage == 0 &&
       (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_DIBDRVIMAGESIZEZERO)) {
        LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv:Zero biSizeImage, returning memory DC!\n"));
        return hdcMem;
    }

    try {

        // Copy the wholething into a temp file. First get a temp file name
        if ((nSize = GetTempPath (MAX_PATH, pchTempFile)) == 0 ||
             nSize >= MAX_PATH)
            goto hdd_err;

        if (GetTempFileName (pchTempFile,
                             "DIB",
                             0,
                             pchTempFile) == 0)
            goto hdd_err;

        if ((hfile = CreateFile (pchTempFile,
                                GENERIC_READ | GENERIC_WRITE,
                                FILE_SHARE_WRITE,
                                NULL,
                                CREATE_ALWAYS,
                                (FILE_ATTRIBUTE_NORMAL |
                                 FILE_ATTRIBUTE_TEMPORARY |
                                 FILE_FLAG_DELETE_ON_CLOSE),
                                NULL)) == INVALID_HANDLE_VALUE) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv CreateFile failed\n"));
            goto hdd_err;
        }

        // call back to get the size of the global object
        // associated with vpbmi16
        Parm16.WndProc.wParam = HIWORD(vpbmi16);

        CallBack16(RET_GETDIBSIZE,
                   &Parm16,
                   0,
                   (PVPVOID)&SelectorLimit);

        Parm16.WndProc.wParam = HIWORD(vpbmi16);

        if (SelectorLimit == 0xffffffff || SelectorLimit == 0) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv Invalid Selector %x\n",HIWORD(vpbmi16)));
            goto hdd_err;
        }

        SelectorLimit++;

        OriginalSelLimit = SelectorLimit;

        CallBack16(RET_GETDIBFLAGS,
                   &Parm16,
                   0,
                   (PVPVOID)&OriginalFlags);

        if (OriginalFlags == 0x4) { //GA_DGROUP
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv GA_DGROUP Not Handled\n"));
            goto hdd_err;
        }

        GETVDMPTR(vpBase16, SelectorLimit, pbmi16);

        nbmiSize = GetBMI16Size(vpbmi16, (WORD) DIB_RGB_COLORS, &dwClrUsed);

        // Under NT CreateDIBSection will fail if the offset to the bits
        // is not dword aligned. So we may have to add some space at the top
        // of the section to get the offset correctly aligned.

        nAlignmentSpace = (nbmiSize+LOWORD(vpbmi16)) % 4;

        if (nAlignmentSpace) {
            if (WriteFile (hfile,
                           pbmi16,
                           nAlignmentSpace,
                           &nBytesWritten,
                           NULL) == FALSE ||
                           nBytesWritten != (INT) nAlignmentSpace)
            goto hdd_err;
        }

        //
        // detect a clinical case of bitedit screwing around dib.drv 
        // 
        // code below is using dib macros declared in wdib.h
        // namely:
        //      DibNumColors - yields max number of colors in dib
        //      DibColors    - yields pointer to a dib color table
        //  
        // Function W32CheckDibColorIndices checks to see if DIB color
        // table looks like a number (defined usually by biClrImportant)
        // of WORD indices in a sequential order (0, 1, 2, ...)
        // if this is the case, app is trying to use undocumented feature 
        // of DIB.DRV that turns color matching off in this case. 
        // Since we cannot enforce that rule, we approximate it by filling
        // color table by a number of known (and always same) entries
        // When blitting occurs, no color matching will be performed (when 
        // both target and destination are of this very nature).
        // For no reason at all we fill color table with vga colors. 
        // Sequential indices could have worked just as well. 
        //    
        // Modifications are made to memory pointed to by lpbmi32

        if (W32CheckDibColorIndices((LPBITMAPINFOHEADER)lpbmi32)) {
            INT i, nColors;
            LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpbmi32;
            LPRGBQUAD lprgbq = (LPRGBQUAD)DibColors(lpbmi);

            nColors = DibNumColors(lpbmi);
            lpbmi->biClrImportant = nColors;

            switch (lpbmi->biBitCount) {
                case 1:
                    lprgbq[0] = rgbVGA[0];
                    lprgbq[1] = rgbVGA[0x0f];
                    break;

                case 4:
                    RtlCopyMemory(lprgbq, rgbVGA, sizeof(rgbVGA));
                    break;
                    
                case 8:
                    RtlCopyMemory(lprgbq,     rgbVGA,   8*sizeof(RGBQUAD));
                    RtlCopyMemory(lprgbq+248, rgbVGA+8, 8*sizeof(RGBQUAD));
                    RtlCopyMemory(lprgbq+8,   rgb4,   2*sizeof(RGBQUAD));
                    RtlCopyMemory(lprgbq+246, rgb4+2, 2*sizeof(RGBQUAD));
                    for (i = 10; i < 246; ++i) {
                        lprgbq[i].rgbBlue = i; 
                        lprgbq[i].rgbGreen= 0;
                        lprgbq[i].rgbRed  = 0;
                        lprgbq[i].rgbReserved = 0;
                    }
                    break;

                default: // this should never happen
                    break;
            }            
        }

        if (WriteFile (hfile,
                       pbmi16,
                       SelectorLimit,
                       &nBytesWritten,
                       NULL) == FALSE || nBytesWritten != (INT) SelectorLimit)
            goto hdd_err;

        if (SelectorLimit < 64*1024) {
            if (SetFilePointer (hfile,
                                64*1024+nAlignmentSpace,
                                NULL,
                                FILE_BEGIN) == -1)
                goto hdd_err;

            if (SetEndOfFile (hfile) == FALSE)
                goto hdd_err;

            SelectorLimit = 64*1024;
        }

        if ((hsec = CreateFileMapping (hfile,
                                       NULL,
                                       PAGE_READWRITE | SEC_COMMIT,
                                       0,
                                       SelectorLimit+nAlignmentSpace,
                                       NULL)) == NULL) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv CreateFileMapping Failed\n"));
            goto hdd_err;
        }

        // Now create the DIB section
        if ((hbm = CreateDIBSection (hdcMem,
                                lpbmi32,
                                DIB_RGB_COLORS,
                                &pvBits,
                                hsec,
                                nAlignmentSpace + LOWORD(vpbmi16) + nbmiSize
                                )) == NULL) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv CreateDibSection Failed\n"));
            goto hdd_err;
        }

        FREEVDMPTR(pbmi16);

        if((pvBits = MapViewOfFile(hsec,
                         FILE_MAP_WRITE,
                         0,
                         0,
                         SelectorLimit+nAlignmentSpace)) == NULL) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv MapViewOfFile Failed\n"));
            goto hdd_err;
        }

        pvBits = (PVOID) ((ULONG)pvBits + nAlignmentSpace);

        SelectObject (hdcMem, hbm);

        GdiSetBatchLimit(1);

#ifndef i386
        if (!NT_SUCCESS(VdmAddVirtualMemory((ULONG)pvBits,
                                            (ULONG)SelectorLimit,
                                            (PULONG)&pvIntelBits))) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv VdmAddVirtualMemory failed\n"));
            goto hdd_err;
        }

        // On risc platforms, the intel base + the intel linear address
        // of the DIB section is not equal to the DIB section's process
        // address. This is because of the VdmAddVirtualMemory call
        // above. So here we zap the correct address into the flataddress
        // array.
        if (!VdmAddDescriptorMapping(HIWORD(vpbmi16),
                                    (USHORT) ((SelectorLimit+65535)/65536),
                                    (ULONG) pvIntelBits,
                                    (ULONG) pvBits)) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv VdmAddDescriptorMapping failed\n"));
            goto hdd_err;
        }

#else
        pvIntelBits = pvBits;
#endif

        // Finally set the selectors to the new DIB
        Parm16.WndProc.wParam = HIWORD(vpbmi16);
        Parm16.WndProc.lParam = (LONG)pvIntelBits;
        Parm16.WndProc.wMsg   = 0x10; // GA_NOCOMPACT
        Parm16.WndProc.hwnd   = 1;    // set so it's not randomly 0

        CallBack16(RET_SETDIBSEL,
                   &Parm16,
                   0,
                   (PVPVOID)&RetVal);

        if (!RetVal) {
            LOGDEBUG(LOG_ALWAYS,("\nWOW::W32HandleDibDrv Callback set_sel_for_dib failed\n"));
            goto hdd_err;
        }


        // Store all the relevant information so that DeleteDC could
        // free all the resources later.
        if (W32AddDibInfo(hdcMem, 
                          hfile, 
                          hsec, 
                          nAlignmentSpace,
                          pvBits, 
                          pvIntelBits, 
                          hbm, 
                          OriginalSelLimit,
                          (USHORT)OriginalFlags,
                          (USHORT)((HIWORD(vpbmi16)))) == FALSE) 
            goto hdd_err;


        // Finally spit out the dump for debugging
        LOGDEBUG(6,("\t\tWOW::W32HandleDibDrv hdc=%04x nAlignment=%04x\n\t\tNewDib=%x OldDib=%04x:%04x DibSize=%x DibFlags=%x\n",hdcMem,nAlignmentSpace,pvBits,HIWORD(vpbmi16),LOWORD(vpbmi16),OriginalSelLimit,(USHORT)OriginalFlags));

        bRet = TRUE;
hdd_err:;
    }
    finally {
        if (!bRet) {

            if (hdcMem) {    
                DeleteDC (hdcMem);
                hdcMem = NULL;
            }
            if (hfile)
                CloseHandle (hfile);

            if (hsec)
                CloseHandle (hsec);

            if (hbm)
                CloseHandle (hbm);
        }
    }
    return hdcMem;
}