From 8c46a4c67e321801d99078a7fb22af6a20e4aa7b Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sat, 30 Dec 2017 20:35:00 +0000 Subject: Copy Development as new Advanced git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@3104 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/ppm/sldtoppm.c | 220 ++++++++++++++++++++++++++++------------------- 1 file changed, 131 insertions(+), 89 deletions(-) (limited to 'converter') diff --git a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c index 550eed5b..5ce92c2b 100644 --- a/converter/ppm/sldtoppm.c +++ b/converter/ppm/sldtoppm.c @@ -50,7 +50,7 @@ struct spoint { /* Screen polygon */ -struct spolygon { +struct spolygon { int npoints, /* Number of points in polygon */ fill; /* Fill type */ struct spoint pt[11]; /* Actual points */ @@ -130,7 +130,7 @@ sli(void) { /* SLIB -- Input byte from slide file */ -static int +static int slib(void) { unsigned char ch; @@ -154,85 +154,127 @@ vscale(int * const px, +static void +upcase(const char * const sname, + char * const uname) { + + unsigned int i; + const char * ip; + + for (i = 0, ip = sname; i < 31; ++i) { + char const ch = *ip++; + + if (ch != EOS) + uname[i] = islower(ch) ? toupper(ch) : ch; + } + uname[i] = EOS; +} + + + +static void +skipBytes(FILE * const fileP, + unsigned int const count) { + + unsigned int i; + + for (i = 0; i < count; ++i) + getc(fileP); +} + + + +static void +scanDirectory(FILE * const slFileP, + long const dirPos, + bool const dirOnly, + const char * const uname, + bool * const foundP) { +/*---------------------------------------------------------------------------- + Scan the directory at the current position in *slFileP, either listing + the directory ('dirOnly' true) or searching for a slide named + 'uname' ('dirOnly' false). + + 'dirPos' is the offset in the file of the directory, i.e. the current + position of *slFileP. + + In the latter case, return as *foundP whether the slide name is there. +-----------------------------------------------------------------------------*/ + bool found; + bool eof; + long pos; + unsigned char libent[36]; + + for (found = false, eof = false, pos = dirPos; !found && !eof; ) { + size_t readCt; + readCt = fread(libent, 36, 1, slFileP); + if (readCt != 1) + eof = true; + else { + /* The directory entry is 32 bytes of NUL-terminated slide name + followed by 4 bytes of offset of the next directory entry. + */ + const char * const slideName = (const char *)(&libent[0]); + if (strnlen(slideName, 32) == 32) + pm_error("Invalid input: slide name field is not " + "nul-terminated"); + else { + if (strlen(slideName) == 0) + eof = true; + else { + pos += 36; + if (dirOnly) { + pm_message(" %s", slideName); + } else if (streq(slideName, uname)) { + long const dpos = + (((((libent[35] << 8) | libent[34]) << 8) | + libent[33]) << 8) | libent[32]; + + if ((slFileP == stdin) || + (fseek(slFileP, dpos, 0) == -1)) { + + skipBytes(slFileP, dpos - pos); + } + found = true; + } + } + } + } + } + *foundP = found; +} + /* SLIDEFIND -- Find a slide in a library or, if DIRONLY is nonzero, print a directory listing of the library. If UCASEN is nonzero, the requested slide name is converted to upper case. */ static void -slidefind(const char * const sname, - bool const dironly, +slidefind(const char * const slideName, + bool const dirOnly, bool const ucasen) { - char uname[32]; - unsigned char libent[36]; - long pos; + char uname[32]; /* upper case translation of 'slideName' */ + char header[32]; /* (supposed) header read from file */ bool found; - bool eof; - if (dironly) + if (dirOnly) pm_message("Slides in library:"); else { - unsigned int i; - const char * ip; - - ip = sname; /* initial value */ - - for (i = 0; i < 31; ++i) { - char const ch = *ip++; - if (ch == EOS) - break; - - { - char const upperCh = - ucasen && islower(ch) ? toupper(ch) : ch; - - uname[i] = upperCh; - } - } - uname[i] = EOS; + upcase(slideName, uname); } - + /* Read slide library header and verify. */ - - if ((fread(libent, 32, 1, slfile) != 1) || - (!strneq((char *)libent, "AutoCAD Slide Library 1.0\015\012\32", 32))) { + + if ((fread(header, 32, 1, slfile) != 1) || + (!STRSEQ(header, "AutoCAD Slide Library 1.0\r\n\32"))) { pm_error("not an AutoCAD slide library file."); } - pos = 32; - - /* Search for a slide with the requested name or list the directory */ - - for (found = false, eof = false; !found && !eof; ) { - size_t readCt; - readCt = fread(libent, 36, 1, slfile); - if (readCt != 1) - eof = true; - else if (strnlen((char *)libent, 32) == 0) - eof = true; - if (!eof) { - pos += 36; - if (dironly) { - pm_message(" %s", libent); - } else if (strneq((char *)libent, uname, 32)) { - long dpos; - - dpos = (((((libent[35] << 8) | libent[34]) << 8) | - libent[33]) << 8) | libent[32]; - - if ((slfile == stdin) || (fseek(slfile, dpos, 0) == -1)) { - dpos -= pos; - - while (dpos-- > 0) - getc(slfile); - } - found = true; - } - } - } - if (!found && !dironly) - pm_error("slide '%s' not in library.", sname); + scanDirectory(slfile, 32, dirOnly, ucasen ? uname : slideName, &found); + + if (!found && !dirOnly) + pm_error("slide '%s' not in library.", slideName); } @@ -295,14 +337,14 @@ flood(struct spolygon * const poly, assert(poly->pt[i].x >= 0 && poly->pt[i].x < pixcols); assert(poly->pt[i].y >= 0 && poly->pt[i].y < pixrows); ppmd_line(pixels, pixcols, pixrows, pixmaxval, - poly->pt[i].x, iydots - poly->pt[i].y, + poly->pt[i].x, iydots - poly->pt[i].y, poly->pt[(i + 1) % poly->npoints].x, iydots - poly->pt[(i + 1) % poly->npoints].y, ppmd_fill_drawproc, handle); } ppmd_fill(pixels, pixcols, pixrows, pixmaxval, handle, PPMD_NULLDRAWPROC, (char *) &rgbcolor); - + ppmd_fill_destroy(handle); } @@ -333,11 +375,11 @@ slider(slvecfn slvec, {"AutoCAD Slide\r\n\32", 86,2, 0,0, 0.0, 0}; int curcolor = 7; /* Current vector color */ pixel rgbcolor; /* Pixel used to clear pixmap */ - + lx = ly = 32000; - + /* Process the header of the slide file. */ - + sdrawkcab = false; /* Initially guess byte order is OK */ fread(slfrof.slh, 17, 1, slfile); fread(&slfrof.sntype, sizeof(char), 1, slfile); @@ -361,12 +403,12 @@ slider(slvecfn slvec, pm_error("incompatible slide file format"); /* Build SDSAR value from long scaled version. */ - + ldsar = 0L; for (i = 3; i >= 0; --i) ldsar = (ldsar << 8) | ubfr[i]; slfrof.sdsar = ((double) ldsar) / 1E7; - + /* Examine the byte order test value. If it's backwards, set the byte-reversal flag and correct all of the values we've read in so far. @@ -380,7 +422,7 @@ slider(slvecfn slvec, rshort(slfrof.shwfill); #undef rshort } - + /* Dump the header if we're blithering. */ if (blither || info) { @@ -455,29 +497,29 @@ slider(slvecfn slvec, } iydots = sysize - 1; } - + if (adjust) { pm_message( "Resized from %dx%d to %dx%d to correct pixel aspect ratio.", slfrof.sxdots + 1, slfrof.sydots + 1, ixdots + 1, iydots + 1); } - + /* Allocate image buffer and clear it to black. */ - + pixels = ppm_allocarray(pixcols = ixdots + 1, pixrows = iydots + 1); PPM_ASSIGN(rgbcolor, 0, 0, 0); ppmd_filledrectangle(pixels, pixcols, pixrows, pixmaxval, 0, 0, pixcols, pixrows, PPMD_NULLDRAWPROC, (char *) &rgbcolor); - + if ((rescale = slfrof.sxdots != ixdots || slfrof.sydots != iydots || slfrof.sdsar != dsar) != 0) { - + /* Rescale all coords. so they'll look (more or less) right on this display. */ - + xfac = (ixdots + 1) * 0x10000L; xfac /= (long) (slfrof.sxdots + 1); yfac = (iydots + 1) * 0x10000L; @@ -490,7 +532,7 @@ slider(slvecfn slvec, } poly.npoints = 0; /* No flood in progress. */ - + while ((cw = sli()) != 0xFC00) { switch (cw & 0xFF00) { case 0xFB00: /* Short vector compressed */ @@ -508,10 +550,10 @@ slider(slvecfn slvec, slx = vec.f.x; /* Save scaled point */ sly = vec.f.y; break; - + case 0xFC00: /* End of file */ break; - + case 0xFD00: /* Flood command */ vec.f.x = sli(); vec.f.y = sli(); @@ -538,7 +580,7 @@ slider(slvecfn slvec, poly.npoints++; } break; - + case 0xFE00: /* Common endpoint compressed */ vec.f.x = lx + extend(cw & 0xFF); vec.f.y = ly + slib(); @@ -553,7 +595,7 @@ slider(slvecfn slvec, slx = vec.f.x; /* Save scaled point */ sly = vec.f.y; break; - + case 0xFF00: /* Change color */ curcolor = cw & 0xFF; break; @@ -661,7 +703,7 @@ main(int argc, } /* If a file name is specified, open it. Otherwise read from - standard input. + standard input. */ if (argn < argc) { @@ -670,24 +712,24 @@ main(int argc, } else { slfile = stdin; } - + if (argn != argc) { /* Extra bogus arguments ? */ pm_usage(usage); } - + /* If we're extracting an item from a slide library, position the input stream to the start of the chosen slide. */ - + if (dironly || slobber) slidefind(slobber, dironly, ucasen); - + if (!dironly) { slider(draw, flood); ppm_writeppm(stdout, pixels, pixcols, pixrows, pixmaxval, 0); } pm_close(slfile); pm_close(stdout); - + return 0; } -- cgit 1.4.1