⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olepicture.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
  return S_OK;
}


/************************************************************************
 *    IConnectionPointContainer
 */
static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
  IConnectionPointContainer* iface,
  REFIID riid,
  VOID** ppvoid)
{
  OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);

  return IPicture_QueryInterface((IPicture *)This,riid,ppvoid);
}

static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
  IConnectionPointContainer* iface)
{
  OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);

  return IPicture_AddRef((IPicture *)This);
}

static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
  IConnectionPointContainer* iface)
{
  OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);

  return IPicture_Release((IPicture *)This);
}

static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints(
  IConnectionPointContainer* iface,
  IEnumConnectionPoints** ppEnum)
{
  OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);

  FIXME("(%p,%p), stub!\n",This,ppEnum);
  return E_NOTIMPL;
}

static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint(
  IConnectionPointContainer* iface,
  REFIID riid,
  IConnectionPoint **ppCP)
{
  OLEPictureImpl *This = impl_from_IConnectionPointContainer(iface);
  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP);
  if (!ppCP)
      return E_POINTER;
  *ppCP = NULL;
  if (IsEqualGUID(riid,&IID_IPropertyNotifySink))
      return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP);
  FIXME("no connection point for %s\n",debugstr_guid(riid));
  return CONNECT_E_NOCONNECTION;
}


/************************************************************************
 *    IPersistStream
 */

/************************************************************************
 * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface(
  IPersistStream* iface,
  REFIID     riid,
  VOID**     ppvoid)
{
  OLEPictureImpl *This = impl_from_IPersistStream(iface);

  return IPicture_QueryInterface((IPicture *)This, riid, ppvoid);
}

/************************************************************************
 * OLEPictureImpl_IPersistStream_AddRef (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef(
  IPersistStream* iface)
{
  OLEPictureImpl *This = impl_from_IPersistStream(iface);

  return IPicture_AddRef((IPicture *)This);
}

/************************************************************************
 * OLEPictureImpl_IPersistStream_Release (IUnknown)
 *
 * See Windows documentation for more details on IUnknown methods.
 */
static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
  IPersistStream* iface)
{
  OLEPictureImpl *This = impl_from_IPersistStream(iface);

  return IPicture_Release((IPicture *)This);
}

/************************************************************************
 * OLEPictureImpl_IPersistStream_GetClassID
 */
static HRESULT WINAPI OLEPictureImpl_GetClassID(
  IPersistStream* iface,CLSID* pClassID)
{
  TRACE("(%p)\n", pClassID);
  memcpy(pClassID, &CLSID_StdPicture, sizeof(*pClassID));
  return S_OK;
}

/************************************************************************
 * OLEPictureImpl_IPersistStream_IsDirty
 */
static HRESULT WINAPI OLEPictureImpl_IsDirty(
  IPersistStream* iface)
{
  OLEPictureImpl *This = impl_from_IPersistStream(iface);
  FIXME("(%p),stub!\n",This);
  return E_NOTIMPL;
}

#ifdef SONAME_LIBJPEG

static void *libjpeg_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(jpeg_std_error);
MAKE_FUNCPTR(jpeg_CreateDecompress);
MAKE_FUNCPTR(jpeg_read_header);
MAKE_FUNCPTR(jpeg_start_decompress);
MAKE_FUNCPTR(jpeg_read_scanlines);
MAKE_FUNCPTR(jpeg_finish_decompress);
MAKE_FUNCPTR(jpeg_destroy_decompress);
#undef MAKE_FUNCPTR

static void *load_libjpeg(void)
{
    if((libjpeg_handle = wine_dlopen(SONAME_LIBJPEG, RTLD_NOW, NULL, 0)) != NULL) {

#define LOAD_FUNCPTR(f) \
    if((p##f = wine_dlsym(libjpeg_handle, #f, NULL, 0)) == NULL) { \
        libjpeg_handle = NULL; \
        return NULL; \
    }

        LOAD_FUNCPTR(jpeg_std_error);
        LOAD_FUNCPTR(jpeg_CreateDecompress);
        LOAD_FUNCPTR(jpeg_read_header);
        LOAD_FUNCPTR(jpeg_start_decompress);
        LOAD_FUNCPTR(jpeg_read_scanlines);
        LOAD_FUNCPTR(jpeg_finish_decompress);
        LOAD_FUNCPTR(jpeg_destroy_decompress);
#undef LOAD_FUNCPTR
    }
    return libjpeg_handle;
}

/* for the jpeg decompressor source manager. */
static void _jpeg_init_source(j_decompress_ptr cinfo) { }

static boolean _jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
    ERR("(), should not get here.\n");
    return FALSE;
}

static void _jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes) {
    TRACE("Skipping %ld bytes...\n", num_bytes);
    cinfo->src->next_input_byte += num_bytes;
    cinfo->src->bytes_in_buffer -= num_bytes;
}

static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) {
    ERR("(desired=%d), should not get here.\n",desired);
    return FALSE;
}
static void _jpeg_term_source(j_decompress_ptr cinfo) { }
#endif /* SONAME_LIBJPEG */

struct gifdata {
    unsigned char *data;
    unsigned int curoff;
    unsigned int len;
};

static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
    struct gifdata *gd = (struct gifdata*)gif->UserData;

    if (len+gd->curoff > gd->len) {
        FIXME("Trying to read %d bytes, but only %d available.\n",len, gd->len-gd->curoff);
        len = gd->len - gd->curoff;
    }
    memcpy(data, gd->data+gd->curoff, len);
    gd->curoff += len;
    return len;
}


static HRESULT OLEPictureImpl_LoadGif(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
    struct gifdata 	gd;
    GifFileType 	*gif;
    BITMAPINFO		*bmi;
    HDC			hdcref;
    LPBYTE              bytes;
    int                 i,j,ret;
    GifImageDesc        *gid;
    SavedImage          *si;
    ColorMapObject      *cm;
    int                 transparent = -1;
    ExtensionBlock      *eb;
    int                 padding;

    gd.data   = xbuf;
    gd.curoff = 0;
    gd.len    = xread;
    gif = DGifOpen((void*)&gd, _gif_inputfunc);
    ret = DGifSlurp(gif);
    if (ret == GIF_ERROR) {
      FIXME("Failed reading GIF using libgif.\n");
      return E_FAIL;
    }
    TRACE("screen height %d, width %d\n", gif->SWidth, gif->SHeight);
    TRACE("color res %d, backgcolor %d\n", gif->SColorResolution, gif->SBackGroundColor);
    TRACE("imgcnt %d\n", gif->ImageCount);
    if (gif->ImageCount<1) {
      FIXME("GIF stream does not have images inside?\n");
      return E_FAIL;
    }
    TRACE("curimage: %d x %d, on %dx%d, interlace %d\n",
      gif->Image.Width, gif->Image.Height,
      gif->Image.Left, gif->Image.Top,
      gif->Image.Interlace
    );
    /* */
    padding = (gif->SWidth+3) & ~3;
    si   = gif->SavedImages+0;
    gid  = &(si->ImageDesc);
    cm   = gid->ColorMap;
    if (!cm) cm = gif->SColorMap;
    bmi  = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(cm->ColorCount)*sizeof(RGBQUAD));
    bytes= HeapAlloc(GetProcessHeap(),0,padding*gif->SHeight);
    
    /* look for the transparent color extension */
    for (i = 0; i < si->ExtensionBlockCount; ++i) {
	eb = si->ExtensionBlocks + i;
	if (eb->Function == 0xF9 && eb->ByteCount == 4) {
	    if ((eb->Bytes[0] & 1) == 1) {
		transparent = (unsigned char)eb->Bytes[3];
	    }
	}
    }

    for (i = 0; i < cm->ColorCount; i++) {
      bmi->bmiColors[i].rgbRed = cm->Colors[i].Red;
      bmi->bmiColors[i].rgbGreen = cm->Colors[i].Green;
      bmi->bmiColors[i].rgbBlue = cm->Colors[i].Blue;
      if (i == transparent) {
	  This->rgbTrans = RGB(bmi->bmiColors[i].rgbRed,
			       bmi->bmiColors[i].rgbGreen,
			       bmi->bmiColors[i].rgbBlue);
      }
    }

    /* Map to in picture coordinates */
    for (i = 0, j = 0; i < gid->Height; i++) {
        if (gif->Image.Interlace) {
            memcpy(
                bytes + (gid->Top + j) * padding + gid->Left,
                si->RasterBits + i * gid->Width,
                gid->Width);

            /* Lower bits of interlaced counter encode current interlace */
            if (j & 1) j += 2;      /* Currently filling odd rows */
            else if (j & 2) j += 4; /* Currently filling even rows not multiples of 4 */
            else j += 8;            /* Currently filling every 8th row or 4th row in-between */

            if (j >= gid->Height && i < gid->Height && (j & 1) == 0) {
                /* End of current interlace, go to next interlace */
                if (j & 2) j = 1;       /* Next iteration fills odd rows */
                else if (j & 4) j = 2;  /* Next iteration fills even rows not mod 4 and not mod 8 */
                else j = 4;             /* Next iteration fills rows in-between rows mod 6 */
            }
        } else {
            memcpy(
                bytes + (gid->Top + i) * padding + gid->Left,
                si->RasterBits + i * gid->Width,
                gid->Width);
        }
    }

    bmi->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
    bmi->bmiHeader.biWidth		= gif->SWidth;
    bmi->bmiHeader.biHeight		= -gif->SHeight;
    bmi->bmiHeader.biPlanes		= 1;
    bmi->bmiHeader.biBitCount		= 8;
    bmi->bmiHeader.biCompression	= BI_RGB;
    bmi->bmiHeader.biSizeImage		= padding*gif->SHeight;
    bmi->bmiHeader.biXPelsPerMeter	= 0;
    bmi->bmiHeader.biYPelsPerMeter	= 0;
    bmi->bmiHeader.biClrUsed		= cm->ColorCount;
    bmi->bmiHeader.biClrImportant	= 0;

    hdcref = GetDC(0);
    This->desc.u.bmp.hbitmap=CreateDIBitmap(
	    hdcref,
	    &bmi->bmiHeader,
	    CBM_INIT,
	    bytes,
	    bmi,
	    DIB_RGB_COLORS
    );

    if (transparent > -1) {
	/* Create the Mask */
	HDC hdc = CreateCompatibleDC(0);
	HDC hdcMask = CreateCompatibleDC(0);
	HBITMAP hOldbitmap; 
	HBITMAP hOldbitmapmask;

        unsigned int monopadding = (((unsigned)(gif->SWidth + 31)) >> 5) << 2;
        HBITMAP hTempMask;

        This->hbmXor = CreateDIBitmap(
            hdcref,
            &bmi->bmiHeader,
            CBM_INIT,
            bytes,
            bmi,
            DIB_RGB_COLORS
        );

        bmi->bmiColors[0].rgbRed = 0;
        bmi->bmiColors[0].rgbGreen = 0;
        bmi->bmiColors[0].rgbBlue = 0;
        bmi->bmiColors[1].rgbRed = 255;
        bmi->bmiColors[1].rgbGreen = 255;
        bmi->bmiColors[1].rgbBlue = 255;

        bmi->bmiHeader.biBitCount		= 1;
        bmi->bmiHeader.biSizeImage		= monopadding*gif->SHeight;
        bmi->bmiHeader.biClrUsed		= 2;

        for (i = 0; i < gif->SHeight; i++) {
            unsigned char * colorPointer = bytes + padding * i;
            unsigned char * monoPointer = bytes + monopadding * i;
            for (j = 0; j < gif->SWidth; j++) {
                unsigned char pixel = colorPointer[j];
                if ((j & 7) == 0) monoPointer[j >> 3] = 0;
                if (pixel == (transparent & 0x000000FFU)) monoPointer[j >> 3] |= 1 << (7 - (j & 7));
            }
        }
        hdcref = GetDC(0);
        hTempMask = CreateDIBitmap(
                hdcref,
                &bmi->bmiHeader,
                CBM_INIT,
                bytes,
                bmi,
                DIB_RGB_COLORS
        );
        DeleteDC(hdcref);

        bmi->bmiHeader.biHeight = -bmi->bmiHeader.biHeight;
        This->hbmMask = CreateBitmap(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 1, 1, NULL);
	hOldbitmap = SelectObject(hdc, hTempMask);
	hOldbitmapmask = SelectObject(hdcMask, This->hbmMask);

        SetBkColor(hdc, RGB(255, 255, 255));
	BitBlt(hdcMask, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, hdc, 0, 0, SRCCOPY);

	/* We no longer need the original bitmap, so we apply the first
	   transformation with the mask to speed up the rendering */
        SelectObject(hdc, This->hbmXor);
	SetBkColor(hdc, RGB(0,0,0));
	SetTextColor(hdc, RGB(255,255,255));
	BitBlt(hdc, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 
		 hdcMask, 0, 0,  SRCAND);

	SelectObject(hdc, hOldbitmap);
	SelectObject(hdcMask, hOldbitmapmask);
	DeleteDC(hdcMask);
	DeleteDC(hdc);
        DeleteObject(hTempMask);
    }
    
    DeleteDC(hdcref);
    This->desc.picType = PICTYPE_BITMAP;
    OLEPictureImpl_SetBitmap(This);
    DGifCloseFile(gif);
    HeapFree(GetProcessHeap(),0,bytes);
    return S_OK;
}

static HRESULT OLEPictureImpl_LoadJpeg(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
#ifdef SONAME_LIBJPEG
    struct jpeg_decompress_struct	jd;
    struct jpeg_error_mgr		jerr;
    int					ret;
    JDIMENSION				x;
    JSAMPROW				samprow,oldsamprow;
    BITMAPINFOHEADER			bmi;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -