Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
source/fileCache.c
/****************************************************/ |
/* */ |
/* File: fileCache.c */ |
/* */ |
/* Program: Imageer */ |
/* */ |
/* By: Jason Hodges-Harris */ |
/* */ |
/* Created: 12/01/95 00:00:00 AM */ |
/* */ |
/* Version: 1.0.0d3 */ |
/* */ |
/* Copyright: © 1995-96 Apple Computer, Inc., */ |
/* all rights reserved. */ |
/* */ |
/****************************************************/ |
/**** Macintosh Toolbox Headers *****/ |
#ifndef __FILES__ |
#include <Files.h> |
#endif |
#ifndef __FOLDERS__ |
#include <Folders.h> |
#endif |
#ifndef __SCRIPT__ |
#include <Script.h> |
#endif |
#ifndef __STANDARDFILE__ |
#include <StandardFile.h> |
#endif |
#ifndef __STRING__ |
#include <string.h> |
#endif |
#ifndef __STRINGS__ |
#include <Strings.h> |
#endif |
#ifndef __TEXTUTILS__ |
#include <TextUtils.h> |
#endif |
#ifndef __TYPES__ |
#include <Types.h> |
#endif |
/**** Application headers and prototypes ****/ |
#ifndef __IMAGEERAPPHEADER__ |
#include "Imageer.app.h" |
#endif |
#ifndef __IMAGEERPROTOSHEADER__ |
#include "Imageer.protos.h" |
#endif |
/**** Global variables ****/ |
extern long gTempFolderDirID, |
gTempFileCount; |
extern short gTempFolderVolRef; |
/**** Test to find if temporary folder exists ****/ |
// function tests for existence of the Temporary Folder inside the System Folder |
// and creates folder if not present |
#pragma segment imageCache |
OSErr FindTempFolder(void) |
{ |
OSErr error = noErr; |
Boolean tempExists = false; |
error = FindFolder(kOnSystemDisk, kTemporaryFolderType, |
kCreateFolder,&gTempFolderVolRef, |
&gTempFolderDirID); |
if (error) |
DisplayAlert (rGenWarning,rFileIOMessages,iCreateTempFldrErr); |
return error; |
} |
/**** Remove image docs temporary files ****/ |
// Delete temp file(s) specified in boolean input parameters |
// used to hold Color QD cache information for undo/redo |
#pragma segment imageCache |
OSErr RemoveTempFile(ImageDocHndl theDocHndl, Boolean delUndoFile, Boolean delRedoFile) |
{ |
OSErr error = noErr; |
HLock((Handle)theDocHndl); |
if (delUndoFile) |
{ |
error = FSpDelete(&(*theDocHndl)->theTempUndoFileSpec); |
(*theDocHndl)->hasUndoTemp = false; |
} |
if (delRedoFile) |
{ |
error |= FSpDelete(&(*theDocHndl)->theTempRedoFileSpec); |
(*theDocHndl)->hasRedoTemp = false; |
} |
HUnlock((Handle)theDocHndl); |
error = noErr; // currently ignore error checking |
if (error) |
DisplayAlert (rGenWarning,rFileIOMessages,iDeleteTempFileErr); |
return error; |
} |
/**** Save temporary Undo file ****/ |
// save cache file information from current image window prior |
// to image manipulation after removing previous obselete temporary file(s). |
#pragma segment imageCache |
OSErr SaveTempImageFile(ImageDocHndl theDocHndl, short tempFileOp) |
{ |
Str255 theMenuString, |
theResString; |
OSErr error = noErr; |
Boolean isRedoTempFile = false; |
(*theDocHndl)->theLastAction = tempFileOp; |
GetMenuItemText(GetMHandle(mEdit),iUndo,theMenuString); |
GetIndString (theResString,rMenuItems,iOpRedo); |
if (EqualString(theMenuString,theResString,true,true)) |
isRedoTempFile = true; |
if (!isRedoTempFile) |
RemoveTempFile(theDocHndl, true, true); |
else |
RemoveTempFile(theDocHndl, false, true); |
switch (tempFileOp) |
{ |
case kPixMapOp: |
error = SavePixMaptoTemp(theDocHndl, isRedoTempFile); |
if (error) |
{ |
(*theDocHndl)->theUndoState = kCannotUndo; |
DebugStr("\pError saving image PixMap to temp file."); |
} |
break; |
case kColorTableOp: |
error = SaveCTabtoTemp(theDocHndl, isRedoTempFile); |
if (error) |
{ |
(*theDocHndl)->theUndoState = kCannotUndo; |
DebugStr("\pError saving image colorTable to temp file."); |
} |
break; |
case kGXTransformOp: |
break; |
} |
SetUndoItemText((*theDocHndl)->theUndoState); |
return error; |
} |
/**** Load temporary file ****/ |
// Retrieve stored temporary file information and use to revert offscreen image to old state |
#pragma segment imageCache |
OSErr LoadTempImageFile(ImageDocHndl theDocHndl) |
{ |
Str255 theMenuString, |
theResString; |
OSErr error = noErr; |
short tempFileOpType = (*theDocHndl)->theLastAction; |
Boolean isRedoTempFile = false; |
(*theDocHndl)->theLastAction = tempFileOpType; |
GetMenuItemText(GetMHandle(mEdit),iUndo,theMenuString); |
GetIndString (theResString,rMenuItems,iOpRedo); |
if (EqualString(theMenuString,theResString,true,true)) |
isRedoTempFile = true; |
switch (tempFileOpType) |
{ |
case kPixMapOp: |
if (!isRedoTempFile) |
error = SavePixMaptoTemp(theDocHndl, true); |
error |= LoadTemptoPixMap(theDocHndl, isRedoTempFile); |
if (error) |
DebugStr("\pError loading image PixMap from temp file."); |
break; |
case kColorTableOp: |
if (!isRedoTempFile) |
error = SaveCTabtoTemp(theDocHndl, true); |
error |= LoadTemptoCTab(theDocHndl, isRedoTempFile); |
if (error) |
DebugStr("\pError loading image color table from temp file."); |
break; |
case kGXTransformOp: |
break; |
} |
if (isRedoTempFile) |
(*theDocHndl)->theUndoState = kCanUndo; |
SetUndoItemText((*theDocHndl)->theUndoState); |
return error; |
} |
/**** Save Pixmap Data to temporary file ****/ |
// Store locked down offscreen GWorld Pixmap in temp file for undo/redo operation |
#pragma segment imageCache |
OSErr SavePixMaptoTemp(ImageDocHndl theDocHndl, Boolean isRedoFile) |
{ |
PixMapHandle thePixMapHndl = nil; |
Ptr pixMapData; |
long width, |
height, |
fileSize, |
diskSpace, |
count; |
Str63 tempFileName, |
fileNumStr; |
short fileRefNum, |
theVolRef; |
OSErr error = noErr; |
thePixMapHndl = GetGWorldPixMap((**theDocHndl).theImageWorld); |
if (PixMap32Bit(thePixMapHndl)) |
SaveSetMMUMode(true); |
if (!LockPixels(thePixMapHndl)) |
error = kFailedLockPixels; |
if (!error) |
{ |
width = (**thePixMapHndl).rowBytes & 0x3FFF; |
height = (**theDocHndl).theImageYSize; |
fileSize = width*height; |
error = GetVInfo(gTempFolderVolRef, 0,&theVolRef, &diskSpace); |
if (error) |
{ |
DebugStr("\pCouldn't get information for Temporory folder volume."); |
return kDefaultAppError; |
} |
// Test for adequate space on hard disk to save file information. |
// Display warning dialog and return without saving data if disk is full |
if (fileSize > diskSpace) |
{ |
DisplayAlert (rGenWarning,rFileIOMessages,iDiskFullErr); |
return kDefaultAppError; |
} |
pixMapData = GetPixBaseAddr(thePixMapHndl); |
if (isRedoFile) |
{ |
(*theDocHndl)->theTempRedoFileSpec.vRefNum = gTempFolderVolRef; |
(*theDocHndl)->theTempRedoFileSpec.parID = gTempFolderDirID; |
(*theDocHndl)->hasRedoTemp = true; |
(*theDocHndl)->theUndoState = kCanRedo; |
} |
else |
{ |
(*theDocHndl)->theTempUndoFileSpec.vRefNum = gTempFolderVolRef; |
(*theDocHndl)->theTempUndoFileSpec.parID = gTempFolderDirID; |
(*theDocHndl)->hasUndoTemp = true; |
(*theDocHndl)->theUndoState = kCanUndo; |
} |
// Create new temporary file name |
// using an incremental number appended to filename to keep unique. |
strcpy((char*)tempFileName,(char*)"\pTempFile"); |
NumToString(gTempFileCount,fileNumStr); |
gTempFileCount++; |
p2cstr(tempFileName); |
p2cstr(fileNumStr); |
strcat((char*)tempFileName,(char *)fileNumStr); |
c2pstr((char*)tempFileName); |
// Save undo/redo file after first creating and opening new file. |
if (!isRedoFile) |
{ |
strcpy((char*)(*theDocHndl)->theTempUndoFileSpec.name,(char*)tempFileName); |
error = FSpCreate(&(*theDocHndl)->theTempUndoFileSpec, |
(OSType)AppCreator, 'Imtp', smSystemScript); |
if (!error) |
error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum); |
} |
else |
{ |
strcpy((char*)(*theDocHndl)->theTempRedoFileSpec.name,(char*)tempFileName); |
error = FSpCreate(&(*theDocHndl)->theTempRedoFileSpec, |
(OSType)AppCreator, 'Imtp', smSystemScript); |
if (!error) |
error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum); |
} |
if (!error) |
{ |
for (count = 0;count < height;count++) |
{ |
error = FSWrite(fileRefNum,&width,pixMapData); |
if (error) |
DebugStr("\pError Writing Pixmap to Temp File."); |
pixMapData+=width; |
} |
error = FSClose(fileRefNum); |
} |
UnlockPixels(thePixMapHndl); |
} |
SaveSetMMUMode(false); |
return error; |
} |
/**** Load Pixmap Data from temp file ****/ |
// Retrieve temporary file. Locking down the Offscreen Pixmap, |
// before reading in the data directly. |
#pragma segment imageCache |
OSErr LoadTemptoPixMap(ImageDocHndl theDocHndl, Boolean isRedoFile) |
{ |
PixMapHandle thePixMapHndl = nil; |
Ptr pixMapData; |
long width, |
height, |
count; |
short fileRefNum; |
OSErr error = noErr; |
thePixMapHndl = GetGWorldPixMap((**theDocHndl).theImageWorld); |
if (PixMap32Bit(thePixMapHndl)) |
SaveSetMMUMode(true); |
if (!LockPixels(thePixMapHndl)) |
error = kFailedLockPixels; |
if (!error) |
{ |
width = (**thePixMapHndl).rowBytes & 0x3FFF; |
height = (**theDocHndl).theImageYSize; |
pixMapData = GetPixBaseAddr(thePixMapHndl); // base addr of GWorld |
if (isRedoFile) |
error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum); |
else |
error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum); |
if (!error) |
{ |
for (count = 0;count < height;count++) |
{ |
FSRead(fileRefNum,&width,pixMapData); |
pixMapData+=width; |
} |
error = FSClose(fileRefNum); |
} |
UnlockPixels(thePixMapHndl); |
} |
SaveSetMMUMode(false); |
return error; |
} |
/**** Save Color QuickDraw color table to temp file ****/ |
// For indexed Color QuickDraw images, the color table |
// information of the offscreen copy of the image is saved. |
// The Color Table's handle is locked down, size determined, |
// a new file created and the contents written out |
// with a unique name if no error is reported. |
#pragma segment imageCache |
OSErr SaveCTabtoTemp(ImageDocHndl theDocHndl, Boolean isRedoFile) |
{ |
CTabHandle cTabHndl; |
long fileSize, |
diskSpace; |
short fileRefNum, |
theVolRef; |
OSErr error = noErr; |
Str63 tempFileName, |
fileNumStr; |
HLock((Handle)(*(*theDocHndl)->theImageWorld->portPixMap)->pmTable); |
cTabHndl = (*(*theDocHndl)->theImageWorld->portPixMap)->pmTable; |
fileSize = GetHandleSize((Handle)cTabHndl); |
error = GetVInfo(gTempFolderVolRef, 0,&theVolRef, &diskSpace); |
if (error) |
{ |
DebugStr("\pCouldn't get information for Temporory folder volume."); |
return kDefaultAppError; |
} |
if (fileSize > diskSpace) |
{ |
DisplayAlert (rGenWarning,rFileIOMessages,iDiskFullErr); |
return kDefaultAppError; |
} |
if (isRedoFile) |
{ |
(*theDocHndl)->theTempRedoFileSpec.vRefNum = gTempFolderVolRef; |
(*theDocHndl)->theTempRedoFileSpec.parID = gTempFolderDirID; |
(*theDocHndl)->hasRedoTemp = true; |
(*theDocHndl)->theUndoState = kCanRedo; |
} |
else |
{ |
(*theDocHndl)->theTempUndoFileSpec.vRefNum = gTempFolderVolRef; |
(*theDocHndl)->theTempUndoFileSpec.parID = gTempFolderDirID; |
(*theDocHndl)->hasUndoTemp = true; |
(*theDocHndl)->theUndoState = kCanUndo; |
} |
strcpy((char*)tempFileName,(char*)"\pTempFile"); |
NumToString(gTempFileCount,fileNumStr); |
gTempFileCount++; |
p2cstr(tempFileName); |
p2cstr(fileNumStr); |
strcat((char*)tempFileName,(char *)fileNumStr); |
c2pstr((char*)tempFileName); |
if (isRedoFile) |
{ |
strcpy((char*)(*theDocHndl)->theTempRedoFileSpec.name,(char*)tempFileName); |
error = FSpCreate(&(*theDocHndl)->theTempRedoFileSpec, |
(OSType)AppCreator, 'Imtp', smSystemScript); |
if (!error) |
error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum); |
if (!error) |
{ |
FSWrite(fileRefNum,&fileSize,(*cTabHndl)); |
error = FSClose(fileRefNum); |
} |
} |
else |
{ |
strcpy((char*)(*theDocHndl)->theTempUndoFileSpec.name,(char*)tempFileName); |
error = FSpCreate(&(*theDocHndl)->theTempUndoFileSpec, |
(OSType)AppCreator, 'Imtp', smSystemScript); |
if (!error) |
error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum); |
if (!error) |
{ |
error = FSWrite(fileRefNum,&fileSize,*cTabHndl); |
if (error) |
DebugStr("\pError Writing Pixmap to Temp File."); |
error = FSClose(fileRefNum); |
} |
} |
HUnlock((Handle)cTabHndl); |
return error; |
} |
/**** Load temporary file to Color QuickDraw color table ****/ |
// Load the saved color table cache file into the locked down |
// handle of a Color QD image's offscreen ColorTable handle |
// structure and force the Color Manager to recalculate the Color Table. |
#pragma segment imageCache |
OSErr LoadTemptoCTab(ImageDocHndl theDocHndl, Boolean isRedoFile) |
{ |
CTabHandle cTabHndl; |
long fileSize; |
short fileRefNum; |
OSErr error = noErr; |
HLock((Handle)(*(*theDocHndl)->theImageWorld->portPixMap)->pmTable); |
cTabHndl = (*(*theDocHndl)->theImageWorld->portPixMap)->pmTable; |
fileSize = GetHandleSize((Handle)cTabHndl); |
if (isRedoFile) |
error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum); |
else |
error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum); |
if (!error) |
{ |
FSRead(fileRefNum,&fileSize,(*cTabHndl)); |
error = FSClose(fileRefNum); |
} |
CTabChanged(cTabHndl); |
HUnlock((Handle)cTabHndl); |
return error; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14