mirror of
https://github.com/aaronsgiles/JPEGView.git
synced 2024-06-14 12:29:33 +00:00
92bdb55672
These are the sources for the final official release of JPEGView for the Mac, back in 1994.
1 line
6.9 KiB
C
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);
|
|
}
|