home *** CD-ROM | disk | FTP | other *** search
- #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
-