/* this works only, if gdiplus.dll is there. * It should be there on * Windows XP and newer * On Win98 and up, if .NET is installed */ int dr_screenshot_png(const char *filename, int w, int h, unsigned short *data, int bitdepth ) { // first we try as PNG CLSID encoderClsid; int ok=FALSE; ULONG *myImage = NULL; struct GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; HMODULE hGDIplus = LoadLibraryA( "gdiplus.dll" ); if(hGDIplus==NULL) { return FALSE; } // retrieve names ... GdiplusStartup = (int (WINAPI *)(ULONG_PTR *,struct GdiplusStartupInput *,void *)) GetProcAddress( hGDIplus, "GdiplusStartup" ); GdiplusShutdown = (int (WINAPI *)(ULONG_PTR)) GetProcAddress( hGDIplus, "GdiplusShutdown" ); GdipGetImageEncodersSize = (int (WINAPI *)(UINT *,UINT *)) GetProcAddress( hGDIplus, "GdipGetImageEncodersSize" ); GdipGetImageEncoders = (int (WINAPI *)(UINT,UINT,ImageCodecInfo *)) GetProcAddress( hGDIplus, "GdipGetImageEncoders" ); GdipCreateBitmapFromScan0 = (int (WINAPI *)(INT,INT,INT,INT,BYTE *,ULONG **)) GetProcAddress( hGDIplus, "GdipCreateBitmapFromScan0" ); GdipDeleteCachedBitmap = (int (WINAPI *)(ULONG *)) GetProcAddress( hGDIplus, "GdipDeleteCachedBitmap" ); GdipSaveImageToFile = (int (WINAPI *)(ULONG *,const WCHAR *,const CLSID *,const EncoderParameters *)) GetProcAddress( hGDIplus, "GdipSaveImageToFile" ); /* Win2k can do without init, WinXP not ... */ gdiplusStartupInput.GdiplusVersion = 1; gdiplusStartupInput.DebugEventCallback = NULL; gdiplusStartupInput.SuppressBackgroundThread = FALSE; gdiplusStartupInput.SuppressExternalCodecs = FALSE; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); if( bitdepth==8 ) { GdipCreateBitmapFromScan0(w, h, ((w + 7) & 0xFFF8), PixelFormat8bppIndexed , (BYTE*)data, &myImage); } else { GdipCreateBitmapFromScan0(w, h, ((w + 15) & 0xFFF0) * 2, bitdepth == 16 ? PixelFormat16bppRGB565 : PixelFormat16bppRGB555, (BYTE*)data, &myImage); } if( myImage==NULL && bitdepth>8 ) { /* we may have XP or newer => have to convert them to 32 first to save them ... Grrrr */ BYTE *newdata = malloc( w*h*4 ); BYTE *dest = newdata; unsigned short *src = data; int ww = ((w+15) & 0xFFF0); int x, y; for( y=0; y<h; y++ ) { for( x=0; x<w; x++ ) { unsigned short color = src[x]; *dest++ = (color & 0xF800)>>8; *dest++ = (color & 0x07E0)>>3; *dest++ = (color & 0x001F)<<5; *dest++ = 0xFF; } src += ww; } GdipCreateBitmapFromScan0(w, h, w * 4, PixelFormat24bppRGB, newdata, &myImage); free( newdata ); }
static GF_Err gdip_attach_surface_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat) { GpMatrix *mat; u32 pFormat; GPGRAPH(); if (pitch_y%4) return GF_NOT_SUPPORTED; switch (pixelFormat) { case GF_PIXEL_ALPHAGREY: pFormat = PixelFormat16bppGrayScale; if (pitch_x != 2) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_555: pFormat = PixelFormat16bppRGB555; if (pitch_x != 2) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_565: pFormat = PixelFormat16bppRGB565; if (pitch_x != 2) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_24: pFormat = PixelFormat24bppRGB; if (pitch_x != 3) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_32: pFormat = PixelFormat32bppRGB; if (pitch_x != 4) return GF_NOT_SUPPORTED; break; case GF_PIXEL_ARGB: pFormat = PixelFormat32bppARGB; if (pitch_x != 4) return GF_NOT_SUPPORTED; break; default: return GF_NOT_SUPPORTED; } GdipCreateBitmapFromScan0(width, height, pitch_y, pFormat, (unsigned char*)pixels, &_graph->pBitmap); GdipGetImageGraphicsContext(_graph->pBitmap, &_graph->graph); _graph->w = width; _graph->h = height; if (_graph->center_coords) { GdipCreateMatrix(&mat); GdipScaleMatrix(mat, 1.0, -1.0, MatrixOrderAppend); GdipTranslateMatrix(mat, (Float) width/2, (Float) height/2, MatrixOrderAppend); GdipSetWorldTransform(_graph->graph, mat); GdipDeleteMatrix(mat); } GdipSetPixelOffsetMode(_graph->graph, GDIP_PIXEL_MODE); return GF_OK; }
static void test_emfonly(void) { GpStatus stat; GpMetafile *metafile; GpGraphics *graphics; HDC hdc, metafile_dc; HENHMETAFILE hemf; BOOL ret; static const GpRectF frame = {0.0, 0.0, 100.0, 100.0}; static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}}; static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0}; HBRUSH hbrush, holdbrush; GpBitmap *bitmap; ARGB color; hdc = CreateCompatibleDC(0); stat = GdipRecordMetafile(hdc, EmfTypeEmfOnly, &frame, MetafileFrameUnitPixel, description, &metafile); expect(Ok, stat); DeleteDC(hdc); if (stat != Ok) return; stat = GdipGetHemfFromMetafile(metafile, &hemf); expect(InvalidParameter, stat); stat = GdipGetImageGraphicsContext((GpImage*)metafile, &graphics); expect(Ok, stat); stat = GdipGetDC(graphics, &metafile_dc); expect(Ok, stat); if (stat != Ok) { GdipDeleteGraphics(graphics); GdipDisposeImage((GpImage*)metafile); return; } hbrush = CreateSolidBrush(0xff0000); holdbrush = SelectObject(metafile_dc, hbrush); Rectangle(metafile_dc, 25, 25, 75, 75); SelectObject(metafile_dc, holdbrush); DeleteObject(hbrush); stat = GdipReleaseDC(graphics, metafile_dc); expect(Ok, stat); stat = GdipDeleteGraphics(graphics); expect(Ok, stat); check_metafile(metafile, emfonly_records, "emfonly metafile", dst_points, &frame, UnitPixel); stat = GdipCreateBitmapFromScan0(100, 100, 0, PixelFormat32bppARGB, NULL, &bitmap); expect(Ok, stat); stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); expect(Ok, stat); play_metafile(metafile, graphics, emfonly_records, "emfonly playback", dst_points, &frame, UnitPixel); stat = GdipBitmapGetPixel(bitmap, 15, 15, &color); expect(Ok, stat); expect(0, color); stat = GdipBitmapGetPixel(bitmap, 50, 50, &color); expect(Ok, stat); expect(0xff0000ff, color); stat = GdipDeleteGraphics(graphics); expect(Ok, stat); stat = GdipDisposeImage((GpImage*)bitmap); expect(Ok, stat); stat = GdipGetHemfFromMetafile(metafile, &hemf); expect(Ok, stat); stat = GdipDisposeImage((GpImage*)metafile); expect(Ok, stat); check_emfplus(hemf, emfonly_records, "emfonly emf"); ret = DeleteEnhMetaFile(hemf); ok(ret != 0, "Failed to delete enhmetafile %p\n", hemf); }
int main (int argc, char **argv) { GpBitmap *bitmap; BitmapData d, q; Rect r; int i, j; unsigned long *lptr; unsigned char *cptr; BYTE *scan0 = (BYTE*) GdipAlloc(10 * 10 * 4); GpStatus status = GdipCreateBitmapFromScan0 (10, 10, 10 * 4, PixelFormat32bppARGB, scan0, &bitmap); CHECK_STATUS(1); printf ("Full rectangle, no format conversion, read only\n"); r.X = 0; r.Y = 0; r.Width = 10; r.Height = 10; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppARGB, &d); CHECK_STATUS(1); printf ("Attempt to re-lock (should fail)\n"); status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppARGB, &q); CHECK_STATUS(0); printf ("Unlock\n"); status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); /* lptr = (unsigned long *) bitmap->active_bitmap->scan0; for (j = 0; j < 10; j++) { for (i = 0; i < 10; i++) { *lptr++ = j | j << 8 | i << 16 | i << 24; } } */ memset (&d, 0x00, sizeof (BitmapData)); printf ("\nHalf rectangle, no format conversion, read only\n"); r.X = 5; r.Y = 5; r.Width = 5; r.Height = 5; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppARGB, &d); CHECK_STATUS(1); for (j = 0; j < 5; j++) { lptr = (unsigned long *) d.Scan0 + j * d.Stride; printf ("%d: ", j); for (i = 0; i < 5; i++) { printf ("%08lx ", *lptr++); } printf ("\n"); } printf ("Modifying (setting to 0xff)\n"); memset (d.Scan0, 0xff, d.Stride * d.Height); printf ("Unlocking\n"); status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); /* printf ("Original data after unlock (shouldn't be 0xffffffff): 0x%08x\n", ((unsigned long *)(bitmap->active_bitmap->scan0))[55]); if (((unsigned long *)(bitmap->active_bitmap->scan0))[55] == 0xffffffff) printf ("==> FAIL!\n"); */ memset (&d, 0x00, sizeof (BitmapData)); printf ("\nHalf rectangle, 32bpp ARGB -> 32bpp RGB, read only\n"); r.X = 5; r.Y = 5; r.Width = 5; r.Height = 5; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead, PixelFormat32bppRGB, &d); CHECK_STATUS(1); lptr = (unsigned long *) d.Scan0; for (j = 0; j < 5; j++) { printf ("%d: ", j); for (i = 0; i < 5; i++) { printf ("%08lx ", *lptr++); } printf ("\n"); } status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); memset (&d, 0x00, sizeof (BitmapData)); printf ("\nHalf rectangle, 32bpp ARGB -> 24bpp RGB, read/write only\n"); r.X = 5; r.Y = 5; r.Width = 5; r.Height = 5; status = GdipBitmapLockBits (bitmap, &r, ImageLockModeRead | ImageLockModeWrite, PixelFormat24bppRGB, &d); CHECK_STATUS(1); for (j = 0; j < 5; j++) { cptr = (unsigned char *) (d.Scan0 + (j * d.Stride)); printf ("%d: ", j); for (i = 0; i < 5; i++) { printf ("%02x%02x%02x ", cptr[0], cptr[1], cptr[2]); cptr += 3; } printf ("\n"); } printf ("Modifying (setting to 0xaabbcc)\n"); for (j = 0; j < 5; j++) { cptr = (unsigned char *) (d.Scan0 + (j * d.Stride)); for (i = 0; i < 5; i++) { *cptr++ = 0xcc; *cptr++ = 0xbb; *cptr++ = 0xaa; } } status = GdipBitmapUnlockBits (bitmap, &d); CHECK_STATUS(1); /* printf ("Original data after Unlock (should be all 0xffaabbcc):\n"); for (j = 5; j < 10; j++) { lptr = (unsigned long *) (bitmap->active_bitmap->Scan0 + j * bitmap->active_bitmap->Stride) + 5; printf ("%d: ", j); for (i = 5; i < 10; i++) { printf ("%08x ", *lptr++); } printf ("\n"); } */ GdipFree (scan0); return 0; }