diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2007-01-21 19:50:56 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2007-01-21 19:50:56 +0000 |
commit | 309587a52754c104178eaec4ca6dc7d98bc54c11 (patch) | |
tree | 27856abd8e6be0b24ca4d1d452a412c86d4ab0cf /editor/ppm3d.c | |
parent | 581931fe0b8c9fe0aae80e0d14acf08d7a5f5e01 (diff) | |
download | netpbm-mirror-309587a52754c104178eaec4ca6dc7d98bc54c11.tar.gz netpbm-mirror-309587a52754c104178eaec4ca6dc7d98bc54c11.tar.xz netpbm-mirror-309587a52754c104178eaec4ca6dc7d98bc54c11.zip |
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@214 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor/ppm3d.c')
-rw-r--r-- | editor/ppm3d.c | 308 |
1 files changed, 214 insertions, 94 deletions
diff --git a/editor/ppm3d.c b/editor/ppm3d.c index c37ceeb1..fd9a10dd 100644 --- a/editor/ppm3d.c +++ b/editor/ppm3d.c @@ -1,18 +1,92 @@ -/* ppmto3d.c - convert a portable pixmap to a portable graymap -** -** Copyright (C) 1989 by Jef Poskanzer. -** -** Permission to use, copy, modify, and distribute this software and its -** documentation for any purpose and without fee is hereby granted, provided -** that the above copyright notice appear in all copies and that both that -** copyright notice and this permission notice appear in supporting -** documentation. This software is provided "as is" without express or -** implied warranty. -*/ +/*============================================================================= + ppmto3d +=============================================================================== + This program converts two PPM images into an anaglyph stereogram image PPM. + (for viewing with red/blue 3D glasses). +=============================================================================*/ + +#include <assert.h> + +#include "shhopt.h" +#include "mallocvar.h" #include "ppm.h" #include "lum.h" + + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * leftInputFileName; /* '-' if stdin */ + const char * rghtInputFileName; /* '-' if stdin */ + unsigned int offset; + unsigned int color; +}; + + + +static void +parseCommandLine(int argc, char ** argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + parse program command line described in Unix standard form by argc + and argv. Return the information in the options as *cmdlineP. + + If command line is internally inconsistent (invalid options, etc.), + issue error message to stderr and abort program. + + Note that the strings we return are stored in the storage that + was passed to us as the argv array. We also trash *argv. +-----------------------------------------------------------------------------*/ + optEntry * option_def; + /* Instructions to optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "color", OPT_FLAG, NULL, + &cmdlineP->color, 0 ); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3( &argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (argc-1 < 2) + pm_error("You must specify at least two arguments: left and right " + "input file names. You specified %u", argc-1); + else { + cmdlineP->leftInputFileName = argv[1]; + cmdlineP->rghtInputFileName = argv[2]; + + if (argc-1 > 2) { + int const offsetnum = atoi(argv[3]); + + if (offsetnum <= 0) + pm_error("Offset must be a positive number. You specified " + "'%s'", argv[3]); + else + cmdlineP->offset = offsetnum; + + if (argc-1 > 3) + pm_error("Program takes at most 3 arguments: left and " + "right input file names and offset. " + "You specified %u", argc-1); + } else + cmdlineP->offset = 30; + } +} + + + static void computeGrayscaleRow(const pixel * const inputRow, gray * const outputRow, @@ -34,105 +108,151 @@ computeGrayscaleRow(const pixel * const inputRow, +static void +compute3dRow(pixel * const lPixelrow, + gray * const lGrayrow, + pixel * const rPixelrow, + gray * const rGrayrow, + pixel * const pixelrow, + unsigned int const cols, + unsigned int const offset) { + + unsigned int col; + gray * lgP; + gray * rgP; + pixel * pP; + + assert(offset <= cols); + + for (col = 0, pP = pixelrow, lgP = lGrayrow, rgP = rGrayrow; + col < cols + offset; + ++col) { + + if (col < offset/2) + ++lgP; + else if (col >= offset/2 && col < offset) { + pixval const blu = (float) *lgP; + pixval const red = 0; + PPM_ASSIGN(*pP, red, blu, blu); + ++lgP; + ++pP; + } else if (col >= offset && col < cols) { + pixval const red = (float) *rgP; + pixval const blu = (float) *lgP; + PPM_ASSIGN(*pP, red, blu, blu); + ++lgP; + ++rgP; + ++pP; + } else if (col >= cols && col < cols + offset/2) { + pixval const blu = 0; + pixval const red = (float) *rgP; + PPM_ASSIGN(*pP, red, blu, blu); + ++rgP; + ++pP; + } else + ++rgP; + } +} + + + +static void +write3dRaster(FILE * const ofP, + FILE * const lIfP, + FILE * const rIfP, + unsigned int const cols, + unsigned int const rows, + pixval const maxval, + int const lFormat, + int const rFormat, + unsigned int const offset) { + + pixel * lPixelrow; + gray * lGrayrow; + pixel * rPixelrow; + gray * rGrayrow; + pixel * pixelrow; + + unsigned int row; + + lPixelrow = ppm_allocrow (cols); + lGrayrow = pgm_allocrow (cols); + rPixelrow = ppm_allocrow (cols); + rGrayrow = pgm_allocrow (cols); + pixelrow = ppm_allocrow (cols); + + for (row = 0; row < rows; ++row) { + ppm_readppmrow(lIfP, lPixelrow, cols, maxval, lFormat); + ppm_readppmrow(rIfP, rPixelrow, cols, maxval, rFormat); + + computeGrayscaleRow(lPixelrow, lGrayrow, maxval, cols); + computeGrayscaleRow(rPixelrow, rGrayrow, maxval, cols); + + compute3dRow(lPixelrow, lGrayrow, rPixelrow, rGrayrow, + pixelrow, cols, offset); + + ppm_writeppmrow(ofP, pixelrow, cols, maxval, 0); + } + + ppm_freerow(pixelrow); + pgm_freerow(rGrayrow); + ppm_freerow(rPixelrow); + pgm_freerow(lGrayrow); + ppm_freerow(lPixelrow); +} + + + int -main (int argc, char *argv[]) { +main(int argc, char *argv[]) { + + struct cmdlineInfo cmdline; + FILE * lIfP; + FILE * rIfP; - int offset; - int cols, rows, row; - pixel* pixelrow; + int cols, rows; pixval maxval; - FILE* Lifp; - pixel* Lpixelrow; - gray* Lgrayrow; - int Lrows, Lcols, Lformat; - pixval Lmaxval; + int lRows, lCols; + int lFormat; + pixval lMaxval; - FILE* Rifp; - pixel* Rpixelrow; - gray* Rgrayrow; - int Rrows, Rcols, Rformat; - pixval Rmaxval; + int rRows, rCols; + int rFormat; + pixval rMaxval; - ppm_init (&argc, argv); + ppm_init(&argc, argv); - if (argc-1 > 3 || argc-1 < 2) - pm_error("Wrong number of arguments (%d). Arguments are " - "leftppmfile rightppmfile [horizontal_offset]", argc-1); + parseCommandLine(argc, argv, &cmdline); - Lifp = pm_openr (argv[1]); - Rifp = pm_openr (argv[2]); + lIfP = pm_openr(cmdline.leftInputFileName); + rIfP = pm_openr(cmdline.rghtInputFileName); - if (argc-1 >= 3) - offset = atoi (argv[3]); - else - offset = 30; - - ppm_readppminit (Lifp, &Lcols, &Lrows, &Lmaxval, &Lformat); - ppm_readppminit (Rifp, &Rcols, &Rrows, &Rmaxval, &Rformat); + ppm_readppminit(lIfP, &lCols, &lRows, &lMaxval, &lFormat); + ppm_readppminit(rIfP, &rCols, &rRows, &rMaxval, &rFormat); - if ((Lcols != Rcols) || (Lrows != Rrows) || - (Lmaxval != Rmaxval) || - (PPM_FORMAT_TYPE(Lformat) != PPM_FORMAT_TYPE(Rformat))) + if ((lCols != rCols) || (lRows != rRows) || + (lMaxval != rMaxval) || + (PPM_FORMAT_TYPE(lFormat) != PPM_FORMAT_TYPE(rFormat))) pm_error ("Pictures are not of same size and format"); - cols = Lcols; - rows = Lrows; - maxval = Lmaxval; + cols = lCols; + rows = lRows; + maxval = lMaxval; + + if (cmdline.offset >= cols) + pm_error("Offset (%u columns) is not less than width of images " + "(%u columns)", cmdline.offset, cols); - ppm_writeppminit (stdout, cols, rows, maxval, 0); - Lpixelrow = ppm_allocrow (cols); - Lgrayrow = pgm_allocrow (cols); - Rpixelrow = ppm_allocrow (cols); - Rgrayrow = pgm_allocrow (cols); - pixelrow = ppm_allocrow (cols); + ppm_writeppminit(stdout, cols, rows, maxval, 0); - for (row = 0; row < rows; ++row) { - ppm_readppmrow(Lifp, Lpixelrow, cols, maxval, Lformat); - ppm_readppmrow(Rifp, Rpixelrow, cols, maxval, Rformat); - - computeGrayscaleRow(Lpixelrow, Lgrayrow, maxval, cols); - computeGrayscaleRow(Rpixelrow, Rgrayrow, maxval, cols); - { - int col; - gray* LgP; - gray* RgP; - pixel* pP; - for (col = 0, pP = pixelrow, LgP = Lgrayrow, RgP = Rgrayrow; - col < cols + offset; - ++col) { - - if (col < offset/2) - ++LgP; - else if (col >= offset/2 && col < offset) { - const pixval Blue = (pixval) (float) *LgP; - const pixval Red = (pixval) 0; - PPM_ASSIGN (*pP, Red, Blue, Blue); - ++LgP; - ++pP; - } else if (col >= offset && col < cols) { - const pixval Red = (pixval) (float) *RgP; - const pixval Blue = (pixval) (float) *LgP; - PPM_ASSIGN (*pP, Red, Blue, Blue); - ++LgP; - ++RgP; - ++pP; - } else if (col >= cols && col < cols + offset/2) { - const pixval Blue = (pixval) 0; - const pixval Red = (pixval) (float) *RgP; - PPM_ASSIGN (*pP, Red, Blue, Blue); - ++RgP; - ++pP; - } else - ++RgP; - } - } - ppm_writeppmrow(stdout, pixelrow, cols, maxval, 0); - } + write3dRaster(stdout, lIfP, rIfP, cols, rows, maxval, + lFormat, rFormat, cmdline.offset); - pm_close(Lifp); - pm_close(Rifp); + pm_close(lIfP); + pm_close(rIfP); pm_close(stdout); return 0; } + |