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.