VirtualBox

Changeset 31958 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Aug 25, 2010 1:28:44 PM (14 years ago)
Author:
vboxsync
Message:

Main: thumbnail PNG API, refactoring

Location:
trunk/src/VBox/Main
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/DisplayImpl.cpp

    r31718 r31958  
    4343
    4444#include <VBox/com/array.h>
    45 #include <png.h>
    4645
    4746/**
     
    145144#define sSSMDisplayVer 0x00010001
    146145
    147 #define kMaxSizePNG 1024
    148146#define kMaxSizeThumbnail 64
    149147
     
    206204}
    207205
    208 typedef struct PNGWriteCtx
    209 {
    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     else
    271     {
    272         /* Large screenshot, scale. */
    273         if (cx > cy)
    274         {
    275             cxBitmap = kMaxSizePNG;
    276             cyBitmap = (kMaxSizePNG * cy) / cx;
    277         }
    278         else
    279         {
    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         else
    305         {
    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                     else
    374                     {
    375                         rc = VERR_GENERAL_FAILURE; /* Something within libpng. */
    376                     }
    377                 }
    378                 else
    379                 {
    380                     rc = VERR_NO_MEMORY;
    381                 }
    382 
    383                 png_destroy_write_struct(&png_ptr, info_ptr ? &info_ptr
    384                                                             : (png_infopp)NULL);
    385             }
    386             else
    387             {
    388                 rc = VERR_NO_MEMORY;
    389             }
    390 
    391             RTMemFree(row_pointers);
    392         }
    393         else
    394         {
    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 
    408206DECLCALLBACK(void)
    409207Display::displaySSMSaveScreenshot(PSSMHANDLE pSSM, void *pvUser)
     
    449247            /* Prepare a small thumbnail and a PNG screenshot. */
    450248            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);
    452250
    453251            /* This can be called from any thread. */
     
    26722470        uint32_t cyPNG = 0;
    26732471
    2674         displayMakePNG(pu8Data, width, height, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 0);
     2472        DisplayMakePNG(pu8Data, width, height, &pu8PNG, &cbPNG, &cxPNG, &cyPNG, 0);
    26752473
    26762474        com::SafeArray<BYTE> screenData (cbPNG);
  • trunk/src/VBox/Main/MachineImpl.cpp

    r31825 r31958  
    4747#include "GuestImpl.h"
    4848#include "StorageControllerImpl.h"
     49#include "DisplayImpl.h"
    4950
    5051#ifdef VBOX_WITH_USB
     
    54475448}
    54485449
    5449 STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight)
     5450
     5451STDMETHODIMP Machine::ReadSavedThumbnailPNGToArray(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))
    54505452{
    54515453    LogFlowThisFunc(("\n"));
    54525454
    5453     CheckComArgNotNull(aSize);
    54545455    CheckComArgNotNull(aWidth);
    54555456    CheckComArgNotNull(aHeight);
     5457    CheckComArgOutSafeArrayPointerValid(aData);
    54565458
    54575459    if (aScreenId != 0)
     
    54685470    uint32_t u32Height = 0;
    54695471
    5470     int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 1 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
     5472    int vrc = readSavedDisplayScreenshot(mSSData->mStateFilePath, 0 /* u32Type */, &pu8Data, &cbData, &u32Width, &u32Height);
    54715473
    54725474    if (RT_FAILURE(vrc))
     
    54755477                        vrc);
    54765478
    5477     *aSize = cbData;
    54785479    *aWidth = u32Width;
    54795480    *aHeight = u32Height;
    54805481
     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
    54815495    freeSavedDisplayScreenshot(pu8Data);
    54825496
     
    54845498}
    54855499
    5486 STDMETHODIMP Machine::ReadSavedScreenshotPNGToArray(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData))
     5500STDMETHODIMP Machine::QuerySavedScreenshotPNGSize(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight)
    54875501{
    54885502    LogFlowThisFunc(("\n"));
    54895503
     5504    CheckComArgNotNull(aSize);
    54905505    CheckComArgNotNull(aWidth);
    54915506    CheckComArgNotNull(aHeight);
    5492     CheckComArgOutSafeArrayPointerValid(aData);
    54935507
    54945508    if (aScreenId != 0)
     
    55125526                        vrc);
    55135527
     5528    *aSize = cbData;
    55145529    *aWidth = u32Width;
    55155530    *aHeight = u32Height;
    55165531
     5532    freeSavedDisplayScreenshot(pu8Data);
     5533
     5534    return S_OK;
     5535}
     5536
     5537STDMETHODIMP 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
    55175568    com::SafeArray<BYTE> png(cbData);
    5518     for (unsigned i = 0; i < cbData; i++)
    5519         png[i] = pu8Data[i];
     5569    png.initFrom(pu8Data, cbData);
    55205570    png.detachTo(ComSafeArrayOutArg(aData));
    55215571
  • trunk/src/VBox/Main/Makefile.kmk

    r31911 r31958  
    260260        $(PATH_LIB)/SSMStandalone$(VBOX_SUFF_LIB) \
    261261        $(LIB_DDU)
     262VBoxSVC_SDKS =  VBOX_LIBPNG
    262263VBoxSVC_LIBS.solaris = \
    263264        adm \
     
    308309        HostPower.cpp \
    309310        EventImpl.cpp \
     311        DisplayPNGUtil.cpp \
     312        DisplayResampleImage.cpp \
    310313        $(VBOX_AUTOGEN_EVENT_CPP) \
    311314        $(if $(VBOX_WITH_VRDP),VRDPServerImpl.cpp,) \
     
    633636        MouseImpl.cpp \
    634637        DisplayImpl.cpp \
     638        DisplayPNGUtil.cpp \
    635639        DisplayResampleImage.cpp \
    636640        MachineDebuggerImpl.cpp \
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r31818 r31958  
    34273427  <interface
    34283428     name="IMachine" extends="$unknown"
    3429      uuid="70ddc295-39fb-46e2-a93b-854e123b2b97"
     3429     uuid="5c3e7670-aa0d-460a-8d0b-9111b69a3906"
    34303430     wsmap="managed"
    34313431     >
     
    39863986      </desc>
    39873987    </attribute>
    3988      
     3988
    39893989    <attribute name="faultToleranceSyncInterval" type="unsigned long">
    39903990      <desc>
     
    55405540        <desc>
    55415541          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.
    55425568        </desc>
    55435569      </param>
     
    1086210888    </method>
    1086310889
    10864      <method name="takeScreenShotPNGToArray">
     10890    <method name="takeScreenShotPNGToArray">
    1086510891      <desc>
    1086610892        Takes a guest screen shot of the requested size and returns it as
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r31718 r31958  
    280280                        int srcW, int srcH);
    281281
     282int 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
    282286#endif // ____H_DISPLAYIMPL
    283287/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/include/MachineImpl.h

    r31818 r31958  
    510510    STDMETHOD(QuerySavedThumbnailSize)(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight);
    511511    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));
    512513    STDMETHOD(QuerySavedScreenshotPNGSize)(ULONG aScreenId, ULONG *aSize, ULONG *aWidth, ULONG *aHeight);
    513514    STDMETHOD(ReadSavedScreenshotPNGToArray)(ULONG aScreenId, ULONG *aWidth, ULONG *aHeight, ComSafeArrayOut(BYTE, aData));
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette