static int commonFormat(int const formatA, int const formatB) { /*---------------------------------------------------------------------------- Return a viable format for the result of composing the two formats 'formatA' and 'formatB'. -----------------------------------------------------------------------------*/ int retval; int const typeA = PAM_FORMAT_TYPE(formatA); int const typeB = PAM_FORMAT_TYPE(formatB); if (typeA == PAM_TYPE || typeB == PAM_TYPE) retval = PAM_FORMAT; else if (typeA == PPM_TYPE || typeB == PPM_TYPE) retval = PPM_FORMAT; else if (typeA == PGM_TYPE || typeB == PGM_TYPE) retval = PGM_FORMAT; else if (typeA == PBM_TYPE || typeB == PBM_TYPE) retval = PBM_FORMAT; else { /* Results are undefined for this case, so we do a hail Mary. */ retval = formatA; } return retval; }
static void computeOutputType(sample * const maxvalP, int * const formatP, char * const tupleTypeP, unsigned int * const depthP, unsigned int const nfiles, const struct pam * const imgs) { unsigned int i; sample maxval; int format; const char * tupleType; unsigned int depth; assert(nfiles > 0); /* initial guesses */ maxval = imgs[0].maxval; format = imgs[0].format; depth = imgs[0].depth; tupleType = imgs[0].tuple_type; for (i = 1; i < nfiles; ++i) { if (PAM_FORMAT_TYPE(imgs[i].format) > PAM_FORMAT_TYPE(format)) { format = imgs[i].format; tupleType = imgs[i].tuple_type; } maxval = MAX(maxval, imgs[i].maxval); depth = MAX(depth, imgs[i].depth); } *maxvalP = maxval; *formatP = format; *depthP = depth; memcpy(tupleTypeP, tupleType, sizeof(imgs[0].tuple_type)); }
int main(int argc, char **argv) { struct pam *imgs; struct pam outimg; struct pam p; int nfiles; int i, j; unsigned int q[10]; coord *coords; const char *headfname = NULL; const char *datafname = NULL; const char *prefix = ""; FILE *header; FILE *data; char **names; char *c; optEntry *option_def = malloc(100*sizeof(optEntry)); /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int option_def_index; option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3( 0, "data", OPT_STRING, &datafname, NULL, 0); OPTENT3( 0, "header", OPT_STRING, &headfname, NULL, 0); OPTENT3('q', "quality", OPT_UINT, &qfactor, NULL, 0); OPTENT3('p', "prefix", OPT_STRING, &prefix, NULL, 0); OPTENT3('0', "0", OPT_FLAG, NULL, &q[0], 0); OPTENT3('1', "1", OPT_FLAG, NULL, &q[1], 0); OPTENT3('2', "2", OPT_FLAG, NULL, &q[2], 0); OPTENT3('3', "3", OPT_FLAG, NULL, &q[3], 0); OPTENT3('4', "4", OPT_FLAG, NULL, &q[4], 0); OPTENT3('5', "5", OPT_FLAG, NULL, &q[5], 0); OPTENT3('6', "6", OPT_FLAG, NULL, &q[6], 0); OPTENT3('7', "7", OPT_FLAG, NULL, &q[7], 0); OPTENT3('8', "8", OPT_FLAG, NULL, &q[8], 0); OPTENT3('9', "9", OPT_FLAG, NULL, &q[9], 0); opt.opt_table = option_def; opt.short_allowed = FALSE; opt.allowNegNum = FALSE; pnm_init(&argc, argv); /* Check for flags. */ optParseOptions3(&argc, argv, opt, sizeof(opt), 0); if (headfname) header = pm_openw(headfname); if (datafname) data = pm_openw(datafname); for (i = 0; i < 10; ++i) { if (q[i]) { quality = i; switch (quality) { case 0: case 1: break; case 2: case 3: case 4: case 5: case 6: qfactor = 100 * (8 - quality); break; case 7: qfactor = 150; break; case 8: qfactor = 125; break; case 9: qfactor = 100; break; } } } if (1 < argc) nfiles = argc - 1; else nfiles = 1; MALLOCARRAY(imgs, nfiles); MALLOCARRAY(coords, nfiles); MALLOCARRAY(names, nfiles); if (!imgs || !coords || !names) pm_error("out of memory"); if (1 < argc) { for (i = 0; i < nfiles; ++i) { if (strchr(argv[i+1], ':')) { imgs[i].file = pm_openr(strchr(argv[i+1], ':') + 1); *strchr(argv[i+1], ':') = 0; names[i] = argv[i+1]; } else { imgs[i].file = pm_openr(argv[i+1]); names[i] = argv[i+1]; } } } else { imgs[0].file = stdin; } pnm_readpaminit(imgs[0].file, &imgs[0], PAM_STRUCT_SIZE(tuple_type)); outimg.maxval = imgs[0].maxval; outimg.format = imgs[0].format; memcpy(outimg.tuple_type, imgs[0].tuple_type, sizeof(imgs[0].tuple_type)); outimg.depth = imgs[0].depth; for (i = 1; i < nfiles; ++i) { pnm_readpaminit(imgs[i].file, &imgs[i], PAM_STRUCT_SIZE(tuple_type)); if (PAM_FORMAT_TYPE(imgs[i].format) > PAM_FORMAT_TYPE(outimg.format)) outimg.format = imgs[i].format, memcpy(outimg.tuple_type, imgs[i].tuple_type, sizeof(imgs[i].tuple_type)); outimg.maxval = imax(imgs[i].maxval, outimg.maxval); outimg.depth = imax(imgs[i].depth, outimg.depth); } for (i = 0; i < nfiles - 1; ++i) for (j = i + 1; j < nfiles; ++j) if (imgs[j].width * imgs[j].height > imgs[i].width * imgs[i].height) p = imgs[i], imgs[i] = imgs[j], imgs[j] = p, c = names[i], names[i] = names[j], names[j] = c; findpack(imgs, nfiles, coords); outimg.height = outimg.width = 0; for (i = 0; i < nfiles; ++i) { outimg.width = imax(outimg.width, imgs[i].width + coords[i].x); outimg.height = imax(outimg.height, imgs[i].height + coords[i].y); } outimg.size = sizeof(outimg); outimg.len = sizeof(outimg); outimg.file = stdout; outimg.bytes_per_sample = 0; for (i = outimg.maxval; i; i >>= 8) ++outimg.bytes_per_sample; writePam(&outimg, nfiles, coords, imgs); if (datafname) { fprintf(data, ":0:0:%u:%u\n", outimg.width, outimg.height); for (i = 0; i < nfiles; ++i) { fprintf(data, "%s:%u:%u:%u:%u\n", names[i], coords[i].x, coords[i].y, imgs[i].width, imgs[i].height); } } if (headfname) { fprintf(header, "#define %sOVERALLX %u\n" "#define %sOVERALLY %u\n" "\n", prefix, outimg.width, prefix, outimg.height); for (i = 0; i < nfiles; ++i) { *strchr(names[i], '.') = 0; for (j = 0; names[i][j]; ++j) { if (ISLOWER(names[i][j])) names[i][j] = TOUPPER(names[i][j]); } fprintf(header, "#define %s%sX %u\n" "#define %s%sY %u\n" "#define %s%sSZX %u\n" "#define %s%sSZY %u\n" "\n", prefix, names[i], coords[i].x, prefix, names[i], coords[i].y, prefix, names[i], imgs[i].width, prefix, names[i], imgs[i].height); } } for (i = 0; i < nfiles; ++i) pm_close(imgs[i].file); pm_close(stdout); if (headfname) pm_close(header); if (datafname) pm_close(data); return 0; }