This is ImageSvGIF.m in view mode; [Download] [Up]
#import "../ImageSave.h" #import <appkit/NXImage.h> #import <appkit/SavePanel.h> #import <stdio.h> #import <libc.h> #import <string.h> #import "../ToyView.h" #import "../ToyWin.h" #import "../ColorMap.h" #import "../strfunc.h" #import "../common.h" #import "save.h" #import "GifSavePanel.h" #define MANY_COLORS (-1) /* must be < 0 */ @implementation ImageSave (SaveGIF) /* Local Method */ - (char *)getSaveIntlName: (const char *)path ext: (const char *)ex interlace: (BOOL *)intp { GifSavePanel *savePanel; char *stmp, *sav = NULL; stmp = [ImageSave mk_tmpname:path ext:ex nopath:YES]; savePanel = [[GifSavePanel new] loadNib]; if ([savePanel runModalForDirectory: saveDir file: stmp]) { sav = [ImageSave mk_tmpname: [savePanel filename] ext:ex nopath:NO]; if (sav == NULL || *sav == 0) return NULL; strcpy(saveDir, [savePanel directory]); *intp = [savePanel interlace]; } return sav; } - (int)getPalette:(ColorMap *)colormap info:(commonInfo *)cinf map:(unsigned char **)map needAlpha:(BOOL)alflag err:(int *)code { int cnum, err; BOOL hasalpha; err = 0; if (cinf->palette != NULL) { if ([colormap allocPalColor] == nil) { err = Err_MEMORY; goto EXIT; } cnum = [colormap regPalColorWithAlpha: alflag]; if (cnum > FIXcount) err = MANY_COLORS; goto EXIT; } if ([colormap allocFullColor] == nil) { err = Err_MEMORY; goto EXIT; } cnum = alflag ? [colormap getAllColor:map limit:FIXcount alpha:&hasalpha] : [colormap getAllColor:map limit:FIXcount]; if (hasalpha) ++cnum; if (cnum > FIXcount) err = MANY_COLORS; else { (void)[colormap getNormalmap: &cnum]; cinf->palette = [colormap getPalette]; cinf->palsteps = cnum; } EXIT: if (err) { *code = err; return 0; } return cinf->palsteps; } - (char *)saveAsGif: (char *)gifname { char *sav, *result = NULL; commonInfo *cinf; ColorMap *colormap = nil; unsigned char *map[MAXPLANE]; int cnum, err; static BOOL interl = NO; cinf = [toyView commonInfo]; if (cinf->cspace == NX_CMYKColorSpace) { warnAlert([toyWin filename], Err_SAV_IMPL); return NULL; } if (gifname) /* Called after reduction */ sav = gifname; else { sav = [self getSaveIntlName: [toyWin filename] ext: "gif" interlace: &interl]; if (sav == NULL) /* canceled */ return NULL; } if ((err = [toyWin getBitmap:map info: &cinf]) != 0) goto EXIT; if ((err = initGetPixel(cinf)) != 0) goto EXIT; colormap = [[ColorMap alloc] init]; cnum = [self getPalette:colormap info:cinf map:map needAlpha:YES err:&err]; if (cnum == 0) { const char *ask, *cancel, *reduce; if (err != MANY_COLORS) goto EXIT; ask = NXLocalizedString( "Reduction Start", NULL, GIF_Reduction); cancel = NXLocalizedString("Cancel", NULL, Stop_SAVE); reduce = NXLocalizedString("Reduce", NULL, BMP_Reduce); if (NXRunAlertPanel("", ask, reduce, cancel, NULL)) result = sav; /* Save after reduction */ goto EXIT; } if (!err) { FILE *fp; int transp; transp = (cinf->alpha && cinf->palette) ? cinf->palsteps : -1; if ((fp = fopen(sav, "w")) == NULL) { errAlert(sav, Err_SAVE); [colormap free]; [toyWin freeTempBitmap]; return NULL; // Don't goto EXIT. } GIFEncode(fp, cinf, map, cnum, transp, interl, cinf->palette); (void)fclose(fp); [toyWin resetFilename:sav]; } EXIT: if (colormap) [colormap free]; [toyWin freeTempBitmap]; if (err) { errAlert(sav, err); (void)unlink(sav); } /* result != NULL --> This method is called again after Reduction */ return result; } - saveAsPng: sender { commonInfo *cinf; commonInfo copyinf; FILE *fp; ColorMap *colormap = nil; char *sav; unsigned char *map[MAXPLANE]; int err; static BOOL interl = NO; cinf = [toyView commonInfo]; if (cinf->cspace == NX_CMYKColorSpace) { warnAlert([toyWin filename], Err_SAV_IMPL); return NULL; } if ((sav = [self getSaveIntlName: [toyWin filename] ext: "png" interlace: &interl]) == NULL) /* canceled */ return NULL; if ((fp = fopen(sav, "w")) == NULL) { errAlert(sav, Err_SAVE); return self; } err = [toyWin getBitmap:map info: &cinf]; if (!err) err = initGetPixel(cinf); if (err) goto EXIT; if (cinf->cspace != NX_RGBColorSpace) { /* Monochrome */ copyinf = *cinf; copyinf.palette = NULL; /* No need to allocate palette */ copyinf.palsteps = 0; cinf = ©inf; }else { colormap = [[ColorMap alloc] init]; (void) [self getPalette:colormap info:cinf map:map needAlpha:YES err:&err]; err = 0; /* Error is ignored */ } resetPixel(map, 0); pngwrite(fp, cinf, appDir, interl); /* fp is closed in pngwrite */ EXIT: if (colormap) [colormap free]; [toyWin freeTempBitmap]; if (err) { errAlert(sav, err); (void)unlink(sav); }else [toyWin resetFilename:sav]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.