home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / ImageSave.bproj / ImageSave.m < prev    next >
Encoding:
Text File  |  1996-12-03  |  7.5 KB  |  312 lines

  1. #import "../ImageSave.h"
  2. #import <appkit/NXImage.h>
  3. #import <appkit/SavePanel.h>
  4. #import <appkit/NXEPSImageRep.h>
  5. #import <appkit/NXBitmapImageRep.h>
  6. #import <stdio.h>
  7. #import <libc.h>
  8. #import <string.h>
  9. #import <sys/file.h>
  10. #import "../ToyView.h"
  11. #import "../ToyWin.h"
  12. #import "../ToyWinEPS.h"
  13. #import "../ColorMap.h"
  14. #import "../strfunc.h"
  15. #import "../common.h"
  16. #import "save.h"
  17. #import "JpegSavePanel.h"
  18. #import "TiffSavePanel.h"
  19.  
  20. /* This data is used by ImageSave family */
  21. char saveDir[MAXFILENAMELEN];
  22. char *appDir = NULL;
  23.  
  24.  
  25. @implementation ImageSave
  26.  
  27. + (char *)mk_tmpname:(const char *)path ext:(const char *)ex nopath:(BOOL)flag
  28. {
  29.     static char    srcfn[MAXFILENAMELEN];
  30.     int    i, j;
  31.  
  32.     if (flag) {
  33.         for (i = j = 0; path[i]; i++)
  34.             if (path[i] == '/') j = i + 1;
  35.     }else
  36.         j = 0;
  37.     strcpy(srcfn, path + j);
  38.     for (i = j = 0; srcfn[i]; i++)
  39.         if (srcfn[i] == '.') j = i + 1;
  40.     if (j == 0)
  41.         srcfn[i] = '.',  j = i + 1;
  42.     while (*ex)
  43.         srcfn[j++] = *ex++;
  44.     srcfn[j] = 0;
  45.     return srcfn;
  46. }
  47.  
  48.  
  49. - initWithWin: aToyWin
  50. {
  51.     [super init];
  52.     toyWin = aToyWin;
  53.     toyView = [toyWin toyView];
  54.     if (!saveDir[0] || access(saveDir, X_OK) != 0)
  55.         strcpy(saveDir, getenv("HOME"));
  56.     if (appDir == NULL) {
  57.         appDir = str_dup(NXArgv[0]); /* alloc only */
  58.         (void) dircopy(appDir, NXArgv[0], NO);
  59.     }
  60.     return self;
  61. }
  62.  
  63.  
  64. - (char *)getSavename: (const char *)path with:(int)itype
  65. {
  66.     SavePanel *savePanel;
  67.     char    *stmp, *sav = NULL;
  68.     const char *ex = NULL;
  69.  
  70.     switch (itype) {
  71.     case Type_eps: ex = "eps";  break;
  72.     case Type_bmp: ex = "bmp";  break;
  73.     case Type_gif: ex = "gif";  break;
  74.     case Type_ppm: ex = "pnm";  break;
  75.     case Type_jpg: ex = "jpg";  break;
  76.     case Type_xbm: ex = "xbm";  break;
  77.     case Type_jbg: ex = "bie";  break;
  78.     case Type_png: ex = "png";  break;
  79.     }
  80.     stmp = [ImageSave mk_tmpname:path ext:ex nopath:YES];
  81.     savePanel = [SavePanel new];
  82.     if ([savePanel runModalForDirectory: saveDir file: stmp]) {
  83.         sav = [ImageSave mk_tmpname:
  84.                 [savePanel filename] ext:ex nopath:NO];
  85.         if (sav == NULL || *sav == 0)
  86.             return NULL;
  87.         strcpy(saveDir, [savePanel directory]);
  88.     }
  89.     return sav;
  90. }
  91.  
  92. /* Local Method */
  93. - (char *)getSaveTiffName: (const char *)path jpeg: (BOOL)flag
  94.     compress: (int *)type by: (float *)factor
  95. {
  96.     TiffSavePanel *savePanel;
  97.     char    *stmp, *sav = NULL;
  98.     static    float jpegFactor = 25.0; /* Default */
  99.  
  100.     stmp = [ImageSave mk_tmpname:path ext:"tiff" nopath:YES];
  101.     savePanel = [[TiffSavePanel new] init: jpegFactor jpeg: flag];
  102.     if ([savePanel runModalForDirectory: saveDir file: stmp]) {
  103.         sav = [ImageSave mk_tmpname:
  104.                 [savePanel filename] ext:"tiff" nopath:NO];
  105.         if (sav == NULL || *sav == 0)
  106.             return NULL;
  107.         strcpy(saveDir, [savePanel directory]);
  108.         [savePanel compressType: type with: factor];
  109.         if (*type == NX_TIFF_COMPRESSION_JPEG)
  110.             jpegFactor = *factor;
  111.     }
  112.     return sav;
  113. }
  114.  
  115. /* Local Method */
  116. - (char *)getSaveJpegName: (const char *)path by: (float *)factor : (BOOL *)progress
  117. {
  118.     JpegSavePanel *savePanel;
  119.     char    *stmp, *sav = NULL;
  120.     static    float jpegFactor = 25.0; /* Default */
  121.  
  122.     stmp = [ImageSave mk_tmpname:path ext:"jpg" nopath:YES];
  123.     savePanel = [[JpegSavePanel new] initFactor: jpegFactor];
  124.     if ([savePanel runModalForDirectory: saveDir file: stmp]) {
  125.         sav = [ImageSave mk_tmpname:
  126.                 [savePanel filename] ext:"jpg" nopath:NO];
  127.         if (sav == NULL || *sav == 0)
  128.             return NULL;
  129.         strcpy(saveDir, [savePanel directory]);
  130.         *factor = jpegFactor = [savePanel compressFactor];
  131.         *progress = [savePanel progressive];
  132.     }
  133.     return sav;
  134. }
  135.  
  136. /* Local Method */
  137. - saveEPSAsTiff: sender
  138. {
  139.     NXStream *stream;
  140.     FILE    *fd;
  141.     char    *sav;
  142.     int    type, ch;
  143.     float    factor;
  144.  
  145.     sav = [self getSaveTiffName: [toyWin filename] jpeg: NO
  146.         compress: &type by: &factor];
  147.     if (sav == NULL) /* canceled */
  148.         return self;
  149.     if ((fd = fopen(sav, "w")) == NULL) {
  150.         errAlert(sav, Err_SAVE);
  151.         return self;
  152.     }
  153.     /* type = none/lzw */
  154.     stream = [(ToyWinEPS *)toyWin openTiffStream:
  155.             (type != NX_TIFF_COMPRESSION_NONE)];
  156.     if (stream == NULL) {
  157.         (void) fclose(fd);
  158.         errAlert(sav, Err_SAVE);
  159.         return self;
  160.     }
  161.     while ((ch = NXGetc(stream)) != EOF)
  162.         putc(ch, fd);
  163.     NXCloseMemory(stream, NX_FREEBUFFER);
  164.     (void)fclose(fd);
  165.     return self;
  166. }
  167.  
  168. - saveAsTiff: sender
  169. {
  170.     NXStream *stream;
  171.     int    fd = -1;
  172.     char    *sav;
  173.     commonInfo *cinf;
  174.     NXBitmapImageRep *rep;
  175.     BOOL    jflag;
  176.     int    type;
  177.     float    factor;
  178.  
  179.     cinf = [toyView commonInfo];
  180.     if (cinf->type == Type_eps)
  181.         return [self saveEPSAsTiff: sender];
  182.  
  183.     rep = (NXBitmapImageRep *)[[toyView image] bestRepresentation];
  184.     jflag = (cinf->bits > 2  /* && cinf->type != Type_eps */
  185.         && [rep canBeCompressedUsing: NX_TIFF_COMPRESSION_JPEG]);
  186.     sav = [self getSaveTiffName: [toyWin filename] jpeg: jflag
  187.         compress: &type by: &factor];
  188.     if (sav == NULL) /* canceled */
  189.         return self;
  190.     /* BUG ?  Over Writing LZW on no-compression */
  191.     if (access(sav, F_OK|W_OK) == 0)
  192.         unlink(sav);
  193.     if ((fd = open(sav, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0
  194.     || (stream = NXOpenFile(fd, NX_WRITEONLY)) == NULL) {
  195.         if (fd >= 0) (void) close(fd);
  196.         errAlert(sav, Err_SAVE);
  197.         return self;
  198.     }
  199.     if (factor < 1.0) factor = 1.0;
  200.     else if (factor > 255.0) factor = 255.0;
  201.     [rep writeTIFF:stream usingCompression:type andFactor:factor];
  202.     NXClose(stream);
  203.     (void)close(fd);
  204.     if (type != NX_TIFF_COMPRESSION_JPEG)
  205.         [toyWin resetFilename:sav];
  206.     return self;
  207. }
  208.  
  209. - saveAsEPS: sender
  210. {
  211.     NXStream *stream;
  212.     char    *sav;
  213.     commonInfo *cinf;
  214.  
  215.     sav = [self getSavename: [toyWin filename] with:Type_eps];
  216.     if (sav == NULL) /* canceled */
  217.         return self;
  218.     if ((stream = [toyWin openEPSStream]) == NULL) {
  219.         errAlert(sav, Err_MEMORY);
  220.         return self;
  221.     }
  222.     if (NXSaveToFile(stream, sav))
  223.         errAlert(sav, Err_SAVE);
  224.     NXCloseMemory(stream, NX_FREEBUFFER);
  225.     cinf = [toyView commonInfo];
  226.     if (cinf->type == Type_eps)
  227.         [toyWin resetFilename:sav];
  228.     return self;
  229. }
  230.  
  231.  
  232. - saveAsType: (int)itype    /* BMP, PPM, JPG, or JBIG */
  233. {
  234.     FILE    *fp;
  235.     char    *sav;
  236.     commonInfo *cinf;
  237.     ColorMap *colormap = nil;
  238.     unsigned char *map[MAXPLANE];
  239.     float    jpegFactor;
  240.     BOOL    progress = NO;
  241.     int    cnum = 0, err = 0;
  242.  
  243.     cinf = [toyView commonInfo];
  244.     if (cinf->cspace == NX_CMYKColorSpace) {
  245.         warnAlert([toyWin filename], Err_SAV_IMPL);
  246.         return self;
  247.     }
  248.     if (itype == Type_jbg
  249.     && (cinf->bits > 2 || cinf->numcolors != 1)) {
  250.         /* ignore alpha, ignore 2 bits gray. Because of EPS... */
  251.         warnAlert([toyWin filename], Err_SAV_IMPL);
  252.         return self;
  253.     }
  254.  
  255.     if (itype == Type_jpg)
  256.         sav = [self getSaveJpegName:[toyWin filename]
  257.                 by:&jpegFactor : &progress];
  258.     else
  259.         sav = [self getSavename:[toyWin filename] with: itype];
  260.     if (sav == NULL) /* canceled */
  261.         return self;
  262.     if ((fp = fopen(sav, "w")) == NULL) {
  263.         errAlert(sav, Err_SAVE);
  264.         return self;
  265.     }
  266.  
  267.     err = [toyWin getBitmap:map info: &cinf];
  268.     if (!err) err = initGetPixel(cinf);
  269.     if (err) goto EXIT;
  270.  
  271.     if (itype == Type_ppm) {
  272.         resetPixel(map, 0);
  273.         err = ppmwrite(fp, cinf, map);
  274.         goto EXIT;
  275.     }else if (itype == Type_jpg) {
  276.         int q;
  277.         resetPixel(map, 0);
  278.         q = (255.0 - jpegFactor) / 2.55 + 0.5;
  279.         q = (q < 0) ? 0 : ((q > 100) ? 100 : q);
  280.         err = jpgwrite(fp, cinf, appDir, q, progress);
  281.         fp = NULL;
  282.         goto EXIT;
  283.     }else if (itype == Type_jbg) {
  284.         resetPixel(map, 0);
  285.         err = jbigwrite(fp, cinf, map[0], appDir);
  286.         fp = NULL;
  287.         goto EXIT;
  288.     }
  289.     /* bmp only */
  290.     colormap = [[ColorMap alloc] init];
  291.     cnum = [self getPalette:colormap
  292.             info:cinf map:map needAlpha:NO err:&err];
  293.     err = 0;    /* Error is ignored */
  294.     if (cnum == 0)
  295.         saveBmpbmap(fp, cinf, FIXcount + 1, NULL, map);
  296.     else
  297.         saveBmpbmap(fp, cinf, cnum, cinf->palette, map);
  298.  
  299. EXIT:
  300.     if (fp) (void)fclose(fp);
  301.     if (colormap) [colormap free];
  302.     [toyWin freeTempBitmap];
  303.     if (err) {
  304.         errAlert(sav, err);
  305.         (void)unlink(sav);
  306.     }else if (itype != Type_jpg)
  307.         [toyWin resetFilename:sav];
  308.     return self;
  309. }
  310.  
  311. @end
  312.