JPEGView/Source/C/PICT.c
Aaron Giles 92bdb55672 JPEGView 3.3 for Macintosh
These are the sources for the final official release of JPEGView for the
Mac, back in 1994.
2015-02-05 00:18:10 -08:00

1 line
28 KiB
C

/*********************************************************/
/* This source code copyright (c) 1991-2001, Aaron Giles */
/* See the Read Me file for licensing information. */
/* Contact email: mac@aarongiles.com */
/*********************************************************/
#if THINK_C
#include "THINK.Header"
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif
typedef struct PICTPrivates {
Rect qdRect;
long totalLines;
} PICTPrivates, *PICTPrivatesPtr, **PICTPrivatesHandle;
/*
* Local variables:
* lPICTImage = pointer to the image for use when extracting PICT information
* lPICTPreview = handle to the preview image, if one was requested for saving
*
*/
static Handle gPICTComments;
static Rect gPICTSrcRect, gPICTDstRect;
static ImageHandle gPICTImage;
static JVDrawParamsHandle gPICTParams;
static long gTotalLines, gCurrentLines;
static Boolean gHasObjects;
static StdPixUPP gProgressPixProc = nil, gAddColorsPixProc, gInitPixProc;
static QDBitsUPP gDummyBitsProc, gInitBitsProc;
static QDTextUPP gDummyTextProc, gInitTextProc;
static QDLineUPP gDummyLineProc, gInitLineProc;
static QDRectUPP gDummyRectProc, gInitRectProc;
static QDRRectUPP gDummyRRectProc, gInitRRectProc;
static QDOvalUPP gDummyOvalProc, gInitOvalProc;
static QDArcUPP gDummyArcProc, gInitArcProc;
static QDPolyUPP gDummyPolyProc, gInitPolyProc;
static QDRgnUPP gDummyRgnProc, gInitRgnProc;
static void InitPICTUPPs(void);
static pascal void ProgressPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
RgnHandle mask, PixMap *matte, Rect *matteRect, short flags);
static pascal void AddColorsPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
RgnHandle mask, PixMap *matte, Rect *matteRect, short flags);
static pascal void InitPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
RgnHandle mask, PixMap *matte, Rect *matteRect, short callOldBits);
static pascal void InitBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
RgnHandle mask);
static pascal void InitTextProc(short count, const void *textAddr, Point numer, Point denom);
static pascal void InitLineProc(Point newPt);
static pascal void InitRectProc(GrafVerb verb, const Rect *r);
static pascal void InitRRectProc(GrafVerb verb, const Rect *r, short ovalWidth,
short ovalHeight);
static pascal void InitOvalProc(GrafVerb verb, const Rect *r);
static pascal void InitArcProc(GrafVerb verb, const Rect *r, short startAngle, short arcAngle);
static pascal void InitPolyProc(GrafVerb verb, PolyHandle poly);
static pascal void InitRgnProc(GrafVerb verb, RgnHandle rgn);
static pascal void DummyBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
RgnHandle mask);
static pascal void DummyTextProc(short count, const void *textAddr, Point numer, Point denom);
static pascal void DummyLineProc(Point newPt);
static pascal void DummyRectProc(GrafVerb verb, const Rect *r);
static pascal void DummyRRectProc(GrafVerb verb, const Rect *r, short ovalWidth,
short ovalHeight);
static pascal void DummyOvalProc(GrafVerb verb, const Rect *r);
static pascal void DummyArcProc(GrafVerb verb, const Rect *r, short startAngle, short arcAngle);
static pascal void DummyPolyProc(GrafVerb verb, PolyHandle poly);
static pascal void DummyRgnProc(GrafVerb verb, RgnHandle rgn);
/*
* idPICT(theData, theSize)
*
* Purpose: Attempts to identify an image as a PICT
* Inputs: theData = pointer to the loaded data
* theSize = size of the loaded data
* Returns: true for a positive PICT ID
*
*/
Boolean idPICT(uchar *theData, long theSize, short refNum, FSSpec *theSpec)
{
#if applec
#pragma unused(refNum, theSpec)
#endif
ushort *theShort = (ushort *)(theData + kHeaderSize + 10);
PicPtr thePicture = (PicPtr)(theData + kHeaderSize);
if (theSize < kHeaderSize + 12) return false;
if (Width(&thePicture->picFrame) > 0 && Height(&thePicture->picFrame) > 0) {
while (!*theShort) theShort++;
if (*theShort == 0x0011 || *theShort == 0x1101) return true;
}
return false;
}
/*
* OpenPICT(theImage)
*
* Purpose: Initializes the image record for a PICT image
* Inputs: theImage = image record for the PICT image
* Returns: nothing
*
*/
OSErr OpenPICT(ImageHandle theImage)
{
Fixed hRes = 0x480000L, vRes = 0x480000L;
Rect *theRect, fullQRect;
OSErr theErr = noErr;
ushort *theShort;
uchar *theData;
Str63 theDesc;
if (!((*theImage)->privateData = NewHandleClear(sizeof(PICTPrivates))))
return memFullErr;
theData = (uchar *)*(*theImage)->data;
theShort = (ushort *)(theData + 10);
theRect = (Rect *)(theData + 2);
(*(PICTPrivatesHandle)(*theImage)->privateData)->qdRect = (*theImage)->qrect = *theRect;
while (!*theShort) theShort++;
if (*theShort == 0x0011 && theShort[2] == 0x0c00 && theShort[3] == 0xfffe) {
theRect = (Rect *)(theShort + 9);
hRes = *(long *)(theShort + 5);
vRes = *(long *)(theShort + 7);
}
(*theImage)->grect = *theRect;
if (Width(&(*theImage)->grect) <= 0 || Height(&(*theImage)->grect) <= 0 ||
Width(&(*theImage)->qrect) <= 0 || Height(&(*theImage)->qrect) <= 0)
return gIntError = errCorruptImage, codecBadDataErr;
GetImageInfo(theImage);
fullQRect = (*theImage)->grect;
fullQRect.left = Fix2Long(FixMul(FixDiv(0x480000L, hRes), Long2Fix(fullQRect.left)));
fullQRect.right = Fix2Long(FixMul(FixDiv(0x480000L, hRes), Long2Fix(fullQRect.right)));
fullQRect.top = Fix2Long(FixMul(FixDiv(0x480000L, vRes), Long2Fix(fullQRect.top)));
fullQRect.bottom = Fix2Long(FixMul(FixDiv(0x480000L, vRes), Long2Fix(fullQRect.bottom)));
(*theImage)->crect = (*theImage)->qrect;
MapRect(&(*theImage)->crect, &fullQRect, &(*theImage)->grect);
(*theImage)->compression = (*theImage)->desc.cType;
if ((*theImage)->desc.height)
if (Height(&(*theImage)->crect) > (*theImage)->desc.height)
(*theImage)->flags |= ifBanded;
if ((*theImage)->crect.right < ((*theImage)->grect.right - 5) ||
(*theImage)->crect.left > ((*theImage)->grect.left + 5) ||
(*theImage)->crect.bottom < ((*theImage)->grect.bottom - 5) ||
(*theImage)->crect.top > ((*theImage)->grect.top + 5))
(*theImage)->flags |= ifCropped;
/* if ((*theImage)->compression == kJPEGCompression && !gHasObjects) {
if (Height(&(*theImage)->crect) > (*theImage)->desc.height)
(*theImage)->flags |= ifBanded;
if ((Width(&(*theImage)->crect) < (*theImage)->desc.width) ||
(Height(&(*theImage)->crect) < (*theImage)->desc.height))
(*theImage)->flags |= ifCropped;
}*/
/*
Old mechanism for detecting cropping vs. scaled DPI
//--- deal with cropped images??
if ((*theData)->compressionType == 'jpeg' && !gHasObjects) {
if (Height(&(*theImage)->crect) > (*theImage)->desc.height)
(*theImage)->flags |= ifBanded;
if ((Width(&(*theImage)->crect) < (*theImage)->desc.width) ||
(Height(&(*theImage)->crect) < (*theImage)->desc.height))
(*theImage)->flags |= ifCropped;
if (Cropped(theImage) && !Banded(theImage)) {
Rect crect = (*theImage)->crect, grect;
MySetRect(&grect, 0, 0, (*theImage)->desc.width, (*theImage)->desc.height);
MapRect(&crect, &(*theImage)->grect, &(*theImage)->qrect);
MapRect(&crect, &lPICTDstRect, &lPICTSrcRect);
if (crect.right > grect.right) crect.right = grect.right;
if (crect.left < grect.left) crect.left = grect.left;
if (crect.bottom > grect.bottom) crect.bottom = grect.bottom;
if (crect.top < grect.top) crect.top = grect.top;
(*theImage)->grect = grect;
theErr = DoSetImageBounds(theImage, &grect);
(*theImage)->crect = crect;
if (EqualSizeRect(&crect, &grect)) (*theImage)->flags &= ~ifCropped;
}
}
*/
if (!(*theImage)->ipalette &&
((*theImage)->depth == 36 || (*theImage)->depth == 40)) {
(*theImage)->ipalette = NewPalette(1L << ((*theImage)->depth - 32), nil, pmTolerant, 0);
if ((*theImage)->ipalette)
CopyPalette(GreyPalette((*theImage)->depth - 32), (*theImage)->ipalette, 0, 0, 256);
}
if ((*theImage)->compression == 'raw ') (*theImage)->compression = 0L;
if ((*theImage)->compression) {
BlockMove((*theImage)->desc.name, theDesc, *(*theImage)->desc.name + 1);
AddString(theDesc, gString[strQuality]);
StuffNumber(theDesc, 1, (*theImage)->desc.spatialQuality >> 8);
StuffNumber0(theDesc, 2, (((*theImage)->desc.spatialQuality & 0xff) * 100) >> 8, 2);
} else BlockMove(gString[strUncompressed], theDesc, *gString[strUncompressed] + 1);
BlockMove(theDesc, (*theImage)->compressionDesc, *theDesc + 1);
return theErr;
}
/*
* DrawPICT(theImage, theGWorld, srcRect, dstRect, dither, progProc)
*
* Purpose: Draws the PICT image within its cropping rectange in the proper window
* Inputs: theImage = image record for the PICT image
* theGWorld = the destination GWorld to draw into
* srcRect = the source rectangle
* dstRect = the destination rectangle
* dstRgn = the destination clipping region
* dither = flag: true if we should dither this guy
* progProc = the progress procedure record to be used
* Returns: nothing
*
*/
OSErr DrawPICT(Handle theHandle, JVDrawParamsHandle theParams)
{
Rect globRect = (*theParams)->bounds;
char hState = HGetState(theHandle);
OSErr theErr;
if (!gProgressPixProc) InitPICTUPPs();
((CGrafPtr)qd.thePort)->grafProcs->newProc1 = (UniversalProcPtr)gProgressPixProc;
gPICTParams = theParams;
gTotalLines = (*(PICTPrivatesHandle)(*theParams)->privateData)->totalLines;
gCurrentLines = 0;
PushPort();
ClipRect(&globRect);
RGBForeColor(&gBlack);
RGBBackColor(&gWhite);
HLock(theHandle);
KeepSpinning();
if (gQTVersion) theErr = DrawTrimmedPicture((PicHandle)theHandle, &globRect,
qd.thePort->visRgn, false, nil);
else DrawPicture((PicHandle)theHandle, &globRect), theErr = noErr;
if ((*theParams)->progress.aborted) theErr = codecAbortErr;
KeepSpinning();
HSetState(theHandle, hState);
PopPort();
return theErr;
}
/*
* ProgressPixProc(src, srcRect, matrix, mode, mask, matte, matteRect, callOldBits)
*
* Purpose: Routine called when a compressed PixMap is found in a PICT; we
* intercept it and call FDecompressImage, making the progress updates
* work to some extent....
* Inputs: src = the compressed PixMap
* srcRect = the rectangle of the image in the source coordinates
* matrix = the transformation matrix
* mode = the drawing mode
* mask = the output masking region
* matte = the output matte, described as a PixMap
* matteRect = the bounding rectangle for the output matte
* callOldBits = flag saying if we should call the old routine
* Returns: nothing
*
*/
pascal void ProgressPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
RgnHandle mask, PixMap *matte, Rect *matteRect, short flags)
{
PixMapHandle dst = GetGWorldPixMap((CGrafPtr)qd.thePort);
NestedProgress theProc = (*gPICTParams)->progress;
ImageDescriptionHandle theDesc;
ICMProgressProcRecord progProc;
ICMDataProcRecord dataProc;
OSErr theErr;
long bufSize;
Ptr theData;
if ((*gPICTParams)->progress.aborted || ((*gPICTParams)->progress.aborted = CheckAbort(gPICTParams)))
return;
theErr = GetCompressedPixMapInfo(src, &theDesc, &theData, &bufSize, &dataProc,
&progProc);
if (theErr == noErr) {
KeepSpinning();
(*gPICTParams)->progress.begin = FixRatio(gCurrentLines, gTotalLines);
(*gPICTParams)->progress.begin = theProc.begin +
FixMul((*gPICTParams)->progress.begin, theProc.end - theProc.begin);
(*gPICTParams)->progress.end = FixRatio(gCurrentLines + Height(srcRect), gTotalLines);
(*gPICTParams)->progress.end = theProc.begin +
FixMul((*gPICTParams)->progress.end, theProc.end - theProc.begin);
if ((*gPICTParams)->progress.prog.progressProc)
CallICMProgressProc((*gPICTParams)->progress.prog.progressProc,
codecProgressUpdatePercent, 0x00000000L,
(*gPICTParams)->progress.prog.progressRefCon);
FixBits((CGrafPtr)qd.thePort, true);
InstallQDxDispatchPatch(true);
FDecompressImage(StripAddress(theData), theDesc, dst, srcRect, matrix, mode,
mask, &matte, matteRect, codecHighQuality, anyCodec, bufSize, &dataProc,
(ICMProgressProcRecordPtr)&theProc);
RemoveQDxDispatchPatch();
FixBits((CGrafPtr)qd.thePort, false);
if ((*gPICTParams)->progress.prog.progressProc && !(*gPICTParams)->progress.aborted)
CallICMProgressProc((*gPICTParams)->progress.prog.progressProc,
codecProgressUpdatePercent, 0x00010000L,
(*gPICTParams)->progress.prog.progressRefCon);
KeepSpinning();
(*gPICTParams)->progress.begin = theProc.begin;
(*gPICTParams)->progress.end = theProc.end;
gCurrentLines += Height(srcRect);
} else StdPix(src, srcRect, matrix, mode | 0x80, mask, matte, matteRect, flags);
if (gSlideShow && !(*gPICTParams)->progress.aborted)
(*gPICTParams)->progress.aborted = CheckAbort(gPICTParams);
}
/*
* LoadPICT(theFile, theImage)
*
* Purpose: Allocates memory and loads the PICT image in
* Inputs: theFile = the input file
* theImage = image record
* Returns: nothing
*
*/
OSErr LoadPICT(short theFile, ImageHandle theImage)
{
OSErr theErr = noErr;
long theSize;
KeepSpinning();
GetEOF(theFile, &theSize);
if ((theSize -= kHeaderSize) < 0) return errCorruptImage, codecBadDataErr;
if (!MakeMemAvailable(theSize)) return gIntError = errNoLoadMemory, memFullErr;
if ((*theImage)->data = NewHandle(theSize)) {
SetFPos(theFile, fsFromStart, kHeaderSize);
HLock((*theImage)->data);
SpinIndef();
theErr = FSRead(theFile, &theSize, *(*theImage)->data);
KeepSpinning();
HUnlock((*theImage)->data);
if (theErr == noErr) return theErr;
else DisposeHandle((*theImage)->data);
gIntError = errCantReadFile;
} else gIntError = errNoLoadMemory, theErr = memFullErr;
return theErr;
}
static void InitPICTUPPs(void)
{
gProgressPixProc = NewStdPixProc((ProcPtr)ProgressPixProc);
gAddColorsPixProc = NewStdPixProc((ProcPtr)AddColorsPixProc);
gInitPixProc = NewStdPixProc((ProcPtr)InitPixProc);
gInitBitsProc = NewQDBitsProc((ProcPtr)InitBitsProc);
gInitTextProc = NewQDTextProc((ProcPtr)InitTextProc);
gInitLineProc = NewQDLineProc((ProcPtr)InitLineProc);
gInitRectProc = NewQDRectProc((ProcPtr)InitRectProc);
gInitRRectProc = NewQDRRectProc((ProcPtr)InitRRectProc);
gInitOvalProc = NewQDOvalProc((ProcPtr)InitOvalProc);
gInitArcProc = NewQDArcProc((ProcPtr)InitArcProc);
gInitPolyProc = NewQDPolyProc((ProcPtr)InitPolyProc);
gInitRgnProc = NewQDRgnProc((ProcPtr)InitRgnProc);
gDummyBitsProc = NewQDBitsProc((ProcPtr)DummyBitsProc);
gDummyTextProc = NewQDTextProc((ProcPtr)DummyTextProc);
gDummyLineProc = NewQDLineProc((ProcPtr)DummyLineProc);
gDummyRectProc = NewQDRectProc((ProcPtr)DummyRectProc);
gDummyRRectProc = NewQDRRectProc((ProcPtr)DummyRRectProc);
gDummyOvalProc = NewQDOvalProc((ProcPtr)DummyOvalProc);
gDummyArcProc = NewQDArcProc((ProcPtr)DummyArcProc);
gDummyPolyProc = NewQDPolyProc((ProcPtr)DummyPolyProc);
gDummyRgnProc = NewQDRgnProc((ProcPtr)DummyRgnProc);
}
/*
* GetImageInfo(theImage)
*
* Purpose: Retrieves the image description and CLUT from a given PICT
* Inputs: theImage = image record for the PICT image
* Returns: nothing
*
*/
void GetImageInfo(ImageHandle theImage)
{
char hState = HGetState((*theImage)->data);
Rect theRect = (*theImage)->qrect;
CQDProcs theProcs, *oldProcs;
gPICTImage = theImage;
gPICTComments = nil;
gTotalLines = 0;
gHasObjects = false;
PushPort();
MySetPort(gGenericGWorld);
SetStdCProcs(&theProcs);
if (!gProgressPixProc) InitPICTUPPs();
theProcs.newProc1 = (UniversalProcPtr)gInitPixProc;
theProcs.bitsProc = gInitBitsProc;
theProcs.textProc = gInitTextProc;
theProcs.lineProc = gInitLineProc;
theProcs.rectProc = gInitRectProc;
theProcs.rRectProc = gInitRRectProc;
theProcs.ovalProc = gInitOvalProc;
theProcs.arcProc = gInitArcProc;
theProcs.polyProc = gInitPolyProc;
theProcs.rgnProc = gInitRgnProc;
oldProcs = gGenericGWorld->grafProcs;
gGenericGWorld->grafProcs = &theProcs;
HLock((*theImage)->data);
KeepSpinning();
if (gQTVersion) DrawTrimmedPicture((PicHandle)(*theImage)->data, &theRect, nil, false, nil);
else DrawPicture((PicHandle)(*theImage)->data, &theRect);
KeepSpinning();
HSetState((*theImage)->data, hState);
gGenericGWorld->grafProcs = oldProcs;
PopPort();
if (!(*theImage)->depth) (*theImage)->depth = 1;
if (gHasObjects) (*theImage)->flags |= ifNeedsWhiteBG + ifNoOnscreenProg;
(*theImage)->comments = gPICTComments;
(*(PICTPrivatesHandle)(*theImage)->privateData)->totalLines = gTotalLines;
}
/*
* SavePICTFile(theSpec, theHandle)
*
* Purpose: Writes the PICT image out to the specified file
* Inputs: theSpec = a pointer to the output file spec
* theHandle = the handle of the data to be written
* Returns: an OSErr describing what went wrong
*
*/
OSErr SavePICT(FSSpec *theSpec, Handle theHandle, GWorldPtr thePreview, Rect *theRect, Handle privates)
{
#if applec
#pragma unused(thePreview, theRect, privates)
#endif
long theSize = GetHandleSize(theHandle);
char hState = HGetState(theHandle);
uchar *theHeader[kHeaderSize];
short theFile;
OSErr theErr;
long i;
for (i = 0; i < kHeaderSize; theHeader[i++] = 0);
KeepSpinning();
theErr = FSpCreate(theSpec, kCreator, kPICTType, 0);
if (theErr == noErr) {
KeepSpinning();
theErr = FSpOpenDF(theSpec, fsWrPerm, &theFile);
if (theErr == noErr) {
KeepSpinning();
theErr = FSWrite(theFile, &i, theHeader);
if (theErr == noErr) {
HLock(theHandle);
SpinIndef();
theErr = FSWrite(theFile, &theSize, *theHandle);
KeepSpinning();
if (theErr == noErr) {
HSetState(theHandle, hState);
FSClose(theFile);
return theErr;
} else gIntError = errCantWriteFile;
HSetState(theHandle, hState);
} else gIntError = errCantWriteFile;
FSClose(theFile);
} else gIntError = errCantOpenFile;
FSpDelete(theSpec);
} else gIntError = errCantCreateFile;
return theErr;
}
/*
* FixPICT(addPreview)
*
* Purpose: Performs the JFIF->PICT conversion on the active image, add the color
* table, crops it, and creates a preview if requested
* Inputs: addPreview = flag: true if we should add a preview image
* theSize = pointer to a long where we will return the size
* Returns: an OSErr describing what went wrong
*
*/
OSErr FixPICT(ImageHandle theImage, Handle *finalData, Boolean palette)
{
OSErr theErr = noErr;
Handle oldData;
if ((*theImage)->format->inType != kPICTType &&
(*theImage)->format->inType != kSCRNType &&
(*theImage)->format->inType != kJPEGType)
return errAETypeError;
oldData = *finalData = (*theImage)->data;
if ((*theImage)->format->inType == kJPEGType) {
KeepSpinning();
*finalData = WrapJPEG(oldData, (*theImage)->depth);
if ((*theImage)->data != oldData) DisposeHandle(oldData);
if (!*finalData) return memFullErr;
oldData = *finalData;
}
if (palette) {
KeepSpinning();
*finalData = AddColors(oldData, theImage);
if ((*theImage)->data != oldData) DisposeHandle(oldData);
if (!*finalData) return gIntError = errNoColorsMemory, memFullErr;
oldData = *finalData;
}
return theErr;
}
/*
* AddColors(theHandle, theImage)
*
* Purpose: Adds the image's palette to the image description of the PICT
* Inputs: theHandle = handle to the image data
* theImage = handle to the associated image
* Returns: a handle to the cropped image
*
*/
Handle AddColors(Handle theHandle, ImageHandle theImage)
{
PixMapHandle thePixMap = GetGWorldPixMap(gGenericGWorld);
CQDProcs theProcs, *oldProcs = gGenericGWorld->grafProcs;
long theSize = GetHandleSize(theHandle);
char hState = HGetState(theHandle);
Rect theRect = (*theImage)->qrect;
OpenCPicParams theParams;
Handle dstHandle;
OSErr theErr;
if (!(*theImage)->qpalette) return theHandle;
if (MakeMemAvailable(theSize + 16384L)) {
theParams.srcRect = theRect;
theParams.hRes = theParams.vRes = 0x480000L;
theParams.version = -2;
theParams.reserved1 = theParams.reserved2 = 0;
SetStdCProcs(&theProcs);
if (!gProgressPixProc) InitPICTUPPs();
theProcs.newProc1 = (UniversalProcPtr)gAddColorsPixProc;
theProcs.bitsProc = gDummyBitsProc;
theProcs.textProc = gDummyTextProc;
theProcs.lineProc = gDummyLineProc;
theProcs.rectProc = gDummyRectProc;
theProcs.rRectProc = gDummyRRectProc;
theProcs.ovalProc = gDummyOvalProc;
theProcs.arcProc = gDummyArcProc;
theProcs.polyProc = gDummyPolyProc;
theProcs.rgnProc = gDummyRgnProc;
gGenericGWorld->grafProcs = &theProcs;
PushPort();
MySetPort(gGenericGWorld);
ClipRect(&theParams.srcRect);
if (dstHandle = (Handle)OpenCPicture(&theParams)) {
LockPixels(thePixMap);
HLock(theHandle);
gPICTImage = theImage;
KeepSpinning();
theErr = DrawTrimmedPicture((PicHandle)theHandle, &theParams.srcRect, nil,
false, (ICMProgressProcRecordPtr)&gDummyProg);
KeepSpinning();
HSetState(theHandle, hState);
UnlockPixels(thePixMap);
ClosePicture();
gGenericGWorld->grafProcs = oldProcs;
if ((theErr == noErr) && !EmptyRect(&(*(PicHandle)dstHandle)->picFrame)) {
PopPort();
return dstHandle;
}
DisposeHandle(dstHandle);
} else theErr = memFullErr;
gGenericGWorld->grafProcs = oldProcs;
PopPort();
} else theErr = memFullErr;
return nil;
}
/*
* AddColorsPixProc(src, srcRect, matrix, mode, mask, matte, matteRect, callOldBits)
*
* Purpose: Dummy routine called when a compressed PixMap is found in a PICT; we just
* add a color table to the ImageDescription
* Inputs: src = the compressed PixMap
* srcRect = the rectangle of the image in the source coordinates
* matrix = the transformation matrix
* mode = the drawing mode
* mask = the output masking region
* matte = the output matte, described as a PixMap
* matteRect = the bounding rectangle for the output matte
* callOldBits = flag saying if we should call the old routine
* Returns: nothing
*
*/
pascal void AddColorsPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
RgnHandle mask, PixMap *matte, Rect *matteRect, short flags)
{
#if applec
#pragma unused(flags)
#endif
PixMapHandle dst = GetGWorldPixMap((CGrafPtr)qd.thePort);
ImageDescriptionHandle theDesc;
ICMProgressProcRecord progProc;
CTabHandle theColors = nil;
ICMDataProcRecord dataProc;
OSErr theError;
long bufSize;
Ptr theData;
KeepSpinning();
if (GetCompressedPixMapInfo(src, &theDesc, &theData, &bufSize, &dataProc, &progProc)
== noErr) {
if (theColors = (CTabHandle)AnyNewHandle(sizeof(ColorTable))) {
Palette2CTab((*gPICTImage)->qpalette, theColors);
(*theColors)->ctSeed = GetCTSeed();
SetImageDescriptionCTable(theDesc, theColors);
DisposeHandle((Handle)theColors);
theError = SetCompressedPixMapInfo(src, theDesc, theData, bufSize,
&dataProc, &progProc);
}
}
StdPix(src, srcRect, matrix, mode, mask, matte, matteRect, 0);
}
//=====================================================================================
// Dummy QuickDraw bottlenecks to filter out non-PixMaps within PICTs
//=====================================================================================
/*
* InitPixProc(src, srcRect, matrix, mode, mask, matte, matteRect, callOldBits)
*
* Purpose: Dummy routine called when a compressed PixMap is found in a PICT; we just
* copy the image description to a handle lPICTDesc
* Inputs: src = the compressed PixMap
* srcRect = the rectangle of the image in the source coordinates
* matrix = the transformation matrix
* mode = the drawing mode
* mask = the output masking region
* matte = the output matte, described as a PixMap
* matteRect = the bounding rectangle for the output matte
* callOldBits = flag saying if we should call the old routine
* Returns: nothing
*
*/
pascal void InitPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
RgnHandle mask, PixMap *matte, Rect *matteRect, short callOldBits)
{
#if applec
#pragma unused(mode, mask, matte, matteRect, callOldBits)
#endif
ImageDescriptionHandle theDesc;
ICMProgressProcRecord progProc;
CTabHandle theColors = nil;
ICMDataProcRecord dataProc;
long bufSize;
Ptr theData;
gTotalLines += Height(srcRect);
gPICTSrcRect = *srcRect;
gPICTDstRect = *srcRect;
TransformRect(matrix, &gPICTDstRect, nil);
if (!GetCompressedPixMapInfo(src, &theDesc, &theData, &bufSize, &dataProc, &progProc)) {
if ((*theDesc)->cType == kJPEGCompression) {
if (!VerifyJPEGData((uchar *)theData, bufSize)) gIntError = errBadJPEG;
ExtractComments(theData, bufSize, &gPICTComments);
}
BlockMove(*theDesc, &(*gPICTImage)->desc, sizeof(ImageDescription));
(*gPICTImage)->depth = (*theDesc)->depth;
if ((*theDesc)->clutID != -1) {
GetImageDescriptionCTable(theDesc, &theColors);
if (theColors) {
(*gPICTImage)->ipalette = NewPalette((*theColors)->ctSize + 1, theColors,
pmTolerant, 0);
DisposeHandle((Handle)theColors);
}
}
}
}
/*
* InitBitsProc(src, srcRect, dstRect, mode, mask)
*
* Purpose: Routine called in place of CopyBits for our images; here we check for a
* custom color table
* Inputs: src = the compressed PixMap
* srcRect = the rectangle of the image in the source coordinates
* dstRect = the destination rectangle
* mode = the drawing mode
* mask = the output masking region
* Returns: nothing
*
*/
pascal void InitBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
RgnHandle mask)
{
#if applec
#pragma unused(srcRect, dstRect, mode, mask)
#endif
if (!(*gPICTImage)->depth) {
if (src->rowBytes & 0x8000) {
(*gPICTImage)->depth = src->pixelSize;
if ((src->pixelSize <= 8) && src->pmTable)
(*gPICTImage)->ipalette = NewPalette((*src->pmTable)->ctSize + 1,
src->pmTable, pmTolerant, 0);
} else (*gPICTImage)->depth = 1;
}
}
pascal void InitTextProc(short count, const void *textAddr, Point numer, Point denom)
{
#if applec
#pragma unused(count, textAddr, numer, denom)
#endif
gHasObjects = true;
}
pascal void InitLineProc(Point newPt)
{
#if applec
#pragma unused(newPt)
#endif
gHasObjects = true;
}
pascal void InitRectProc(GrafVerb verb, const Rect *r)
{
#if applec
#pragma unused(verb, r)
#endif
gHasObjects = true;
}
pascal void InitRRectProc(GrafVerb verb, const Rect *r, short ovalWidth,
short ovalHeight)
{
#if applec
#pragma unused(verb, r, ovalWidth, ovalHeight)
#endif
gHasObjects = true;
}
pascal void InitOvalProc(GrafVerb verb, const Rect *r)
{
#if applec
#pragma unused(verb, r)
#endif
gHasObjects = true;
}
pascal void InitArcProc(GrafVerb verb, const Rect *r, short startAngle, short arcAngle)
{
#if applec
#pragma unused(verb, r, startAngle, arcAngle)
#endif
gHasObjects = true;
}
pascal void InitPolyProc(GrafVerb verb, PolyHandle poly)
{
#if applec
#pragma unused(verb, poly)
#endif
gHasObjects = true;
}
pascal void InitRgnProc(GrafVerb verb, RgnHandle rgn)
{
#if applec
#pragma unused(verb, rgn)
#endif
gHasObjects = true;
}
//=====================================================================================
// Dummy QuickDraw bottlenecks to filter out non-PixMaps within PICTs
//=====================================================================================
pascal void DummyBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
RgnHandle mask)
{
#if applec
#pragma unused(src, srcRect, dstRect, mode, mask)
#endif
}
pascal void DummyTextProc(short count, const void *textAddr, Point numer, Point denom)
{
#if applec
#pragma unused(count, textAddr, numer, denom)
#endif
}
pascal void DummyLineProc(Point newPt)
{
#if applec
#pragma unused(newPt)
#endif
}
pascal void DummyRectProc(GrafVerb verb, const Rect *r)
{
#if applec
#pragma unused(verb, r)
#endif
}
pascal void DummyRRectProc(GrafVerb verb, const Rect *r, short ovalWidth,
short ovalHeight)
{
#if applec
#pragma unused(verb, r, ovalWidth, ovalHeight)
#endif
}
pascal void DummyOvalProc(GrafVerb verb, const Rect *r)
{
#if applec
#pragma unused(verb, r)
#endif
}
pascal void DummyArcProc(GrafVerb verb, const Rect *r, short startAngle, short arcAngle)
{
#if applec
#pragma unused(verb, r, startAngle, arcAngle)
#endif
}
pascal void DummyPolyProc(GrafVerb verb, PolyHandle poly)
{
#if applec
#pragma unused(verb, poly)
#endif
}
pascal void DummyRgnProc(GrafVerb verb, RgnHandle rgn)
{
#if applec
#pragma unused(verb, rgn)
#endif
}