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

  1. #import "../ImageSave.h"
  2. #import <appkit/NXImage.h>
  3. #import <appkit/SavePanel.h>
  4. #import <stdio.h>
  5. #import <libc.h>
  6. #import <string.h>
  7. #import "../ToyView.h"
  8. #import "../ToyWin.h"
  9. #import "../ColorMap.h"
  10. #import "../strfunc.h"
  11. #import "../common.h"
  12. #import "save.h"
  13. #import "GifSavePanel.h"
  14.  
  15. #define  MANY_COLORS    (-1)    /* must be < 0 */
  16.  
  17.  
  18. @implementation ImageSave (SaveGIF)
  19.  
  20. /* Local Method */
  21. - (char *)getSaveIntlName: (const char *)path
  22.         ext: (const char *)ex interlace: (BOOL *)intp
  23. {
  24.     GifSavePanel *savePanel;
  25.     char    *stmp, *sav = NULL;
  26.  
  27.     stmp = [ImageSave mk_tmpname:path ext:ex nopath:YES];
  28.     savePanel = [[GifSavePanel new] loadNib];
  29.     if ([savePanel runModalForDirectory: saveDir file: stmp]) {
  30.         sav = [ImageSave mk_tmpname:
  31.                 [savePanel filename] ext:ex nopath:NO];
  32.         if (sav == NULL || *sav == 0)
  33.             return NULL;
  34.         strcpy(saveDir, [savePanel directory]);
  35.         *intp = [savePanel interlace];
  36.     }
  37.     return sav;
  38. }
  39.  
  40.  
  41. - (int)getPalette:(ColorMap *)colormap info:(commonInfo *)cinf
  42.     map:(unsigned char **)map needAlpha:(BOOL)alflag err:(int *)code
  43. {
  44.     int cnum, err;
  45.     BOOL hasalpha;
  46.  
  47.     err = 0;
  48.     if (cinf->palette != NULL) {
  49.         if ([colormap allocPalColor] == nil) {
  50.             err = Err_MEMORY;
  51.             goto EXIT;
  52.         }
  53.         cnum = [colormap regPalColorWithAlpha: alflag];
  54.         if (cnum > FIXcount)
  55.             err = MANY_COLORS;
  56.         goto EXIT;
  57.     }
  58.  
  59.     if ([colormap allocFullColor] == nil) {
  60.         err = Err_MEMORY;
  61.         goto EXIT;
  62.     }
  63.     cnum = alflag
  64.         ? [colormap getAllColor:map limit:FIXcount alpha:&hasalpha]
  65.         : [colormap getAllColor:map limit:FIXcount];
  66.     if (hasalpha) ++cnum;
  67.     if (cnum > FIXcount)
  68.         err = MANY_COLORS;
  69.     else {
  70.         (void)[colormap getNormalmap: &cnum];
  71.         cinf->palette = [colormap getPalette];
  72.         cinf->palsteps = cnum;
  73.     }
  74. EXIT:
  75.     if (err) {
  76.         *code = err;
  77.         return 0;
  78.     }
  79.     return cinf->palsteps;
  80. }
  81.  
  82.  
  83. - (char *)saveAsGif: (char *)gifname
  84. {
  85.     char    *sav, *result = NULL;
  86.     commonInfo *cinf;
  87.     ColorMap *colormap = nil;
  88.     unsigned char *map[MAXPLANE];
  89.     int    cnum, err;
  90.     static BOOL    interl = NO;
  91.  
  92.     cinf = [toyView commonInfo];
  93.     if (cinf->cspace == NX_CMYKColorSpace) {
  94.         warnAlert([toyWin filename], Err_SAV_IMPL);
  95.         return NULL;
  96.     }
  97.  
  98.     if (gifname) /* Called after reduction */
  99.         sav = gifname;
  100.     else {
  101.         sav = [self getSaveIntlName: [toyWin filename]
  102.                 ext: "gif" interlace: &interl];
  103.         if (sav == NULL) /* canceled */
  104.             return NULL;
  105.     }
  106.  
  107.     if ((err = [toyWin getBitmap:map info: &cinf]) != 0)
  108.         goto EXIT;
  109.     if ((err = initGetPixel(cinf)) != 0)
  110.         goto EXIT;
  111.  
  112.     colormap = [[ColorMap alloc] init];
  113.     cnum = [self getPalette:colormap
  114.         info:cinf map:map needAlpha:YES err:&err];
  115.     if (cnum == 0) {
  116.         const char *ask, *cancel, *reduce;
  117.         if (err != MANY_COLORS)
  118.             goto EXIT;
  119.         ask = NXLocalizedString(
  120.                 "Reduction Start", NULL, GIF_Reduction);
  121.         cancel = NXLocalizedString("Cancel", NULL, Stop_SAVE);
  122.         reduce = NXLocalizedString("Reduce", NULL, BMP_Reduce);
  123.         if (NXRunAlertPanel("", ask, reduce, cancel, NULL))
  124.             result = sav; /* Save after reduction */
  125.         goto EXIT;
  126.     }
  127.  
  128.     if (!err) {
  129.         FILE    *fp;
  130.         int    transp;
  131.  
  132.         transp = (cinf->alpha && cinf->palette) ? cinf->palsteps : -1;
  133.         if ((fp = fopen(sav, "w")) == NULL) {
  134.             errAlert(sav, Err_SAVE);
  135.             [colormap free];
  136.             [toyWin freeTempBitmap];
  137.             return NULL;    // Don't goto EXIT.
  138.         }
  139.         GIFEncode(fp, cinf, map, cnum, transp, interl, cinf->palette);
  140.         (void)fclose(fp);
  141.         [toyWin resetFilename:sav];
  142.     }
  143.  
  144. EXIT:
  145.     if (colormap) [colormap free];
  146.     [toyWin freeTempBitmap];
  147.     if (err) {
  148.         errAlert(sav, err);
  149.         (void)unlink(sav);
  150.     }
  151.     /* result != NULL  -->  This method is called again after Reduction */
  152.     return result;
  153. }
  154.  
  155.  
  156. - saveAsPng: sender
  157. {
  158.     commonInfo *cinf;
  159.     commonInfo copyinf;
  160.     FILE    *fp;
  161.     ColorMap *colormap = nil;
  162.     char    *sav;
  163.     unsigned char *map[MAXPLANE];
  164.     int    err;
  165.     static BOOL    interl = NO;
  166.  
  167.     cinf = [toyView commonInfo];
  168.     if (cinf->cspace == NX_CMYKColorSpace) {
  169.         warnAlert([toyWin filename], Err_SAV_IMPL);
  170.         return NULL;
  171.     }
  172.     if ((sav = [self getSaveIntlName: [toyWin filename]
  173.         ext: "png" interlace: &interl]) == NULL) /* canceled */
  174.         return NULL;
  175.     if ((fp = fopen(sav, "w")) == NULL) {
  176.         errAlert(sav, Err_SAVE);
  177.         return self;
  178.     }
  179.     err = [toyWin getBitmap:map info: &cinf];
  180.     if (!err) err = initGetPixel(cinf);
  181.     if (err) goto EXIT;
  182.     if (cinf->cspace != NX_RGBColorSpace) { /* Monochrome */
  183.         copyinf = *cinf;
  184.         copyinf.palette = NULL;    /* No need to allocate palette */
  185.         copyinf.palsteps = 0;
  186.         cinf = ©inf;
  187.     }else {
  188.         colormap = [[ColorMap alloc] init];
  189.         (void) [self getPalette:colormap
  190.             info:cinf map:map needAlpha:YES err:&err];
  191.         err = 0;    /* Error is ignored */
  192.     }
  193.     resetPixel(map, 0);
  194.     pngwrite(fp, cinf, appDir, interl);
  195.     /* fp is closed in pngwrite */
  196. EXIT:
  197.     if (colormap) [colormap free];
  198.     [toyWin freeTempBitmap];
  199.     if (err) {
  200.         errAlert(sav, err);
  201.         (void)unlink(sav);
  202.     }else
  203.         [toyWin resetFilename:sav];
  204.     return self;
  205. }
  206.  
  207. @end
  208.