bool SmtSmfRasLayer::Fetch(eSmtFetchType type) { if (!IsOpen()) return false; char szImgUrl[MAX_LAYER_FILE_NAME]; SmtDataSourceInfo info; m_pOwnerDs->GetInfo(info); sprintf(szImgUrl,"%s",m_szLayerFileName); long lCodeType = GetImageTypeByFileExt(m_szLayerFileName); CxImage img; if (img.Load(szImgUrl,lCodeType)) { BYTE *pImageBuf = NULL; long lImageBufSize = 0; fRect fLocRect; m_pMemLayer->GetRasterRect(fLocRect); fLocRect.rt.y = fLocRect.lb.y + fLocRect.Width()*img.GetHeight()/img.GetWidth(); if (img.Encode(pImageBuf,lImageBufSize,lCodeType)) { return (SMT_ERR_NONE == m_pMemLayer->CreaterRaster((const char *)pImageBuf,lImageBufSize,fLocRect,lCodeType)); } } return false; }
bool CxImageIG::EncodeLayer (const wchar_t *pcwFilePath, int nLayerIdx, int nLayerPos, RECT *p_rcSubLayer, int nSubLayerOwnerId) { CxIOFile file; if (!file.Open (pcwFilePath, L"r+b")) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "file.Open failed"); // read current header IGHEADER igHeader; if (!decodeHeader (&file, &igHeader)) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "decodeHeader failed"); IGSECTIONHEADER_LAYER *pLayerSections = new IGSECTIONHEADER_LAYER[CXIMAGEIG_MAX_NBLAYERS]; IGSECTIONHEADER_SELECTION *pSelectionSections = new IGSECTIONHEADER_SELECTION[CXIMAGEIG_MAX_NBSELECTIONS]; if (!decodeSections (&file, &igHeader, &pLayerSections[0], &pSelectionSections[0])) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "decodeSections failed"); IGLibrary::IGLayer *pLayer = GetLayer (nLayerPos); if (!pLayer) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "GetLayer failed"); _ASSERTE ((int)pLayer->GetId() == nLayerIdx && "CxImageIG::EncodeLayer FAILED"); bool bIsSubLayerOwner = false; int nLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nLayerIdx, bIsSubLayerOwner); if (nLayerSectionIndex < 0) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "findLayerSectionIndex failed"); if ((nLayerSectionIndex > igHeader.nNbLayers) || (nLayerSectionIndex >= CXIMAGEIG_MAX_NBLAYERS)) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "findLayerSectionIndex failed"); CxImage cxSubLayer; CxImage *pEncodingLayer = pLayer; int nSubLayerWidth = 0; int nSubLayerHeight = 0; if (p_rcSubLayer) { // Encode sub-layer nSubLayerWidth = p_rcSubLayer->right - p_rcSubLayer->left + 1; nSubLayerHeight = p_rcSubLayer->bottom - p_rcSubLayer->top + 1; cxSubLayer.Create (nSubLayerWidth, nSubLayerHeight, 24); cxSubLayer.AlphaCreate (255); BYTE *pLayerBits = NULL; BYTE *pSubLayerBits = NULL; for (int i = 0; i < nSubLayerHeight; i++) { pSubLayerBits = cxSubLayer.GetBits (i); pLayerBits = pLayer->GetBits (p_rcSubLayer->top + i) + 3 * p_rcSubLayer->left; ::memcpy (pSubLayerBits, pLayerBits, nSubLayerWidth * 3); } BYTE *pLayerAlpha = NULL; BYTE *pSubLayerAlpha = NULL; for (int i = 0; i < nSubLayerHeight; i++) { pLayerAlpha = pLayer->AlphaGetPointer (p_rcSubLayer->left, p_rcSubLayer->top + i); pSubLayerAlpha = cxSubLayer.AlphaGetPointer (0, i); ::memcpy (pSubLayerAlpha, pLayerAlpha, nSubLayerWidth); } pEncodingLayer = &cxSubLayer; int nSubLayerSectionIndex = findLayerSectionIndex (&igHeader, pLayerSections, nSubLayerOwnerId, bIsSubLayerOwner); if (nSubLayerSectionIndex < 0) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "findLayerSectionIndex failed"); pLayerSections [nSubLayerSectionIndex].pnSubLayers [pLayerSections [nSubLayerSectionIndex].nSubLayers++] = nLayerSectionIndex; } ProgressSetRange (pLayer->GetHeight(), 0); ProgressSetMessage (L"Encoding layer..."); // fill layer offset and size pLayerSections [nLayerSectionIndex].nSubLayers = 0; pLayerSections [nLayerSectionIndex].ptOffset.x = p_rcSubLayer ? p_rcSubLayer->left : pLayer->info.xOffset; pLayerSections [nLayerSectionIndex].ptOffset.y = p_rcSubLayer ? p_rcSubLayer->top : pLayer->info.yOffset; pLayerSections [nLayerSectionIndex].ptSize.x = p_rcSubLayer ? p_rcSubLayer->right - p_rcSubLayer->left + 1 : pLayer->GetWidth(); pLayerSections [nLayerSectionIndex].ptSize.y = p_rcSubLayer ? p_rcSubLayer->bottom - p_rcSubLayer->top + 1 : pLayer->GetHeight(); if (nLayerSectionIndex == igHeader.nNbLayers) pLayerSections [nLayerSectionIndex].commonHeader.nSectionId = (BYTE)igHeader.nNbSections; pLayerSections [nLayerSectionIndex].commonHeader.nId = nLayerIdx; pLayerSections [nLayerSectionIndex].commonHeader.eSectionType = IGSECTION_LAYER; // set byte offset if (igHeader.nNbSections == 0) pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset = sizeof (IGHEADER) + sizeof (IGSECTIONHEADER_LAYER) * CXIMAGEIG_MAX_NBLAYERS + sizeof (IGSECTIONHEADER_SELECTION) * CXIMAGEIG_MAX_NBSELECTIONS; else pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset = findSectionFirstByteOffset (&igHeader, pLayerSections, pSelectionSections, pLayerSections [nLayerSectionIndex].commonHeader.nSectionId); igHeader.nNbLayers = nLayerSectionIndex + 1; if (igHeader.nNbSelections == 0) { igHeader.nNbSections = pLayerSections [nLayerSectionIndex].commonHeader.nSectionId + 1; igHeader.nNbSelections = igHeader.nNbSections - igHeader.nNbLayers; } else { if (pSelectionSections [igHeader.nNbSelections - 1].commonHeader.nSectionId == pLayerSections [nLayerSectionIndex].commonHeader.nSectionId + 1) igHeader.nNbSections = igHeader.nNbSelections + igHeader.nNbLayers; else { igHeader.nNbSections = pLayerSections [nLayerSectionIndex].commonHeader.nSectionId + 1; igHeader.nNbSelections = igHeader.nNbSections - igHeader.nNbLayers; } } // write layer pixels if (!file.Seek (pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset, SEEK_SET)) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "file.Seek failed"); // set max JPEG quality float fCurQuality = pEncodingLayer->GetJpegQualityF(); pEncodingLayer->SetJpegQualityF (100.0f); // JPEG encoding BYTE *pBuf = new BYTE [CXIMAGEIG_INIT_LAYERSIZE]; CxMemFile memFile (pBuf, CXIMAGEIG_INIT_LAYERSIZE); if (!pEncodingLayer->Encode (&memFile, CXIMAGEIG_LAYERFORMAT)) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "pEncodingLayer->Encode failed"); BYTE *pBufImg = memFile.GetBuffer(); long nSizeBufImg = memFile.Tell(); // reset JPEG quality pEncodingLayer->SetJpegQualityF (fCurQuality); file.Write (pBufImg, nSizeBufImg, 1); delete [] pBufImg; pLayerSections [nLayerSectionIndex].commonHeader.nSizeBuf = nSizeBufImg; // write layer alpha if (!pEncodingLayer->pAlpha) pEncodingLayer->AlphaCreate(255); int nNbPixels = pEncodingLayer->GetWidth() * pEncodingLayer->GetHeight(); file.Write (pEncodingLayer->pAlpha, nNbPixels, 1); pLayerSections [nLayerSectionIndex].commonHeader.nEndByteOffset = pLayerSections [nLayerSectionIndex].commonHeader.nFirstByteOffset + nSizeBufImg + nNbPixels; // write new headers if (!encodeHeader (&file, &igHeader)) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "encodeHeader failed"); if (!encodeSections (&file, &igHeader, pLayerSections, pSelectionSections)) throw IGEXCEPTION (CxImageIGException, "EncodeLayer", "encodeSections failed"); delete [] pLayerSections; delete [] pSelectionSections; return true; }
// If handle_clipboard_request() fails, its caller sends VD_AGENT_CLIPBOARD message with type // VD_AGENT_CLIPBOARD_NONE and no data, so the client will know the request failed. bool VDAgent::handle_clipboard_request(VDAgentClipboardRequest* clipboard_request) { VDAgentMessage* msg; uint32_t msg_size; UINT format; HANDLE clip_data; uint8_t* new_data = NULL; long new_size = 0; size_t len = 0; CxImage image; VDAgentClipboard* clipboard = NULL; if (_clipboard_owner != owner_guest) { vd_printf("Received clipboard request from client while clipboard is not owned by guest"); return false; } if (!(format = get_clipboard_format(clipboard_request->type))) { vd_printf("Unsupported clipboard type %u", clipboard_request->type); return false; } // on encoding only, we use HBITMAP to keep the correct palette if (format == CF_DIB) { format = CF_BITMAP; } if (!IsClipboardFormatAvailable(format) || !OpenClipboard(_hwnd)) { return false; } if (!(clip_data = GetClipboardData(format))) { CloseClipboard(); return false; } switch (clipboard_request->type) { case VD_AGENT_CLIPBOARD_UTF8_TEXT: if (!(new_data = (uint8_t*)GlobalLock(clip_data))) { break; } len = wcslen((LPCWSTR)new_data); new_size = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)new_data, (int)len, NULL, 0, NULL, NULL); break; case VD_AGENT_CLIPBOARD_IMAGE_PNG: case VD_AGENT_CLIPBOARD_IMAGE_BMP: { DWORD cximage_format = get_cximage_format(clipboard_request->type); HPALETTE pal = 0; ASSERT(cximage_format); if (IsClipboardFormatAvailable(CF_PALETTE)) { pal = (HPALETTE)GetClipboardData(CF_PALETTE); } if (!image.CreateFromHBITMAP((HBITMAP)clip_data, pal)) { vd_printf("Image create from handle failed"); break; } if (!image.Encode(new_data, new_size, cximage_format)) { vd_printf("Image encode to type %u failed", clipboard_request->type); break; } vd_printf("Image encoded to %lu bytes", new_size); break; } } if (!new_size) { vd_printf("clipboard is empty"); goto handle_clipboard_request_fail; } if ((_max_clipboard != -1) && (new_size > _max_clipboard)) { vd_printf("clipboard is too large (%ld > %d), discarding", new_size, _max_clipboard); goto handle_clipboard_request_fail; } msg_size = sizeof(VDAgentMessage) + sizeof(VDAgentClipboard) + new_size; msg = (VDAgentMessage*)new uint8_t[msg_size]; msg->protocol = VD_AGENT_PROTOCOL; msg->type = VD_AGENT_CLIPBOARD; msg->opaque = 0; msg->size = (uint32_t)(sizeof(VDAgentClipboard) + new_size); clipboard = (VDAgentClipboard*)msg->data; clipboard->type = clipboard_request->type; switch (clipboard_request->type) { case VD_AGENT_CLIPBOARD_UTF8_TEXT: WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)new_data, (int)len, (LPSTR)clipboard->data, new_size, NULL, NULL); GlobalUnlock(clip_data); break; case VD_AGENT_CLIPBOARD_IMAGE_PNG: case VD_AGENT_CLIPBOARD_IMAGE_BMP: memcpy(clipboard->data, new_data, new_size); image.FreeMemory(new_data); break; } CloseClipboard(); write_clipboard(msg, msg_size); delete[] (uint8_t *)msg; return true; handle_clipboard_request_fail: if (clipboard_request->type == VD_AGENT_CLIPBOARD_UTF8_TEXT) { GlobalUnlock(clip_data); } CloseClipboard(); return false; }