This is ImageSave.m in view mode; [Download] [Up]
#import "../ImageSave.h" #import <appkit/NXImage.h> #import <appkit/SavePanel.h> #import <appkit/NXEPSImageRep.h> #import <appkit/NXBitmapImageRep.h> #import <stdio.h> #import <libc.h> #import <string.h> #import <sys/file.h> #import "../ToyView.h" #import "../ToyWin.h" #import "../ToyWinEPS.h" #import "../ColorMap.h" #import "../strfunc.h" #import "../common.h" #import "save.h" #import "JpegSavePanel.h" #import "TiffSavePanel.h" /* This data is used by ImageSave family */ char saveDir[MAXFILENAMELEN]; char *appDir = NULL; @implementation ImageSave + (char *)mk_tmpname:(const char *)path ext:(const char *)ex nopath:(BOOL)flag { static char srcfn[MAXFILENAMELEN]; int i, j; if (flag) { for (i = j = 0; path[i]; i++) if (path[i] == '/') j = i + 1; }else j = 0; strcpy(srcfn, path + j); for (i = j = 0; srcfn[i]; i++) if (srcfn[i] == '.') j = i + 1; if (j == 0) srcfn[i] = '.', j = i + 1; while (*ex) srcfn[j++] = *ex++; srcfn[j] = 0; return srcfn; } - initWithWin: aToyWin { [super init]; toyWin = aToyWin; toyView = [toyWin toyView]; if (!saveDir[0] || access(saveDir, X_OK) != 0) strcpy(saveDir, getenv("HOME")); if (appDir == NULL) { appDir = str_dup(NXArgv[0]); /* alloc only */ (void) dircopy(appDir, NXArgv[0], NO); } return self; } - (char *)getSavename: (const char *)path with:(int)itype { SavePanel *savePanel; char *stmp, *sav = NULL; const char *ex = NULL; switch (itype) { case Type_eps: ex = "eps"; break; case Type_bmp: ex = "bmp"; break; case Type_gif: ex = "gif"; break; case Type_ppm: ex = "pnm"; break; case Type_jpg: ex = "jpg"; break; case Type_xbm: ex = "xbm"; break; case Type_jbg: ex = "bie"; break; case Type_png: ex = "png"; break; } stmp = [ImageSave mk_tmpname:path ext:ex nopath:YES]; savePanel = [SavePanel new]; 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]); } return sav; } /* Local Method */ - (char *)getSaveTiffName: (const char *)path jpeg: (BOOL)flag compress: (int *)type by: (float *)factor { TiffSavePanel *savePanel; char *stmp, *sav = NULL; static float jpegFactor = 25.0; /* Default */ stmp = [ImageSave mk_tmpname:path ext:"tiff" nopath:YES]; savePanel = [[TiffSavePanel new] init: jpegFactor jpeg: flag]; if ([savePanel runModalForDirectory: saveDir file: stmp]) { sav = [ImageSave mk_tmpname: [savePanel filename] ext:"tiff" nopath:NO]; if (sav == NULL || *sav == 0) return NULL; strcpy(saveDir, [savePanel directory]); [savePanel compressType: type with: factor]; if (*type == NX_TIFF_COMPRESSION_JPEG) jpegFactor = *factor; } return sav; } /* Local Method */ - (char *)getSaveJpegName: (const char *)path by: (float *)factor : (BOOL *)progress { JpegSavePanel *savePanel; char *stmp, *sav = NULL; static float jpegFactor = 25.0; /* Default */ stmp = [ImageSave mk_tmpname:path ext:"jpg" nopath:YES]; savePanel = [[JpegSavePanel new] initFactor: jpegFactor]; if ([savePanel runModalForDirectory: saveDir file: stmp]) { sav = [ImageSave mk_tmpname: [savePanel filename] ext:"jpg" nopath:NO]; if (sav == NULL || *sav == 0) return NULL; strcpy(saveDir, [savePanel directory]); *factor = jpegFactor = [savePanel compressFactor]; *progress = [savePanel progressive]; } return sav; } /* Local Method */ - saveEPSAsTiff: sender { NXStream *stream; FILE *fd; char *sav; int type, ch; float factor; sav = [self getSaveTiffName: [toyWin filename] jpeg: NO compress: &type by: &factor]; if (sav == NULL) /* canceled */ return self; if ((fd = fopen(sav, "w")) == NULL) { errAlert(sav, Err_SAVE); return self; } /* type = none/lzw */ stream = [(ToyWinEPS *)toyWin openTiffStream: (type != NX_TIFF_COMPRESSION_NONE)]; if (stream == NULL) { (void) fclose(fd); errAlert(sav, Err_SAVE); return self; } while ((ch = NXGetc(stream)) != EOF) putc(ch, fd); NXCloseMemory(stream, NX_FREEBUFFER); (void)fclose(fd); return self; } - saveAsTiff: sender { NXStream *stream; int fd = -1; char *sav; commonInfo *cinf; NXBitmapImageRep *rep; BOOL jflag; int type; float factor; cinf = [toyView commonInfo]; if (cinf->type == Type_eps) return [self saveEPSAsTiff: sender]; rep = (NXBitmapImageRep *)[[toyView image] bestRepresentation]; jflag = (cinf->bits > 2 /* && cinf->type != Type_eps */ && [rep canBeCompressedUsing: NX_TIFF_COMPRESSION_JPEG]); sav = [self getSaveTiffName: [toyWin filename] jpeg: jflag compress: &type by: &factor]; if (sav == NULL) /* canceled */ return self; /* BUG ? Over Writing LZW on no-compression */ if (access(sav, F_OK|W_OK) == 0) unlink(sav); if ((fd = open(sav, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0 || (stream = NXOpenFile(fd, NX_WRITEONLY)) == NULL) { if (fd >= 0) (void) close(fd); errAlert(sav, Err_SAVE); return self; } if (factor < 1.0) factor = 1.0; else if (factor > 255.0) factor = 255.0; [rep writeTIFF:stream usingCompression:type andFactor:factor]; NXClose(stream); (void)close(fd); if (type != NX_TIFF_COMPRESSION_JPEG) [toyWin resetFilename:sav]; return self; } - saveAsEPS: sender { NXStream *stream; char *sav; commonInfo *cinf; sav = [self getSavename: [toyWin filename] with:Type_eps]; if (sav == NULL) /* canceled */ return self; if ((stream = [toyWin openEPSStream]) == NULL) { errAlert(sav, Err_MEMORY); return self; } if (NXSaveToFile(stream, sav)) errAlert(sav, Err_SAVE); NXCloseMemory(stream, NX_FREEBUFFER); cinf = [toyView commonInfo]; if (cinf->type == Type_eps) [toyWin resetFilename:sav]; return self; } - saveAsType: (int)itype /* BMP, PPM, JPG, or JBIG */ { FILE *fp; char *sav; commonInfo *cinf; ColorMap *colormap = nil; unsigned char *map[MAXPLANE]; float jpegFactor; BOOL progress = NO; int cnum = 0, err = 0; cinf = [toyView commonInfo]; if (cinf->cspace == NX_CMYKColorSpace) { warnAlert([toyWin filename], Err_SAV_IMPL); return self; } if (itype == Type_jbg && (cinf->bits > 2 || cinf->numcolors != 1)) { /* ignore alpha, ignore 2 bits gray. Because of EPS... */ warnAlert([toyWin filename], Err_SAV_IMPL); return self; } if (itype == Type_jpg) sav = [self getSaveJpegName:[toyWin filename] by:&jpegFactor : &progress]; else sav = [self getSavename:[toyWin filename] with: itype]; if (sav == NULL) /* canceled */ return self; 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 (itype == Type_ppm) { resetPixel(map, 0); err = ppmwrite(fp, cinf, map); goto EXIT; }else if (itype == Type_jpg) { int q; resetPixel(map, 0); q = (255.0 - jpegFactor) / 2.55 + 0.5; q = (q < 0) ? 0 : ((q > 100) ? 100 : q); err = jpgwrite(fp, cinf, appDir, q, progress); fp = NULL; goto EXIT; }else if (itype == Type_jbg) { resetPixel(map, 0); err = jbigwrite(fp, cinf, map[0], appDir); fp = NULL; goto EXIT; } /* bmp only */ colormap = [[ColorMap alloc] init]; cnum = [self getPalette:colormap info:cinf map:map needAlpha:NO err:&err]; err = 0; /* Error is ignored */ if (cnum == 0) saveBmpbmap(fp, cinf, FIXcount + 1, NULL, map); else saveBmpbmap(fp, cinf, cnum, cinf->palette, map); EXIT: if (fp) (void)fclose(fp); if (colormap) [colormap free]; [toyWin freeTempBitmap]; if (err) { errAlert(sav, err); (void)unlink(sav); }else if (itype != Type_jpg) [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.