bool WglBitmapBufferedContext::createOffScreenBitmap(const int colorBitCount, const int colorPlaneCount)
{
#if 0
	// method #1
	memBmp_ = CreateCompatibleBitmap(hDC_, drawRegion_.getWidth(), drawRegion_.getHeight());
	//memBmp_ = CreateCompatibleBitmap(hDC_, (int)std::floor(viewingRegion_.getWidth() + 0.5), (int)std::floor(viewingRegion_.getHeight() + 0.5));
#else
	// method #2
	const size_t bufSize = !isPaletteUsed_ ? sizeof(BITMAPINFO) : sizeof(BITMAPINFO) + sizeof(RGBQUAD) * 255;
	const boost::scoped_array<unsigned char> buf(new unsigned char [bufSize]);
	memset(buf.get(), 0, bufSize);
	BITMAPINFO &bmiDIB = *(BITMAPINFO *)buf.get();

	// Following routine aligns given value to 4 bytes boundary.
	// The current implementation of DIB rendering in Windows 95/98/NT seems to be free from this alignment
	// but old version compatibility is needed.
#if 1
	const int width = ((drawRegion_.getWidth() + 3) / 4 * 4 > 0) ? drawRegion_.getWidth() : 4;
	const int height = (0 == drawRegion_.getHeight()) ? 1 : drawRegion_.getHeight();
#else
	const int viewingWidth = (int)std::floor(viewingRegion_.getWidth() + 0.5);
	const int viewingHeight = (int)std::floor(viewingRegion_.getHeight() + 0.5);
	const int width = ((viewingWidth + 3) / 4 * 4 > 0) ? viewingWidth : 4;
	const int height = (0 == viewingHeight) ? 1 : viewingHeight;
#endif

	bmiDIB.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	bmiDIB.bmiHeader.biWidth		= width;
	bmiDIB.bmiHeader.biHeight		= height;
	bmiDIB.bmiHeader.biPlanes		= colorPlaneCount;
	bmiDIB.bmiHeader.biBitCount		= colorBitCount;
	if (!isPaletteUsed_)
	{
		bmiDIB.bmiHeader.biCompression	= BI_RGB;
		bmiDIB.bmiHeader.biSizeImage	= 0;  // for BI_RGB

	   // offscreen surface generated by the DIB section
		memBmp_ = CreateDIBSection(memDC_, &bmiDIB, DIB_RGB_COLORS, &dibBits_, NULL, 0);
	}
	else
	{
		// FIXME [check] >>
		bmiDIB.bmiHeader.biCompression	= colorBitCount > 4 ? BI_RLE8 : BI_RLE4;
		bmiDIB.bmiHeader.biSizeImage	= width * height * 3;

		// when using 256 color
		PALETTEENTRY paletteEntry[256];
		GetPaletteEntries(shPalette_, 0, 256, paletteEntry);
		for (int i = 0; i < 256; ++i)
		{
			bmiDIB.bmiColors[i].rgbRed = paletteEntry[i].peRed;
			bmiDIB.bmiColors[i].rgbGreen = paletteEntry[i].peGreen;
			bmiDIB.bmiColors[i].rgbBlue = paletteEntry[i].peBlue;
			bmiDIB.bmiColors[i].rgbReserved = 0;
		}

		// offscreen surface generated by the DIB section
		memBmp_ = CreateDIBSection(memDC_, &bmiDIB, DIB_PAL_COLORS, &dibBits_, NULL, 0);
	}
	if (NULL == memBmp_ || NULL == dibBits_) return false;
	oldBmp_ = (HBITMAP)SelectObject(memDC_, memBmp_);
#endif

	return true;
}
Example #2
0
/******************************************************************************
 *		OleTranslateColor	[OLEAUT32.421]
 *
 * Convert an OLE_COLOR to a COLORREF.
 *
 * PARAMS
 *  clr       [I] Color to convert
 *  hpal      [I] Handle to a palette for the conversion
 *  pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok
 *
 * RETURNS
 *  Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL.
 *  Failure: E_INVALIDARG, if any argument is invalid.
 *
 * FIXME
 *  Document the conversion rules.
 */
HRESULT WINAPI OleTranslateColor(
  OLE_COLOR clr,
  HPALETTE  hpal,
  COLORREF* pColorRef)
{
  COLORREF colorref;
  BYTE b = HIBYTE(HIWORD(clr));

  TRACE("(%08x, %p, %p)\n", clr, hpal, pColorRef);

  /*
   * In case pColorRef is NULL, provide our own to simplify the code.
   */
  if (pColorRef == NULL)
    pColorRef = &colorref;

  switch (b)
  {
    case 0x00:
    {
      if (hpal != 0)
        *pColorRef =  PALETTERGB(GetRValue(clr),
                                 GetGValue(clr),
                                 GetBValue(clr));
      else
        *pColorRef = clr;

      break;
    }

    case 0x01:
    {
      if (hpal != 0)
      {
        PALETTEENTRY pe;
        /*
         * Validate the palette index.
         */
        if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0)
          return E_INVALIDARG;
      }

      *pColorRef = clr;

      break;
    }

    case 0x02:
      *pColorRef = clr;
      break;

    case 0x80:
    {
      int index = LOBYTE(LOWORD(clr));

      /*
       * Validate GetSysColor index.
       */
      if ((index < COLOR_SCROLLBAR) || (index > COLOR_MENUBAR))
        return E_INVALIDARG;

      *pColorRef =  GetSysColor(index);

      break;
    }

    default:
      return E_INVALIDARG;
  }

  return S_OK;
}
Example #3
0
/******************************************************************************
 *              OleDuplicateData        [OLE32.@]
 *
 * Duplicates clipboard data.
 *
 * PARAMS
 *  hSrc     [I] Handle of the source clipboard data.
 *  cfFormat [I] The clipboard format of hSrc.
 *  uiFlags  [I] Flags to pass to GlobalAlloc.
 *
 * RETURNS
 *  Success: handle to the duplicated data.
 *  Failure: NULL.
 */
HANDLE WINAPI OleDuplicateData(HANDLE hSrc, CLIPFORMAT cfFormat,
	                          UINT uiFlags)
{
    HANDLE hDst = NULL;

    TRACE("(%p,%x,%x)\n", hSrc, cfFormat, uiFlags);

    if (!uiFlags) uiFlags = GMEM_MOVEABLE;

    switch (cfFormat)
    {
    case CF_ENHMETAFILE:
        hDst = CopyEnhMetaFileW(hSrc, NULL);
        break;
    case CF_METAFILEPICT:
        hDst = CopyMetaFileW(hSrc, NULL);
        break;
    case CF_PALETTE:
        {
            LOGPALETTE * logpalette;
            UINT nEntries = GetPaletteEntries(hSrc, 0, 0, NULL);
            if (!nEntries) return NULL;
            logpalette = HeapAlloc(GetProcessHeap(), 0,
                FIELD_OFFSET(LOGPALETTE, palPalEntry[nEntries]));
            if (!logpalette) return NULL;
            if (!GetPaletteEntries(hSrc, 0, nEntries, logpalette->palPalEntry))
            {
                HeapFree(GetProcessHeap(), 0, logpalette);
                return NULL;
            }
            logpalette->palVersion = 0x300;
            logpalette->palNumEntries = (WORD)nEntries;

            hDst = CreatePalette(logpalette);

            HeapFree(GetProcessHeap(), 0, logpalette);
            break;
        }
    case CF_BITMAP:
        {
            LONG size;
            BITMAP bm;
            if (!GetObjectW(hSrc, sizeof(bm), &bm))
                return NULL;
            size = GetBitmapBits(hSrc, 0, NULL);
            if (!size) return NULL;
            bm.bmBits = HeapAlloc(GetProcessHeap(), 0, size);
            if (!bm.bmBits) return NULL;
            if (GetBitmapBits(hSrc, size, bm.bmBits))
                hDst = CreateBitmapIndirect(&bm);
            HeapFree(GetProcessHeap(), 0, bm.bmBits);
            break;
        }
    default:
        {
            SIZE_T size = GlobalSize(hSrc);
            LPVOID pvSrc = NULL;
            LPVOID pvDst = NULL;

            /* allocate space for object */
            if (!size) return NULL;
            hDst = GlobalAlloc(uiFlags, size);
            if (!hDst) return NULL;

            /* lock pointers */
            pvSrc = GlobalLock(hSrc);
            if (!pvSrc)
            {
                GlobalFree(hDst);
                return NULL;
            }
            pvDst = GlobalLock(hDst);
            if (!pvDst)
            {
                GlobalUnlock(hSrc);
                GlobalFree(hDst);
                return NULL;
            }
            /* copy data */
            memcpy(pvDst, pvSrc, size);

            /* cleanup */
            GlobalUnlock(hDst);
            GlobalUnlock(hSrc);
        }
    }

    TRACE("returning %p\n", hDst);
    return hDst;
}
Example #4
0
static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,
    HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)
{
    BITMAP bm;
    HRESULT hr;
    WICPixelFormatGUID format;
    IWICBitmapLock *lock;
    UINT size, num_palette_entries = 0;
    PALETTEENTRY entry[256];

    TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap);

    if (!bitmap) return E_INVALIDARG;

    if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm))
        return WINCODEC_ERR_WIN32ERROR;

    if (hpal)
    {
        num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry);
        if (!num_palette_entries)
            return WINCODEC_ERR_WIN32ERROR;
    }

    /* TODO: Figure out the correct format for 16, 32, 64 bpp */
    switch(bm.bmBitsPixel)
    {
    case 1:
        format = GUID_WICPixelFormat1bppIndexed;
        break;
    case 4:
        format = GUID_WICPixelFormat4bppIndexed;
        break;
    case 8:
        format = GUID_WICPixelFormat8bppIndexed;
        break;
    case 16:
        if (!get_16bpp_format(hbm, &format))
            return E_INVALIDARG;
        break;
    case 24:
        format = GUID_WICPixelFormat24bppBGR;
        break;
    case 32:
        switch (option)
        {
        case WICBitmapUseAlpha:
            format = GUID_WICPixelFormat32bppBGRA;
            break;
        case WICBitmapUsePremultipliedAlpha:
            format = GUID_WICPixelFormat32bppPBGRA;
            break;
        case WICBitmapIgnoreAlpha:
            format = GUID_WICPixelFormat32bppBGR;
            break;
        default:
            return E_INVALIDARG;
        }
        break;
    case 48:
        format = GUID_WICPixelFormat48bppRGB;
        break;
    default:
        FIXME("unsupported %d bpp\n", bm.bmBitsPixel);
        return E_INVALIDARG;
    }

    hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, &format, option, bitmap);
    if (hr != S_OK) return hr;

    hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
    if (hr == S_OK)
    {
        BYTE *buffer;
        HDC hdc;
        char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
        BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;

        IWICBitmapLock_GetDataPointer(lock, &size, &buffer);

        hdc = CreateCompatibleDC(0);

        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmi->bmiHeader.biBitCount = 0;
        GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS);
        bmi->bmiHeader.biHeight = -bm.bmHeight;
        GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS);

        DeleteDC(hdc);
        IWICBitmapLock_Release(lock);

        if (num_palette_entries)
        {
            IWICPalette *palette;
            WICColor colors[256];
            UINT i;

            hr = PaletteImpl_Create(&palette);
            if (hr == S_OK)
            {
                for (i = 0; i < num_palette_entries; i++)
                    colors[i] = 0xff000000 | entry[i].peRed << 16 |
                                entry[i].peGreen << 8 | entry[i].peBlue;

                hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries);
                if (hr == S_OK)
                    hr = IWICBitmap_SetPalette(*bitmap, palette);

                IWICPalette_Release(palette);
            }
        }
    }

    if (hr != S_OK)
    {
        IWICBitmap_Release(*bitmap);
        *bitmap = NULL;
    }

    return hr;
}
Example #5
0
//+------------------------------------------------------------------------
//
//  Member:     COffScreenContext::CreateDDSurface
//
//  Synopsis:   Create a DD surface with the specified dimensions and palette.
//
//-------------------------------------------------------------------------
BOOL COffScreenContext::CreateDDSurface(long width, long height, HPALETTE hpal)
{
	HRESULT hr = InitSurface();
	if(FAILED(hr))
	{
		return FALSE;
	}

	DDPIXELFORMAT* pPF = PixelFormat(_hdcWnd, _cBitsPixel);
	if(!pPF)
	{
		return FALSE;
	}

	DDSURFACEDESC ddsd;

	ddsd.dwSize = sizeof(ddsd);
	ddsd.ddpfPixelFormat = *pPF;
	ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_DATAEXCHANGE|DDSCAPS_OWNDC;
	if(_fUse3D)
	{
		ddsd.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE;
	}
	ddsd.dwWidth = width;
	ddsd.dwHeight = height;
	hr = g_pDirectDraw->CreateSurface(&ddsd, &_pDDSurface, NULL);
	if(FAILED(hr))
	{
		return FALSE;
	}

	// set color table
	if(_cBitsPixel <= 8)
	{
		IDirectDrawPalette*	pDDPal;
		PALETTEENTRY*		pPal;
		PALETTEENTRY		pal256[256];
		long				cEntries;
		DWORD				pcaps;

		if(_cBitsPixel == 8)
		{
			cEntries = GetPaletteEntries(hpal, 0, 256, pal256);
			pPal = pal256;
			pcaps = DDPCAPS_8BIT;
		}
		else if(_cBitsPixel == 4)
		{
			cEntries = 16;
			pPal = g_pal16;
			pcaps = DDPCAPS_4BIT;
		}
		else if(_cBitsPixel == 1)
		{
			cEntries = 2;
			pPal = g_pal2;
			pcaps = DDPCAPS_1BIT;
		}
		else
		{
			Assert(0 && "invalid cBitsPerPixel");
			return FALSE;
		}

		// create and initialize a new DD palette
		hr = g_pDirectDraw->CreatePalette(pcaps|DDPCAPS_INITIALIZE, pPal, &pDDPal, NULL);
		if(SUCCEEDED(hr))
		{
			// attach the DD palette to the DD surface
			hr = _pDDSurface->SetPalette(pDDPal);
			pDDPal->Release();
		}
		if(FAILED(hr))
		{
			return FALSE;
		}
	}

	hr = _pDDSurface->GetDC(&_hdcMem);
	return SUCCEEDED(hr);
}
Example #6
0
//+------------------------------------------------------------------------
//
//  Member:     COffScreenContext::GetDDSurface
//
//  Synopsis:   Create a suitable DD surface or get one from the cache.
//
//-------------------------------------------------------------------------
BOOL COffScreenContext::GetDDSurface(HPALETTE hpal)
{
	HRESULT hr;
	LOCK_SECTION(g_csOscCache);

	if(!g_OscCache._fInUse)
	{
		ClearDDBCache(); // don't allow both DD & DDB in the cache

		if(g_OscCache._pDDSurface != NULL)
		{
			Assert(g_OscCache._fUseDD);
			if(_widthActual>g_OscCache._size.cx
				|| _heightActual>g_OscCache._size.cy
				|| _cBitsPixel!=g_OscCache._cBitsPixel
				|| (_fUse3D&&!g_OscCache._fUse3D))
			{
				++g_OscCache._cMisses;
				ClearSurfaceCache();
			}
			else
			{
				++g_OscCache._cHits;
				g_OscCache._fInUse = TRUE;
				_pDDSurface = g_OscCache._pDDSurface;
				_pDDSurface->AddRef();
				_hdcMem = g_OscCache._hdcMem;
				_widthActual = g_OscCache._size.cx;
				_heightActual = g_OscCache._size.cy;
			}
		}
		if(g_OscCache._pDDSurface == NULL)
		{
			// use max area allowed for the cache, so we get max reuse potential
			// favor width over height for those wide text runs
			// also adjust the max size in a growing fashion based on former allocations
			g_OscCache._size.cx = max(g_OscCache._size.cx, max(min(g_OscCache._areaTgt/_heightActual, g_OscCache._sizeTgt.cx), _widthActual));
			g_OscCache._size.cy = max(g_OscCache._size.cy , max(g_OscCache._areaTgt/g_OscCache._size.cx, _heightActual));
			if(!CreateDDSurface(g_OscCache._size.cx, g_OscCache._size.cy, hpal))
			{
				return FALSE;
			}
			Trace0("surface cache created\n");
			g_OscCache._fInUse = TRUE;
			g_OscCache._fUseDD = TRUE;
			g_OscCache._fUse3D = _fUse3D;
			g_OscCache._pDDSurface = _pDDSurface;
			g_OscCache._pDDSurface->AddRef(); // addref the global surface
			g_OscCache._cBitsPixel = _cBitsPixel;
			g_OscCache._hdcMem = _hdcMem;
			g_OscCache._hpal = hpal;
			_widthActual = g_OscCache._size.cx;
			_heightActual = g_OscCache._size.cy;
		}
	}
	else
	{
		Trace0("surface cache in use\n");
	}

	if(_pDDSurface == NULL)
	{
		if(!CreateDDSurface(_widthActual, _heightActual, hpal))
		{
			return FALSE;
		}
	}

	// reset the color table when using cache
	if(_cBitsPixel==8 && _pDDSurface==g_OscCache._pDDSurface
		&& (hpal!=g_OscCache._hpal || hpal!=g_hpalHalftone))
	{
		IDirectDrawPalette* pDDPal;
		PALETTEENTRY pal256[256];
		long cEntries;

		cEntries = GetPaletteEntries(hpal, 0, 256, pal256);

		// get the DD palette and set entries
		hr = _pDDSurface->GetPalette(&pDDPal);
		if(SUCCEEDED(hr))
		{
			hr = pDDPal->SetEntries(0, 0, cEntries, pal256);
			pDDPal->Release();
			if(SUCCEEDED(hr))
			{
				g_OscCache._hpal = hpal;
			}
		}
	}

	return TRUE;
}
Example #7
0
void tkSetFogRamp(int density, int startIndex)
{
    HPALETTE CurrentPal;
    PALETTEENTRY *pPalEntry;
    UINT n, i, j, k, intensity, fogValues, colorValues;

    if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
    {
        n = GetPaletteEntries( CurrentPal, 0, 0, NULL );

        pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );

        if ( NULL != pPalEntry)
        {
            fogValues = 1 << density;
            colorValues = 1 << startIndex;
            for (i = 0; i < colorValues; i++) {
                for (j = 0; j < fogValues; j++) {
                    k = i * fogValues + j;

                    intensity = i * fogValues + j * colorValues;
                    //mf: not sure what they're trying to do here
                    //intensity = (intensity << 8) | intensity; ???

                // This is a workaround for a GDI palette "feature".  If any of
                // the static colors are repeated in the palette, those colors
                // will map to the first occurance.  So, for our case where there
                // are only two static colors (black and white), if a white
                // color appears anywhere in the palette other than in the last
                // entry, the static white will remap to the first white.  This
                // destroys the nice one-to-one mapping we are trying to achieve.
                //
                // There are two ways to workaround this.  The first is to
                // simply not allow a pure white anywhere but in the last entry.
                // Such requests are replaced with an attenuated white of
                // (0xFE, 0xFE, 0xFE).
                //
                // The other way is to mark these extra whites with PC_RESERVED
                // which will cause GDI to skip these entries when mapping colors.
                // This way the app gets the actual colors requested, but can
                // have side effects on other apps.
                //
                // Both solutions are included below.  The PC_RESERVED solution is
                // the one currently enabled.  It may have side effects, but taking
                // over the static colors as we are is a really big side effect that
                // should swamp out the effects of using PC_RESERVED.
                if (intensity > 0xFF)
                  intensity = 0xFF;
                pPalEntry[k].peRed =pPalEntry[k].peGreen = pPalEntry[k].peBlue = (BYTE) intensity;
                pPalEntry[k].peFlags = 0;

                }
            }

            SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
            FreeMemory( pPalEntry );

            DelayPaletteRealization();
        }
    }
}
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 ;
}
Example #9
0
//************************************************************************
void SpeedCheck( LPOFFSCREEN lpOffScreen, PDIB pdib )
//************************************************************************
{
#ifdef UNUSED
RGBQUAD rgb1, rgb2;

if (!lpOffScreen)
	return;

HDC hdc;
if ( !(hdc = GetDC(NULL)) )
	return;

WORD wNumEntries;
GetObject( GetApp()->m_hPal, sizeof(WORD), (LPSTR)&wNumEntries );
PALETTEENTRY sEntries[256], pEntries[256];
GetPaletteEntries( GetApp()->m_hPal, 0, wNumEntries, pEntries );
GetSystemPaletteEntries( hdc, 0, 256, sEntries );
ReleaseDC( NULL, hdc );

if ( wNumEntries != 256 )
	{
	Debug( "GetApp()->m_hPal only has %d entries\n", wNumEntries );
	}

// Compare the app's palette with the system palette
int i;
for ( i=0; i<256; i++ )
	{
	if ( pEntries[i].peRed	 != sEntries[i].peRed	||
		 pEntries[i].peBlue	 != sEntries[i].peBlue	||
		 pEntries[i].peGreen != sEntries[i].peGreen )
//		 pEntries[i].peFlags != sEntries[i].peFlags )
		{
		Debug( "GetApp()->m_hPal compare with syspal; entry %d (%d,%d,%d) (%d,%d,%d)\n", i,
			pEntries[i].peRed, pEntries[i].peGreen, pEntries[i].peBlue,
			sEntries[i].peRed, sEntries[i].peGreen, sEntries[i].peBlue );
//		break;
		}
	}

PDIB pdibr, pdibw;
LPWORD lpIndices;

// Compare the system palette with the WRITABLE offscreen
if ( pdibw = lpOffScreen->GetWritableDIB() )
	{
	RGBQUAD FAR *lprgbQuad = pdibw->GetColors();
	for ( i=0; i<256; i++ )
		{
		rgb1 = lprgbQuad[i];
		if ( rgb1.rgbRed   != sEntries[i].peRed	  ||
			 rgb1.rgbGreen != sEntries[i].peGreen ||
			 rgb1.rgbBlue  != sEntries[i].peBlue )
			{
			Debug( "OS writable compare with syspal; entry %d (%d,%d,%d) (%d,%d,%d)\n", i,
				rgb1.rgbRed, rgb1.rgbGreen, rgb1.rgbBlue,
				sEntries[i].peRed, sEntries[i].peGreen, sEntries[i].peBlue );
//			break;
			}
		}
	}

// Compare the READONLY offscreen with the WRITABLE offscreen
if ( (pdibr = lpOffScreen->GetReadOnlyDIB()) &&
	 (pdibw = lpOffScreen->GetWritableDIB()) )
	{
	RGBQUAD FAR *lprQuad = pdibr->GetColors();
	RGBQUAD FAR *lpwQuad = pdibw->GetColors();
	for ( i=0; i<256; i++ )
		{
		rgb1 = lprQuad[i];
		rgb2 = lpwQuad[i];
		if ( rgb1.rgbRed   != rgb2.rgbRed	||
			 rgb1.rgbGreen != rgb2.rgbGreen ||
			 rgb1.rgbBlue  != rgb2.rgbBlue )
			{
			Debug( "OS readonly compare with OS writable; entry %d (%d,%d,%d) (%d,%d,%d)\n", i,
				rgb1.rgbRed, rgb1.rgbGreen, rgb1.rgbBlue,
				rgb2.rgbRed, rgb2.rgbGreen, rgb2.rgbBlue );
//			break;
			}
		}
	}

// Compare the WRITABLE offscreen with a passed DIB
if ( (pdibw = lpOffScreen->GetWritableDIB()) && pdib )
	{
	RGBQUAD FAR *lpQuad = pdib->GetColors();
	RGBQUAD FAR *lpwQuad = pdibw->GetColors();
	for ( i=0; i<256; i++ )
		{
		rgb1 = lpwQuad[i];
		rgb2 = lpQuad[i];
		if ( rgb1.rgbRed   != rgb2.rgbRed	||
			 rgb1.rgbGreen != rgb2.rgbGreen ||
			 rgb1.rgbBlue  != rgb2.rgbBlue )
			{
			Debug( "OS writable compare with passed dib; entry %d (%d,%d,%d) (%d,%d,%d)\n", i,
				rgb1.rgbRed, rgb1.rgbGreen, rgb1.rgbBlue,
				rgb2.rgbRed, rgb2.rgbGreen, rgb2.rgbBlue );
//			break;
			}
		}
	}

// See if the WRITABLE offscreen is set to indices
if ( pdibw = lpOffScreen->GetWritableDIB() )
	{
	lpIndices = (LPWORD)pdibw->GetColors();
	for ( i=0; i<256; i++ )
		{
		if ( lpIndices[i] != (WORD)i )
			{
//			Debug( "OS writable not indices; entry %d (%d)\n", i, lpIndices[i] );
//			break;
			}
		}
	}

// See if the READONLY offscreen is set to indices
if ( pdibr = lpOffScreen->GetReadOnlyDIB() )
	{
	lpIndices = (LPWORD)pdibr->GetColors();
	for ( i=0; i<256; i++ )
		{
		if ( lpIndices[i] != (WORD)i )
			{
//			Debug( "OS readonly not indices; entry %d (%d)\n", i, lpIndices[i] );
//			break;
			}
		}
	}

#endif
}
Example #10
0
/****************************************************************************
*
*     FUNCTION: CopyColorTable
*
*     PURPOSE:  Copies the color table from one CF_DIB to another.
*
*     PARAMS:   LPBITMAPINFO lpTarget - pointer to target DIB
*               LPBITMAPINFO lpSource - pointer to source DIB
*
*     RETURNS:  BOOL - TRUE for success, FALSE for failure
*
* History:
*                July '95 - Created
*
\****************************************************************************/
BOOL CopyColorTable( LPBITMAPINFO lpTarget, LPBITMAPINFO lpSource )
{
    // What we do depends on the target's color depth
    switch( lpTarget->bmiHeader.biBitCount )
    {
        // 8bpp - need 256 entry color table
        case 8:
            if( lpSource->bmiHeader.biBitCount == 8 )
            { // Source is 8bpp too, copy color table
                memcpy( lpTarget->bmiColors, lpSource->bmiColors, 256*sizeof(RGBQUAD) );
                return TRUE;
            }
            else
            { // Source is != 8bpp, use halftone palette                
                HPALETTE        hPal;
                HDC            	hDC = GetDC( NULL );
                PALETTEENTRY    pe[256];
                UINT            i;

                hPal = CreateHalftonePalette( hDC );
                ReleaseDC( NULL, hDC );
                GetPaletteEntries( hPal, 0, 256, pe );
                DeleteObject( hPal );
                for(i=0;i<256;i++)
                {
                    lpTarget->bmiColors[i].rgbRed = pe[i].peRed;
                    lpTarget->bmiColors[i].rgbGreen = pe[i].peGreen;
                    lpTarget->bmiColors[i].rgbBlue = pe[i].peBlue;
                    lpTarget->bmiColors[i].rgbReserved = pe[i].peFlags;
                }
                return TRUE;
            }
        break; // end 8bpp

        // 4bpp - need 16 entry color table
        case 4:
            if( lpSource->bmiHeader.biBitCount == 4 )
            { // Source is 4bpp too, copy color table
                memcpy( lpTarget->bmiColors, lpSource->bmiColors, 16*sizeof(RGBQUAD) );
                return TRUE;
            }
            else
            { // Source is != 4bpp, use system palette
                HPALETTE        hPal;
                PALETTEENTRY    pe[256];
                UINT            i;

                hPal = GetStockObject( DEFAULT_PALETTE );
                GetPaletteEntries( hPal, 0, 16, pe );
                for(i=0;i<16;i++)
                {
                    lpTarget->bmiColors[i].rgbRed = pe[i].peRed;
                    lpTarget->bmiColors[i].rgbGreen = pe[i].peGreen;
                    lpTarget->bmiColors[i].rgbBlue = pe[i].peBlue;
                    lpTarget->bmiColors[i].rgbReserved = pe[i].peFlags;
                }
                return TRUE;
            }
        break; // end 4bpp

        // 1bpp - need 2 entry mono color table
        case 1:
            lpTarget->bmiColors[0].rgbRed = 0;
            lpTarget->bmiColors[0].rgbGreen = 0;
            lpTarget->bmiColors[0].rgbBlue = 0;
            lpTarget->bmiColors[0].rgbReserved = 0;
            lpTarget->bmiColors[1].rgbRed = 255;
            lpTarget->bmiColors[1].rgbGreen = 255;
            lpTarget->bmiColors[1].rgbBlue = 255;
            lpTarget->bmiColors[1].rgbReserved = 0;
        break; // end 1bpp

        // no color table for the > 8bpp modes
        case 32:
        case 24:
        case 16:
        default:
            return TRUE;
        break;
    }
    return TRUE;
}
Example #11
0
/*
 * clipboard_data_to_bytes - データをバイト列に変換
 */
BYTE *clipboard_data_to_bytes(const DATA_INFO *di, DWORD *ret_size)
{
	BYTE *ret = NULL;
	BYTE *tmp;
	DWORD i;
	DWORD size = 0;

	if (di->data == NULL) {
		return NULL;
	}

	switch (di->format) {
	case CF_PALETTE:
		// パレット
		i = 0;
		GetObject(di->data, sizeof(WORD), &i);
		size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * i);
		if ((ret = mem_calloc(size)) == NULL) {
			break;
		}
		((LOGPALETTE *)ret)->palVersion = 0x300;
		((LOGPALETTE *)ret)->palNumEntries = (WORD)i;
		GetPaletteEntries(di->data, 0, i, ((LOGPALETTE *)ret)->palPalEntry);
		break;

	case CF_DSPBITMAP:
	case CF_BITMAP:
		// ビットマップ
		if ((ret = bitmap_to_dib(di->data, &size)) == NULL) {
			break;
		}
		break;

	case CF_OWNERDISPLAY:
		break;

	case CF_DSPMETAFILEPICT:
	case CF_METAFILEPICT:
		// メタファイル
		if ((tmp = GlobalLock(di->data)) == NULL) {
			break;
		}
		size = GetMetaFileBitsEx(((METAFILEPICT *)tmp)->hMF, 0, NULL);
		if ((ret = mem_alloc(size + sizeof(METAFILEPICT))) == NULL) {
			GlobalUnlock(di->data);
			break;
		}
		CopyMemory(ret, tmp, sizeof(METAFILEPICT));
		if (GetMetaFileBitsEx(((METAFILEPICT *)tmp)->hMF, size, ret + sizeof(METAFILEPICT)) == 0) {
			mem_free(&ret);
			GlobalUnlock(di->data);
			break;
		}
		size += sizeof(METAFILEPICT);
		GlobalUnlock(di->data);
		break;

	case CF_DSPENHMETAFILE:
	case CF_ENHMETAFILE:
		// 拡張メタファイル
		size = GetEnhMetaFileBits(di->data, 0, NULL);
		if ((ret = mem_alloc(size)) == NULL) {
			break;
		}
		if (GetEnhMetaFileBits(di->data, size, ret) == 0) {
			mem_free(&ret);
			break;
		}
		break;

	default:
		// その他
		if ((tmp = GlobalLock(di->data)) == NULL) {
			break;
		}
		size = di->size;
		if ((ret = mem_alloc(size)) == NULL) {
			GlobalUnlock(di->data);
			break;
		}
		CopyMemory(ret, tmp, size);
		GlobalUnlock(di->data);
		break;
	}
	if (ret_size != NULL) {
		*ret_size = size;
	}
	return ret;
}
Example #12
0
/*
 * clipboard_copy_data - クリップボードデータのコピーを作成
 */
HANDLE clipboard_copy_data(const UINT format, const HANDLE data, DWORD *ret_size)
{
	HANDLE ret = NULL;
	BYTE *from_mem, *to_mem;
	LOGPALETTE *lpal;
	WORD pcnt;

	if (data == NULL) {
		return NULL;
	}

	switch (format) {
	case CF_PALETTE:
		// パレット
		pcnt = 0;
		if (GetObject(data, sizeof(WORD), &pcnt) == 0) {
			return NULL;
		}
		if ((lpal = mem_calloc(sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * pcnt))) == NULL) {
			return NULL;
		}
		lpal->palVersion = 0x300;
		lpal->palNumEntries = pcnt;
		if (GetPaletteEntries(data, 0, pcnt, lpal->palPalEntry) == 0) {
			mem_free(&lpal);
			return NULL;
		}

		ret = CreatePalette(lpal);
		*ret_size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * pcnt);

		mem_free(&lpal);
		break;

	case CF_DSPBITMAP:
	case CF_BITMAP:
		// ビットマップ
		if ((to_mem = bitmap_to_dib(data, ret_size)) == NULL) {
			return NULL;
		}
		ret = dib_to_bitmap(to_mem);
		mem_free(&to_mem);
		break;

	case CF_OWNERDISPLAY:
		*ret_size = 0;
		break;

	case CF_DSPMETAFILEPICT:
	case CF_METAFILEPICT:
		// コピー元ロック
		if ((from_mem = GlobalLock(data)) == NULL) {
			return NULL;
		}
		// メタファイル
		if ((ret = GlobalAlloc(GHND, sizeof(METAFILEPICT))) == NULL) {
			GlobalUnlock(data);
			return NULL;
		}
		// コピー先ロック
		if ((to_mem = GlobalLock(ret)) == NULL) {
			GlobalFree(ret);
			GlobalUnlock(data);
			return NULL;
		}
		CopyMemory(to_mem, from_mem, sizeof(METAFILEPICT));
		if ((((METAFILEPICT *)to_mem)->hMF = CopyMetaFile(((METAFILEPICT *)from_mem)->hMF, NULL)) != NULL) {
			*ret_size = sizeof(METAFILEPICT) + GetMetaFileBitsEx(((METAFILEPICT *)to_mem)->hMF, 0, NULL);
		}
		// ロック解除
		GlobalUnlock(ret);
		GlobalUnlock(data);
		break;

	case CF_DSPENHMETAFILE:
	case CF_ENHMETAFILE:
		// 拡張メタファイル
		if ((ret = CopyEnhMetaFile(data, NULL)) != NULL) {
			*ret_size = GetEnhMetaFileBits(ret, 0, NULL);
		}
		break;

	default:
		// その他
		// メモリチェック
		if (IsBadReadPtr(data, 1) == TRUE) {
			return NULL;
		}
		// サイズ取得
		if ((*ret_size = GlobalSize(data)) == 0) {
			return NULL;
		}
		// コピー元ロック
		if ((from_mem = GlobalLock(data)) == NULL) {
			return NULL;
		}

		// コピー先確保
		if ((ret = GlobalAlloc(GHND, *ret_size)) == NULL) {
			GlobalUnlock(data);
			return NULL;
		}
		// コピー先ロック
		if ((to_mem = GlobalLock(ret)) == NULL) {
			GlobalFree(ret);
			GlobalUnlock(data);
			return NULL;
		}

		// コピー
		CopyMemory(to_mem, from_mem, *ret_size);

		// ロック解除
		GlobalUnlock(ret);
		GlobalUnlock(data);
		break;
	}
	return ret;
}
Example #13
0
//---------------------------------------------------------------------------
void __fastcall TDeePNG::SaveToStream(Classes::TStream * Stream)
{
	// SaveToStream method
	// warning: this method would change the pixelformat to pf24bit
	// if the pixelformat is pfDevice, pf15bit, pf16bit, or pfCustom.


	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	png_bytep row_buffer = NULL;

	try
	{
		// create png_struct
		png_ptr = png_create_write_struct_2
			(PNG_LIBPNG_VER_STRING,
			(png_voidp)this, DeePNG_error, DeePNG_warning,
			(png_voidp)this, DeePNG_malloc, DeePNG_free);


		// create png_info
		info_ptr = png_create_info_struct(png_ptr);

		// set write function
		png_set_write_fn(png_ptr, (png_voidp)Stream,
			DeePNG_write_data, DeePNG_flush);


		// set IHDR
		if(PixelFormat == pfDevice || PixelFormat == pf15bit ||
			PixelFormat == pf16bit || PixelFormat == pfCustom)
			PixelFormat = pf24bit;

		bool grayscale = IsGrayscaleBitmap(this);
		int colordepth = GetBitmapColorDepth(this);

		int w = Width;
		int h = Height;

		int color_type;
		if(grayscale)
			color_type = PNG_COLOR_TYPE_GRAY;
		else if(colordepth <= 8)
			color_type = PNG_COLOR_TYPE_PALETTE;
		else if(colordepth == 32)
			color_type = PNG_COLOR_TYPE_RGB_ALPHA;
		else
			color_type = PNG_COLOR_TYPE_RGB;

		png_set_IHDR(png_ptr, info_ptr, w, h,
			colordepth < 8 ? colordepth : 8,
			color_type, PNG_INTERLACE_NONE,
			PNG_COMPRESSION_TYPE_DEFAULT,
			PNG_FILTER_TYPE_DEFAULT);

		// set oFFs
		if(ofs_set)
			png_set_oFFs(png_ptr, info_ptr, ofs_x, ofs_y, ofs_unit);

		// set palette
		if(color_type == PNG_COLOR_TYPE_PALETTE)
		{
			png_color *palette = (png_colorp)png_malloc(png_ptr, 256 * sizeof(png_color));
			PALETTEENTRY palentry[256];
			int num_palette = GetPaletteEntries(Palette, 0, (1<<colordepth), palentry);
			for(int i = 0; i < num_palette; i++)
			{
				palette[i].red = palentry[i].peRed;
				palette[i].green = palentry[i].peGreen;
				palette[i].blue = palentry[i].peBlue;
			}
			png_set_PLTE(png_ptr, info_ptr, palette, num_palette);
		}

		// write info
		png_write_info(png_ptr, info_ptr);

		// write vpAg private chunk
		if(vpag_set)
		{
			png_byte png_vpAg[5] = {118, 112,  65, 103, '\0'};
			unsigned char vpag_chunk_data[9];
		#define PNG_write_be32(p, a) (\
			((unsigned char *)(p))[0] = (unsigned char)(((a) >>24) & 0xff), \
			((unsigned char *)(p))[1] = (unsigned char)(((a) >>16) & 0xff), \
			((unsigned char *)(p))[2] = (unsigned char)(((a) >> 8) & 0xff), \
			((unsigned char *)(p))[3] = (unsigned char)(((a)     ) & 0xff)  )
			PNG_write_be32(vpag_chunk_data,     vpag_w);
			PNG_write_be32(vpag_chunk_data + 4, vpag_h);
			vpag_chunk_data[8] = (unsigned char)vpag_unit;
			png_write_chunk(png_ptr, png_vpAg, vpag_chunk_data, 9);
		}

/*
		// change RGB order
		if(color_type = PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
		   png_set_bgr(png_ptr);
		// ???? why this does not work ?
*/
		// write image
		if(color_type == PNG_COLOR_TYPE_RGB)
		{
			row_buffer = (png_bytep)png_malloc(png_ptr, 3 * w + 6);
			try
			{
				png_bytep row_pointer = row_buffer;

				for(int i = 0; i < h; i++)
				{
					png_bytep in = (png_bytep)ScanLine[i];
					png_bytep out = row_buffer;
					for(int x = 0; x < w; x++)
					{
						out[2] = in[0];
						out[1] = in[1];
						out[0] = in[2];
						out += 3;
						in += 3;
					}
					png_write_row(png_ptr, row_pointer);
				}
			}
			catch(...)
			{
				png_free(png_ptr, row_buffer);
				throw;
			}
			png_free(png_ptr, row_buffer);
		}
		else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA)
		{
			row_buffer = (png_bytep)png_malloc(png_ptr, 4 * w + 6);
			try
			{
				png_bytep row_pointer = row_buffer;

				for(int i = 0; i < h; i++)
				{
					png_bytep in = (png_bytep)ScanLine[i];
					png_bytep out = row_buffer;
					for(int x = 0; x < w; x++)
					{
						out[2] = in[0];
						out[1] = in[1];
						out[0] = in[2];
						out[3] = in[3];
						out += 4;
						in += 4;
					}
					png_write_row(png_ptr, row_pointer);
				}
			}
			catch(...)
			{
				png_free(png_ptr, row_buffer);
				throw;
			}
			png_free(png_ptr, row_buffer);
		}
		else
		{
			for(int i = 0; i < h; i++)
			{
				png_bytep row_pointer = (png_bytep)ScanLine[i];
				png_write_row(png_ptr, row_pointer);
			}
		}


		// finish writing
		png_write_end(png_ptr, info_ptr);

	}
	catch(...)
	{
		png_destroy_write_struct(&png_ptr, &info_ptr);
		throw;
	}

	png_destroy_write_struct(&png_ptr, &info_ptr);
}