mirror of
https://github.com/aaronsgiles/JPEGView.git
synced 2024-06-07 12:29:30 +00:00
92bdb55672
These are the sources for the final official release of JPEGView for the Mac, back in 1994.
1 line
7.6 KiB
C
1 line
7.6 KiB
C
/*********************************************************/
|
|
/* This source code copyright (c) 1991-2001, Aaron Giles */
|
|
/* See the Read Me file for licensing information. */
|
|
/* Contact email: mac@aarongiles.com */
|
|
/*********************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include "jpeglib.h"
|
|
#include "jerror.h"
|
|
|
|
static OSErr DecompressJPEGImage(struct jpeg_decompress_struct *cinfo, PixMapHandle dstPixMap, ICMProgressProcRecordPtr prog);
|
|
static void CopyPixMapToDestination(PixMapHandle srcPixMap, short startRow);
|
|
|
|
GLOBAL void
|
|
InitIJGSource (j_decompress_ptr cinfo, Handle theHandle);
|
|
|
|
extern OSErr DrawJPEG(Handle theHandle, JVDrawParamsHandle theParams)
|
|
{
|
|
NestedProgress theProgress = (*theParams)->progress;
|
|
struct jpeg_decompress_struct cinfo;
|
|
char hState = HGetState(theHandle);
|
|
struct jpeg_error_mgr jerr;
|
|
GWorldPtr theGWorld;
|
|
OSErr theErr;
|
|
|
|
HLock(theHandle);
|
|
cinfo.err = jpeg_std_error(&jerr);
|
|
jpeg_create_decompress(&cinfo);
|
|
InitIJGSource(&cinfo, theHandle);
|
|
jpeg_read_header(&cinfo, true);
|
|
SysBeep(1);
|
|
jpeg_start_decompress(&cinfo);
|
|
SysBeep(1);
|
|
/* {
|
|
// note: need to set depth to 8 for grayscale images
|
|
theGWorld = NewTempGWorld(cinfo.output_width, cinfo.output_height, (cinfo.out_color_components == 1) ? 40 : 32, nil);
|
|
if (theGWorld) {
|
|
theErr = DecompressJPEGImage(&cinfo, GetGWorldPixMap(theGWorld), (ICMProgressProcRecordPtr)&theProgress);
|
|
if ((*theParams)->progress.aborted) theErr = codecAbortErr;
|
|
DisposeGWorld(theGWorld);
|
|
} else gIntError = errNoDrawMemory, theErr = memFullErr;
|
|
}*/
|
|
SysBeep(1);
|
|
jpeg_finish_decompress(&cinfo);
|
|
SysBeep(1);
|
|
jpeg_destroy_decompress(&cinfo);
|
|
HSetState(theHandle, hState);
|
|
return noErr;
|
|
}
|
|
|
|
static OSErr DecompressJPEGImage(struct jpeg_decompress_struct *cinfo, PixMapHandle dstPixMap, ICMProgressProcRecordPtr prog)
|
|
{
|
|
char pState = GetPixelsState(dstPixMap);
|
|
RgnHandle dstRgn = qd.thePort->visRgn;
|
|
ulong bandRow = 0, row, bufferRows = Height(&(*dstPixMap)->bounds);
|
|
char mmuMode = true32b;
|
|
OSErr theErr = noErr;
|
|
uchar *rowStart;
|
|
JSAMPARRAY scanLines;
|
|
|
|
LockPixels(dstPixMap);
|
|
rowStart = (uchar *)GetPixBaseAddr(dstPixMap);
|
|
if (scanLines = (JSAMPARRAY)NewPtrClear(bufferRows * sizeof(JSAMPROW))) {
|
|
for (row = 0; row < bufferRows; row++) scanLines[row] = rowStart, rowStart += (*dstPixMap)->rowBytes & 0x3fff;
|
|
for (row = 0; row < cinfo->output_height; row += bufferRows) {
|
|
SwapMMUMode(&mmuMode);
|
|
jpeg_read_scanlines(cinfo, scanLines, bufferRows);
|
|
SwapMMUMode(&mmuMode);
|
|
CopyPixMapToDestination(dstPixMap, row);
|
|
}
|
|
/*
|
|
for (row = 0; row < ; 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);
|
|
}
|
|
|
|
//============================================================================================
|
|
//============================================================================================
|
|
//=========================== ==================================
|
|
//=========================== IJG Data Source Object Code ==================================
|
|
//=========================== ==================================
|
|
//============================================================================================
|
|
//============================================================================================
|
|
|
|
/* Expanded data source object for stdio input */
|
|
|
|
typedef struct {
|
|
struct jpeg_source_mgr pub; /* public fields */
|
|
} my_source_mgr;
|
|
|
|
typedef my_source_mgr * my_src_ptr;
|
|
|
|
/*
|
|
* Initialize source --- called by jpeg_read_header
|
|
* before any data is actually read.
|
|
*/
|
|
|
|
METHODDEF void
|
|
init_source (j_decompress_ptr cinfo)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Fill the input buffer --- called whenever buffer is emptied.
|
|
*/
|
|
|
|
METHODDEF boolean
|
|
fill_input_buffer (j_decompress_ptr cinfo)
|
|
{
|
|
static JOCTET dummyBuffer[] = { (JOCTET)0xff, (JOCTET)JPEG_EOI };
|
|
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
|
|
WARNMS(cinfo, JWRN_JPEG_EOF);
|
|
src->pub.next_input_byte = (JOCTET *)&dummyBuffer;
|
|
src->pub.bytes_in_buffer = 2;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* Skip data --- used to skip over a potentially large amount of
|
|
* uninteresting data (such as an APPn marker).
|
|
*/
|
|
|
|
METHODDEF void
|
|
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* An additional method that can be provided by data source modules is the
|
|
* resync_to_restart method for error recovery in the presence of RST markers.
|
|
* For the moment, this source module just uses the default resync method
|
|
* provided by the JPEG library. That method assumes that no backtracking
|
|
* is possible.
|
|
*/
|
|
|
|
|
|
/*
|
|
* Terminate source --- called by jpeg_finish_decompress
|
|
* after all data has been read. Often a no-op.
|
|
*/
|
|
|
|
METHODDEF void
|
|
term_source (j_decompress_ptr cinfo)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Prepare for input from a memory handle.
|
|
*/
|
|
|
|
GLOBAL void
|
|
InitIJGSource (j_decompress_ptr cinfo, Handle theHandle)
|
|
{
|
|
my_src_ptr src;
|
|
|
|
/* The source object and input buffer are made permanent so that a series
|
|
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
|
* only before the first one. (If we discarded the buffer at the end of
|
|
* one image, we'd likely lose the start of the next one.)
|
|
* This makes it unsafe to use this manager and a different source
|
|
* manager serially with the same JPEG object. Caveat programmer.
|
|
*/
|
|
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
|
cinfo->src = (struct jpeg_source_mgr *)
|
|
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
sizeof(my_source_mgr));
|
|
src = (my_src_ptr) cinfo->src;
|
|
}
|
|
|
|
src = (my_src_ptr) cinfo->src;
|
|
src->pub.init_source = init_source;
|
|
src->pub.fill_input_buffer = fill_input_buffer;
|
|
src->pub.skip_input_data = skip_input_data;
|
|
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
|
src->pub.term_source = term_source;
|
|
src->pub.bytes_in_buffer = GetHandleSize(theHandle);
|
|
src->pub.next_input_byte = (JOCTET *)StripAddress(*theHandle);
|
|
}
|