home *** CD-ROM | disk | FTP | other *** search
- #import "../ImageSave.h"
- #import <appkit/NXImage.h>
- #import <appkit/SavePanel.h>
- #import <stdio.h>
- #import <libc.h>
- #import <string.h>
- #import "../ToyView.h"
- #import "../ToyWin.h"
- #import "../ColorMap.h"
- #import "../strfunc.h"
- #import "../common.h"
- #import "save.h"
- #import "GifSavePanel.h"
-
- #define MANY_COLORS (-1) /* must be < 0 */
-
-
- @implementation ImageSave (SaveGIF)
-
- /* Local Method */
- - (char *)getSaveIntlName: (const char *)path
- ext: (const char *)ex interlace: (BOOL *)intp
- {
- GifSavePanel *savePanel;
- char *stmp, *sav = NULL;
-
- stmp = [ImageSave mk_tmpname:path ext:ex nopath:YES];
- savePanel = [[GifSavePanel new] loadNib];
- 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]);
- *intp = [savePanel interlace];
- }
- return sav;
- }
-
-
- - (int)getPalette:(ColorMap *)colormap info:(commonInfo *)cinf
- map:(unsigned char **)map needAlpha:(BOOL)alflag err:(int *)code
- {
- int cnum, err;
- BOOL hasalpha;
-
- err = 0;
- if (cinf->palette != NULL) {
- if ([colormap allocPalColor] == nil) {
- err = Err_MEMORY;
- goto EXIT;
- }
- cnum = [colormap regPalColorWithAlpha: alflag];
- if (cnum > FIXcount)
- err = MANY_COLORS;
- goto EXIT;
- }
-
- if ([colormap allocFullColor] == nil) {
- err = Err_MEMORY;
- goto EXIT;
- }
- cnum = alflag
- ? [colormap getAllColor:map limit:FIXcount alpha:&hasalpha]
- : [colormap getAllColor:map limit:FIXcount];
- if (hasalpha) ++cnum;
- if (cnum > FIXcount)
- err = MANY_COLORS;
- else {
- (void)[colormap getNormalmap: &cnum];
- cinf->palette = [colormap getPalette];
- cinf->palsteps = cnum;
- }
- EXIT:
- if (err) {
- *code = err;
- return 0;
- }
- return cinf->palsteps;
- }
-
-
- - (char *)saveAsGif: (char *)gifname
- {
- char *sav, *result = NULL;
- commonInfo *cinf;
- ColorMap *colormap = nil;
- unsigned char *map[MAXPLANE];
- int cnum, err;
- static BOOL interl = NO;
-
- cinf = [toyView commonInfo];
- if (cinf->cspace == NX_CMYKColorSpace) {
- warnAlert([toyWin filename], Err_SAV_IMPL);
- return NULL;
- }
-
- if (gifname) /* Called after reduction */
- sav = gifname;
- else {
- sav = [self getSaveIntlName: [toyWin filename]
- ext: "gif" interlace: &interl];
- if (sav == NULL) /* canceled */
- return NULL;
- }
-
- if ((err = [toyWin getBitmap:map info: &cinf]) != 0)
- goto EXIT;
- if ((err = initGetPixel(cinf)) != 0)
- goto EXIT;
-
- colormap = [[ColorMap alloc] init];
- cnum = [self getPalette:colormap
- info:cinf map:map needAlpha:YES err:&err];
- if (cnum == 0) {
- const char *ask, *cancel, *reduce;
- if (err != MANY_COLORS)
- goto EXIT;
- ask = NXLocalizedString(
- "Reduction Start", NULL, GIF_Reduction);
- cancel = NXLocalizedString("Cancel", NULL, Stop_SAVE);
- reduce = NXLocalizedString("Reduce", NULL, BMP_Reduce);
- if (NXRunAlertPanel("", ask, reduce, cancel, NULL))
- result = sav; /* Save after reduction */
- goto EXIT;
- }
-
- if (!err) {
- FILE *fp;
- int transp;
-
- transp = (cinf->alpha && cinf->palette) ? cinf->palsteps : -1;
- if ((fp = fopen(sav, "w")) == NULL) {
- errAlert(sav, Err_SAVE);
- [colormap free];
- [toyWin freeTempBitmap];
- return NULL; // Don't goto EXIT.
- }
- GIFEncode(fp, cinf, map, cnum, transp, interl, cinf->palette);
- (void)fclose(fp);
- [toyWin resetFilename:sav];
- }
-
- EXIT:
- if (colormap) [colormap free];
- [toyWin freeTempBitmap];
- if (err) {
- errAlert(sav, err);
- (void)unlink(sav);
- }
- /* result != NULL --> This method is called again after Reduction */
- return result;
- }
-
-
- - saveAsPng: sender
- {
- commonInfo *cinf;
- commonInfo copyinf;
- FILE *fp;
- ColorMap *colormap = nil;
- char *sav;
- unsigned char *map[MAXPLANE];
- int err;
- static BOOL interl = NO;
-
- cinf = [toyView commonInfo];
- if (cinf->cspace == NX_CMYKColorSpace) {
- warnAlert([toyWin filename], Err_SAV_IMPL);
- return NULL;
- }
- if ((sav = [self getSaveIntlName: [toyWin filename]
- ext: "png" interlace: &interl]) == NULL) /* canceled */
- return NULL;
- 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 (cinf->cspace != NX_RGBColorSpace) { /* Monochrome */
- copyinf = *cinf;
- copyinf.palette = NULL; /* No need to allocate palette */
- copyinf.palsteps = 0;
- cinf = ©inf;
- }else {
- colormap = [[ColorMap alloc] init];
- (void) [self getPalette:colormap
- info:cinf map:map needAlpha:YES err:&err];
- err = 0; /* Error is ignored */
- }
- resetPixel(map, 0);
- pngwrite(fp, cinf, appDir, interl);
- /* fp is closed in pngwrite */
- EXIT:
- if (colormap) [colormap free];
- [toyWin freeTempBitmap];
- if (err) {
- errAlert(sav, err);
- (void)unlink(sav);
- }else
- [toyWin resetFilename:sav];
- return self;
- }
-
- @end
-