about summary refs log tree commit diff
path: root/generator/pamstereogram.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2012-12-30 03:41:48 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2012-12-30 03:41:48 +0000
commitdfedbf6375ee62772b9049b023d0598953309385 (patch)
tree93f8a2e6805c13cb23dd8c6989f018d31f711ccd /generator/pamstereogram.c
parent91b60799c42e87bf67c44cca4ca7f5b60c6c8da2 (diff)
downloadnetpbm-mirror-dfedbf6375ee62772b9049b023d0598953309385.tar.gz
netpbm-mirror-dfedbf6375ee62772b9049b023d0598953309385.tar.xz
netpbm-mirror-dfedbf6375ee62772b9049b023d0598953309385.zip
Replace negative -guidesize trick with -guidetop/-guidebottom
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1820 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'generator/pamstereogram.c')
-rw-r--r--generator/pamstereogram.c218
1 files changed, 136 insertions, 82 deletions
diff --git a/generator/pamstereogram.c b/generator/pamstereogram.c
index 6a9fdd44..115dd6f0 100644
--- a/generator/pamstereogram.c
+++ b/generator/pamstereogram.c
@@ -70,17 +70,19 @@ struct cmdlineInfo {
     unsigned int crosseyed;      /* -crosseyed option */
     unsigned int makemask;       /* -makemask option */
     unsigned int dpi;            /* -dpi option */
-    float eyesep;                /* -eyesep option */
-    float depth;                 /* -depth option */
+    float        eyesep;         /* -eyesep option */
+    float        depth;          /* -depth option */
     unsigned int maxvalSpec;     /* -maxval option count */
-    unsigned int maxval;         /* -maxval option value x*/
-    int guidesize;               /* -guidesize option */
+    unsigned int maxval;         /* -maxval option value */
+    unsigned int guidetop;       /* -guidetop option count */
+    unsigned int guidebottom;    /* -guidebottom option count */
+    unsigned int guidesize;      /* -guidesize option value */
     unsigned int magnifypat;     /* -magnifypat option */
     unsigned int xshift;         /* -xshift option */
     unsigned int yshift;         /* -yshift option */
-    const char * patFilespec;    /* -patfile option.  Null if none */
-    const char * texFilespec;    /* -texfile option.  Null if none */
-    const char * bgColorName;    /* -bgcolor option */
+    const char * patfile;        /* -patfile option.  Null if none */
+    const char * texfile;        /* -texfile option.  Null if none */
+    const char * bgcolor;        /* -bgcolor option */
     unsigned int smoothing;      /* -smoothing option */
     unsigned int randomseed;     /* -randomseed option */
     unsigned int randomseedSpec; /* -randomseed option count */
@@ -144,10 +146,10 @@ parseCommandLine(int                  argc,
 
     unsigned int patfileSpec, texfileSpec, dpiSpec, eyesepSpec, depthSpec,
         guidesizeSpec, magnifypatSpec, xshiftSpec, yshiftSpec,
-        bgColorNameSpec, smoothingSpec, planesSpec;
+        bgcolorSpec, smoothingSpec, planesSpec;
 
     unsigned int blackandwhite, grayscale, color;
-    const char ** nearFarPlanes;
+    const char ** planes;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
 
@@ -172,6 +174,10 @@ parseCommandLine(int                  argc,
             &depthSpec,               0);
     OPTENT3(0, "maxval",          OPT_UINT,   &cmdlineP->maxval,
             &cmdlineP->maxvalSpec,    0);
+    OPTENT3(0, "guidetop",        OPT_FLAG,   NULL,
+            &cmdlineP->guidetop,      0);
+    OPTENT3(0, "guidebottom",     OPT_FLAG,   NULL,
+            &cmdlineP->guidebottom,   0);
     OPTENT3(0, "guidesize",       OPT_INT,    &cmdlineP->guidesize,
             &guidesizeSpec,           0);
     OPTENT3(0, "magnifypat",      OPT_UINT,   &cmdlineP->magnifypat,
@@ -180,17 +186,17 @@ parseCommandLine(int                  argc,
             &xshiftSpec,              0);
     OPTENT3(0, "yshift",          OPT_UINT,   &cmdlineP->yshift,
             &yshiftSpec,              0);
-    OPTENT3(0, "patfile",         OPT_STRING, &cmdlineP->patFilespec,
+    OPTENT3(0, "patfile",         OPT_STRING, &cmdlineP->patfile,
             &patfileSpec,             0);
-    OPTENT3(0, "texfile",         OPT_STRING, &cmdlineP->texFilespec,
+    OPTENT3(0, "texfile",         OPT_STRING, &cmdlineP->texfile,
             &texfileSpec,             0);
-    OPTENT3(0, "bgcolor",         OPT_STRING, &cmdlineP->bgColorName,
-            &bgColorNameSpec,         0);
+    OPTENT3(0, "bgcolor",         OPT_STRING, &cmdlineP->bgcolor,
+            &bgcolorSpec,             0);
     OPTENT3(0, "randomseed",      OPT_UINT,   &cmdlineP->randomseed,
             &cmdlineP->randomseedSpec, 0);
     OPTENT3(0, "smoothing",       OPT_UINT,   &cmdlineP->smoothing,
             &smoothingSpec,           0);
-    OPTENT3(0, "planes",          OPT_STRINGLIST, &nearFarPlanes,
+    OPTENT3(0, "planes",          OPT_STRINGLIST, &planes,
             &planesSpec,              0);
 
     opt.opt_table = option_def;
@@ -216,11 +222,11 @@ parseCommandLine(int                  argc,
         }
     }
     if (!patfileSpec)
-        cmdlineP->patFilespec = NULL;
+        cmdlineP->patfile = NULL;
     if (!texfileSpec)
-        cmdlineP->texFilespec = NULL;
-    if (!bgColorNameSpec)
-        cmdlineP->bgColorName = NULL;
+        cmdlineP->texfile = NULL;
+    if (!bgcolorSpec)
+        cmdlineP->bgcolor = NULL;
     if (!smoothingSpec)
         cmdlineP->smoothing = 0;
 
@@ -246,12 +252,16 @@ parseCommandLine(int                  argc,
             pm_error("-maxval must be at most %u.  You specified %u",
                      PNM_OVERALLMAXVAL, cmdlineP->maxval);
     }
-    if (bgColorNameSpec && !texfileSpec)
+    if (bgcolorSpec && !texfileSpec)
         pm_message("warning: -bgcolor has no effect "
                    "except in conjunction with -texfile");
 
+    if (guidesizeSpec && !(cmdlineP->guidetop || cmdlineP->guidebottom))
+        pm_error("-guidesize has no meaning "
+                 "without -guidetop or -guidebottom");
+
     if (!guidesizeSpec)
-        cmdlineP->guidesize = 0;
+        cmdlineP->guidesize = 3;
 
     if (!magnifypatSpec)
         cmdlineP->magnifypat = 1;
@@ -264,30 +274,30 @@ parseCommandLine(int                  argc,
     if (!yshiftSpec)
         cmdlineP->yshift = 0;
 
-    if (xshiftSpec && !cmdlineP->patFilespec)
+    if (xshiftSpec && !cmdlineP->patfile)
         pm_error("-xshift is valid only with -patfile");
-    if (yshiftSpec && !cmdlineP->patFilespec)
+    if (yshiftSpec && !cmdlineP->patfile)
         pm_error("-yshift is valid only with -patfile");
 
-    if (cmdlineP->makemask && cmdlineP->patFilespec)
+    if (cmdlineP->makemask && cmdlineP->patfile)
         pm_error("You may not specify both -makemask and -patfile");
 
-    if (cmdlineP->patFilespec && blackandwhite)
+    if (cmdlineP->patfile && blackandwhite)
         pm_error("-blackandwhite is not valid with -patfile");
-    if (cmdlineP->patFilespec && grayscale)
+    if (cmdlineP->patfile && grayscale)
         pm_error("-grayscale is not valid with -patfile");
-    if (cmdlineP->patFilespec && color)
+    if (cmdlineP->patfile && color)
         pm_error("-color is not valid with -patfile");
-    if (cmdlineP->patFilespec && cmdlineP->maxvalSpec)
+    if (cmdlineP->patfile && cmdlineP->maxvalSpec)
         pm_error("-maxval is not valid with -patfile");
 
-    if (cmdlineP->texFilespec && blackandwhite)
+    if (cmdlineP->texfile && blackandwhite)
         pm_error("-blackandwhite is not valid with -texfile");
-    if (cmdlineP->texFilespec && grayscale)
+    if (cmdlineP->texfile && grayscale)
         pm_error("-grayscale is not valid with -texfile");
-    if (cmdlineP->texFilespec && color)
+    if (cmdlineP->texfile && color)
         pm_error("-color is not valid with -texfile");
-    if (cmdlineP->texFilespec && cmdlineP->maxvalSpec)
+    if (cmdlineP->texfile && cmdlineP->maxvalSpec)
         pm_error("-maxval is not valid with -texfile");
     if (planesSpec && eyesepSpec)
         pm_error("-planes is not valid with -eyesep");
@@ -296,7 +306,7 @@ parseCommandLine(int                  argc,
 
     if (planesSpec) {
         float nearPlane, farPlane;
-        parseNearFarPlanes(nearFarPlanes, &nearPlane, &farPlane);
+        parseNearFarPlanes(planes, &nearPlane, &farPlane);
         cmdlineP->eyesep = 2.0*farPlane/cmdlineP->dpi;
         cmdlineP->depth = 2.0*(farPlane-nearPlane) / (2.0*farPlane-nearPlane);
     }
@@ -547,9 +557,9 @@ initPatternPixel(outGenerator *     const outGenP,
 
     MALLOCVAR_NOFAIL(stateP);
 
-    assert(cmdline.patFilespec);
+    assert(cmdline.patfile);
 
-    patternFileP = pm_openr(cmdline.patFilespec);
+    patternFileP = pm_openr(cmdline.patfile);
 
     stateP->patTuples =
         pnm_readpam(patternFileP,
@@ -589,18 +599,18 @@ readTextureImage(struct cmdlineInfo const cmdline,
     MALLOCVAR_NOFAIL(textureP);
     texPamP = &textureP->pam;
 
-    textureFileP = pm_openr(cmdline.texFilespec);
+    textureFileP = pm_openr(cmdline.texfile);
     textureP->imageData =
         pnm_readpam(textureFileP, texPamP, PAM_STRUCT_SIZE(tuple_type));
     pm_close(textureFileP);
 
-    if (cmdline.bgColorName)
+    if (cmdline.bgcolor)
         textureP->bgColor =
-            pnm_parsecolor(cmdline.bgColorName, texPamP->maxval);
+            pnm_parsecolor(cmdline.bgcolor, texPamP->maxval);
     else
         textureP->bgColor =
             pnm_backgroundtuple(texPamP, textureP->imageData);
-    textureP->replaceBgColor = (cmdline.patFilespec != NULL);
+    textureP->replaceBgColor = (cmdline.patfile != NULL);
     textureP->smoothing = cmdline.smoothing;
 
     if (cmdline.verbose) {
@@ -608,10 +618,9 @@ readTextureImage(struct cmdlineInfo const cmdline,
             pnm_colorname(texPamP, textureP->bgColor, 1);
 
         reportImageParameters("Texture file", texPamP);
-        if (cmdline.bgColorName && strcmp(colorname, cmdline.bgColorName))
+        if (cmdline.bgcolor && strcmp(colorname, cmdline.bgcolor))
             pm_message("Texture background color: %s (%s)",
-                       cmdline.bgColorName, colorname);
-        else
+                       cmdline.bgcolor, colorname);
             pm_message("Texture background color: %s", colorname);
         pm_strfree(colorname);
     }
@@ -619,7 +628,7 @@ readTextureImage(struct cmdlineInfo const cmdline,
     if (texPamP->width != inpamP->width || texPamP->height != inpamP->height)
         pm_error("The texture image must have the same width and height "
                  "as the input image");
-    if (cmdline.patFilespec &&
+    if (cmdline.patfile &&
         (!streq(texPamP->tuple_type, outpamP->tuple_type) ||
          texPamP->maxval != outpamP->maxval))
         pm_error("The texture image must be of the same tuple type "
@@ -632,6 +641,21 @@ readTextureImage(struct cmdlineInfo const cmdline,
 
 
 
+static unsigned int
+totalGuideHeight(struct cmdlineInfo const cmdline) {
+
+    /* Each pair of guides is cmdline.guidesize high, and we add that much
+       white above and below as well, so the total vertical space is three
+       times cmdline.giudesize.
+    */
+
+    return
+        (cmdline.guidetop ? 3 * cmdline.guidesize : 0) +
+        (cmdline.guidebottom ? 3 * cmdline.guidesize : 0);
+}
+
+
+
 static void
 createoutputGenerator(struct cmdlineInfo const cmdline,
                       const struct pam * const inPamP,
@@ -644,11 +668,10 @@ createoutputGenerator(struct cmdlineInfo const cmdline,
     outGenP->pam.size   = sizeof(struct pam);
     outGenP->pam.len    = PAM_STRUCT_SIZE(tuple_type);
     outGenP->pam.file   = stdout;
-    outGenP->pam.height = inPamP->height + 3 * abs(cmdline.guidesize);
-        /* Allow room for guides. */
+    outGenP->pam.height = inPamP->height + totalGuideHeight(cmdline);
     outGenP->pam.width  = inPamP->width;
 
-    if (cmdline.patFilespec) {
+    if (cmdline.patfile) {
         /* Background pixels should come from the pattern file. */
 
         initPatternPixel(outGenP, cmdline);
@@ -660,7 +683,7 @@ createoutputGenerator(struct cmdlineInfo const cmdline,
 
     outGenP->pam.bytes_per_sample = pnm_bytespersample(outGenP->pam.maxval);
 
-    if (cmdline.texFilespec) {
+    if (cmdline.texfile) {
         readTextureImage(cmdline, inPamP, &outGenP->pam, &outGenP->textureP);
         outGenP->pam = outGenP->textureP->pam;
     } else
@@ -688,7 +711,7 @@ static void
 makeWhiteRow(const struct pam * const pamP,
              tuple *            const tuplerow) {
 
-    int col;
+    unsigned int col;
 
     for (col = 0; col < pamP->width; ++col) {
         unsigned int plane;
@@ -705,64 +728,97 @@ writeRowCopies(const struct pam *  const outPamP,
                unsigned int        const copyCount) {
 
     unsigned int i;
+
     for (i = 0; i < copyCount; ++i)
         pnm_writepamrow(outPamP, outrow);
 }
 
 
 
-/* Draw a pair of guide boxes. */
 static void
-drawguides(int                const guidesize,
+writeWhiteRows(const struct pam * const outPamP,
+               unsigned int       const count) {
+
+    tuple * outrow;             /* One row of output data */
+
+    outrow = pnm_allocpamrow(outPamP);
+
+    makeWhiteRow(outPamP, outrow);
+
+    writeRowCopies(outPamP, outrow, count);
+
+    pnm_freerow(outrow);
+}
+
+
+
+static void
+drawguides(unsigned int       const guidesize,
            const struct pam * const outPamP,
            double             const eyesep,
            unsigned int       const dpi,
            double             const depthOfField) {
-
+/*----------------------------------------------------------------------------
+   Draw a pair of guide boxes, left and right.
+-----------------------------------------------------------------------------*/
     int const far = separation(0, eyesep, dpi, depthOfField);
         /* Space between the two guide boxes. */
     int const width = outPamP->width;    /* Width of the output image */
 
-    tuple *outrow;             /* One row of output data */
+    tuple * outrow;             /* One row of output data */
     tuple blackTuple;
-    int col;
+    unsigned int col;
 
     pnm_createBlackTuple(outPamP, &blackTuple);
 
     outrow = pnm_allocpamrow(outPamP);
+    
+    /* Put some white rows before the guides */
+    writeWhiteRows(outPamP, guidesize);
 
-    /* Leave some blank rows before the guides. */
+    /* Initialize the row buffer to white */
     makeWhiteRow(outPamP, outrow);
-    writeRowCopies(outPamP, outrow, guidesize);
 
-    /* Draw the guides. */
-    if ((width - far + guidesize)/2 < 0 ||
-        (width + far - guidesize)/2 >= width)
+    if (far > width + guidesize)
         pm_message("warning: the guide boxes are completely out of bounds "
-                   "at %d DPI", dpi);
-    else if ((width - far - guidesize)/2 < 0 ||
-             (width + far + guidesize)/2 >= width)
-        pm_message("warning: the guide boxes are partially out of bounds "
-                   "at %d DPI", dpi);
-
-    for (col = (width - far - guidesize)/2;
-         col < (width - far + guidesize)/2;
-         ++col)
-        if (col >= 0 && col < width)
+                   "at %u DPI", dpi);
+    else {
+        unsigned int leftBeg, leftEnd, rightBeg, rightEnd;
+
+        assert(far <= width + guidesize);
+        leftEnd  = (width - far + guidesize)/2;
+        assert(guidesize <= width + far);
+        rightBeg = (width + far - guidesize)/2;
+
+        if (far + guidesize > width) {
+            pm_message("warning: the guide boxes are partially out of bounds "
+                       "at %u DPI", dpi);
+            
+            leftBeg  = 0;
+            rightEnd = width;
+        } else {
+            assert(far + guidesize <= width);
+            leftBeg  = (width - far - guidesize)/2;
+            rightEnd = (width + far + guidesize)/2;
+        }
+        
+        /* Draw the left guide black in the buffer */
+        assert(leftEnd < outPamP->width);
+        for (col = leftBeg; col < leftEnd; ++col)
             pnm_assigntuple(outPamP, outrow[col], blackTuple);
 
-    for (col = (width + far - guidesize)/2;
-         col < (width + far + guidesize)/2;
-         ++col)
-        if (col >= 0 && col < width)
+        /* Draw the right guide black in the buffer */
+        assert(rightEnd <= outPamP->width);
+        for (col = rightBeg; col < rightEnd; ++col)
             pnm_assigntuple(outPamP, outrow[col], blackTuple);
+    }
+    /* Write out the guide rows */
 
-    writeRowCopies(outPamP,outrow, guidesize);
-
-    /* Leave some blank rows after the guides. */
-    makeWhiteRow(outPamP, outrow);
     writeRowCopies(outPamP, outrow, guidesize);
 
+    /* Put some white rows after the guides */
+    writeWhiteRows(outPamP, guidesize);
+
     pnm_freerow(outrow);
 }
 
@@ -1225,9 +1281,8 @@ produceStereogram(FILE *             const ifP,
 
     pnm_writepaminit(&outputGeneratorP->pam);
 
-    /* Draw guide boxes at the top, if desired. */
-    if (cmdline.guidesize < 0)
-        drawguides(-cmdline.guidesize, &outputGeneratorP->pam,
+    if (cmdline.guidetop)
+        drawguides(cmdline.guidesize, &outputGeneratorP->pam,
                    cmdline.eyesep,
                    cmdline.dpi, cmdline.depth);
 
@@ -1236,12 +1291,11 @@ produceStereogram(FILE *             const ifP,
                   cmdline.crosseyed, cmdline.makemask, cmdline.magnifypat,
                   cmdline.smoothing);
 
-    /* Draw guide boxes at the bottom, if desired. */
-    if (cmdline.guidesize > 0)
+    if (cmdline.guidebottom)
         drawguides(cmdline.guidesize, &outputGeneratorP->pam,
                    cmdline.eyesep, cmdline.dpi, cmdline.depth);
 
-    if (cmdline.texFilespec) {
+    if (cmdline.texfile) {
         pnm_freepamarray(outputGeneratorP->textureP->imageData,
                          &outputGeneratorP->textureP->pam);
         free(outputGeneratorP->textureP);
@@ -1273,7 +1327,7 @@ reportParameters(struct cmdlineInfo const cmdline) {
     pm_message("Near pattern width: %u / %u = %u pixels",
                sep1, cmdline.magnifypat, sep1 / cmdline.magnifypat);
     pm_message("Unique 3-D depth levels possible: %u", sep0 - sep1 + 1);
-    if (cmdline.patFilespec && (cmdline.xshift || cmdline.yshift))
+    if (cmdline.patfile && (cmdline.xshift || cmdline.yshift))
         pm_message("Pattern shift: (%u, %u)", cmdline.xshift, cmdline.yshift);
 }