JPEGView/Source/C/PNTG.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
6.9 KiB
C

/*********************************************************/
/* This source code copyright (c) 1991-2001, Aaron Giles */
/* See the Read Me file for licensing information. */
/* Contact email: mac@aarongiles.com */
/*********************************************************/
//=====================================================================================
// Generic includes for Macintosh headers
//=====================================================================================
#if THINK_C
#include "THINK.Header"
#include <stddef.h>
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif
//=====================================================================================
// Includes specific to this module
//=====================================================================================
#include "PNTG.h"
//=====================================================================================
// Prototypes for functions local to this module
//=====================================================================================
static OSErr DecompressPNTGImage(uchar *dataStart, PixMapHandle dstPixMap,
ICMProgressProcRecordPtr prog, Size length);
static void CopyPixMapToDestination(PixMapHandle srcPixMap, short startRow);
//=====================================================================================
// Boolean idPNTG(uchar *theData, long theSize)
//=====================================================================================
// Examines the given data and attempts to identify it as a PNTG image.
//=====================================================================================
extern Boolean idPNTG(uchar *theData, long theSize, short refNum, FSSpec *theSpec)
{
#if applec
#pragma unused(theData, theSize, theSpec)
#endif
OSErr theErr;
long size;
theErr = GetEOF(refNum, &size);
return (theErr == noErr && size <= (512 + 720 * 73));
}
//=====================================================================================
// OSErr OpenPNTG(ImageHandle theImage)
//=====================================================================================
// Initializes the image record for a PNTG image.
//=====================================================================================
extern OSErr OpenPNTG(ImageHandle theImage)
{
OSErr theErr = noErr;
(*theImage)->grect.right = 576;
(*theImage)->grect.bottom = 720;
(*theImage)->depth = 1;
(*theImage)->qrect = (*theImage)->crect = (*theImage)->grect;
(*theImage)->compression = kPackBitsCompression;
BlockMove(gString[strPackBits], (*theImage)->compressionDesc, *gString[strPackBits] + 1);
return theErr;
}
//=====================================================================================
// OSErr DrawPNTG(Handle theHandle, JVDrawParamsHandle theParams)
//=====================================================================================
// Draws a PNTG image into the specified GWorld, from the srcRect into the dstRect,
// clipping as dstRgn specifies.
//=====================================================================================
extern OSErr DrawPNTG(Handle theHandle, JVDrawParamsHandle theParams)
{
NestedProgress theProgress = (*theParams)->progress;
char hState = HGetState(theHandle);
OSErr theErr = noErr;
GWorldPtr theGWorld;
uchar *dataStart;
if (theProgress.prog.progressProc) CallICMProgressProc(theProgress.prog.progressProc,
codecProgressUpdatePercent, 0x00000000L, theProgress.prog.progressRefCon);
HLockHi(theHandle);
if (theErr == noErr) {
dataStart = (uchar *)StripAddress(*theHandle);
theGWorld = NewTempGWorld(576, 720, 1, nil);
if (theGWorld) {
theErr = DecompressPNTGImage(dataStart, GetGWorldPixMap(theGWorld),
(ICMProgressProcRecordPtr)&theProgress, GetHandleSize(theHandle));
if ((*theParams)->progress.aborted) theErr = codecAbortErr;
DisposeGWorld(theGWorld);
} else gIntError = errNoDrawMemory, theErr = memFullErr;
}
HSetState(theHandle, hState);
if (theProgress.prog.progressProc) CallICMProgressProc(theProgress.prog.progressProc,
codecProgressUpdatePercent, 0x00010000L, theProgress.prog.progressRefCon);
return theErr;
}
//=====================================================================================
// OSErr DecompressPNTGImage(uchar *dataStart, PixMapHandle dstPixMap,
// ICMProgressProcRecordPtr prog, Size length)
//=====================================================================================
// Oversees the decompression of a PNTG image, handling banding, and calling the
// appropriate function to perform the actual decompression.
//=====================================================================================
static OSErr DecompressPNTGImage(uchar *dataStart, PixMapHandle dstPixMap,
ICMProgressProcRecordPtr prog, Size length)
{
uchar *ptr, *rowStart, *dst, *dataEnd = dataStart + length;
char pState = GetPixelsState(dstPixMap);
RgnHandle dstRgn = qd.thePort->visRgn;
ulong bandRow = 0, row;
char mmuMode = true32b;
OSErr theErr = noErr;
LockPixels(dstPixMap);
rowStart = (uchar *)GetPixBaseAddr(dstPixMap);
ptr = dataStart + 512;
for (row = 0; row < 720; row++) {
if (ptr < dataStart || ptr > dataEnd) {
theErr = codecBadDataErr;
break;
}
SwapMMUMode(&mmuMode);
dst = rowStart;
UnpackBits((Ptr *)&ptr, (Ptr *)&dst, 576 / 8);
SwapMMUMode(&mmuMode);
rowStart += ((*dstPixMap)->rowBytes & 0x3fff);
if (!(row & 63) && prog->progressProc)
theErr = (OSErr)CallICMProgressProc(prog->progressProc,
codecProgressUpdatePercent,
FixRatio(row, 720), prog->progressRefCon);
if (++bandRow == Height(&(*dstPixMap)->bounds)) {
CopyPixMapToDestination(dstPixMap, row - bandRow + 1);
bandRow = 0;
rowStart = (uchar *)GetPixBaseAddr(dstPixMap);
}
if (theErr != noErr) break;
}
if (theErr == noErr && bandRow) CopyPixMapToDestination(dstPixMap, row - bandRow);
SetPixelsState(dstPixMap, pState);
return theErr;
}
//=====================================================================================
// void CopyPixMapToDestination(PixMapHandle srcPixMap, short startRow)
//=====================================================================================
// Copies the band contained in srcPixMap to the destination, offset from the top by
// startRow.
//=====================================================================================
static void CopyPixMapToDestination(PixMapHandle srcPixMap, short startRow)
{
Rect srcRect = (*srcPixMap)->bounds, dstRect = (*srcPixMap)->bounds;
PixMapHandle dstPixMap = GetGWorldPixMap((CGrafPtr)qd.thePort);
char srcState = HGetState((Handle)srcPixMap);
char dstState = HGetState((Handle)dstPixMap);
OffsetRect(&dstRect, 0, startRow);
HLock((Handle)srcPixMap);
HLock((Handle)dstPixMap);
CopyBits((BitMap *)*srcPixMap, (BitMap *)*dstPixMap, &srcRect, &dstRect,
srcCopy + ditherCopy, qd.thePort->visRgn);
HSetState((Handle)dstPixMap, dstState);
HSetState((Handle)srcPixMap, srcState);
}