This is GIFWriting.m in view mode; [Download] [Up]
///////////////////////////////////////////////////////////////////////////////
// FILENAME: GIFWriting.m
// SUMMARY: Implementation of a GIFWriting category to NXImage
// SUPERCLASS: Object:NXImage(GIFWriting)
// INTERFACE: None
// AUTHOR: Rohit Khare
// COPYRIGHT: (c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION COMMENTS
// This code uses the netPBM distribution. Currently, it creates a temp
// tiff (uncompressed) in /tmp and then opens a pipe to a string of netPBM
// filters assumed to be located in [NXApp mainBundle], then copies those
// bytes to the target stream.
// In the future, we should rework the code to directly access the netPBM
// and libTIFF libraries. Transparency support would also be mondo cool.
///////////////////////////////////////////////////////////////////////////////
// HISTORY
// 10/30/94: Extended to use OmniImageFilter as first resort (for HP-PA).
// 07/16/94: Created. Derived from netPBM.
///////////////////////////////////////////////////////////////////////////////
#import "eTextKernel.h"
#import "GIFWriting.h"
#import "_FormatWritingImageView.h"
#import <machkit/NXData.h>
@implementation NXImage (GIFWriting)
- writeGIFtoPath_Poskanzer:(const char *)destPath
{
char tempPath[MAXPATHLEN];
char cmd[4*MAXPATHLEN];
const char *appPath;
id iv;
iv = [_FormatWritingImageView new];
[iv useImage:self];
sprintf(tempPath, "/tmp/eTextGifConversion.%x.tiff", [NXApp uniqueID]);
[iv dumpTIFF:tempPath];
// no fs flag; I don't think ppmquant improves colors with it.
// Ideally, we'd run ppmquant iff we really needed to. but for simplicity
// we always call it. Does this cause aesthetic errors?
NXLogError("GIFWriting: generating %s", destPath);
appPath = [[NXBundle mainBundle] directory];
sprintf(cmd,"\"%s/tifftopnm\" \"%s\" | \"%s/ppmquant\" 256 | \"%s/ppmtogif\" > \"%s\"",
appPath, tempPath, appPath, appPath, destPath);
system(cmd);
unlink(tempPath);
return self;
}
- writeGIFtoPath:(const char *)destPath
{
NXAtom *OIFtypes;
static NXAtom gifType = NULL;
if (!gifType) gifType = NXUniqueString("image format gif");
// Can OIF handle this?
OIFtypes = [Pasteboard typesFilterableTo:gifType];
if (OIFtypes && *OIFtypes) {
id conversionPB,data;
NXStream *t;
char *tiffbytes; int len, maxlen;
// Add TIFF data to a PBoard
t = NXOpenMemory(NULL,0,NX_READWRITE);
[self writeTIFF:t];
NXGetMemoryBuffer(t, &tiffbytes, &len, &maxlen);
data = [[NXData alloc] initWithData:(void *)tiffbytes size:maxlen dealloc:YES];
conversionPB = [Pasteboard newByFilteringData:data ofType:NXTIFFPboardType];
if ([conversionPB findAvailableTypeFrom:&gifType num:1]) {
NXStream *s = [conversionPB readTypeToStream:gifType];
if (s) {
NXSaveToFile(s, destPath);
NXCloseMemory(s, NX_FREEBUFFER);
} else {
// OK, try the Poskanzer pipeline
[self writeGIFtoPath_Poskanzer:destPath];
}
} else {
// OK, try the Poskanzer pipeline
[self writeGIFtoPath_Poskanzer:destPath];
}
// Attempt to free the data from VM.
[conversionPB free];
[data free];
NXCloseMemory(t, NX_FREEBUFFER);
free(OIFtypes);
} else {
// OK, try the Poskanzer pipeline
[self writeGIFtoPath_Poskanzer:destPath];
}
return self;
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.