Windows NT 4.0 source code leak
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

/****************************************************************************
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);
}