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; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.