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; }
////////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers void CMainFrame::OnEditPaste() { CDemoDoc *NewDoc=(CDemoDoc*)((CDemoApp*)AfxGetApp())->demoTemplate->OpenDocumentFile(NULL); if (NewDoc) { if (OpenClipboard()) { HANDLE hData=NULL; if (hData = GetClipboardData(((CDemoApp*)AfxGetApp())->GetCF())){ //custom CxImage object CxImage *newima = new CxImage(); DWORD dwSize = GlobalSize(hData); if (dwSize) { BYTE *lpVoid = (BYTE *)GlobalLock(hData); newima->UnDump(lpVoid); GlobalUnlock(lpVoid); } NewDoc->image = newima; } else if (hData = GetClipboardData(CF_DIB)){ // check if bitmap CxImage *newima = new CxImage(); newima->CreateFromHANDLE(hData); NewDoc->image = newima; } else { #if CXIMAGE_SUPPORT_WMF if (hData = GetClipboardData(CF_ENHMETAFILE)) //check if metafile { HENHMETAFILE hMeta = (HENHMETAFILE)hData; ENHMETAHEADER emh; GetEnhMetaFileHeader(hMeta, sizeof(emh), &emh); int cx,cy; cx = (int)((emh.rclBounds.right - emh.rclBounds.left)/2.54); cy = (int)((emh.rclBounds.bottom - emh.rclBounds.top)/2.54); HDC hDC0 = ::GetDC(0); // screen dc HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy); HDC hDC = CreateCompatibleDC(hDC0); // memory dc compatible with screen ::ReleaseDC(0, hDC0); // don't need anymore. get rid of it. if (hDC && hBitmap){ RECT rc = {0,0,cx,cy}; int bpp = ::GetDeviceCaps(hDC, BITSPIXEL); HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap); // paint the background DWORD dwBack = RGB(255, 255, 255); //GetSysColor(COLOR_WINDOW); DWORD OldColor = SetBkColor(hDC, dwBack); ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL); SetBkColor(hDC, OldColor); // Play the Metafile into Memory DC BOOL bRet = PlayEnhMetaFile(hDC, hMeta, &rc); SelectObject(hDC, hBitmapOld); CxImage *newima = new CxImage(); if(bRet && newima->Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)){ bRet = GetDIBits(hDC, hBitmap, 0, (UINT)cy, newima->GetBits(), (LPBITMAPINFO)newima->GetDIB(), DIB_RGB_COLORS); NewDoc->image = newima; } else { delete newima; } } if (hBitmap) DeleteObject(hBitmap); if (hDC) DeleteDC(hDC); } #endif } } CloseClipboard(); CString s; s.Format(_T("Clipboard Image %d"),((CDemoApp*)AfxGetApp())->m_nDocCount++); NewDoc->SetTitle(s); NewDoc->UpdateAllViews(0,WM_USER_NEWIMAGE); NewDoc->UpdateStatusBar(); } }