mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1485 lines
50 KiB
1485 lines
50 KiB
/****************************************************************************
|
|
SAVE.C
|
|
|
|
$Log: S:\products\wangview\oiwh\display\save.c_v $
|
|
*
|
|
* Rev 1.94 22 Apr 1996 09:01:52 BEG06016
|
|
* Cleaned up error checking.
|
|
*
|
|
* Rev 1.93 12 Apr 1996 18:51:08 RC
|
|
* Saved the pointer data in the marks to named blocks
|
|
*
|
|
* Rev 1.92 11 Apr 1996 15:12:46 BEG06016
|
|
* Optimized named block access some.
|
|
*
|
|
* Rev 1.91 05 Mar 1996 07:38:46 BEG06016
|
|
* Added color and gamma correction.
|
|
* Fixed access violations when freeing pattern brush bitmaps.
|
|
* This is not complete but will allow unlocking of most files.
|
|
*
|
|
* Rev 1.90 28 Feb 1996 08:17:54 BEG06016
|
|
* Fixed saving of semi-valid compression types.
|
|
*
|
|
* Rev 1.89 09 Jan 1996 14:07:12 BLJ
|
|
* Fixed rendering.
|
|
*
|
|
* Rev 1.88 02 Jan 1996 09:57:48 BLJ
|
|
* Changed alot of UINTs to ints.
|
|
* Changed IMG structure to include the image data.
|
|
* Changed lp prefix to p.
|
|
*
|
|
* Rev 1.87 22 Dec 1995 11:11:44 BLJ
|
|
* Added a parameter for zero init'ing to some memory manager calls.
|
|
*
|
|
* Rev 1.86 07 Dec 1995 08:09:26 BLJ
|
|
* Fixed saving scaled AWD images.
|
|
* Now if bScale == TRUE then it will save image data.
|
|
*
|
|
* Rev 1.85 21 Nov 1995 08:31:26 RC
|
|
* Saved the scale value associated with the larger res for awd files, not
|
|
* just the horiz scale everytime
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "privdisp.h"
|
|
|
|
/****************************************************************************
|
|
|
|
FUNCTION: IMGSavetoFileEx
|
|
|
|
PURPOSE: Saves the displayed image in the specified file and page.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI IMGSavetoFileEx(HWND hWnd, LPSAVE_EX_STRUCT pSaveEx, int nFlags){
|
|
|
|
int nStatus;
|
|
PWINDOW pWindow;
|
|
PANO_IMAGE pAnoImage;
|
|
PIMAGE pImage;
|
|
|
|
int nMarkIndex;
|
|
PMARK pMark;
|
|
PIMG pTempImg = 0;
|
|
PIMG pTempImg2 = 0;
|
|
LRECT lrRect;
|
|
LRECT lrScaledSaveRect;
|
|
int nDisplayType;
|
|
BOOL bFileOpen = FALSE;
|
|
int nScale;
|
|
FIO_INFORMATION FioInfo;
|
|
BOOL bSaveOriginal;
|
|
IMAGE DummyImage;
|
|
PBITMAPINFOHEADER pDib;
|
|
BOOL bRenderForm = FALSE;
|
|
PARM_SCROLL_STRUCT ScrollStruct;
|
|
HPALETTE hSavePal;
|
|
FIO_INFO_MISC MiscInfo;
|
|
int nHScale;
|
|
int nVScale;
|
|
DWORD dwFlags;
|
|
int nHRes;
|
|
int nVRes;
|
|
IMAGE_CORRECTIONS Corrections;
|
|
|
|
|
|
memset(&FioInfo, 0, sizeof(FIO_INFORMATION));
|
|
|
|
CheckError2( Init(hWnd, &pWindow, &pAnoImage, TRUE, TRUE));
|
|
if (!pSaveEx){
|
|
nStatus = Error (DISPLAY_NULLPOINTERINVALID);
|
|
goto Exit;
|
|
}
|
|
// Check for operation in progress.
|
|
if (pAnoImage->Annotations.ppMarks){
|
|
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
|
|
if (pMark){
|
|
OiOpEndOperation(hWnd);
|
|
pMark = pAnoImage->Annotations.ppMarks[pAnoImage->Annotations.nMarks];
|
|
if (pMark){
|
|
OiOpEndOperation(hWnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
pImage = pAnoImage->pBaseImage;
|
|
|
|
CheckError2( ValidateCache(hWnd, pAnoImage));
|
|
CheckError2( TranslateScale(pWindow->nScale, pImage->nHRes, pImage->nVRes, &nHScale, &nVScale));
|
|
|
|
memset(&MiscInfo, 0, sizeof(FIO_INFO_MISC));
|
|
MiscInfo.LastInfo.BandSize = 0;
|
|
MiscInfo.LastInfo.Rotation = pImage->nFileRotation;
|
|
|
|
if (pSaveEx->bScale){
|
|
switch (pSaveEx->uScaleFactor){
|
|
case SD_EIGHTXSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR * 8;
|
|
break;
|
|
|
|
case SD_FOURXSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR * 4;
|
|
break;
|
|
|
|
case SD_TWOXSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR * 2;
|
|
break;
|
|
|
|
case SD_FULLSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR * 1;
|
|
break;
|
|
|
|
case SD_HALFSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR / 2;
|
|
break;
|
|
|
|
case SD_QUARTERSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR / 4;
|
|
break;
|
|
|
|
case SD_EIGHTHSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR / 8;
|
|
break;
|
|
|
|
case SD_SIXTEENTHSIZE:
|
|
pSaveEx->uScaleFactor = SCALE_DENOMINATOR /16;
|
|
break;
|
|
|
|
case SD_SCALEUP1:
|
|
case SD_SCALEDOWN1:
|
|
case SD_FIT_WINDOW:
|
|
case SD_FIT_HORIZONTAL:
|
|
case SD_FIT_VERTICAL:
|
|
case SD_USEBOX:
|
|
nStatus = Error(DISPLAY_INVALIDSCALE);
|
|
goto Exit;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if ((pSaveEx->FioInfoCgbw.compress_type & FIO_TYPES_MASK) == FIO_1D2D){
|
|
pSaveEx->FioInfoCgbw.compress_type
|
|
= (pSaveEx->FioInfoCgbw.compress_type & ~FIO_TYPES_MASK) | FIO_2D;
|
|
pSaveEx->FioInfoCgbw.compress_info1 &= ~(FIO_FULL_EOL | FIO_PACKED_LINES);
|
|
}
|
|
|
|
if ((pSaveEx->FioInfoCgbw.compress_type & FIO_TYPES_MASK) == FIO_LZW){
|
|
pSaveEx->FioInfoCgbw.compress_type
|
|
= (pSaveEx->FioInfoCgbw.compress_type & ~FIO_TYPES_MASK) | FIO_0D;
|
|
}
|
|
|
|
// this is to adjust the size of the image to be the same before and after the save by
|
|
// changing the saved images scale info (for AWD files only)
|
|
if (pSaveEx->bScale){
|
|
nScale = ((pWindow->nScale * SCALE_DENOMINATOR) / pSaveEx->uScaleFactor);
|
|
MiscInfo.LastInfo.ScaleX = nScale / 10;
|
|
MiscInfo.LastInfo.ScaleY = nScale / 10;
|
|
}else{
|
|
MiscInfo.LastInfo.ScaleX = nHScale / 10;
|
|
MiscInfo.LastInfo.ScaleY = nVScale / 10;
|
|
}
|
|
if (pSaveEx->bUpdateLastViewed){
|
|
if (pImage->nHRes >= pImage->nVRes){
|
|
pImage->nFileScale = nHScale;
|
|
}else{
|
|
pImage->nFileScale = nVScale;
|
|
}
|
|
pImage->nFileScaleFlags = 0;
|
|
pImage->bFileScaleValid = TRUE;
|
|
}
|
|
MiscInfo.bLastInfoValid = TRUE;
|
|
|
|
// This is part of the change to comment out saving the data if it was "only" inverted.
|
|
// It is known that this means that the state of this bit may not be correct
|
|
// and probably isn't.
|
|
// MiscInfo.LastInfo.Flags = pImage->nFileHScaleFlags & FIO_LASTINFO_INVERT;
|
|
MiscInfo.LastInfo.Flags = 0;
|
|
|
|
if ((nFlags & SAVE_ONLY_MODIFIED) && !((int) pImage->bArchive & ~ARCHIVE_ROTATED_IMAGE)
|
|
&& !strcmp(pSaveEx->lpFileName, pImage->szFileName) && !pAnoImage->bArchive
|
|
&& !pSaveEx->bScale && !pSaveEx->bConvertImageType && !pSaveEx->bRenderAnnotations){
|
|
nStatus = IMGFilePutInfo(hWnd, pImage->szFileName, pImage->nFilePageNum, &MiscInfo);
|
|
// !nStatus = normal operation.
|
|
// nStatus == FIO_UNSUPPORTED_FILE_TYPE = Save all image data regardless.
|
|
// nStatus == anything else = error.
|
|
if (nStatus != FIO_UNSUPPORTED_FILE_TYPE){
|
|
if (nStatus){
|
|
Error(nStatus);
|
|
}
|
|
goto Exit;
|
|
}
|
|
}
|
|
MiscInfo.LastInfo.Flags = FIO_LASTINFO_INVERT;
|
|
MiscInfo.LastInfo.Rotation = 0;
|
|
|
|
|
|
// Check for protected marks, and scaleability.
|
|
if (pSaveEx->bUpdateImageFile){
|
|
for (nMarkIndex = 0; nMarkIndex < pAnoImage->Annotations.nMarks; nMarkIndex++){
|
|
pMark = pAnoImage->Annotations.ppMarks[nMarkIndex];
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_VISIBLE && !pMark->Attributes.bVisible){
|
|
continue;
|
|
}
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_SELECTED && !pMark->bSelected){
|
|
continue;
|
|
}
|
|
if (pSaveEx->bScale){
|
|
CheckError2( CanMarkBeScaled(hWnd, pMark, pSaveEx->uScaleFactor));
|
|
}
|
|
}
|
|
}
|
|
|
|
// check to see if there is a form mark, and if so is it being rendered
|
|
if (pAnoImage->Annotations.nMarks){
|
|
pMark = pAnoImage->Annotations.ppMarks[0];
|
|
// setting bRenderForm will not render the form nnless psaveex->brenderannotations
|
|
// is also set. That check happens later
|
|
if ((int) pMark->Attributes.uType == OIOP_AN_FORM){
|
|
if ((pSaveEx->uAnnotations & 0x0003) != SAVE_ANO_NONE
|
|
&& (pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_ALL){
|
|
bRenderForm = TRUE;
|
|
}
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_VISIBLE){
|
|
if (pMark->Attributes.bVisible){
|
|
bRenderForm = TRUE;
|
|
}
|
|
}
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_SELECTED){
|
|
if (pMark->bSelected){
|
|
bRenderForm = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!pSaveEx->bScale && !pSaveEx->bRenderAnnotations && !pSaveEx->bConvertImageType){
|
|
bSaveOriginal = TRUE;
|
|
}else{
|
|
bSaveOriginal = FALSE;
|
|
}
|
|
|
|
if (!pSaveEx->bScale){
|
|
pSaveEx->uScaleFactor = 1000;
|
|
pSaveEx->uScaleAlgorithm = OI_SCALE_ALG_NORMAL;
|
|
}
|
|
|
|
// Default to file save.
|
|
nHScale = pSaveEx->uScaleFactor;
|
|
nVScale = pSaveEx->uScaleFactor;
|
|
|
|
// Perform Scaling.
|
|
if (!bSaveOriginal){
|
|
CheckError2( TranslateScale(pSaveEx->uScaleFactor, pImage->nHRes, pImage->nVRes, &nHScale, &nVScale));
|
|
|
|
// Get the image ready for the save.
|
|
lrScaledSaveRect.left = 0;
|
|
lrScaledSaveRect.top = 0;
|
|
lrScaledSaveRect.right = pImage->nWidth;
|
|
lrScaledSaveRect.bottom = pImage->nHeight;
|
|
ConvertRect2(&lrScaledSaveRect, CONV_FULLSIZE_TO_SCALED, nHScale, nVScale, 0, 0);
|
|
|
|
switch (pSaveEx->uScaleAlgorithm){
|
|
case OI_SCALE_ALG_USE_DEFAULT:
|
|
case OI_SCALE_ALG_NORMAL:
|
|
case OI_SCALE_ALG_STAMP:
|
|
nDisplayType = pImage->pImg->nType;
|
|
break;
|
|
case OI_SCALE_ALG_AVERAGE_TO_GRAY4:
|
|
nDisplayType = ITYPE_GRAY4;
|
|
break;
|
|
case OI_SCALE_ALG_AVERAGE_TO_GRAY8:
|
|
nDisplayType = ITYPE_GRAY8;
|
|
break;
|
|
case OI_SCALE_ALG_BW_MINORITY:
|
|
case OI_SCALE_ALG_BW_MAJORITY:
|
|
nDisplayType = ITYPE_BI_LEVEL;
|
|
break;
|
|
default:
|
|
nStatus = Error(DISPLAY_DATACORRUPTED);
|
|
goto Exit;
|
|
}
|
|
|
|
SetLRect(lrRect, 0, 0, 0, 0);
|
|
if (pSaveEx->bConvertImageType){
|
|
nDisplayType = pSaveEx->uImageType;
|
|
if (nDisplayType == ITYPE_PAL8){
|
|
nDisplayType = ITYPE_COMPAL8;
|
|
}
|
|
if (nDisplayType == ITYPE_GRAY8 && pSaveEx->bRenderAnnotations){
|
|
nDisplayType = ITYPE_GRAY7;
|
|
}
|
|
if (nDisplayType == ITYPE_PAL4){
|
|
nStatus = Error(DISPLAY_IMAGETYPENOTSUPPORTED);
|
|
goto Exit;
|
|
}
|
|
}
|
|
CheckError2( CorrectBufferSize(&pTempImg, nDisplayType, lrScaledSaveRect, lrRect));
|
|
Corrections.nBrightness = 1000;
|
|
Corrections.nContrast = 1000;
|
|
Corrections.nColorRed = 1000;
|
|
Corrections.nColorGreen = 1000;
|
|
Corrections.nColorBlue = 1000;
|
|
Corrections.nGammaRed = 1000;
|
|
Corrections.nGammaGreen = 1000;
|
|
Corrections.nGammaBlue = 1000;
|
|
if (pSaveEx->bRenderAnnotations && bRenderForm){
|
|
CheckError2( FillImgRectFromOriginal(pImage, pAnoImage->pBasePlusFormImg,
|
|
pTempImg, lrScaledSaveRect, lrScaledSaveRect, nHScale, nVScale,
|
|
pSaveEx->uScaleAlgorithm, TRUE, &Corrections));
|
|
}else{
|
|
CheckError2( FillImgRectFromOriginal(pImage, pImage->pImg,
|
|
pTempImg, lrScaledSaveRect, lrScaledSaveRect, nHScale, nVScale,
|
|
pSaveEx->uScaleAlgorithm, TRUE, &Corrections));
|
|
}
|
|
}
|
|
|
|
|
|
// Render annotations.
|
|
if (pSaveEx->bRenderAnnotations){
|
|
DummyImage.nWidth = pTempImg->nWidth;
|
|
DummyImage.nHeight = pTempImg->nHeight;
|
|
DummyImage.nRWDataType = pTempImg->nType;
|
|
switch (pTempImg->nType){
|
|
case ITYPE_BI_LEVEL:
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
memset (DummyImage.PaletteTable, 0, 1024);
|
|
hSavePal = 0;
|
|
break;
|
|
|
|
case ITYPE_GRAY4:
|
|
memcpy (DummyImage.PaletteTable, (PSTR) &Gray4PaletteTable, 64);
|
|
hSavePal = hCommonPal;
|
|
break;
|
|
|
|
case ITYPE_PAL4:
|
|
memcpy (DummyImage.PaletteTable, (PSTR) &pImage->PaletteTable, 64);
|
|
hSavePal = hCommonPal;
|
|
break;
|
|
|
|
case ITYPE_GRAY7:
|
|
memcpy (DummyImage.PaletteTable, (PSTR) &Gray7PaletteTable, 512);
|
|
hSavePal = hGray7Pal;
|
|
break;
|
|
|
|
case ITYPE_GRAY8:
|
|
memcpy (DummyImage.PaletteTable, (PSTR) &Gray8PaletteTable, 512);
|
|
hSavePal = hGray8Pal;
|
|
break;
|
|
|
|
case ITYPE_COMPAL8:
|
|
memcpy (DummyImage.PaletteTable, (PSTR) &CommonPaletteTable, NUMBER_OF_PALETTES * 4);
|
|
hSavePal = hCommonPal;
|
|
break;
|
|
|
|
case ITYPE_CUSPAL8:
|
|
memcpy (DummyImage.PaletteTable, (PSTR) &pImage->PaletteTable, pImage->nPaletteEntries * 4);
|
|
hSavePal = pImage->hCusPal;
|
|
break;
|
|
|
|
default:
|
|
nStatus = Error(DISPLAY_DATACORRUPTED);
|
|
goto Exit;
|
|
}
|
|
lrRect.left = 0;
|
|
lrRect.top = 0;
|
|
lrRect.right = DummyImage.nWidth;
|
|
lrRect.bottom = DummyImage.nHeight;
|
|
#ifdef old
|
|
// Fony up the vertical resolution in order to fake out RenderIP;
|
|
nHRes = pImage->nHRes;
|
|
nVRes = pImage->nVRes;
|
|
if (nHRes >= nVRes){
|
|
pImage->nVRes = pImage->nHRes;
|
|
}else{
|
|
pImage->nHRes = pImage->nVRes;
|
|
}
|
|
|
|
nTempScale = pWindow->nScale;
|
|
pWindow->nScale = pSaveEx->uScaleFactor;
|
|
#endif
|
|
nStatus = RenderIP(hWnd, NULL, pWindow, &DummyImage, pTempImg, &pTempImg2,
|
|
lrRect, hSavePal, TRUE, pSaveEx->uAnnotations,
|
|
&pDib, FALSE, &pAnoImage->Annotations.ppMarks,
|
|
&pAnoImage->Annotations.nMarks, nHScale, nVScale);
|
|
#ifdef old
|
|
pWindow->nScale = (int)nTempScale;
|
|
pImage->nHRes = nHRes;
|
|
pImage->nVRes = nVRes;
|
|
#endif
|
|
if (nStatus){
|
|
goto Exit;
|
|
}
|
|
FreeImgBuf(&pTempImg);
|
|
MoveImage(&pTempImg2, &pTempImg);
|
|
}
|
|
|
|
|
|
// Save the image to the file.
|
|
if (bSaveOriginal){
|
|
bFileOpen = TRUE;
|
|
pSaveEx->FioInfoCgbw.image_type = pImage->pImg->nType;
|
|
pSaveEx->FioInfoCgbw.page_opts = pSaveEx->uPageOpts;
|
|
CheckError2( OpenFileForWrite(hWnd, pWindow, pImage,
|
|
pImage->pImg, &FioInfo, &MiscInfo, pSaveEx, nFlags));
|
|
CheckError2( SaveImageToFile(hWnd, pWindow, pImage, pImage->pImg, &FioInfo, pSaveEx, nFlags));
|
|
}else{
|
|
nHRes = pImage->nHRes;
|
|
nVRes = pImage->nVRes;
|
|
if (pImage->nHRes >= pImage->nVRes){
|
|
pImage->nVRes = pImage->nHRes;
|
|
}else{
|
|
pImage->nHRes = pImage->nVRes;
|
|
}
|
|
// pImage->nWidth = pTempImg->nWidth;
|
|
// pImage->nHeight = pTempImg->nHeight;
|
|
bFileOpen = TRUE;
|
|
pSaveEx->FioInfoCgbw.image_type = pTempImg->nType;
|
|
pSaveEx->FioInfoCgbw.page_opts = pSaveEx->uPageOpts;
|
|
if (nStatus = OpenFileForWrite(hWnd, pWindow, pImage,
|
|
pTempImg, &FioInfo, &MiscInfo, pSaveEx, nFlags)){
|
|
pImage->nHRes = nHRes;
|
|
pImage->nVRes = nVRes;
|
|
goto Exit;
|
|
}
|
|
if (nStatus = SaveImageToFile(hWnd, pWindow, pImage,
|
|
pTempImg, &FioInfo, pSaveEx, nFlags)){
|
|
pImage->nHRes = nHRes;
|
|
pImage->nVRes = nVRes;
|
|
goto Exit;
|
|
}
|
|
pImage->nHRes = nHRes;
|
|
pImage->nVRes = nVRes;
|
|
}
|
|
|
|
|
|
// Save annotation data here.
|
|
if (!pSaveEx->bRenderAnnotations){
|
|
CheckError2( SaveAnnotationsToFile(hWnd, pWindow, pImage, pSaveEx, nHScale, nVScale));
|
|
}
|
|
|
|
// Set flag FALSE before close to prevent exit code from closing it again.
|
|
bFileOpen = FALSE;
|
|
CheckError2( CloseFileForWrite(hWnd, pImage));
|
|
CheckError2( InvalidateAllDisplayRects(pWindow, pImage, NULL, TRUE));
|
|
// clear the archive bit on the cached version of the file
|
|
if (!strcmp(pSaveEx->lpFileName, pImage->szFileName) &&
|
|
(pSaveEx->nPage == (int) pImage->nFilePageNum)){
|
|
pAnoImage->bArchive = 0;
|
|
pImage->bArchive = 0;
|
|
}
|
|
// Ignor errors because if the file doesn't exist it returns an error.
|
|
IMGCacheDiscardFileCgbw(hWnd, pSaveEx->lpFileName, pSaveEx->nPage);
|
|
pAnoImage = 0;
|
|
pImage = 0;
|
|
|
|
if (pSaveEx->bUpdateImageFile){
|
|
nScale = ((pWindow->nScale * SCALE_DENOMINATOR) / pSaveEx->uScaleFactor);
|
|
CheckError2( IMGGetParmsCgbw(hWnd, PARM_SCROLL, &ScrollStruct,
|
|
PARM_PIXEL | PARM_FULLSIZE | PARM_ABSOLUTE));
|
|
ScrollStruct.lHorz = (ScrollStruct.lHorz * pWindow->nScale) / nScale;
|
|
ScrollStruct.lVert = (ScrollStruct.lVert * pWindow->nScale) / nScale;
|
|
dwFlags = OI_DISP_NO;
|
|
if (!pWindow->bScrollBarsEnabled){
|
|
dwFlags |= OI_NOSCROLL;
|
|
}
|
|
CheckError2( IMGCloseDisplay(hWnd));
|
|
IMGCacheDiscardFileCgbw(hWnd, pSaveEx->lpFileName, pSaveEx->nPage);
|
|
pAnoImage = 0;
|
|
pImage = 0;
|
|
|
|
CheckError2( IMGDisplayFile(hWnd, pSaveEx->lpFileName, pSaveEx->nPage, dwFlags));
|
|
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SCALE, &nScale, 0));
|
|
CheckError2( IMGSetParmsCgbw(hWnd, PARM_SCROLL, &ScrollStruct,
|
|
PARM_PIXEL | PARM_FULLSIZE | PARM_ABSOLUTE));
|
|
if (nFlags & PARM_REPAINT){
|
|
CheckError2( IMGRepaintDisplay(hWnd, (PRECT) -1));
|
|
}
|
|
}
|
|
|
|
|
|
Exit:
|
|
FreeImgBuf(&pTempImg);
|
|
if (!nStatus && pAnoImage && pImage){
|
|
pAnoImage->bArchive = 0;
|
|
pImage->bArchive = 0;
|
|
}
|
|
|
|
if (bFileOpen){
|
|
// Handle all file closing here.
|
|
if (!nStatus){
|
|
nStatus = CloseFileForWrite(hWnd, pImage);
|
|
}else{
|
|
CloseFileForWrite(hWnd, pImage);
|
|
// Don't delete the file. It might be a can't overwrite file error.
|
|
}
|
|
}
|
|
|
|
DeInit(TRUE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CloseFileForWrite
|
|
|
|
PURPOSE: Closes a file.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CloseFileForWrite(HWND hWnd, PIMAGE pImage){
|
|
|
|
int nStatus;
|
|
|
|
|
|
if (pImage->hFileProp){
|
|
if (nStatus = IMGFileClose(pImage->hFileProp, hWnd)){
|
|
Error(nStatus);
|
|
}
|
|
pImage->hFileProp = 0;
|
|
}
|
|
|
|
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: OpenFileForWrite
|
|
|
|
PURPOSE: Opens a file.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI OpenFileForWrite(HWND hWnd, PWINDOW pWindow, PIMAGE pImage,
|
|
PIMG pImg, LP_FIO_INFORMATION pFioInfo,
|
|
LP_FIO_INFO_MISC pMiscInfo, LPSAVE_EX_STRUCT pSaveEx,
|
|
int nFlags){
|
|
|
|
int nStatus;
|
|
|
|
int nLinesPerStrip;
|
|
int nFioImageType;
|
|
//int nJunk;
|
|
|
|
BOOL bFileOpen = FALSE;
|
|
PANO_IMAGE pAnoImage;
|
|
|
|
//int nFileId;
|
|
|
|
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
|
|
#ifdef NoImage
|
|
if (pSaveEx->bDontSaveImage){
|
|
if (pSaveEx->FioInfoCgbw.page_opts == FIO_OVERWRITE_FILE){
|
|
if ((nFileId = IMGFileBinaryOpen32(hWnd, pSaveEx->lpFileName,
|
|
OF_CREATE, &nJunk, &nStatus)) < 0){
|
|
Error(nStatus);
|
|
goto Exit;
|
|
}
|
|
}else{
|
|
if ((nFileId = IMGFileBinaryOpen32(hWnd, pSaveEx->lpFileName,
|
|
OF_EXIST, &nJunk, &nStatus)) != FALSE){
|
|
Error(nStatus);
|
|
goto Exit;
|
|
}
|
|
if (nFileId){
|
|
nStatus = Error(FIO_OPEN_WRITE_ERROR);
|
|
goto Exit;
|
|
}
|
|
if ((nFileId = IMGFileBinaryOpen32(hWnd, pSaveEx->lpFileName,
|
|
OF_CREATE, &nJunk, &nStatus)) < 0){
|
|
Error(nStatus);
|
|
goto Exit;
|
|
}
|
|
}
|
|
pImage->hFileProp = nFileId;
|
|
goto Exit;
|
|
}
|
|
#endif
|
|
|
|
// Image is included. Therefore we have to nse imaging calls.
|
|
|
|
// Make sure Wiisfio knows our bit order.
|
|
switch (pSaveEx->FioInfoCgbw.compress_type & FIO_TYPES_MASK){
|
|
case FIO_0D :
|
|
case FIO_1D :
|
|
case FIO_2D :
|
|
case FIO_PACKED:
|
|
case FIO_GLZW :
|
|
case FIO_LZW :
|
|
pSaveEx->FioInfoCgbw.compress_info1 |= FIO_EXPAND_LTR;
|
|
// 9-26-95 It was mandated via management that we not force FIO_COMPRESSED_LTR to be set.
|
|
// pSaveEx->FioInfoCgbw.compress_info1 |= FIO_COMPRESSED_LTR;
|
|
break;
|
|
case FIO_TJPEG :
|
|
break;
|
|
}
|
|
|
|
if (pImg->nType == ITYPE_CUSPAL8 || pImg->nType == ITYPE_COMPAL8){
|
|
pSaveEx->FioInfoCgbw.image_type = ITYPE_PAL8;
|
|
}else{
|
|
pSaveEx->FioInfoCgbw.image_type = pImg->nType;
|
|
}
|
|
|
|
nFioImageType = pSaveEx->FioInfoCgbw.image_type;
|
|
|
|
CheckError( GetCompRowsPerStrip( pImg->nHeight,
|
|
pImg->nWidth, pSaveEx->FioInfoCgbw.image_type,
|
|
pSaveEx->FioInfoCgbw.compress_type, &nLinesPerStrip));
|
|
|
|
if (!pSaveEx->uFileType){
|
|
pSaveEx->uFileType = FIO_TIF;
|
|
}
|
|
|
|
pFioInfo->filename = pSaveEx->lpFileName;
|
|
pFioInfo->page_number = pSaveEx->nPage;
|
|
pFioInfo->page_count = 0;
|
|
pFioInfo->horizontal_dpi = pImage->nHRes;
|
|
pFioInfo->vertical_dpi = pImage->nVRes;
|
|
pFioInfo->horizontal_pixels = pImg->nWidth;
|
|
pFioInfo->vertical_pixels = pImg->nHeight;
|
|
pFioInfo->compression_type = pSaveEx->FioInfoCgbw.compress_type;
|
|
pFioInfo->file_type = pSaveEx->uFileType;
|
|
pFioInfo->strips_per_image = ( pImg->nHeight + (nLinesPerStrip - 1)) / nLinesPerStrip;
|
|
pFioInfo->rows_strip = nLinesPerStrip;
|
|
|
|
switch (pImg->nType){
|
|
case ITYPE_BI_LEVEL:
|
|
pFioInfo->bits_per_sample = 1;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = 0;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = 0;
|
|
break;
|
|
case ITYPE_PAL8:
|
|
case ITYPE_CUSPAL8:
|
|
pFioInfo->bits_per_sample = 8;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = pImage->nPaletteEntries;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = pImage->PaletteTable;
|
|
break;
|
|
case ITYPE_COMPAL8:
|
|
pFioInfo->bits_per_sample = 8;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = NUMBER_OF_PALETTES;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = CommonPaletteTable;
|
|
break;
|
|
case ITYPE_PAL4:
|
|
pFioInfo->bits_per_sample = 4;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = pImage->nPaletteEntries;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = pImage->PaletteTable;
|
|
break;
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
pFioInfo->bits_per_sample = 24;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = 0;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = 0;
|
|
break;
|
|
case ITYPE_GRAY4:
|
|
pFioInfo->bits_per_sample = 4;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = 16;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = CommonPaletteTable;
|
|
break;
|
|
case ITYPE_GRAY8:
|
|
pFioInfo->bits_per_sample = 8;
|
|
pFioInfo->samples_per_pix = 1;
|
|
pSaveEx->FioInfoCgbw.palette_entries = 256;
|
|
pSaveEx->FioInfoCgbw.lppalette_table = Gray8PaletteTable;
|
|
break;
|
|
case ITYPE_GRAY12:
|
|
case ITYPE_GRAY16:
|
|
case ITYPE_NONE:
|
|
default:
|
|
nStatus = Error(DISPLAY_IMAGETYPENOTSUPPORTED);
|
|
goto Exit;
|
|
}
|
|
|
|
// Setup the encrypt flag.
|
|
// pSaveEx->FioInfoCgbw.fio_flags = FIO_IMAGE_DATA | FIO_ANNO_DATA | FIO_HITIFF_DATA;
|
|
pSaveEx->FioInfoCgbw.fio_flags = FIO_IMAGE_DATA;
|
|
memset(pSaveEx->FioInfoCgbw.reserved, 0, sizeof(pSaveEx->FioInfoCgbw.reserved));
|
|
|
|
if (pAnoImage->Annotations.nMarks && !pSaveEx->bRenderAnnotations){
|
|
switch (pSaveEx->uAnnotations & 0x0003){
|
|
case SAVE_ANO_NONE:
|
|
break;
|
|
|
|
case SAVE_ANO_ALL:
|
|
case SAVE_ANO_VISIBLE:
|
|
pSaveEx->FioInfoCgbw.fio_flags |= FIO_ANNO_DATA;
|
|
break;
|
|
|
|
case SAVE_ANO_SELECTED:
|
|
pSaveEx->FioInfoCgbw.fio_flags |= FIO_ANNO_DATA;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
pFioInfo->filename = pSaveEx->lpFileName;
|
|
CheckError( IMGFileOpenForWrite(&pImage->hFileProp, hWnd, pFioInfo,
|
|
&pSaveEx->FioInfoCgbw, pMiscInfo, ALIGN_BYTE));
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: SaveImageToFile
|
|
|
|
PURPOSE: Saves an IPpack image buffer to an already open file.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI SaveImageToFile(HWND hWnd, PWINDOW pWindow, PIMAGE pImage,
|
|
PIMG pImg, LP_FIO_INFORMATION pFioInfo,
|
|
LPSAVE_EX_STRUCT pSaveEx, int nFlags){
|
|
|
|
int nStatus;
|
|
|
|
|
|
#ifdef UseOicomex
|
|
COMP_CALL_SPEC CompCallSpec;
|
|
#endif
|
|
|
|
|
|
#ifndef UseOicomex
|
|
int nBytesPerLine;
|
|
int nLinesPerBuffer;
|
|
DWORD dwLine;
|
|
DWORD dwLines;
|
|
PSTR pAddress;
|
|
int nBufferSize;
|
|
PSTR pBuffer = 0;
|
|
#endif
|
|
|
|
BOOL bFileOpen = FALSE;
|
|
|
|
|
|
#ifdef UseOicomex
|
|
// Use oicomex to save the files data.
|
|
|
|
// If we just did open for jpeg, we need to clean np memory -- jar 3.6
|
|
// I don't nnderstand why oicomex needs this and not wiisfio, but see
|
|
// Joe Russo if you have any questions.
|
|
if (pFioInfoCgbw->compress_type == FIO_TJPEG){
|
|
OICompressJpegCleanUp();
|
|
}
|
|
|
|
CompCallSpec.image_handle = hImage;
|
|
CheckError( OICompress(SEQFILE, hWnd, &CompCallSpec, &FioInfo, pFioInfoCgbw));
|
|
#endif
|
|
|
|
#ifndef UseOicomex
|
|
// Use wiisfio to save the files data.
|
|
|
|
// Wiisfio modifies the data in the buffer that is passed into it.
|
|
// Therefore wiisfio MUST nse a seperate buffer.
|
|
|
|
nBytesPerLine = ((pFioInfo->horizontal_pixels * pFioInfo->bits_per_sample *
|
|
pFioInfo->samples_per_pix) + 7) / 8;
|
|
nLinesPerBuffer = 30719 / nBytesPerLine;
|
|
nBufferSize = nBytesPerLine * nLinesPerBuffer;
|
|
CheckError2( AllocateMemory(nBufferSize, (PPSTR) &pBuffer, NO_INIT));
|
|
|
|
for (dwLine = 0; dwLine < pFioInfo->vertical_pixels;){
|
|
pAddress = &pImg->bImageData[0] + (dwLine * pImg->nBytesPerLine);
|
|
dwLines = pImg->nHeight - dwLine;
|
|
dwLines = min(min(dwLines, (UINT) nLinesPerBuffer), pFioInfo->vertical_pixels - dwLine);
|
|
nBufferSize = dwLines * nBytesPerLine;
|
|
memcpy(pBuffer, pAddress, nBufferSize);
|
|
CheckError( IMGFileWriteData(pImage->hFileProp, hWnd, &dwLines, pBuffer, FIO_IMAGE_DATA, 0));
|
|
dwLine += dwLines;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
Exit:
|
|
FreeMemory((PPSTR) &pBuffer);
|
|
return(nStatus);
|
|
}
|
|
|
|
// <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
|
|
#ifdef old
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: SavetoFileCgbwF
|
|
|
|
PURPOSE: Saves the displayed image in the specified file and page.
|
|
|
|
INPUT: hWnd - Identifies the image window of the image
|
|
to be saved.
|
|
pFileName - Points to a null-terminated character
|
|
string that names the file to save the image in.
|
|
nPage - Specifies page number to save the image in.
|
|
wOWFlag - Flag is TRUE the file will be overwritten
|
|
if it exist.
|
|
pFioInfoCgbw - A pointer to a structure containing
|
|
certain image info.
|
|
nFlags - various flags for the save.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI SavetoFileCgbwF(HWND hWnd, PSTR pFileName, int nPage, int nPageOpts,
|
|
int nFileType, LP_FIO_INFO_CGBW pFioInfoCgbw, int nFlags){
|
|
|
|
int nStatus;
|
|
PWINDOW pWindow;
|
|
PANO_IMAGE pAnoImage;
|
|
|
|
SAVE_EX_STRUCT SaveEx;
|
|
|
|
CheckError2( Init(hWnd, &pWindow, &pAnoImage, TRUE, TRUE));
|
|
|
|
memset(&SaveEx, 0, sizeof(SAVE_EX_STRUCT));
|
|
SaveEx.pFileName = pFileName;
|
|
SaveEx.nPage = nPage;
|
|
SaveEx.nPageOpts = nPageOpts;
|
|
SaveEx.nFileType = nFileType;
|
|
SaveEx.FioInfoCgbw = *pFioInfoCgbw;
|
|
SaveEx.bUpdateImageFile = TRUE;
|
|
SaveEx.bScale = FALSE;
|
|
SaveEx.nScaleFactor = 1000;
|
|
SaveEx.bUpdateDisplayScale = FALSE;
|
|
SaveEx.nScaleAlgorithm = OI_SCALE_ALG_NORMAL;
|
|
|
|
if (!(nFlags & SAVE_TEMP)){
|
|
SaveEx.bUpdateImageFile = TRUE;
|
|
}else{
|
|
SaveEx.bUpdateImageFile = FALSE;
|
|
}
|
|
|
|
CheckError2( IMGSavetoFileEx(hWnd, &SaveEx, nFlags));
|
|
|
|
|
|
Exit:
|
|
DeInit(TRUE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: IMGSavetoFile
|
|
|
|
PURPOSE: Saves the displayed image in the specified file and page.
|
|
|
|
INPUT: hWnd - Identifies the image window of the image
|
|
to be saved.
|
|
pFileName - Points to a null-terminated character
|
|
string that names the file to save the image in.
|
|
nPage - Specifies page number to save the image in.
|
|
wOWFlag - Flag is TRUE the file will be overwritten
|
|
if it exist.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI IMGSavetoFile(HWND hWnd, PSTR pFileName, int nPage, BOOL bOWFlag){
|
|
|
|
int nStatus;
|
|
|
|
PWINDOW pWindow;
|
|
PANO_IMAGE pAnoImage;
|
|
PIMAGE pImage;
|
|
|
|
int nFileType;
|
|
FIO_INFO_CGBW FioInfoCgbw;
|
|
|
|
WORD wCompressType;
|
|
WORD wCompressInfo1;
|
|
|
|
|
|
CheckError2( Init(hWnd, &pWindow, &pAnoImage, TRUE, TRUE));
|
|
pImage = pAnoImage->pBaseImage;
|
|
|
|
FioInfoCgbw.image_type = pImage->nRWDataType;
|
|
switch (pImage->nRWDataType){
|
|
case ITYPE_BI_LEVEL:
|
|
CheckError( IMGGetImgCodingCgbw(hWnd, BWFORMAT, &wCompressType, &wCompressInfo1, FALSE));
|
|
CheckError( IMGGetFileType(hWnd, BWFORMAT, &nFileType, FALSE));
|
|
break;
|
|
|
|
case ITYPE_GRAY4:
|
|
case ITYPE_GRAY8:
|
|
case ITYPE_GRAY12:
|
|
case ITYPE_GRAY16:
|
|
CheckError( )IMGGetImgCodingCgbw(hWnd, GRAYFORMAT, &wCompressType, &wCompressInfo1, FALSE);
|
|
CheckError( IMGGetFileType(hWnd, GRAYFORMAT, &nFileType, FALSE));
|
|
break;
|
|
case ITYPE_PAL8:
|
|
case ITYPE_COMPAL8:
|
|
case ITYPE_PAL4:
|
|
case ITYPE_CUSPAL8:
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
CheckError( IMGGetImgCodingCgbw(hWnd, COLORFORMAT, &wCompressType, &wCompressInfo1, FALSE));
|
|
CheckError( IMGGetFileType(hWnd, COLORFORMAT, &nFileType, FALSE));
|
|
break;
|
|
|
|
case ITYPE_NONE:
|
|
default:
|
|
nStatus = Error(DISPLAY_IMAGETYPENOTSUPPORTED);
|
|
goto Exit;
|
|
}
|
|
|
|
FioInfoCgbw.compress_type = wCompressType;
|
|
FioInfoCgbw.compress_info1 = wCompressInfo1;
|
|
|
|
CheckError2( IMGSavetoFileCgbw(hWnd, pFileName, nPage, bOWFlag, nFileType, &FioInfoCgbw));
|
|
|
|
|
|
Exit:
|
|
DeInit(TRUE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: IMGSavetoFileCgbw
|
|
|
|
PURPOSE: Saves the displayed image in the specified file and page.
|
|
|
|
INPUT: hWnd - Identifies the image window of the image
|
|
to be saved.
|
|
pFileName - Points to a null-terminated character
|
|
string that names the file to save the image in.
|
|
nPage - Specifies page number to save the image in.
|
|
wOWFlag - Flag is TRUE the file will be overwritten
|
|
if it exist.
|
|
pFioInfoCgbw - A pointer to a structure containing
|
|
certain image info.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI IMGSavetoFileCgbw(HWND hWnd, PSTR pFileName, int nPage,
|
|
BOOL bOWFlag, int nFileType, LP_FIO_INFO_CGBW pFioInfoCgbw){
|
|
|
|
int nStatus;
|
|
|
|
Start();
|
|
|
|
nStatus = SavetoFileCgbwF(hWnd, pFileName, nPage,
|
|
bOWFlag, nFileType, pFioInfoCgbw, 0);
|
|
|
|
End();
|
|
return nStatus;
|
|
}
|
|
#endif
|
|
|
|
// <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
|
|
#ifdef new
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: IMGSaveClienttoFile
|
|
|
|
PURPOSE: Saves the displayed image in the specified file and page.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI IMGSaveClienttoFile(HWND hWnd, LPSAVE_EX_STRUCT pSaveEx,
|
|
int nImageType, int nFlags){
|
|
|
|
int nStatus;
|
|
PWINDOW pWindow;
|
|
PANO_IMAGE pAnoImage;
|
|
PIMAGE pImage;
|
|
|
|
PIMG pTempImg = 0;
|
|
RECT rScreenRect;
|
|
PBITMAPINFOHEADER pDib;
|
|
BOOL bFileOpen = FALSE;
|
|
FIO_INFORMATION FioInfo;
|
|
|
|
|
|
CheckError2( Init(hWnd, &pWindow, &pAnoImage, TRUE, TRUE));
|
|
pImage = pAnoImage->pBaseImage;
|
|
|
|
// Get client rect and convert them to screen coords.
|
|
GetClientRect(hWnd, &rScreenRect);
|
|
ClientToScreen(hWnd, (PPOINT) &rScreenRect.left);
|
|
ClientToScreen(hWnd, (PPOINT) &rScreenRect.right);
|
|
|
|
CheckError2( CopyScreenToDib(hWnd, rScreenRect, nImageType, &pDib, 0));
|
|
CheckError2( DibToIpNoPal(&pTempImg, pDib));
|
|
|
|
bFileOpen = TRUE;
|
|
pSaveEx->FioInfoCgbw.page_opts = pSaveEx->nPageOpts;
|
|
CheckError2( OpenFileForWrite(hWnd, pWindow, pImage, pTempImg, &FioInfo, pSaveEx, nFlags));
|
|
CheckError2( SaveImageToFile(hWnd, pWindow, pImage, pTempImg, &FioInfo, pSaveEx, nFlags));
|
|
|
|
// Set flag FALSE before close to prevent exit code from closing it again.
|
|
bFileOpen = FALSE;
|
|
CheckError2( CloseFileForWrite(hWnd, pImage));
|
|
|
|
|
|
Exit:
|
|
FreeImgBuf(&pTempImg);
|
|
FreeMemory((PPSTR) &pDib);
|
|
if (bFileOpen){
|
|
// Assume bad status if you get here.
|
|
CloseFileForWrite(hWnd, pImage);
|
|
// The file should be cleaned np at filing level, not display
|
|
// IMGFileDeleteFile32(hWnd, pSaveEx->lpFileName);
|
|
}
|
|
DeInit(TRUE, TRUE);
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CopyScreenToDib
|
|
|
|
PURPOSE: Saves the screen as a DIB.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CopyScreenToDib(HWND hWnd, RECT rScreenRect, int nImageType,
|
|
PBITMAPINFOHEADER *ppDib, int nFlags){
|
|
|
|
int nStatus;
|
|
|
|
PBITMAPINFOHEADER pDib = 0;
|
|
HDC hDCScreen = 0;
|
|
HDC hDCMem = 0;
|
|
HBITMAP hBitmap;
|
|
HBITMAP hOldBitmap;
|
|
int nHorzScreenRes;
|
|
int nVertScreenRes;
|
|
int nWidth;
|
|
int nHeight;
|
|
|
|
PSTR pDibImageBits;
|
|
|
|
|
|
if (!(hDCScreen = CreateDC("DISPLAY", NULL, NULL, NULL))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
if (!(hDCMem = CreateCompatibleDC(hDCScreen))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
|
|
nHorzScreenRes = GetDeviceCaps(hDCScreen, HORZRES);
|
|
nVertScreenRes = GetDeviceCaps(hDCScreen, VERTRES);
|
|
|
|
// If empty rectangle, then get full screen.
|
|
if (IsRectEmpty(&rScreenRect)){
|
|
rScreenRect.left = 0;
|
|
rScreenRect.top = 0;
|
|
rScreenRect.right = nHorzScreenRes;
|
|
rScreenRect.bottom= nVertScreenRes;
|
|
}
|
|
|
|
// Make sure bitmap rectangle is visible.
|
|
rScreenRect.left = max(0, rScreenRect.left);
|
|
rScreenRect.top = max(0, rScreenRect.top);
|
|
rScreenRect.right = max(0, min(nHorzScreenRes, rScreenRect.right));
|
|
rScreenRect.bottom = max(0, min(nVertScreenRes, rScreenRect.bottom));
|
|
|
|
nWidth = rScreenRect.right - rScreenRect.left;
|
|
nHeight = rScreenRect.bottom - rScreenRect.top;
|
|
|
|
if (nImageType == ITYPE_BI_LEVEL){
|
|
hBitmap = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
|
|
}else{
|
|
hBitmap = CreateCompatibleBitmap(hDCScreen, nWidth, nHeight);
|
|
}
|
|
|
|
// Select new bitmap into memory DC.
|
|
hOldBitmap = SelectObject(hDCMem, hBitmap);
|
|
|
|
// BitBlt screen DC to memory DC.
|
|
BitBlt(hDCMem, 0, 0, nWidth, nHeight, hDCScreen, rScreenRect.left,
|
|
rScreenRect.top, SRCCOPY);
|
|
|
|
switch (nImageType){
|
|
case ITYPE_BI_LEVEL:
|
|
CheckError2( AllocateMemory(sizeof(BITMAPINFOHEADER)
|
|
+ ((((rScreenRect.right + 31) / 8) & ~3)
|
|
* rScreenRect.bottom), (PPSTR) &pDib, ZERO_INIT));
|
|
pDib->biPlanes = 1;
|
|
pDib->biBitCount = 1;
|
|
pDib->biSizeImage = ((((rScreenRect.right + 31) / 8) & ~3) * rScreenRect.bottom);
|
|
pDibImageBits = (PSTR) pDib + sizeof(BITMAPINFOHEADER);
|
|
break;
|
|
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
CheckError2( AllocateMemory(sizeof(BITMAPINFOHEADER)
|
|
+ ((((rScreenRect.right * 3) + 3) & ~3)
|
|
* rScreenRect.bottom), (PPSTR) &pDib, ZERO_INIT));
|
|
pDib->biPlanes = 1;
|
|
pDib->biBitCount = 24;
|
|
pDib->biSizeImage = ((((rScreenRect.right * 3) + 3) & ~3) * rScreenRect.bottom);
|
|
pDibImageBits = (PSTR) pDib + sizeof(BITMAPINFOHEADER);
|
|
break;
|
|
|
|
case ITYPE_GRAY8:
|
|
case ITYPE_PAL8:
|
|
case ITYPE_CUSPAL8:
|
|
case ITYPE_COMPAL8:
|
|
case ITYPE_GRAY12:
|
|
case ITYPE_GRAY16:
|
|
case ITYPE_PAL4:
|
|
case ITYPE_GRAY4:
|
|
case ITYPE_NONE:
|
|
default:
|
|
nStatus = Error(DISPLAY_IMAGETYPENOTSUPPORTED);
|
|
goto Exit;
|
|
}
|
|
|
|
pDib->biSize = sizeof(BITMAPINFOHEADER);
|
|
(int) pDib->biWidth = rScreenRect.right;
|
|
(int) pDib->biHeight = rScreenRect.bottom;
|
|
pDib->biCompression = BI_RGB;
|
|
pDib->biXPelsPerMeter = 0;
|
|
pDib->biYPelsPerMeter = 0;
|
|
pDib->biClrUsed = 0;
|
|
pDib->biClrImportant = 0;
|
|
|
|
|
|
/* Call GetDIBits with a NON-NULL pBits param, and actually get the
|
|
* bits this time.
|
|
*/
|
|
if (!GetDIBits(hDCMem, hBitmap, 0, (int) pDib->biHeight, pDibImageBits,
|
|
(PBITMAPINFO) pDib, DIB_RGB_COLORS)){
|
|
nStatus = Error(DISPLAY_GETBITMAPBITSFAILED);
|
|
goto Exit;
|
|
}
|
|
|
|
// Save Dib.
|
|
*ppDib = pDib;
|
|
pDib = 0;
|
|
|
|
|
|
Exit:
|
|
if (hDCMem){
|
|
SelectObject(hDCMem, hOldBitmap);
|
|
DeleteDC(hDCMem);
|
|
}
|
|
if (hDCScreen){
|
|
DeleteDC(hDCScreen);
|
|
}
|
|
if (pDib){
|
|
FreeMemory((PPSTR) &pDib);
|
|
*ppDib = NULL;
|
|
}
|
|
|
|
return(nStatus);
|
|
}
|
|
#endif
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: SaveAnnotationsToFile
|
|
|
|
PURPOSE: Saves some or all annotations to a file.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI SaveAnnotationsToFile(HWND hWnd, PWINDOW pWindow, PIMAGE pImage,
|
|
LPSAVE_EX_STRUCT pSaveEx, int nHScale, int nVScale){
|
|
|
|
int nStatus = 0;
|
|
PANO_IMAGE pAnoImage;
|
|
|
|
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_NONE || !pAnoImage->Annotations.nMarks){
|
|
goto Exit;
|
|
}
|
|
|
|
pAnoImage->lAnoStart = 0;
|
|
|
|
CheckError2( SaveAnnotations(hWnd, pWindow, pImage, pSaveEx, nHScale, nVScale));
|
|
CheckError2(FreeMemory((PPSTR) &pAnoImage->hpAnoBlock) );
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: SaveAnnotations
|
|
|
|
PURPOSE: Saves some or all annotations.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI SaveAnnotations(HWND hWnd, PWINDOW pWindow, PIMAGE pImage,
|
|
LPSAVE_EX_STRUCT pSaveEx, int nHScale, int nVScale){
|
|
|
|
int nStatus = 0;
|
|
PANO_IMAGE pAnoImage;
|
|
|
|
int nMarkIndex;
|
|
int nNamedBlockIndex;
|
|
PMARK pMark;
|
|
long lTemp[2];
|
|
|
|
|
|
pAnoImage = pWindow->pDisplay->pAnoImage;
|
|
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_NONE || !pAnoImage->Annotations.nMarks){
|
|
goto Exit;
|
|
}
|
|
|
|
// Save int size.
|
|
lTemp[0] = 1; // 0 = 16 bit Intel, 1 = 32 bit Intel.
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) lTemp));
|
|
|
|
// Save the default mark.
|
|
if ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_ALL){
|
|
// Save the Default mark's named blocks.
|
|
pMark = pAnoImage->Annotations.pDefMark;
|
|
for (nNamedBlockIndex = 0; nNamedBlockIndex < pMark->nNamedBlocks; nNamedBlockIndex++){
|
|
lTemp[0] = SAVE_ANO_DEFAULT_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8,
|
|
(PSTR) pMark->ppNamedBlock[nNamedBlockIndex]->szName));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4,
|
|
(PSTR) &pMark->ppNamedBlock[nNamedBlockIndex]->lSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage,
|
|
pMark->ppNamedBlock[nNamedBlockIndex]->lSize,
|
|
pMark->ppNamedBlock[nNamedBlockIndex]->pBlock));
|
|
}
|
|
if (pMark->pOiAnoDat){
|
|
lTemp[0] = SAVE_ANO_DEFAULT_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiAnoDat));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark->nOiAnoDatSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark->nOiAnoDatSize, pMark->pOiAnoDat));
|
|
|
|
}
|
|
if (pMark->pOiGroup){
|
|
lTemp[0] = SAVE_ANO_DEFAULT_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiGroup));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark->nOiGroupSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark->nOiGroupSize, pMark->pOiGroup));
|
|
|
|
}
|
|
if (pMark->pOiSelect){
|
|
lTemp[0] = SAVE_ANO_DEFAULT_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiSelect));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark->nOiSelectSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark->nOiSelectSize, pMark->pOiSelect));
|
|
|
|
}
|
|
if (pMark->pOiIndex){
|
|
lTemp[0] = SAVE_ANO_DEFAULT_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiIndex));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark->nOiIndexSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark->nOiIndexSize, pMark->pOiIndex));
|
|
}
|
|
}
|
|
|
|
// Save the marks.
|
|
for (nMarkIndex = 0; nMarkIndex < pAnoImage->Annotations.nMarks; nMarkIndex++){
|
|
pMark = pAnoImage->Annotations.ppMarks[nMarkIndex];
|
|
if (((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_VISIBLE && !pMark->Attributes.bVisible)
|
|
|| ((pSaveEx->uAnnotations & 0x0003) == SAVE_ANO_SELECTED
|
|
&& !IsMarkSelected(pWindow, pMark))){
|
|
continue;
|
|
}
|
|
CheckError2( SaveMark(hWnd, pAnoImage, pMark, nHScale, nVScale, pSaveEx->uScaleAlgorithm));
|
|
}
|
|
|
|
CheckError2( BlockedAnoWriteFlushBuffer (hWnd, pAnoImage));
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
//
|
|
/****************************************************************************
|
|
|
|
FUNCTION: SaveMark
|
|
|
|
PURPOSE: Saves an annotation.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI SaveMark(HWND hWnd, PANO_IMAGE pAnoImage, PMARK pMark,
|
|
int nHScale, int nVScale, int nScaleAlgorithm){
|
|
|
|
int nStatus = 0;
|
|
|
|
int nNamedBlockIndex;
|
|
int nDestNamedBlockIndex = 0;
|
|
PMARK pMark2 = 0;
|
|
|
|
long lTemp[2];
|
|
PSTR pTemp;
|
|
PAN_NEW_ROTATE_STRUCT pAnRotation=0;
|
|
BOOL bClipboardOp = 0;
|
|
BOOL bScale;
|
|
|
|
if (nHScale == 1000 && nVScale == 1000){
|
|
bScale = FALSE;
|
|
}
|
|
else{
|
|
bScale = TRUE;
|
|
}
|
|
|
|
CheckError2( GetAMarkNamedBlock(pMark, szOiAnoDat, (PPSTR) &pAnRotation));
|
|
if (pAnRotation){
|
|
bClipboardOp = pAnRotation->bClipboardOp;
|
|
}
|
|
// Make a temporary copy of the mark.
|
|
CheckError2( AllocateMemory(sizeof(MARK), (PPSTR) &pMark2, ZERO_INIT));
|
|
pMark2->bSelected = pMark->bSelected;
|
|
memcpy(&pMark2->Attributes, &pMark->Attributes, sizeof(OIAN_MARK_ATTRIBUTES));
|
|
|
|
for (nNamedBlockIndex = 0; nNamedBlockIndex < pMark->nNamedBlocks; nNamedBlockIndex++){
|
|
if (((int) pMark->Attributes.uType == OIOP_AN_IMAGE_BY_REFERENCE
|
|
|| (int) pMark->Attributes.uType == OIOP_AN_FORM)){
|
|
if (!memcmp(pMark->ppNamedBlock[nNamedBlockIndex]->szName, szOiDIB, 8)){
|
|
continue;
|
|
}
|
|
}
|
|
if (!bClipboardOp){
|
|
if (!memcmp(pMark->ppNamedBlock[nNamedBlockIndex]->szName, szOiZ, 3)){
|
|
continue;
|
|
}
|
|
}
|
|
if (!memcmp(pMark->ppNamedBlock[nNamedBlockIndex]->szName, szOiz, 3)){
|
|
continue;
|
|
}
|
|
memcpy(&Buff1, pMark->ppNamedBlock[nNamedBlockIndex]->szName, 8);
|
|
pTemp = 0;
|
|
CheckError2( AddAMarkNamedBlock(pMark2, Buff1,
|
|
(PPSTR) &pTemp, pMark->ppNamedBlock[nNamedBlockIndex]->lSize));
|
|
memcpy(pMark2->ppNamedBlock[nDestNamedBlockIndex]->pBlock,
|
|
pMark->ppNamedBlock[nNamedBlockIndex]->pBlock,
|
|
pMark->ppNamedBlock[nNamedBlockIndex]->lSize);
|
|
nDestNamedBlockIndex++;
|
|
}
|
|
if (pMark->pOiAnoDat){
|
|
CheckError2( AllocateMemory(pMark->nOiAnoDatSize, (PPSTR) &pMark2->pOiAnoDat, ZERO_INIT));
|
|
memcpy(pMark2->pOiAnoDat, pMark->pOiAnoDat, pMark->nOiAnoDatSize);
|
|
pMark2->nOiAnoDatSize = pMark->nOiAnoDatSize;
|
|
}
|
|
if (pMark->pOiGroup){
|
|
CheckError2( AllocateMemory(pMark->nOiGroupSize, (PPSTR) &pMark2->pOiGroup, ZERO_INIT));
|
|
memcpy(pMark2->pOiGroup, pMark->pOiGroup, pMark->nOiGroupSize);
|
|
pMark2->nOiGroupSize = pMark->nOiGroupSize;
|
|
}
|
|
if (pMark->pOiSelect){
|
|
CheckError2( AllocateMemory(pMark->nOiSelectSize, (PPSTR) &pMark2->pOiSelect, ZERO_INIT));
|
|
memcpy(pMark2->pOiSelect, pMark->pOiSelect, pMark->nOiSelectSize);
|
|
pMark2->nOiSelectSize = pMark->nOiSelectSize;
|
|
}
|
|
if (pMark->pOiIndex){
|
|
CheckError2( AllocateMemory(pMark->nOiIndexSize, (PPSTR) &pMark2->pOiIndex, ZERO_INIT));
|
|
memcpy(pMark2->pOiIndex, pMark->pOiIndex, pMark->nOiIndexSize);
|
|
pMark2->nOiIndexSize = pMark->nOiIndexSize;
|
|
}
|
|
|
|
if (bScale){
|
|
CheckError2( ScaleAnnotation(hWnd, pMark2, nHScale, nVScale, nScaleAlgorithm));
|
|
}
|
|
|
|
if (!pMark2->Attributes.Time){
|
|
pMark2->Attributes.Time = time(NULL);
|
|
}
|
|
|
|
// Save the mark's attributes.
|
|
lTemp[0] = SAVE_ANO_MARK_ATTRIBUTES;
|
|
lTemp[1] = sizeof(OIAN_MARK_ATTRIBUTES);
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, lTemp[1], (PSTR) &pMark2->Attributes));
|
|
|
|
// Save the mark's named blocks.
|
|
for (nNamedBlockIndex = 0; nNamedBlockIndex <
|
|
pMark2->nNamedBlocks; nNamedBlockIndex++){
|
|
if ((pMark2->Attributes.uType == OIOP_AN_IMAGE_BY_REFERENCE
|
|
|| (int) pMark->Attributes.uType == OIOP_AN_FORM)
|
|
&& !memcmp(pMark2->ppNamedBlock[nNamedBlockIndex]->szName,
|
|
szOiDIB, 8)){
|
|
continue;
|
|
}
|
|
lTemp[0] = SAVE_ANO_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8,
|
|
(PSTR) pMark2->ppNamedBlock[nNamedBlockIndex]->szName));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4,
|
|
(PSTR) &pMark2->ppNamedBlock[nNamedBlockIndex]->lSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage,
|
|
pMark2->ppNamedBlock[nNamedBlockIndex]->lSize,
|
|
pMark2->ppNamedBlock[nNamedBlockIndex]->pBlock));
|
|
}
|
|
|
|
// save the pointer data as named blocks
|
|
if (pMark2->pOiAnoDat){
|
|
lTemp[0] = SAVE_ANO_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiAnoDat));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark2->nOiAnoDatSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark2->nOiAnoDatSize, pMark2->pOiAnoDat));
|
|
}
|
|
|
|
if (pMark2->pOiGroup){
|
|
lTemp[0] = SAVE_ANO_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiGroup));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark2->nOiGroupSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark2->nOiGroupSize, pMark2->pOiGroup));
|
|
}
|
|
|
|
if (pMark2->pOiSelect){
|
|
lTemp[0] = SAVE_ANO_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiSelect));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark2->nOiSelectSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark2->nOiSelectSize, pMark2->pOiSelect));
|
|
}
|
|
|
|
if (pMark2->pOiIndex){
|
|
lTemp[0] = SAVE_ANO_MARK_NAMED_BLOCK;
|
|
lTemp[1] = 12;
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, (PSTR) lTemp));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 8, szOiIndex));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, 4, (PSTR) &pMark2->nOiIndexSize));
|
|
CheckError2( BlockedAnoWrite(hWnd, pAnoImage, pMark2->nOiIndexSize, pMark2->pOiIndex));
|
|
}
|
|
|
|
Exit:
|
|
if (pMark2){
|
|
// Delete the temporary copy of the mark.
|
|
if (pMark2->ppNamedBlock){
|
|
while(pMark2->ppNamedBlock){
|
|
DeleteAMarkNamedBlock(pMark2, pMark2->ppNamedBlock[0]->szName);
|
|
}
|
|
}
|
|
FreeMemory((PPSTR) &pMark2);
|
|
}
|
|
return(nStatus);
|
|
}
|