home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/file.h>
- #include <sys/wait.h>
- #include <bsd/libc.h>
- #include "../ppm.h"
- #include "../common.h"
- #include "../strfunc.h"
- #include "save.h"
-
- FILE *openWPipe(FILE *fp, const char **list, int *err)
- {
- int pfd[2];
- int pid;
-
- /* if (*err != 0) then fork() didn't called successfully */
- *err = 0;
- if (list == NULL || access(list[0], X_OK) < 0) {
- *err = Err_FLT_EXEC;
- return NULL; /* not executable */
- }
- (void)pipe(pfd);
- if ((pid = fork()) == 0) { /* child process */
- (void)close(0);
- dup(pfd[0]);
- (void)close(1);
- dup(fileno(fp));
- (void)fclose(fp);
- (void)close(pfd[0]);
- (void)close(pfd[1]);
- execv(list[0], &list[1]);
- exit(1); /* Error */
- }else if (pid < 0) { /* ERROR */
- *err = Err_FLT_EXEC;
- (void)close(pfd[0]);
- (void)close(pfd[1]);
- (void)fclose(fp);
- return NULL;
- }
- (void)close(pfd[0]);
- (void)fclose(fp);
- return fdopen(pfd[1], "w");
- }
-
-
- int ppmwrite(FILE *fp, const commonInfo *cinf, unsigned char **planes)
- {
- int max = 255, sft = 0, n;
- int r, g, b, a;
-
- switch (cinf->bits) {
- case 1: max = 1; sft = 7; break;
- case 2: max = 3; sft = 6; break;
- case 4: max = 15; sft = 4; break;
- case 8: max = 255; sft = 0; break;
- }
-
- if (cinf->numcolors > 1) { /* color */
- /* PPM Binary */
- fprintf(fp, "P6\n# %s\n%d %d %d\n",
- key_comm(cinf), cinf->width, cinf->height, max);
- n = cinf->width * cinf->height;
- if (sft)
- while (n-- > 0) {
- (void) getPixel(&r, &g, &b, &a);
- putc(r >> sft, fp);
- putc(g >> sft, fp);
- putc(b >> sft, fp);
- }
- else
- while (n-- > 0) {
- (void) getPixel(&r, &g, &b, &a);
- putc(r, fp);
- putc(g, fp);
- putc(b, fp);
- }
- }else if (max == 1) { /* Bi-Level */
- /* PBM Binary */
- int x = (cinf->width + 7) >> 3;
- int y = cinf->height;
- unsigned char *p = planes[0];
- fprintf(fp, "P4\n# %s\n%d %d\n",
- key_comm(cinf), cinf->width, cinf->height);
- while (y-- > 0) {
- if (cinf->cspace == NX_OneIsWhiteColorSpace)
- for (n = 0; n < x; n++)
- putc(p[n] ^ 0xff, fp);
- else
- for (n = 0; n < x; n++)
- putc(p[n], fp);
- p += cinf->xbytes;
- }
- }else { /* Gray */
- /* PGM Binary */
- fprintf(fp, "P5\n# %s\n%d %d %d\n",
- key_comm(cinf), cinf->width, cinf->height, max);
- n = cinf->width * cinf->height;
- if (sft)
- while (n-- > 0) {
- (void) getPixel(&r, &g, &b, &a);
- putc(r >> sft, fp);
- }
- else
- while (n-- > 0) {
- (void) getPixel(&r, &g, &b, &a);
- putc(r, fp);
- }
- }
- return 0;
- }
-
-
- int jpgwrite(FILE *fp, const commonInfo *cinf, const char *dir,
- int quality, BOOL progressive)
- {
- int r, g, b, a, n, argp, err;
- char cjpegPath[MAXFILENAMELEN];
- char cjpegQuality[16];
- char comm_text[MAX_COMMENT];
- const char *cmp;
- static char *cjpegArg[10] = {
- NULL, /* 0: Tool Path */
- CJPEG,
- "-quality",
- NULL, /* 3: Quality (0-100) */
- "-optimize",
- NULL, /* 5: -grayscale (maybe) */
- NULL, /* 6: -progressive (maybe) */
- NULL, /* 7: -comment (maybe) */
- NULL, NULL };
-
- sprintf(cjpegPath, "%s/%s", dir, CJPEG);
- cjpegArg[0] = cjpegPath;
- sprintf(cjpegQuality, "%d", quality);
- cjpegArg[3] = cjpegQuality;
- argp = 5;
- if (cinf->numcolors == 1) /* mono */
- cjpegArg[argp++] = "-grayscale";
- if (progressive)
- cjpegArg[argp++] = "-progressive";
- if ((cmp = begin_comm(cinf->memo, YES)) != NULL) {
- int i, cc;
- for (i = 0; cmp[i]; i++) {
- if ((cc = cmp[i] & 0xff) < ' ') cc = ' ';
- comm_text[i] = cc;
- }
- comm_text[i] = 0;
- cjpegArg[argp++] = "-comment";
- cjpegArg[argp++] = comm_text;
- }
- cjpegArg[argp] = NULL;
-
- if ((fp = openWPipe(fp, cjpegArg, &err)) == NULL)
- return err;
-
- n = cinf->width * cinf->height;
- if (cinf->numcolors > 1) { /* color */
- /* PPM Binary */
- fprintf(fp, "P6\n# %s\n%d %d 255\n",
- key_comm(cinf), cinf->width, cinf->height);
- while (n-- > 0) {
- (void) getPixel(&r, &g, &b, &a);
- putc(r, fp);
- putc(g, fp);
- putc(b, fp);
- }
- }else { /* Gray */
- /* PGM Binary */
- fprintf(fp, "P5\n# %s\n%d %d 255\n",
- key_comm(cinf), cinf->width, cinf->height);
- while (n-- > 0) {
- (void) getPixel(&r, &g, &b, &a);
- putc(r, fp);
- }
- }
- (void)fclose(fp);
- wait(0); /* Don't forget */
- return 0;
- }
-
-
- int jbigwrite(FILE *fp, const commonInfo *cinf, const char *map, const char *dir)
- {
- int x, y, xb, xbytes, neg = 0, err = 0;
- char jbigPath[MAXFILENAMELEN];
- const unsigned char *pp, *pmap = NULL;
- static char *jbigArg[4] = {
- NULL, /* 0: Tool Path */
- PBM_JBIG,
- NULL };
-
- sprintf(jbigPath, "%s/%s", dir, PBM_JBIG);
- jbigArg[0] = jbigPath;
-
- if ((fp = openWPipe(fp, jbigArg, &err)) == NULL)
- return err;
-
- xbytes = xb = (cinf->width + 7) >> 3;
- if (cinf->alpha || cinf->bits != 1) {
- pmap = pp = allocBilevelMap(cinf);
- if (!pp) {
- err = Err_MEMORY;
- goto EXIT;
- }
- }else {
- pp = map;
- xbytes = cinf->xbytes;
- neg = (cinf->cspace == NX_OneIsWhiteColorSpace);
- }
- fprintf(fp, "P4\n# %s\n%d %d\n",
- key_comm(cinf), cinf->width, cinf->height);
- for (y = 0; y < cinf->height; y++) {
- if (neg)
- for (x = 0; x < xb; x++)
- putc(*pp++ ^ 0xff, fp);
- else
- for (x = 0; x < xb; x++)
- putc(*pp++, fp);
- for ( ; x < xbytes; x++) ++pp;
- }
- EXIT:
- (void)fclose(fp);
- wait(0); /* Don't forget */
- if (pmap) free((void *)pmap);
- return err;
- }
-
- unsigned char *allocBilevelMap(const commonInfo *cinf)
- {
- unsigned char *pp, *q;
- int x, y, val, mask;
- int r, g, b, a;
- static unsigned short pattern[4][4]= {
- { 102, 153, 102, 153 },
- { 204, 51, 204, 51 },
- { 102, 153, 102, 153 },
- { 204, 51, 204, 51 } };
-
- pp = (unsigned char *)malloc(((cinf->width + 7) >> 3) * cinf->height);
- if (!pp) return NULL;
- q = pp;
- val = 0;
- mask = 0x80;
- x = cinf->width;
- for (y = 0; y < cinf->height; y++) {
- for (x = cinf->width; x > 0; ) {
- (void) getPixel(&r, &g, &b, &a);
- if (pattern[x & 3][y & 3] > r) val |= mask;
- --x;
- if (!(mask >>= 1) || x <= 0) {
- *q++ = val;
- val = 0;
- mask = 0x80;
- }
- }
- }
- return pp;
- }
-