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

📄 olepicture.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
        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);
    pDGifCloseFile(gif);
    HeapFree(GetProcessHeap(),0,bytes);
    return S_OK;
#else
    FIXME("Trying to load GIF, but no support for libgif/libungif compiled in.\n");
    return E_FAIL;
#endif
}

static HRESULT OLEPictureImpl_LoadJpeg(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
#ifdef HAVE_JPEGLIB_H
    struct jpeg_decompress_struct	jd;
    struct jpeg_error_mgr		jerr;
    int					ret;
    JDIMENSION				x;
    JSAMPROW				samprow,oldsamprow;
    BITMAPINFOHEADER			bmi;
    LPBYTE				bits;
    HDC					hdcref;
    struct jpeg_source_mgr		xjsm;
    LPBYTE                              oldbits;
    unsigned int i;

    if(!libjpeg_handle) {
        if(!load_libjpeg()) {
            FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG);
            return E_FAIL;
        }
    }

    /* This is basically so we can use in-memory data for jpeg decompression.
     * We need to have all the functions.
     */
    xjsm.next_input_byte	= xbuf;
    xjsm.bytes_in_buffer	= xread;
    xjsm.init_source		= _jpeg_init_source;
    xjsm.fill_input_buffer	= _jpeg_fill_input_buffer;
    xjsm.skip_input_data	= _jpeg_skip_input_data;
    xjsm.resync_to_restart	= _jpeg_resync_to_restart;
    xjsm.term_source		= _jpeg_term_source;

    jd.err = pjpeg_std_error(&jerr);
    /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h
     * jpeg_create_decompress(&jd); */
    pjpeg_CreateDecompress(&jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct));
    jd.src = &xjsm;
    ret=pjpeg_read_header(&jd,TRUE);
    jd.out_color_space = JCS_RGB;
    pjpeg_start_decompress(&jd);
    if (ret != JPEG_HEADER_OK) {
	ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret);
	HeapFree(GetProcessHeap(),0,xbuf);
	return E_FAIL;
    }

    bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
                     (jd.output_height+1) * ((jd.output_width*jd.output_components + 3) & ~3) );
    samprow=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components);

    oldbits = bits;
    oldsamprow = samprow;
    while ( jd.output_scanline<jd.output_height ) {
      x = pjpeg_read_scanlines(&jd,&samprow,1);
      if (x != 1) {
	FIXME("failed to read current scanline?\n");
	break;
      }
      /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */
      for(i=0;i<jd.output_width;i++,samprow+=jd.output_components) {
	*(bits++) = *(samprow+2);
	*(bits++) = *(samprow+1);
	*(bits++) = *(samprow);
      }
      bits = (LPBYTE)(((UINT_PTR)bits + 3) & ~3);
      samprow = oldsamprow;
    }
    bits = oldbits;

    bmi.biSize		= sizeof(bmi);
    bmi.biWidth		=  jd.output_width;
    bmi.biHeight	= -jd.output_height;
    bmi.biPlanes	= 1;
    bmi.biBitCount	= jd.output_components<<3;
    bmi.biCompression	= BI_RGB;
    bmi.biSizeImage	= jd.output_height*jd.output_width*jd.output_components;
    bmi.biXPelsPerMeter	= 0;
    bmi.biYPelsPerMeter	= 0;
    bmi.biClrUsed	= 0;
    bmi.biClrImportant	= 0;

    HeapFree(GetProcessHeap(),0,samprow);
    pjpeg_finish_decompress(&jd);
    pjpeg_destroy_decompress(&jd);
    hdcref = GetDC(0);
    This->desc.u.bmp.hbitmap=CreateDIBitmap(
	    hdcref,
	    &bmi,
	    CBM_INIT,
	    bits,
	    (BITMAPINFO*)&bmi,
	    DIB_RGB_COLORS
    );
    DeleteDC(hdcref);
    This->desc.picType = PICTYPE_BITMAP;
    OLEPictureImpl_SetBitmap(This);
    HeapFree(GetProcessHeap(),0,bits);
    return S_OK;
#else
    ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
    return E_FAIL;
#endif
}

static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
    BITMAPFILEHEADER	*bfh = (BITMAPFILEHEADER*)xbuf;
    BITMAPINFO		*bi = (BITMAPINFO*)(bfh+1);
    HDC			hdcref;

    /* Does not matter whether this is a coreheader or not, we only use
     * components which are in both
     */
    hdcref = GetDC(0);
    This->desc.u.bmp.hbitmap = CreateDIBitmap(
	hdcref,
	&(bi->bmiHeader),
	CBM_INIT,
	xbuf+bfh->bfOffBits,
	bi,
       DIB_RGB_COLORS
    );
    DeleteDC(hdcref);
    This->desc.picType = PICTYPE_BITMAP;
    OLEPictureImpl_SetBitmap(This);
    return S_OK;
}

static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
{
    HICON hicon;
    CURSORICONFILEDIR	*cifd = (CURSORICONFILEDIR*)xbuf;
    HDC hdcRef;
    int	i;

    /*
    FIXME("icon.idReserved=%d\n",cifd->idReserved);
    FIXME("icon.idType=%d\n",cifd->idType);
    FIXME("icon.idCount=%d\n",cifd->idCount);

    for (i=0;i<cifd->idCount;i++) {
	FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
	FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
	FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
	FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
	FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
	FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
	FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
	FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
    }
    */
    i=0;
    /* If we have more than one icon, try to find the best.
     * this currently means '32 pixel wide'.
     */
    if (cifd->idCount!=1) {
	for (i=0;i<cifd->idCount;i++) {
	    if (cifd->idEntries[i].bWidth == 32)
		break;
	}
	if (i==cifd->idCount) i=0;
    }

    hicon = CreateIconFromResourceEx(
		xbuf+cifd->idEntries[i].dwDIBOffset,
		cifd->idEntries[i].dwDIBSize,
		TRUE, /* is icon */
		0x00030000,
		cifd->idEntries[i].bWidth,
		cifd->idEntries[i].bHeight,
		0
    );
    if (!hicon) {
	FIXME("CreateIcon failed.\n");
	return E_FAIL;
    } else {
	This->desc.picType = PICTYPE_ICON;
	This->desc.u.icon.hicon = hicon;
	This->origWidth = cifd->idEntries[i].bWidth;
	This->origHeight = cifd->idEntries[i].bHeight;
	hdcRef = CreateCompatibleDC(0);
	This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
	This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
	DeleteDC(hdcRef);
	return S_OK;
    }
}

/************************************************************************
 * OLEPictureImpl_IPersistStream_Load (IUnknown)
 *
 * Loads the binary data from the IStream. Starts at current position.
 * There appears to be an 2 DWORD header:
 * 	DWORD magic;
 * 	DWORD len;
 *
 * Currently implemented: BITMAP, ICON, JPEG, GIF
 */
static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
  HRESULT	hr = E_FAIL;
  BOOL		headerisdata = FALSE;
  BOOL		statfailed = FALSE;
  ULONG		xread, toread;
  BYTE 		*xbuf;
  DWORD		header[2];
  WORD		magic;
  STATSTG       statstg;
  OLEPictureImpl *This = impl_from_IPersistStream(iface);
  
  TRACE("(%p,%p)\n",This,pStm);

  /****************************************************************************************
   * Part 1: Load the data
   */
  /* Sometimes we have a header, sometimes we don't. Apply some guesses to find
   * out whether we do.
   *
   * UPDATE: the IStream can be mapped to a plain file instead of a stream in a
   * compound file. This may explain most, if not all, of the cases of "no
   * header", and the header validation should take this into account.
   * At least in Visual Basic 6, resource streams, valid headers are
   *    header[0] == "lt\0\0",
   *    header[1] == length_of_stream.
   *
   * Also handle streams where we do not have a working "Stat" method by
   * reading all data until the end of the stream.
   */
  hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
  if (hr) {
      TRACE("stat failed with hres %lx, proceeding to read all data.\n",hr);
      statfailed = TRUE;
      /* we will read at least 8 byte ... just right below */
      statstg.cbSize.QuadPart = 8;
  }
  hr=IStream_Read(pStm,header,8,&xread);
  if (hr || xread!=8) {
      FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
      return hr;
  }

  headerisdata = FALSE;
  xread = 0;
  if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <= statstg.cbSize.QuadPart-8)) {
      toread = header[1];
  } else {
      if (!memcmp(&(header[0]), "GIF8",     4) ||   /* GIF header */
          !memcmp(&(header[0]), "BM",       2) ||   /* BMP header */
          !memcmp(&(header[0]), "\xff\xd8", 2) ||   /* JPEG header */
          (header[1] > statstg.cbSize.QuadPart)||   /* invalid size */
          (header[1]==0)
      ) {/* Incorrect header, assume none. */
          headerisdata = TRUE;
          toread = statstg.cbSize.QuadPart-8;
          xread = 8;
      } else {
          FIXME("Unknown stream header magic: %08lx\n", header[0]);
          toread = header[1];
      }
  }

  if (statfailed) { /* we don't know the size ... read all we get */
      int sizeinc = 4096;
      int origsize = sizeinc;
      ULONG nread = 42;

      TRACE("Reading all data from stream.\n");
      xbuf = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, origsize);
      if (headerisdata)
          memcpy (xbuf, &header, 8);
      while (1) {
          while (xread < origsize) {
              hr = IStream_Read(pStm,xbuf+xread,origsize-xread,&nread);
              xread+=nread;
              if (hr || !nread)
                  break;
          }
          if (!nread || hr) /* done, or error */
              break;
          if (xread == origsize) {
              origsize += sizeinc;
              sizeinc = 2*sizeinc; /* exponential increase */
              xbuf = HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, xbuf, origsize);
          }
      }
      if (hr)
          TRACE("hr in no-stat loader case is %08lx\n", hr);
      TRACE("loaded %ld bytes.\n", xread);
      This->datalen = xread;
      This->data    = xbuf;
  } else {
      This->datalen = toread+(headerisdata?8:0);
      xbuf = This->data = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, This->datalen);

      if (headerisdata)
          memcpy (xbuf, &header, 8);

      while (xread < This->datalen) {
          ULONG nread;
          hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread);
          xread+=nread;
          if (hr || !nread)
              break;
      }
      if (xread != This->datalen)
          FIXME("Could only read %ld of %d bytes out of stream?\n",xread,This->datalen);
  }
  if (This->datalen == 0) { /* Marks the "NONE" picture */
      This->desc.picType = PICTYPE_NONE;
      return S_OK;
  }


  /****************************************************************************************
   * Part 2: Process the loaded data
   */

  magic = xbuf[0] + (xbuf[1]<<8);
  switch (magic) {
  case 0x4947: /* GIF */
    hr = OLEPictureImpl_LoadGif(This, xbuf, xread);
    break;
  case 0xd8ff: /* JPEG */
    hr = OLEPictureImpl_LoadJpeg(This, xbuf, xread);
    break;
  case 0x4d42: /* Bitmap */
    hr = OLEPictureImpl_LoadDIB(This, xbuf, xread);
    break;
  case 0x0000: { /* ICON , first word is dwReserved */
    hr = OLEPictureImpl_LoadIcon(This, xbuf, xread);
    break;
  }
  default:
  {
    unsigned int i;
    FIXME("Unknown magic %04x, %ld read bytes:\n",magic,xread);
    hr=E_FAIL;
    for (i=0;i<xread+8;i++) {
	if (i<8) MESSAGE("%02x ",((unsigned char*)&header)[i]);
	else MESSAGE("%02x ",xbuf[i-8]);

⌨️ 快捷键说明

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