Changeset 31958 in vbox for trunk/src/VBox/Main
- Timestamp:
- Aug 25, 2010 1:28:44 PM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/DisplayImpl.cpp
r31718 r31958 43 43 44 44 #include <VBox/com/array.h> 45 #include <png.h>46 45 47 46 /** … … 145 144 #define sSSMDisplayVer 0x00010001 146 145 147 #define kMaxSizePNG 1024148 146 #define kMaxSizeThumbnail 64 149 147 … … 206 204 } 207 205 208 typedef struct PNGWriteCtx209 {210 uint8_t *pu8PNG;211 uint32_t cbPNG;212 uint32_t cbAllocated;213 int rc;214 } PNGWriteCtx;215 216 static void PNGAPI png_write_data_fn(png_structp png_ptr, png_bytep p, png_size_t cb)217 {218 PNGWriteCtx *pCtx = (PNGWriteCtx *)png_get_io_ptr(png_ptr);219 LogFlowFunc(("png_ptr %p, p %p, cb %d, pCtx %p\n", png_ptr, p, cb, pCtx));220 221 if (pCtx && RT_SUCCESS(pCtx->rc))222 {223 if (pCtx->cbAllocated - pCtx->cbPNG < cb)224 {225 uint32_t cbNew = pCtx->cbPNG + (uint32_t)cb;226 AssertReturnVoidStmt(cbNew > pCtx->cbPNG && cbNew <= _1G, pCtx->rc = VERR_TOO_MUCH_DATA);227 cbNew = RT_ALIGN_32(cbNew, 4096) + 4096;228 229 void *pNew = RTMemRealloc(pCtx->pu8PNG, cbNew);230 if (!pNew)231 {232 pCtx->rc = VERR_NO_MEMORY;233 return;234 }235 236 pCtx->pu8PNG = (uint8_t *)pNew;237 pCtx->cbAllocated = cbNew;238 }239 240 memcpy(pCtx->pu8PNG + pCtx->cbPNG, p, cb);241 pCtx->cbPNG += (uint32_t)cb;242 }243 }244 245 static void PNGAPI png_output_flush_fn(png_structp png_ptr)246 {247 NOREF(png_ptr);248 /* Do nothing. */249 }250 251 static int displayMakePNG(uint8_t *pu8Data, uint32_t cx, uint32_t cy,252 uint8_t **ppu8PNG, uint32_t *pcbPNG, uint32_t *pcxPNG, uint32_t *pcyPNG,253 uint8_t fLimitSize)254 {255 int rc = VINF_SUCCESS;256 257 uint8_t * volatile pu8Bitmap = NULL; /* gcc setjmp warning */258 uint32_t volatile cbBitmap = 0; /* gcc setjmp warning */259 uint32_t volatile cxBitmap = 0; /* gcc setjmp warning */260 uint32_t volatile cyBitmap = 0; /* gcc setjmp warning */261 262 if (!fLimitSize || (cx < kMaxSizePNG && cy < kMaxSizePNG))263 {264 /* Save unscaled screenshot. */265 pu8Bitmap = pu8Data;266 cbBitmap = cx * 4 * cy;267 cxBitmap = cx;268 cyBitmap = cy;269 }270 else271 {272 /* Large screenshot, scale. */273 if (cx > cy)274 {275 cxBitmap = kMaxSizePNG;276 cyBitmap = (kMaxSizePNG * cy) / cx;277 }278 else279 {280 cyBitmap = kMaxSizePNG;281 cxBitmap = (kMaxSizePNG * cx) / cy;282 }283 284 cbBitmap = cxBitmap * 4 * cyBitmap;285 286 pu8Bitmap = (uint8_t *)RTMemAlloc(cbBitmap);287 288 if (pu8Bitmap)289 {290 uint8_t *dst = pu8Bitmap;291 uint8_t *src = pu8Data;292 int dstW = cxBitmap;293 int dstH = cyBitmap;294 int srcW = cx;295 int srcH = cy;296 int iDeltaLine = cx * 4;297 298 BitmapScale32 (dst,299 dstW, dstH,300 src,301 iDeltaLine,302 srcW, srcH);303 }304 else305 {306 rc = VERR_NO_MEMORY;307 }308 }309 310 LogFlowFunc(("%dx%d -> %dx%d\n", cx, cy, cxBitmap, cyBitmap));311 312 if (RT_SUCCESS(rc))313 {314 png_bytep *row_pointers = (png_bytep *)RTMemAlloc(cyBitmap * sizeof(png_bytep));315 if (row_pointers)316 {317 png_infop info_ptr = NULL;318 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,319 (png_voidp)NULL, /* error/warning context pointer */320 (png_error_ptr)NULL, /* error function */321 (png_error_ptr)NULL /* warning function */);322 if (png_ptr)323 {324 info_ptr = png_create_info_struct(png_ptr);325 if (info_ptr)326 {327 if (!setjmp(png_jmpbuf(png_ptr)))328 {329 PNGWriteCtx ctx;330 ctx.pu8PNG = NULL;331 ctx.cbPNG = 0;332 ctx.cbAllocated = 0;333 ctx.rc = VINF_SUCCESS;334 335 png_set_write_fn(png_ptr,336 (voidp)&ctx,337 png_write_data_fn,338 png_output_flush_fn);339 340 png_set_IHDR(png_ptr, info_ptr,341 cxBitmap, cyBitmap,342 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,343 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);344 345 png_bytep row_pointer = (png_bytep)pu8Bitmap;346 unsigned i = 0;347 for (; i < cyBitmap; i++, row_pointer += cxBitmap * 4)348 {349 row_pointers[i] = row_pointer;350 }351 png_set_rows(png_ptr, info_ptr, &row_pointers[0]);352 353 png_write_info(png_ptr, info_ptr);354 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);355 png_set_bgr(png_ptr);356 357 if (info_ptr->valid & PNG_INFO_IDAT)358 png_write_image(png_ptr, info_ptr->row_pointers);359 360 png_write_end(png_ptr, info_ptr);361 362 rc = ctx.rc;363 364 if (RT_SUCCESS(rc))365 {366 *ppu8PNG = ctx.pu8PNG;367 *pcbPNG = ctx.cbPNG;368 *pcxPNG = cxBitmap;369 *pcyPNG = cyBitmap;370 LogFlowFunc(("PNG %d bytes, bitmap %d bytes\n", ctx.cbPNG, cbBitmap));371 }372 }373 else374 {375 rc = VERR_GENERAL_FAILURE; /* Something within libpng. */376 }377 }378 else379 {380 rc = VERR_NO_MEMORY;381 }382 383 png_destroy_write_struct(&png_ptr, info_ptr ? &info_ptr384 : (png_infopp)NULL);385 }386 else387 {388 rc = VERR_NO_MEMORY;389 }390 391 RTMemFree(row_pointers);392 }393 else394 {395 rc = VERR_NO_MEMORY;396 }397 }398 399 if (pu8Bitmap && pu8Bitmap != pu8Data)400 {401 RTMemFree(pu8Bitmap);402 }403 404 return rc;405 406 }407 408 206 DECLCALLBACK(void) 409 207 Display::displaySSMSaveScreenshot(PSSMHANDLE pSSM, void *pvUser) … … 449 247 /* Prepare a small thumbnail and a PNG screenshot. */ 450 248 displayMakeThumbnail(pu8Data, cx, cy, &pu8Thumbnail, &cbThumbnail, &cxThumbnail, &cyThumbnail); 451 displayMakePNG(pu8Data, cx, cy, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 1);249 DisplayMakePNG(pu8Data, cx, cy, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 1); 452 250 453 251 /* This can be called from any thread. */ … … 2672 2470 uint32_t cyPNG = 0; 2673 2471 2674 displayMakePNG(pu8Data, width, height, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 0);2472 DisplayMakePNG(pu8Data, width, height, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 0); 2675 2473 2676 2474 com::SafeArray<BYTE> screenData (cbPNG); -
trunk/src/VBox/Main/MachineImpl.cpp
r31825 r31958 47 47 #include "GuestImpl.h" 48 48 #include "StorageControllerImpl.h" 49 #include "DisplayImpl.h" 49 50 50 51 #ifdef VBOX_WITH_USB … … 5447 5448 } 5448 5449 5449 STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight) 5450 5451 STDMETHODIMP Machine::ReadSavedThumbnailPNGToArray(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData)) 5450 5452 { 5451 5453 LogFlowThisFunc(("\n")); 5452 5454 5453 CheckComArgNotNull(aSize);5454 5455 CheckComArgNotNull(aWidth); 5455 5456 CheckComArgNotNull(aHeight); 5457 CheckComArgOutSafeArrayPointerValid(aData); 5456 5458 5457 5459 if (aScreenId != 0) … … 5468 5470 uint32_t u32Height = 0; 5469 5471 5470 int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 1/* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);5472 int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height); 5471 5473 5472 5474 if (RT_FAILURE(vrc)) … … 5475 5477 vrc); 5476 5478 5477 *aSize = cbData;5478 5479 *aWidth = u32Width; 5479 5480 *aHeight = u32Height; 5480 5481 5482 uint8_t *pu8PNG = NULL; 5483 uint32_t cbPNG = 0; 5484 uint32_t cxPNG = 0; 5485 uint32_t cyPNG = 0; 5486 5487 DisplayMakePNG(pu8Data, u32Width, u32Height, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 0); 5488 5489 com::SafeArray<BYTE> screenData(cbPNG); 5490 screenData.initFrom(pu8PNG, cbPNG); 5491 RTMemFree(pu8PNG); 5492 5493 screenData.detachTo(ComSafeArrayOutArg(aData)); 5494 5481 5495 freeSavedDisplayScreenshot(pu8Data); 5482 5496 … … 5484 5498 } 5485 5499 5486 STDMETHODIMP Machine:: ReadSavedScreenshotPNGToArray(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))5500 STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight) 5487 5501 { 5488 5502 LogFlowThisFunc(("\n")); 5489 5503 5504 CheckComArgNotNull(aSize); 5490 5505 CheckComArgNotNull(aWidth); 5491 5506 CheckComArgNotNull(aHeight); 5492 CheckComArgOutSafeArrayPointerValid(aData);5493 5507 5494 5508 if (aScreenId != 0) … … 5512 5526 vrc); 5513 5527 5528 *aSize = cbData; 5514 5529 *aWidth = u32Width; 5515 5530 *aHeight = u32Height; 5516 5531 5532 freeSavedDisplayScreenshot(pu8Data); 5533 5534 return S_OK; 5535 } 5536 5537 STDMETHODIMP Machine::ReadSavedScreenshotPNGToArray(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData)) 5538 { 5539 LogFlowThisFunc(("\n")); 5540 5541 CheckComArgNotNull(aWidth); 5542 CheckComArgNotNull(aHeight); 5543 CheckComArgOutSafeArrayPointerValid(aData); 5544 5545 if (aScreenId != 0) 5546 return E_NOTIMPL; 5547 5548 AutoCaller autoCaller(this); 5549 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 5550 5551 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 5552 5553 uint8_t *pu8Data = NULL; 5554 uint32_t cbData = 0; 5555 uint32_t u32Width = 0; 5556 uint32_t u32Height = 0; 5557 5558 int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height); 5559 5560 if (RT_FAILURE(vrc)) 5561 return setError(VBOX_E_IPRT_ERROR, 5562 tr("Saved screenshot thumbnail data is not available (%Rrc)"), 5563 vrc); 5564 5565 *aWidth = u32Width; 5566 *aHeight = u32Height; 5567 5517 5568 com::SafeArray<BYTE> png(cbData); 5518 for (unsigned i = 0; i < cbData; i++) 5519 png[i] = pu8Data[i]; 5569 png.initFrom(pu8Data, cbData); 5520 5570 png.detachTo(ComSafeArrayOutArg(aData)); 5521 5571 -
trunk/src/VBox/Main/Makefile.kmk
r31911 r31958 260 260 $(PATH_LIB)/SSMStandalone$(VBOX_SUFF_LIB) \ 261 261 $(LIB_DDU) 262 VBoxSVC_SDKS = VBOX_LIBPNG 262 263 VBoxSVC_LIBS.solaris = \ 263 264 adm \ … … 308 309 HostPower.cpp \ 309 310 EventImpl.cpp \ 311 DisplayPNGUtil.cpp \ 312 DisplayResampleImage.cpp \ 310 313 $(VBOX_AUTOGEN_EVENT_CPP) \ 311 314 $(if $(VBOX_WITH_VRDP),VRDPServerImpl.cpp,) \ … … 633 636 MouseImpl.cpp \ 634 637 DisplayImpl.cpp \ 638 DisplayPNGUtil.cpp \ 635 639 DisplayResampleImage.cpp \ 636 640 MachineDebuggerImpl.cpp \ -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r31818 r31958 3427 3427 <interface 3428 3428 name="IMachine" extends="$unknown" 3429 uuid=" 70ddc295-39fb-46e2-a93b-854e123b2b97"3429 uuid="5c3e7670-aa0d-460a-8d0b-9111b69a3906" 3430 3430 wsmap="managed" 3431 3431 > … … 3986 3986 </desc> 3987 3987 </attribute> 3988 3988 3989 3989 <attribute name="faultToleranceSyncInterval" type="unsigned long"> 3990 3990 <desc> … … 5540 5540 <desc> 5541 5541 Array with resulting bitmap data. 5542 </desc> 5543 </param> 5544 </method> 5545 5546 <method name="readSavedThumbnailPNGToArray"> 5547 <desc> 5548 Thumbnail in PNG format is retrieved to an array of bytes. 5549 </desc> 5550 <param name="screenId" type="unsigned long" dir="in"> 5551 <desc> 5552 Saved guest screen to read from. 5553 </desc> 5554 </param> 5555 <param name="width" type="unsigned long" dir="out"> 5556 <desc> 5557 Image width. 5558 </desc> 5559 </param> 5560 <param name="height" type="unsigned long" dir="out"> 5561 <desc> 5562 Image height. 5563 </desc> 5564 </param> 5565 <param name="data" type="octet" dir="return" safearray="yes"> 5566 <desc> 5567 Array with resulting PNG data. 5542 5568 </desc> 5543 5569 </param> … … 10862 10888 </method> 10863 10889 10864 10890 <method name="takeScreenShotPNGToArray"> 10865 10891 <desc> 10866 10892 Takes a guest screen shot of the requested size and returns it as -
trunk/src/VBox/Main/include/DisplayImpl.h
r31718 r31958 280 280 int srcW, int srcH); 281 281 282 int DisplayMakePNG(uint8_t *pu8Data, uint32_t cx, uint32_t cy, 283 uint8_t **ppu8PNG, uint32_t *pcbPNG, uint32_t *pcxPNG, uint32_t *pcyPNG, 284 uint8_t fLimitSize); 285 282 286 #endif // ____H_DISPLAYIMPL 283 287 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/include/MachineImpl.h
r31818 r31958 510 510 STDMETHOD(QuerySavedThumbnailSize)(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight); 511 511 STDMETHOD(ReadSavedThumbnailToArray)(ULONG aScreenId, BOOL aBGR, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData)); 512 STDMETHOD(ReadSavedThumbnailPNGToArray)(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData)); 512 513 STDMETHOD(QuerySavedScreenshotPNGSize)(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight); 513 514 STDMETHOD(ReadSavedScreenshotPNGToArray)(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData));
Note:
See TracChangeset
for help on using the changeset viewer.