This is ppmwrite.c in view mode; [Download] [Up]
#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; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.