home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-14 | 55.2 KB | 1,818 lines |
- Newsgroups: comp.sources.misc
- From: jef@well.sf.ca.us (Jef Poskanzer)
- Subject: v26i109: pbmplus - Extended Portable Bitmap Toolkit, Patch10dec91, Part04/05
- Message-ID: <1991Dec15.014818.20591@sparky.imd.sterling.com>
- X-Md4-Signature: dc43b90192afb57db82a35673f079043
- Date: Sun, 15 Dec 1991 01:48:18 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: jef@well.sf.ca.us (Jef Poskanzer)
- Posting-number: Volume 26, Issue 109
- Archive-name: pbmplus/patch10dec91/part04
- Environment: UNIX
- Patch-To: pbmplus: Volume 23, Issue 36-59
-
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file ppm/ppmforge.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 4; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping ppm/ppmforge.c'
- else
- echo 'x - continuing file ppm/ppmforge.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'ppm/ppmforge.c' &&
- X byc = byf + n;
- X t = by - floor(by);
- X t1 = 1 - t;
- X }
- X
- X if (clouds) {
- X
- X /* Render the FFT output as clouds. */
- X
- X for (j = 0; j < screenxsize; j++) {
- X double r = t1 * u1[j] * cp[byf + bxf[j]] +
- X t * u1[j] * cp[byc + bxf[j]] +
- X t * u[j] * cp[byc + bxc[j]] +
- X t1 * u[j] * cp[byf + bxc[j]];
- X pixval w = (r > 127.0) ? (RGBQuant * ((r - 127.0) / 128.0)) :
- X 0;
- X
- X PPM_ASSIGN(*(pixels + j), w, w, RGBQuant);
- X }
- X } else if (stars) {
- X
- X /* Generate a starry sky. Note that no FFT is performed;
- X the output is generated directly from a power law
- X mapping of a pseudorandom sequence into intensities. */
- X
- X for (j = 0; j < screenxsize; j++) {
- X etoile(pixels + j);
- X }
- X } else {
- X for (j = 0; j < screenxsize; j++) {
- X PPM_ASSIGN(*(pixels + j), 0, 0, 0);
- X }
- X azimuth = asin(((((double) i) / (screenysize - 1)) * 2) - 1);
- X icet = pow(abs(sin(azimuth)), 1.0 / icelevel) - 0.5;
- X lcos = (screenysize / 2) * abs(cos(azimuth));
- X rpix = pixels + (screenxsize / 2) - lcos;
- X for (j = (screenxsize / 2) - lcos;
- X j <= (screenxsize / 2) + lcos; j++) {
- X double r = t1 * u1[j] * cp[byf + bxf[j]] +
- X t * u1[j] * cp[byc + bxf[j]] +
- X t * u[j] * cp[byc + bxc[j]] +
- X t1 * u[j] * cp[byf + bxc[j]],
- X ice;
- X int ir, ig, ib;
- X static unsigned char pgnd[][3] = {
- X {206, 205, 0}, {208, 207, 0}, {211, 208, 0},
- X {214, 208, 0}, {217, 208, 0}, {220, 208, 0},
- X {222, 207, 0}, {225, 205, 0}, {227, 204, 0},
- X {229, 202, 0}, {231, 199, 0}, {232, 197, 0},
- X {233, 194, 0}, {234, 191, 0}, {234, 188, 0},
- X {233, 185, 0}, {232, 183, 0}, {231, 180, 0},
- X {229, 178, 0}, {227, 176, 0}, {225, 174, 0},
- X {223, 172, 0}, {221, 170, 0}, {219, 168, 0},
- X {216, 166, 0}, {214, 164, 0}, {212, 162, 0},
- X {210, 161, 0}, {207, 159, 0}, {205, 157, 0},
- X {203, 156, 0}, {200, 154, 0}, {198, 152, 0},
- X {195, 151, 0}, {193, 149, 0}, {190, 148, 0},
- X {188, 147, 0}, {185, 145, 0}, {183, 144, 0},
- X {180, 143, 0}, {177, 141, 0}, {175, 140, 0},
- X {172, 139, 0}, {169, 138, 0}, {167, 137, 0},
- X {164, 136, 0}, {161, 135, 0}, {158, 134, 0},
- X {156, 133, 0}, {153, 132, 0}, {150, 132, 0},
- X {147, 131, 0}, {145, 130, 0}, {142, 130, 0},
- X {139, 129, 0}, {136, 128, 0}, {133, 128, 0},
- X {130, 127, 0}, {127, 127, 0}, {125, 127, 0},
- X {122, 127, 0}, {119, 127, 0}, {116, 127, 0},
- X {113, 127, 0}, {110, 128, 0}, {107, 128, 0},
- X {104, 128, 0}, {102, 127, 0}, { 99, 126, 0},
- X { 97, 124, 0}, { 95, 122, 0}, { 93, 120, 0},
- X { 92, 117, 0}, { 92, 114, 0}, { 92, 111, 0},
- X { 93, 108, 0}, { 94, 106, 0}, { 96, 104, 0},
- X { 98, 102, 0}, {100, 100, 0}, {103, 99, 0},
- X {106, 99, 0}, {109, 99, 0}, {111, 100, 0},
- X {114, 101, 0}, {117, 102, 0}, {120, 103, 0},
- X {123, 102, 0}, {125, 102, 0}, {128, 100, 0},
- X {130, 98, 0}, {132, 96, 0}, {133, 94, 0},
- X {134, 91, 0}, {134, 88, 0}, {134, 85, 0},
- X {133, 82, 0}, {131, 80, 0}, {129, 78, 0}
- X };
- X
- X if (r >= 128) {
- X int ix = ((r - 128) * (ELEMENTS(pgnd) - 1)) / 127;
- X
- X /* Land area. Look up colour based on elevation from
- X precomputed colour map table. */
- X
- X ir = pgnd[ix][0];
- X ig = pgnd[ix][1];
- X ib = pgnd[ix][2];
- X } else {
- X
- X /* Water. Generate clouds above water based on
- X elevation. */
- X
- X ir = ig = r > 64 ? (r - 64) * 4 : 0;
- X ib = 255;
- X }
- X
- X /* Generate polar ice caps. */
- X
- X ice = max(0.0, (icet + glaciers * max(-0.5, (r - 128) / 128.0)));
- X if (ice > 0.125) {
- X ir = ig = ib = 255;
- X }
- X
- X /* Apply limb darkening by cosine rule. */
- X
- X { double dx = 2 * (((screenxsize / 2) - j) /
- X ((double) screenysize)),
- X dxsq = dx * dx,
- X ds, di, inx;
- X double dsq, dsat;
- X di = svx * dx + svy + svz * sqrt(1.0 - dxsq);
- #define PlanetAmbient 0.05
- X if (di < 0)
- X di = 0;
- X di = min(1.0, di);
- X
- X ds = sqrt(dxsq + dysq);
- X ds = min(1.0, ds);
- X
- X /* Calculate atmospheric absorption based on the
- X thickness of atmosphere traversed by light on
- X its way to the surface. */
- X
- #define AtSatFac 1.0
- X dsq = ds * ds;
- X dsat = AtSatFac * ((sqrt(Atthick * Atthick - dsq) -
- X sqrt(1.0 * 1.0 - dsq)) / athfac);
- #define AtSat(x,y) x = ((x)*(1.0-dsat))+(y)*dsat
- X AtSat(ir, 127);
- X AtSat(ig, 127);
- X AtSat(ib, 255);
- X
- X inx = PlanetAmbient + (1.0 - PlanetAmbient) * di;
- X ir *= inx;
- X ig *= inx;
- X ib *= inx;
- X }
- X
- X PPM_ASSIGN(*rpix, ir, ig, ib);
- X rpix++;
- X }
- X
- X /* Left stars */
- X
- #define StarClose 2
- X for (j = 0; j < (screenxsize / 2) - (lcos + StarClose); j++) {
- X etoile(pixels + j);
- X }
- X
- X /* Right stars */
- X
- X for (j = (screenxsize / 2) + (lcos + StarClose);
- X j < screenxsize; j++) {
- X etoile(pixels + j);
- X }
- X }
- X ppm_writeppmrow(stdout, pixels, screenxsize, RGBQuant, FALSE);
- X }
- X pm_close(stdout);
- X
- X ppm_freerow(pixels);
- X if (!stars) {
- X free((char *) cp);
- X free((char *) u);
- X free((char *) u1);
- X free((char *) bxf);
- X free((char *) bxc);
- X }
- }
- X
- /* PLANET -- Make a planet. */
- X
- static Boolean planet()
- {
- X float *a = (float *) 0;
- X int i, j;
- X double rmin = 1e50, rmax = -1e50, rmean, rrange;
- X
- X if (!seedspec) {
- X initseed();
- X }
- X initgauss(rseed);
- X
- X if (!stars) {
- X
- X spectralsynth(&a, meshsize, 3.0 - fracdim);
- X if (a == (float *) 0) {
- X return FALSE;
- X }
- X
- X /* Apply power law scaling if non-unity scale is requested. */
- X
- X if (powscale != 1.0) {
- X for (i = 0; i < meshsize; i++) {
- X for (j = 0; j < meshsize; j++) {
- X double r = Real(a, i, j);
- X
- X if (r > 0) {
- X Real(a, i, j) = pow(r, powscale);
- X }
- X }
- X }
- X }
- X
- X /* Compute extrema for autoscaling. */
- X
- X for (i = 0; i < meshsize; i++) {
- X for (j = 0; j < meshsize; j++) {
- X double r = Real(a, i, j);
- X
- X rmin = min(rmin, r);
- X rmax = max(rmax, r);
- X }
- X }
- X rmean = (rmin + rmax) / 2;
- X rrange = (rmax - rmin) / 2;
- X for (i = 0; i < meshsize; i++) {
- X for (j = 0; j < meshsize; j++) {
- X Real(a, i, j) = (Real(a, i, j) - rmean) / rrange;
- X }
- X }
- X }
- X genplanet(a, meshsize);
- X if (a != (float *) 0) {
- X free((char *) a);
- X }
- X return TRUE;
- }
- X
- /* MAIN -- Main program. */
- X
- int main(argc, argv)
- X int argc;
- X char *argv[];
- {
- X int i;
- X char *usage = "\n\
- X [-width|-xsize <x>] [-height|-ysize <y>] [-mesh <n>]\n\
- X [-clouds] [-dimension <f>] [-power <f>] [-seed <n>]\n\
- X [-hour <f>] [-inclination|-tilt <f>] [-ice <f>] [-glaciers <f>]\n\
- X [-night] [-stars <n>] [-saturation <n>]";
- X Boolean dimspec = FALSE, meshspec = FALSE, powerspec = FALSE,
- X widspec = FALSE, hgtspec = FALSE, icespec = FALSE,
- X glacspec = FALSE, starspec = FALSE, starcspec = FALSE;
- X
- X ppm_init(&argc, argv);
- X i = 1;
- X while ((i < argc) && (argv[i][0] == '-') && (argv[i][1] != '\0')) {
- X
- X if (pm_keymatch(argv[i], "-clouds", 2)) {
- X clouds = TRUE;
- X } else if (pm_keymatch(argv[i], "-night", 2)) {
- X stars = TRUE;
- X } else if (pm_keymatch(argv[i], "-dimension", 2)) {
- X if (dimspec) {
- X pm_error("already specified a dimension");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%lf", &fracdim) != 1))
- X pm_usage(usage);
- X if (fracdim <= 0.0) {
- X pm_error("fractal dimension must be greater than 0");
- X }
- X dimspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-hour", 3)) {
- X if (hourspec) {
- X pm_error("already specified an hour");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%lf", &hourangle) != 1))
- X pm_usage(usage);
- X hourangle = (M_PI / 12.0) * (hourangle + 12.0);
- X hourspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-inclination", 3) ||
- X pm_keymatch(argv[i], "-tilt", 2)) {
- X if (inclspec) {
- X pm_error("already specified an inclination/tilt");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%lf", &inclangle) != 1))
- X pm_usage(usage);
- X inclangle = (M_PI / 180.0) * inclangle;
- X inclspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-mesh", 2)) {
- X unsigned int j;
- X
- X if (meshspec) {
- X pm_error("already specified a mesh size");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%d", &meshsize) != 1))
- X pm_usage(usage);
- X
- X /* Force FFT mesh to the next larger power of 2. */
- X
- X for (j = meshsize; (j & 1) == 0; j >>= 1) ;
- X
- X if (j != 1) {
- X for (j = 2; j < meshsize; j <<= 1) ;
- X meshsize = j;
- X }
- X meshspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-power", 2)) {
- X if (powerspec) {
- X pm_error("already specified a power factor");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%lf", &powscale) != 1))
- X pm_usage(usage);
- X if (powscale <= 0.0) {
- X pm_error("power factor must be greater than 0");
- X }
- X powerspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-ice", 3)) {
- X if (icespec) {
- X pm_error("already specified ice cap level");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%lf", &icelevel) != 1))
- X pm_usage(usage);
- X if (icelevel <= 0.0) {
- X pm_error("ice cap level must be greater than 0");
- X }
- X icespec = TRUE;
- X } else if (pm_keymatch(argv[i], "-glaciers", 2)) {
- X if (glacspec) {
- X pm_error("already specified glacier level");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%lf", &glaciers) != 1))
- X pm_usage(usage);
- X if (glaciers <= 0.0) {
- X pm_error("glacier level must be greater than 0");
- X }
- X glacspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-stars", 3)) {
- X if (starspec) {
- X pm_error("already specified a star fraction");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%d", &starfraction) != 1))
- X pm_usage(usage);
- X starspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-saturation", 3)) {
- X if (starcspec) {
- X pm_error("already specified a star colour saturation");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%d", &starcolour) != 1))
- X pm_usage(usage);
- X starcspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-seed", 3)) {
- X if (seedspec) {
- X pm_error("already specified a random seed");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%d", &rseed) != 1))
- X pm_usage(usage);
- X seedspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-xsize", 2) ||
- X pm_keymatch(argv[i], "-width", 2)) {
- X if (widspec) {
- X pm_error("already specified a width/xsize");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%d", &screenxsize) != 1))
- X pm_usage(usage);
- X widspec = TRUE;
- X } else if (pm_keymatch(argv[i], "-ysize", 2) ||
- X pm_keymatch(argv[i], "-height", 3)) {
- X if (hgtspec) {
- X pm_error("already specified a height/ysize");
- X }
- X i++;
- X if ((i == argc) || (sscanf(argv[i], "%d", &screenysize) != 1))
- X pm_usage(usage);
- X hgtspec = TRUE;
- X } else {
- X pm_usage(usage);
- X }
- X i++;
- X }
- X
- X /* Set defaults when explicit specifications were not given.
- X
- X The default fractal dimension and power scale depend upon
- X whether we're generating a planet or clouds. */
- X
- X if (!dimspec) {
- X fracdim = clouds ? 2.15 : 2.4;
- X }
- X if (!powerspec) {
- X powscale = clouds ? 0.75 : 1.2;
- X }
- X if (!icespec) {
- X icelevel = 0.4;
- X }
- X if (!glacspec) {
- X glaciers = 0.75;
- X }
- X if (!starspec) {
- X starfraction = 100;
- X }
- X if (!starcspec) {
- X starcolour = 125;
- X }
- X
- X /* Force screen to be at least as wide as it is high. Long,
- X skinny screens cause crashes because picture width is
- X calculated based on height. */
- X
- X screenxsize = max(screenysize, screenxsize);
- X screenxsize = (screenxsize + 1) & (~1);
- X exit(planet() ? 0 : 1);
- }
- SHAR_EOF
- echo 'File ppm/ppmforge.c is complete' &&
- chmod 0664 ppm/ppmforge.c ||
- echo 'restore of ppm/ppmforge.c failed'
- Wc_c="`wc -c < 'ppm/ppmforge.c'`"
- test 27513 -eq "$Wc_c" ||
- echo 'ppm/ppmforge.c: original size 27513, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ppm/autocad.h ==============
- if test -f 'ppm/autocad.h' -a X"$1" != X"-c"; then
- echo 'x - skipping ppm/autocad.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ppm/autocad.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ppm/autocad.h' &&
- X
- /* The following table maps the 256 standard AutoCAD colours into RGB
- X values with a Maxval of 255. These colours are actually derived in
- X an algorithmic way from the HLS colour system, but it's easier and
- X faster to just provide a table than to compute the RGB components
- X on the fly from the colour index. */
- X
- static unsigned char acadcol[256][3] = {
- X {0, 0, 0}, {255, 0, 0}, {255, 255, 0}, {0, 255, 0}, {0, 255, 255},
- X {0, 0, 255}, {255, 0, 255}, {255, 255, 255}, {255, 255, 255},
- X {255, 255, 255}, {255, 0, 0}, {255, 127, 127}, {165, 0, 0}, {165, 82, 82},
- X {127, 0, 0}, {127, 63, 63}, {76, 0, 0}, {76, 38, 38}, {38, 0, 0},
- X {38, 19, 19}, {255, 63, 0}, {255, 159, 127}, {165, 41, 0}, {165, 103, 82},
- X {127, 31, 0}, {127, 79, 63}, {76, 19, 0}, {76, 47, 38}, {38, 9, 0},
- X {38, 23, 19}, {255, 127, 0}, {255, 191, 127}, {165, 82, 0}, {165, 124, 82},
- X {127, 63, 0}, {127, 95, 63}, {76, 38, 0}, {76, 57, 38}, {38, 19, 0},
- X {38, 28, 19}, {255, 191, 0}, {255, 223, 127}, {165, 124, 0},
- X {165, 145, 82}, {127, 95, 0}, {127, 111, 63}, {76, 57, 0}, {76, 66, 38},
- X {38, 28, 0}, {38, 33, 19}, {255, 255, 0}, {255, 255, 127}, {165, 165, 0},
- X {165, 165, 82}, {127, 127, 0}, {127, 127, 63}, {76, 76, 0}, {76, 76, 38},
- X {38, 38, 0}, {38, 38, 19}, {191, 255, 0}, {223, 255, 127},
- X {124, 165, 0}, {145, 165, 82}, {95, 127, 0}, {111, 127, 63}, {57, 76, 0},
- X {66, 76, 38}, {28, 38, 0}, {33, 38, 19}, {127, 255, 0}, {191, 255, 127},
- X {82, 165, 0}, {124, 165, 82}, {63, 127, 0}, {95, 127, 63}, {38, 76, 0},
- X {57, 76, 38}, {19, 38, 0}, {28, 38, 19}, {63, 255, 0}, {159, 255, 127},
- X {41, 165, 0}, {103, 165, 82}, {31, 127, 0}, {79, 127, 63}, {19, 76, 0},
- X {47, 76, 38}, {9, 38, 0}, {23, 38, 19}, {0, 255, 0}, {127, 255, 127},
- X {0, 165, 0}, {82, 165, 82}, {0, 127, 0}, {63, 127, 63}, {0, 76, 0},
- X {38, 76, 38}, {0, 38, 0}, {19, 38, 19}, {0, 255, 63}, {127, 255, 159},
- X {0, 165, 41}, {82, 165, 103}, {0, 127, 31}, {63, 127, 79}, {0, 76, 19},
- X {38, 76, 47}, {0, 38, 9}, {19, 38, 23}, {0, 255, 127}, {127, 255, 191},
- X {0, 165, 82}, {82, 165, 124}, {0, 127, 63}, {63, 127, 95}, {0, 76, 38},
- X {38, 76, 57}, {0, 38, 19}, {19, 38, 28}, {0, 255, 191}, {127, 255, 223},
- X {0, 165, 124}, {82, 165, 145}, {0, 127, 95}, {63, 127, 111}, {0, 76, 57},
- X {38, 76, 66}, {0, 38, 28}, {19, 38, 33}, {0, 255, 255}, {127, 255, 255},
- X {0, 165, 165}, {82, 165, 165}, {0, 127, 127}, {63, 127, 127}, {0, 76, 76},
- X {38, 76, 76}, {0, 38, 38}, {19, 38, 38}, {0, 191, 255}, {127, 223, 255},
- X {0, 124, 165}, {82, 145, 165}, {0, 95, 127}, {63, 111, 127}, {0, 57, 76},
- X {38, 66, 76}, {0, 28, 38}, {19, 33, 38}, {0, 127, 255}, {127, 191, 255},
- X {0, 82, 165}, {82, 124, 165}, {0, 63, 127}, {63, 95, 127}, {0, 38, 76},
- X {38, 57, 76}, {0, 19, 38}, {19, 28, 38}, {0, 63, 255}, {127, 159, 255},
- X {0, 41, 165}, {82, 103, 165}, {0, 31, 127}, {63, 79, 127}, {0, 19, 76},
- X {38, 47, 76}, {0, 9, 38}, {19, 23, 38}, {0, 0, 255}, {127, 127, 255},
- X {0, 0, 165}, {82, 82, 165}, {0, 0, 127}, {63, 63, 127}, {0, 0, 76},
- X {38, 38, 76}, {0, 0, 38}, {19, 19, 38}, {63, 0, 255}, {159, 127, 255},
- X {41, 0, 165}, {103, 82, 165}, {31, 0, 127}, {79, 63, 127}, {19, 0, 76},
- X {47, 38, 76}, {9, 0, 38}, {23, 19, 38}, {127, 0, 255}, {191, 127, 255},
- X {82, 0, 165}, {124, 82, 165}, {63, 0, 127}, {95, 63, 127}, {38, 0, 76},
- X {57, 38, 76}, {19, 0, 38}, {28, 19, 38}, {191, 0, 255}, {223, 127, 255},
- X {124, 0, 165}, {145, 82, 165}, {95, 0, 127}, {111, 63, 127}, {57, 0, 76},
- X {66, 38, 76}, {28, 0, 38}, {33, 19, 38}, {255, 0, 255}, {255, 127, 255},
- X {165, 0, 165}, {165, 82, 165}, {127, 0, 127}, {127, 63, 127}, {76, 0, 76},
- X {76, 38, 76}, {38, 0, 38}, {38, 19, 38}, {255, 0, 191}, {255, 127, 223},
- X {165, 0, 124}, {165, 82, 145}, {127, 0, 95}, {127, 63, 111}, {76, 0, 57},
- X {76, 38, 66}, {38, 0, 28}, {38, 19, 33}, {255, 0, 127}, {255, 127, 191},
- X {165, 0, 82}, {165, 82, 124}, {127, 0, 63}, {127, 63, 95}, {76, 0, 38},
- X {76, 38, 57}, {38, 0, 19}, {38, 19, 28}, {255, 0, 63}, {255, 127, 159},
- X {165, 0, 41}, {165, 82, 103}, {127, 0, 31}, {127, 63, 79}, {76, 0, 19},
- X {76, 38, 47}, {38, 0, 9}, {38, 19, 23}, {84, 84, 84}, {118, 118, 118},
- X {152, 152, 152}, {186, 186, 186}, {220, 220, 220}, {255, 255, 255}
- };
- SHAR_EOF
- chmod 0664 ppm/autocad.h ||
- echo 'restore of ppm/autocad.h failed'
- Wc_c="`wc -c < 'ppm/autocad.h'`"
- test 4290 -eq "$Wc_c" ||
- echo 'ppm/autocad.h: original size 4290, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ppm/ppmtoacad.1 ==============
- if test -f 'ppm/ppmtoacad.1' -a X"$1" != X"-c"; then
- echo 'x - skipping ppm/ppmtoacad.1 (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ppm/ppmtoacad.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ppm/ppmtoacad.1' &&
- .TH ppmtoacad 1 "10 October 1991"
- .IX ppmtoacad
- .IX AutoCAD
- .SH NAME
- ppmtoacad - convert portable pixmap to AutoCAD database or slide
- .SH SYNOPSIS
- .na
- .B ppmtoacad
- 'in 15n
- .RB [ -dxb ]
- .RB [ -poly ]
- .RB [ -background
- .IR colour ]
- .RB [ -white ]
- .RB [ -aspect
- .IR ratio ]
- .RB [ -8 ]
- .RI [ ppmfile ]
- .in -15n
- .ad
- .SH DESCRIPTION
- Reads a portable pixmap as input. Produces an AutoCAD\*R slide file or
- binary database import (.dxb) file as output.
- If no
- .I ppmfile
- is specified, input is read from standard input.
- .SH OPTIONS
- .TP
- .B -dxb
- An AutoCAD binary database import (.dxb) file is written. This file
- is read with the DXBIN command and, once loaded, becomes part of
- the AutoCAD geometrical database and can be viewed and edited like
- any other object. Each sequence of identical pixels becomes a
- separate object in the database; this can result in very large AutoCAD
- drawing files. However, if you want to trace over a bitmap, it lets
- you zoom and pan around the bitmap as you wish.
- .TP
- .B -poly
- If the
- .B -dxb
- option is not specified, the output of
- .B ppmtoacad
- is an AutoCAD slide file. Normally each row of pixels is
- represented by an AutoCAD line entity. If
- .B -poly
- is selected, the pixels are rendered as filled polygons. If the
- slide is viewed on a display with higher resolution than the source
- pixmap, this will cause the pixels to expand instead of appearing as
- discrete lines against the screen background colour. Regrettably,
- this representation yields slide files which occupy more disc space
- and take longer to display.
- .TP
- .BI -background " colour"
- Most AutoCAD display drivers can be configured to use any available
- colour as the screen background. Some users perfer a black screen
- background, others white, while splinter groups advocate burnt ocher,
- tawny puce, and shocking grey. Discarding pixels whose closest
- AutoCAD colour representation is equal to the background colour can
- substantially reduce the size of the AutoCAD database or slide file
- needed to represent a bitmap. If no
- .B -background
- colour is specified, the screen background colour is assumed to be
- black. Any AutoCAD colour number may be specified as the screen
- background; colour numbers are assumed to specify the hues defined
- in the standard AutoCAD 256 colour palette.
- .TP
- .B -white
- Since many AutoCAD users choose a white screen background, this option
- is provided as a short-cut. Specifying
- .B -white
- is identical in effect to
- .BR "-background 7" .
- .TP
- .BI -aspect " ratio"
- If the source pixmap had non-square pixels, the ratio of the pixel
- width to pixel height should be specified as
- .IR ratio .
- The resulting slide or .dxb file will be corrected so that pixels on
- the AutoCAD screen will be square. For example, to correct an image made
- for a 320x200 VGA/MCGA screen, specify
- .BR "-aspect 0.8333" .
- .TP
- .B -8
- Restricts the colours in the output file to the 8 RGB shades.
- .PP
- All flags can be abbreviated to their shortest unique prefix.
- .SH BUGS
- AutoCAD has a fixed palette of 256 colours, distributed along the hue,
- lightness, and saturation axes. Pixmaps which contain many
- nearly-identical colours, or colours not closely approximated by
- AutoCAD's palette, may be poorly rendered.
- .PP
- .B ppmtoacad
- works best if the system displaying its output supports the full 256
- colour AutoCAD palette. Monochrome, 8 colour, and 16 colour
- configurations will produce less than optimal results.
- .PP
- When creating a .dxb file or a slide file with the
- .B -poly
- option,
- .B ppmtoacad
- finds both vertical and horizontal runs of identical pixels and
- consolidates them into rectangular regions to reduce the size of the
- output file. This is effective for images with large areas of
- constant colour but it's no substitute for true raster to vector
- conversion. In particular, thin diagonal lines are not optimised at
- all by this process.
- .PP
- Output files can be huge.
- .SH "SEE ALSO"
- AutoCAD Reference Manual:
- .I Slide File Format
- and
- .IR "Binary Drawing Interchange (DXB) Files" ,
- .BR ppm (5)
- .SH AUTHOR
- .RS 5
- .nf
- John Walker
- Autodesk SA
- Avenue des Champs-Montants 14b
- CH-2074 MARIN
- Suisse/Schweiz/Svizzera/Svizra/Switzerland
- .PD 0
- .TP 9
- Usenet:
- kelvin@Autodesk.com
- .TP
- Fax:
- 038/33 88 15
- .TP
- Voice:
- 038/33 76 33
- .fi
- .RE
- .PD
- .PP
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- without any conditions or restrictions. This software is provided ``as
- is'' without express or implied warranty.
- .PP
- AutoCAD and Autodesk are registered trademarks of Autodesk, Inc.
- SHAR_EOF
- chmod 0664 ppm/ppmtoacad.1 ||
- echo 'restore of ppm/ppmtoacad.1 failed'
- Wc_c="`wc -c < 'ppm/ppmtoacad.1'`"
- test 4541 -eq "$Wc_c" ||
- echo 'ppm/ppmtoacad.1: original size 4541, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ppm/ppmtoacad.c ==============
- if test -f 'ppm/ppmtoacad.c' -a X"$1" != X"-c"; then
- echo 'x - skipping ppm/ppmtoacad.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ppm/ppmtoacad.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ppm/ppmtoacad.c' &&
- /*
- X
- X Convert a portable pixmap to an AutoCAD slide or DXB file
- X
- X Author:
- X John Walker
- X Autodesk SA
- X Avenue des Champs-Montants 14b
- X CH-2074 MARIN
- X Switzerland
- X Usenet: kelvin@Autodesk.com
- X Fax: 038/33 88 15
- X Voice: 038/33 76 33
- X
- X Permission to use, copy, modify, and distribute this software and
- X its documentation for any purpose and without fee is hereby
- X granted, without any conditions or restrictions. This software is
- X provided "as is" without express or implied warranty.
- X
- */
- X
- #include <stdio.h>
- #include "ppm.h"
- #include "ppmcmap.h"
- X
- #define TRUE 1
- #define FALSE 0
- X
- #define EOS '\0'
- X
- #define MAXHIST 32767 /* Colour histogram maximum size */
- X
- static pixel **pixels; /* Input pixel map */
- static colorhash_table cht; /* Colour hash table */
- static int curcol = -1; /* Current slide output colour */
- static int polymode = FALSE; /* Output filled polygons ? */
- static int dxbmode = FALSE; /* Output .dxb format ? */
- static int bgcol = -1; /* Screen background colour */
- static double aspect = 1.0; /* Pixel aspect ratio correction */
- static int gamut = 256; /* Output colour gamut */
- X
- #include "autocad.h" /* AutoCAD standard colour assignments */
- X
- /* OUTRUN -- Output a run of pixels. */
- X
- static void outrun(colour, ysize, y, xstart, xend)
- X int colour, ysize, y, xstart, xend;
- {
- X if (colour == 0) {
- X return; /* Let screen background handle this */
- X }
- X
- X if (curcol != colour) {
- X if (dxbmode) {
- X putchar(136);
- X (void) pm_writelittleshort(stdout, colour);
- X } else {
- X (void) pm_writelittleshort(stdout, 0xFF00 | colour);
- X }
- X curcol = colour;
- X }
- X if (polymode) {
- X int v, yb = (ysize - y) + 1, yspan = 1;
- X
- X /* Since we're emitting filled polygons, let's scan downward
- X in the pixmap and see if we can extend the run on this line
- X vertically as well. If so, emit a polygon that handles
- X both the horizontal and vertical run and clear the pixels
- X in the subsequent lines to the background colour. */
- X
- X for (v = y + 1; v <= ysize; v++) {
- X int j, mismatch = FALSE;
- X
- X for (j = xstart; j <= xend; j++) {
- X if (PPM_GETR(pixels[y][j]) != PPM_GETR(pixels[v][j])) {
- X mismatch = TRUE;
- X break;
- X }
- X }
- X if (mismatch) {
- X break;
- X }
- X for (j = xstart; j <= xend; j++) {
- X PPM_ASSIGN(pixels[v][j], 0, 0, 0);
- X }
- X }
- X yspan = v - y;
- X
- X if (dxbmode) {
- X putchar(11); /* Solid */
- X (void) pm_writelittleshort(
- X stdout, (int) (xstart * aspect + 0.4999));
- X (void) pm_writelittleshort(stdout, yb);
- X
- X (void) pm_writelittleshort(
- X stdout, (int) ((xend + 1) * aspect + 0.4999));
- X (void) pm_writelittleshort(stdout, yb);
- X
- X (void) pm_writelittleshort(
- X stdout, (int) (xstart * aspect + 0.4999));
- X (void) pm_writelittleshort(stdout, yb - yspan);
- X
- X (void) pm_writelittleshort(
- X stdout, (int) ((xend + 1) * aspect + 0.4999));
- X (void) pm_writelittleshort(stdout, yb - yspan);
- X } else {
- X (void) pm_writelittleshort(stdout, 0xFD00); /* Solid fill header */
- X (void) pm_writelittleshort(stdout, 4); /* Vertices to follow */
- X (void) pm_writelittleshort(stdout, -2); /* Fill type */
- X
- X (void) pm_writelittleshort(stdout, 0xFD00); /* Solid fill vertex */
- X (void) pm_writelittleshort(stdout, xstart);
- X (void) pm_writelittleshort(stdout, yb);
- X
- X (void) pm_writelittleshort(stdout, 0xFD00); /* Solid fill vertex */
- X (void) pm_writelittleshort(stdout, xend + 1);
- X (void) pm_writelittleshort(stdout, yb);
- X
- X (void) pm_writelittleshort(stdout, 0xFD00); /* Solid fill vertex */
- X (void) pm_writelittleshort(stdout, xend + 1);
- X (void) pm_writelittleshort(stdout, yb - yspan);
- X
- X (void) pm_writelittleshort(stdout, 0xFD00); /* Solid fill vertex */
- X (void) pm_writelittleshort(stdout, xstart);
- X (void) pm_writelittleshort(stdout, yb - yspan);
- X
- X (void) pm_writelittleshort(stdout, 0xFD00); /* Solid fill trailer */
- X (void) pm_writelittleshort(stdout, 4); /* Vertices that precede */
- X (void) pm_writelittleshort(stdout, -2); /* Fill type */
- X }
- X } else {
- X (void) pm_writelittleshort(stdout, xstart); /* Vector: From X */
- X (void) pm_writelittleshort(stdout, ysize - y); /* From Y */
- X (void) pm_writelittleshort(stdout, xend); /* To X */
- X (void) pm_writelittleshort(stdout, ysize - y); /* To Y */
- X }
- }
- X
- /* SLIDEOUT -- Write an AutoCAD slide. */
- X
- static void slideout(xdots, ydots, ncolours, red, green, blue)
- X int xdots, ydots, ncolours;
- X unsigned char *red, *green, *blue;
- {
- X static char sldhead[18] = "AutoCAD Slide\r\n\32";
- X static char dxbhead[20] = "AutoCAD DXB 1.0\r\n\32";
- X unsigned char *acadmap;
- X int i, xsize, ysize;
- X
- X /* If the user has specified a non-black screen background colour,
- X swap the screen background colour into colour index zero and
- X move black into the slot previously occupied by the background
- X colour. */
- X
- X if (bgcol > 0) {
- X acadcol[0][0] = acadcol[bgcol][0];
- X acadcol[0][1] = acadcol[bgcol][1];
- X acadcol[0][2] = acadcol[bgcol][2];
- X acadcol[bgcol][0] = acadcol[bgcol][1] = acadcol[bgcol][2] = 0;
- X }
- X
- X acadmap = (unsigned char *) pm_allocrow(ncolours, sizeof(unsigned char));
- X xsize = polymode ? xdots : (xdots - 1);
- X ysize = polymode ? ydots : (ydots - 1);
- X if (dxbmode) {
- X fwrite(dxbhead, 19, 1, stdout); /* DXB file header */
- X putchar(135); /* Number mode */
- X (void) pm_writelittleshort(stdout, 0); /* ...short integers */
- X } else {
- X fwrite(sldhead, 17, 1, stdout); /* Slide file header */
- X putchar(86); /* Number format indicator */
- X putchar(2); /* File level number */
- X (void) pm_writelittleshort(stdout, xsize); /* Max X co-ordinate value */
- X (void) pm_writelittleshort(stdout, ysize); /* Max Y co-ordinate value */
- X /* Aspect ratio indicator */
- X (void) pm_writelittlelong(
- X stdout, (long) ((((double) xsize) / ysize) * aspect * 1E7));
- X (void) pm_writelittleshort(stdout, 2); /* Polygon fill type */
- X (void) pm_writelittleshort(stdout, 0x1234); /* Byte order indicator */
- X }
- X
- X /* Now build a mapping from the image's computed colour map
- X indices to the closest representation of each colour within
- X AutoCAD's colour repertoire. */
- X
- X for (i = 0; i < ncolours; i++) {
- X int best, j;
- X long dist = 3 * 256 * 256;
- X
- X for (j = 0; j < gamut; j++) {
- X long dr = red[i] - acadcol[j][0],
- X dg = green[i] - acadcol[j][1],
- X db = blue[i] - acadcol[j][2];
- X long tdist = dr * dr + dg * dg + db * db;
- X
- X if (tdist < dist) {
- X dist = tdist;
- X best = j;
- X }
- X }
- X acadmap[i] = best;
- X }
- X
- X /* Swoop over the entire map and replace each RGB pixel with its
- X closest AutoCAD colour representation. We do this in a
- X separate pass since it avoids repetitive mapping of pixels as
- X we examine them for compression. */
- X
- X for (i = 0; i < ydots; i++) {
- X int x;
- X
- X for (x = 0; x < xdots; x++) {
- X PPM_ASSIGN(pixels[i][x],
- X acadmap[ppm_lookupcolor(cht, &pixels[i][x])], 0 ,0);
- X }
- X }
- X
- X /* Output a run-length encoded expression of the pixmap as AutoCAD
- X vectors. */
- X
- X for (i = 0; i < ydots; i++) {
- X int x, rx, rpix = -1, nrun = 0;
- X
- X for (x = 0; x < xdots; x++) {
- X int pix = PPM_GETR(pixels[i][x]);
- X
- X if (pix != rpix) {
- X if (nrun > 0) {
- X if (rpix > 0) {
- X outrun(rpix, ydots - 1, i, rx, x - 1);
- X }
- X }
- X rpix = pix;
- X rx = x;
- X nrun = 1;
- X }
- X }
- X if ((nrun > 0) && (rpix > 0)) {
- X outrun(rpix, ydots - 1, i, rx, xdots - 1);
- X }
- X }
- X if (dxbmode) {
- X putchar(0); /* DXB end sentinel */
- X } else {
- X (void) pm_writelittleshort(stdout, 0xFC00); /* End of file marker */
- X }
- X pm_freerow((char *) acadmap);
- }
- X
- /* Main program. */
- X
- int main(argc, argv)
- X int argc;
- X char* argv[];
- {
- X FILE *ifp;
- X int argn, rows, cols, ncolours, i;
- X int aspectspec = FALSE;
- X pixval maxval;
- X colorhist_vector chv;
- X unsigned char *Red, *Green, *Blue;
- X char *usage =
- X "[-poly] [-dxb] [-white] [-background <col>]\n\
- X [-aspect <f>] [-8] [ppmfile]";
- X
- X ppm_init(&argc, argv);
- X
- X argn = 1;
- X while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != EOS) {
- X if (pm_keymatch(argv[argn], "-dxb", 2)) {
- X dxbmode = polymode = TRUE;
- X } else if (pm_keymatch(argv[argn], "-poly", 2)) {
- X polymode = TRUE;
- X } else if (pm_keymatch(argv[argn], "-white", 2)) {
- X if (bgcol >= 0) {
- X pm_error("already specified a background colour");
- X }
- X bgcol = 7;
- X } else if (pm_keymatch(argv[argn], "-background", 2)) {
- X if (bgcol >= 0) {
- X pm_error("already specified a background colour");
- X }
- X argn++;
- X if ((argn == argc) || (sscanf(argv[argn], "%d", &bgcol) != 1))
- X pm_usage(usage);
- X if (bgcol < 0) {
- X pm_error("background colour must be >= 0 and <= 255");
- X }
- X } else if (pm_keymatch(argv[argn], "-aspect", 2)) {
- X if (aspectspec) {
- X pm_error("already specified an aspect ratio");
- X }
- X argn++;
- X if ((argn == argc) || (sscanf(argv[argn], "%lf", &aspect) != 1))
- X pm_usage(usage);
- X if (aspect <= 0.0) {
- X pm_error("aspect ratio must be greater than 0");
- X }
- X aspectspec = TRUE;
- X } else if (pm_keymatch(argv[argn], "-8", 2)) {
- X gamut = 8;
- X } else {
- X pm_usage(usage);
- X }
- X argn++;
- X }
- X
- X if (argn < argc) {
- X ifp = pm_openr(argv[argn]);
- X argn++;
- X } else {
- X ifp = stdin;
- X }
- X
- X if (argn != argc) {
- X pm_usage(usage);
- X }
- X
- X pixels = ppm_readppm(ifp, &cols, &rows, &maxval);
- X
- X pm_close(ifp);
- X
- X /* Figure out the colormap. Logic for squeezing depth to limit the
- X number of colours in the image was swiped from ppmquant.c. */
- X
- X while (TRUE) {
- X int row, col;
- X pixval newmaxval;
- X pixel *pP;
- X
- X pm_message("computing colourmap...");
- X chv = ppm_computecolorhist(pixels, cols, rows, MAXHIST, &ncolours);
- X if (chv != (colorhist_vector) 0)
- X break;
- X newmaxval = maxval / 2;
- X pm_message(
- X "scaling colours from maxval=%d to maxval=%d to improve clustering...",
- X maxval, newmaxval );
- X for (row = 0; row < rows; ++row) {
- X for (col = 0, pP = pixels[row]; col < cols; ++col, ++pP) {
- X PPM_DEPTH(*pP, *pP, maxval, newmaxval);
- X }
- X }
- X maxval = newmaxval;
- X }
- X pm_message("%d colours found", ncolours);
- X
- X /* Scale the colour map derived for the PPM file into one compatible
- X with AutoCAD's convention of 8 bit intensities. */
- X
- X if (maxval != 255) {
- X pm_message("maxval is not 255 - automatically rescaling colours");
- X }
- X Red = (unsigned char *) pm_allocrow(ncolours, sizeof(unsigned char));
- X Green = (unsigned char *) pm_allocrow(ncolours, sizeof(unsigned char));
- X Blue = (unsigned char *) pm_allocrow(ncolours, sizeof(unsigned char));
- X
- X for (i = 0; i < ncolours; ++i) {
- X if ( maxval == 255 ) {
- X Red[i] = PPM_GETR(chv[i].color);
- X Green[i] = PPM_GETG(chv[i].color);
- X Blue[i] = PPM_GETB( chv[i].color );
- X } else {
- X Red[i] = ((int) PPM_GETR(chv[i].color) * 255) / maxval;
- X Green[i] = ((int) PPM_GETG(chv[i].color) * 255) / maxval;
- X Blue[i] = ((int) PPM_GETB(chv[i].color) * 255) / maxval;
- X }
- X }
- X
- X /* And make a hash table for fast lookup. */
- X
- X cht = ppm_colorhisttocolorhash(chv, ncolours);
- X ppm_freecolorhist(chv);
- X
- X slideout(cols, rows, ncolours, Red, Green, Blue);
- X pm_freerow((char *) Red);
- X pm_freerow((char *) Green);
- X pm_freerow((char *) Blue);
- X exit(0);
- }
- SHAR_EOF
- chmod 0664 ppm/ppmtoacad.c ||
- echo 'restore of ppm/ppmtoacad.c failed'
- Wc_c="`wc -c < 'ppm/ppmtoacad.c'`"
- test 11612 -eq "$Wc_c" ||
- echo 'ppm/ppmtoacad.c: original size 11612, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ppm/sldtoppm.1 ==============
- if test -f 'ppm/sldtoppm.1' -a X"$1" != X"-c"; then
- echo 'x - skipping ppm/sldtoppm.1 (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ppm/sldtoppm.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ppm/sldtoppm.1' &&
- .TH sldtoppm 1 "10 October 1991"
- .IX sldtoppm
- .IX AutoCAD
- .SH NAME
- sldtoppm - convert an AutoCAD slide file into a portable pixmap
- .SH SYNOPSIS
- .na
- .B sldtoppm
- 'in 14n
- .RB [ -adjust ]
- .RB [ -dir ]
- .RB [ -height | -ysize
- .IR s ]
- .RB [ -info ]
- .RB [ -lib | -Lib
- .IR name ]
- .RB [ -scale
- .IR s ]
- .RB [ -verbose ]
- .RB [ -width | -xsize
- .IR s ]
- .RI [ slidefile ]
- .in -14n
- .ad
- .SH DESCRIPTION
- Reads an AutoCAD\*R slide file and outputs a portable pixmap.
- If no
- .I slidefile
- is specified, input is read from standard input.
- The ppmdraw library is used to convert the vector and polygon
- information in the slide file to a pixmap; see the file ppmdraw.h for
- details on this package.
- .SH OPTIONS
- .TP
- .B -adjust
- If the display on which the slide file was created had non-square
- pixels, when the slide is processed with
- .B sldtoppm
- and the
- .B -adjust
- option is not present, the following warning will appear:
- .in +.2i
- Warning - pixels on source screen were non-square.
- .br
- Specifying
- .B -adjust
- will correct image width to compensate.
- .in -.2i
- Specifying the
- .B -adjust
- option causes
- .B sldtoppm
- to scale the width of the image so that pixels in the resulting
- portable pixmap are square (and hence circles appear as true circles,
- not ellipses). The scaling is performed in the vector domain, before
- scan converting the objects. The results are, therefore, superior in
- appearance to what you'd obtain were you to perform the equivalent
- scaling with
- .B pnmscale
- after the bitmap had been created.
- .TP
- .B -dir
- The input is assumed to be an AutoCAD slide library file. A directory
- listing each slide in the library is printed on standard error.
- .TP
- .BI -height " size"
- Scales the image in the vector domain so it is
- .I size
- pixels in height. If no
- .B -width
- or
- .B -xsize
- option is specified, the width will be adjusted to preserve the
- pixel aspect ratio.
- .TP
- .B -info
- Dump the slide file header on standard error, displaying the original
- screen size and aspect ratio among other information.
- .TP
- .BI -lib " name"
- Extracts the slide with the given
- .I name
- from the slide library given as input. The specified
- .I name
- is converted to upper case.
- .TP
- .BI -Lib " name"
- Extracts the slide with the given
- .I name
- from the slide library given as input. The
- .I name
- is used exactly as specified; it is not converted to upper case.
- .TP
- .BI -scale " s"
- Scales the image by factor
- .IR s ,
- which may be any floating point value greater than zero. Scaling is
- done after aspect ratio adjustment, if any. Since scaling is
- performed in the vector domain, before rasterisation, the results look
- much better than running the output of
- .B sldtoppm
- through
- .BR pnmscale .
- .TP
- .B -verbose
- Dumps the slide file header and lists every vector and polygon in the
- file on standard error.
- .TP
- .BI -width " size"
- Scales the image in the vector domain so it is
- .I size
- pixels wide. If no
- .B -height
- or
- .B -ysize
- option is specified, the height will be adjusted to preserve the
- pixel aspect ratio.
- .TP
- .BI -xsize " size"
- Scales the image in the vector domain so it is
- .I size
- pixels wide. If no
- .B -height
- or
- .B -ysize
- option is specified, the height will be adjusted to preserve the
- pixel aspect ratio.
- .TP
- .BI -ysize " size"
- Scales the image in the vector domain so it is
- .I size
- pixels in height. If no
- .B -width
- or
- .B -xsize
- option is specified, the width will be adjusted to preserve the
- pixel aspect ratio.
- .PP
- All flags can be abbreviated to their shortest unique prefix.
- .SH BUGS
- Only Level 2 slides are converted. Level 1 format has been obsolete
- since the advent of AutoCAD Release 9 in 1987, and was not portable
- across machine architectures.
- .PP
- Slide library items with names containing 8 bit (such as ISO) or 16
- bit (Kanji, for example) characters may not be found when chosen with the
- .B -lib
- option unless
- .B sldtoppm
- has been built with character set conversion functions appropriate to
- the locale. You can always retrieve slides from libraries regardless
- of the character set by using the
- .B -Lib
- option and specifying the precise name of library member. Use the
- .B -dir
- option to list the slides in a library if you're unsure of the
- exact name.
- .SH "SEE ALSO"
- AutoCAD Reference Manual:
- .IR "Slide File Format" ,
- .BR pnmscale (1),
- .BR ppm (5)
- .SH AUTHOR
- .RS 5
- .nf
- John Walker
- Autodesk SA
- Avenue des Champs-Montants 14b
- CH-2074 MARIN
- Suisse/Schweiz/Svizzera/Svizra/Switzerland
- .PD 0
- .TP 9
- Usenet:
- kelvin@Autodesk.com
- .TP
- Fax:
- 038/33 88 15
- .TP
- Voice:
- 038/33 76 33
- .fi
- .RE
- .PD
- .PP
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- without any conditions or restrictions. This software is provided ``as
- is'' without express or implied warranty.
- .PP
- AutoCAD and Autodesk are registered trademarks of Autodesk, Inc.
- SHAR_EOF
- chmod 0664 ppm/sldtoppm.1 ||
- echo 'restore of ppm/sldtoppm.1 failed'
- Wc_c="`wc -c < 'ppm/sldtoppm.1'`"
- test 4785 -eq "$Wc_c" ||
- echo 'ppm/sldtoppm.1: original size 4785, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= ppm/sldtoppm.c ==============
- if test -f 'ppm/sldtoppm.c' -a X"$1" != X"-c"; then
- echo 'x - skipping ppm/sldtoppm.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ppm/sldtoppm.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ppm/sldtoppm.c' &&
- /*
- X
- X Convert an AutoCAD slide (.sld) file to PPM format
- X
- X An AutoCAD slide is a compressed sequence of vectors and filled
- X polygons. The ppmdraw package is used to scan convert these
- X geometrical objects into a portable pixmap.
- X
- X Author:
- X John Walker
- X Autodesk SA
- X Avenue des Champs-Montants 14b
- X CH-2074 MARIN
- X Switzerland
- X Usenet: kelvin@Autodesk.com
- X Fax: 038/33 88 15
- X Voice: 038/33 76 33
- X
- X Permission to use, copy, modify, and distribute this software and
- X its documentation for any purpose and without fee is hereby
- X granted, without any conditions or restrictions. This software is
- X provided "as is" without express or implied warranty.
- X
- */
- X
- #include "ppm.h"
- #include "ppmdraw.h"
- #ifdef DEBUG
- #include <assert.h>
- #else
- #define assert(x)
- #endif
- X
- /* Define a variable type accepting numbers -127 <= n <= 127. But note
- X that we still expect it to act UNSIGNED. */
- X
- #define smallint unsigned char /* Small integers */
- X
- #define TRUE 1
- #define FALSE 0
- X
- #define EOS '\0'
- X
- /* Screen point */
- X
- struct spoint {
- X int x, y;
- };
- X
- /* Screen polygon */
- X
- struct spolygon {
- X int npoints, /* Number of points in polygon */
- X fill; /* Fill type */
- X struct spoint pt[11]; /* Actual points */
- };
- X
- /* Screen vector */
- X
- struct svector {
- X struct spoint f; /* From point */
- X struct spoint t; /* To point */
- };
- X
- X
- static int ixdots, iydots; /* Screen size in dots */
- static FILE *slfile; /* Slide file descriptor */
- static int blither = FALSE; /* Dump slide file information ? */
- static int info = FALSE; /* Print header information */
- static pixel **pixels; /* Pixel map */
- static int pixcols, pixrows; /* Pixel map size */
- #define pixmaxval 255 /* Largest pixel value */
- static double uscale = -1; /* Uniform scale factor */
- static int sxsize = -1, sysize = -1; /* Scale to X, Y size ? */
- X
- #include "autocad.h" /* AutoCAD standard colour assignments */
- X
- /* Local variables */
- X
- struct slhead {
- X char slh[17]; /* Primate-readable header */
- X char sntype; /* Machine type (for number compat) */
- X char slevel; /* Format type */
- X short sxdots, sydots; /* Display X, Y dots */
- X double sdsar; /* Display aspect ratio */
- X short shwfill; /* Display hardware fill type */
- X char spad; /* Pad to even byte length */
- };
- X
- static int adjust = FALSE; /* Adjust to correct aspect ratio ? */
- static struct slhead slfrof; /* Slide file header */
- static long xfac, yfac; /* Aspect ratio scale factors */
- X
- static int sdrawkcab; /* Slide drawing kinematic conversion of
- X ass-backwards data flag */
- X
- /* EXTEND -- Turn a smallint into an int with sign extension, whether
- X or not that happens automatically. */
- X
- static int extend(ch)
- X smallint ch;
- {
- X return ((int) ((ch & 0x80) ? (ch | ~0xFF) : ch));
- }
- X
- /* SLI -- Input word from slide file */
- X
- static int sli()
- {
- X short wd;
- X
- X if (fread(&wd, sizeof wd, 1, slfile) != 1) {
- X pm_error("error reading slide file");
- X } else {
- X if (sdrawkcab) {
- X wd = ((wd >> 8) & 0xFF) | (wd << 8);
- X }
- X }
- X return wd;
- }
- X
- /* SLIB -- Input byte from slide file */
- X
- static int slib()
- {
- X smallint ch = 0;
- X
- X if (fread(&ch, sizeof ch, 1, slfile) != 1) {
- X pm_error("error reading slide file");
- X }
- X return extend(ch);
- }
- X
- /* VSCALE -- scale screen coordinates for mismatched display. */
- X
- static void vscale(px, py)
- X int *px, *py;
- {
- X *px = (((unsigned) *px) * xfac) >> 16;
- X *py = (((unsigned) *py) * yfac) >> 16;
- }
- X
- /* SLIDER -- Read slide file. This is called with the name of the
- X file to be read and function pointers to the routines
- X which process vectors and polygon fill requests
- X respectively.
- */
- X
- static void slider(slvec, slflood)
- X void (*slvec)();
- X void (*slflood)();
- {
- X int i, rescale;
- X unsigned char ubfr[4]; /* Utility character buffer */
- X int lx, ly; /* Last x and y point */
- X int slx, sly; /* Last x and y scaled screen point */
- X struct svector vec; /* Screen vector */
- X struct spolygon poly; /* Screen polygon */
- X unsigned short cw; /* Control word */
- X double dsar; /* Screen aspect ratio */
- X long ldsar; /* Scaled long DSAR */
- X short rtest; /* Value to test byte reversal */
- X short btest = 0x1234; /* Value to test byte-reversal */
- X static struct slhead slhi = /* Master slide header sample */
- X {"AutoCAD Slide\r\n\32", 86,2, 0,0, 0.0, 0};
- X int curcolour = 7; /* Current vector colour */
- X pixel rgbcolour; /* Pixel used to clear pixmap */
- X
- X lx = ly = 32000;
- X
- X /* Process the header of the slide file. */
- X
- X sdrawkcab = FALSE; /* Initially guess byte order is OK */
- X fread(slfrof.slh, 17, 1, slfile);
- X fread(&slfrof.sntype, sizeof(char), 1, slfile);
- X fread(&slfrof.slevel, sizeof(char), 1, slfile);
- X fread(&slfrof.sxdots, sizeof(short), 1, slfile);
- X fread(&slfrof.sydots, sizeof(short), 1, slfile);
- X fread(ubfr, 4, 1, slfile);
- X fread(&slfrof.shwfill, sizeof(short), 1, slfile);
- X fread(&rtest, sizeof rtest, 1, slfile);
- X
- X /* Verify that slide format is compatible with this program. */
- X
- X if (strcmp(slfrof.slh, slhi.slh) != 0) {
- X pm_error("this is not an AutoCAD slide file.");
- X }
- X
- X /* Verify that the number format and file level in the header are
- X compatible. All slides written by versions of AutoCAD released
- X since September of 1987 are compatible with this format. */
- X
- X if ((slfrof.sntype != slhi.sntype) || (slfrof.slevel != slhi.slevel)) {
- X pm_error("incompatible slide file format");
- X }
- X
- X /* Build SDSAR value from long scaled version. */
- X
- X ldsar = 0L;
- X for (i = 3; i >= 0; i--) {
- X ldsar = (ldsar << 8) | ubfr[i];
- X }
- X slfrof.sdsar = ((double) ldsar) / 1E7;
- X
- X /* Examine the byte order test value. If it's backwards, set the
- X byte-reversal flag and correct all of the values we've read in
- X so far. */
- X
- X if (btest != rtest) {
- X sdrawkcab = TRUE;
- #define rshort(x) x = ((x >> 8) & 0xFF) | (x << 8)
- X rshort(slfrof.sxdots);
- X rshort(slfrof.sydots);
- X rshort(slfrof.shwfill);
- #undef rshort
- X }
- X
- X /* Dump the header if we're blithering. */
- X
- X if (blither || info) {
- X pm_message("Slide file type %d, level %d, hwfill type %d.",
- X slfrof.sntype, slfrof.slevel, slfrof.shwfill);
- X pm_message("Original screen size %dx%d, aspect ratio %.3f.",
- X slfrof.sxdots + 1, slfrof.sydots + 1, slfrof.sdsar);
- X pm_message("Byte order is %s.",
- X sdrawkcab ? "being reversed" : "the same");
- X }
- X
- X /* If the display aspect ratio indicates that the pixels on the
- X sending screen were not square, adjust the size of the
- X generated bitmap to correct the aspect ratio to square the
- X pixels.
- X
- X We always correct the aspect ratio by adjusting the width of
- X the image. This guarantees that output from the SHADE command,
- X which is essentially scan-line data written in vector form,
- X will not be corrupted. */
- X
- X dsar = ((double) slfrof.sxdots) / slfrof.sydots;
- X if (abs(slfrof.sdsar - dsar) > 0.0001) {
- X if (adjust) {
- X ixdots = slfrof.sxdots * (slfrof.sdsar / dsar) + 0.5;
- X iydots = slfrof.sydots;
- X dsar = ((double) ixdots) / iydots;
- X } else {
- X pm_message("Warning - pixels on source screen were non-square.");
- X pm_message(" Specifying -adjust will correct image width to compensate.");
- X ixdots = slfrof.sxdots;
- X iydots = slfrof.sydots;
- X dsar = slfrof.sdsar;
- X }
- X } else {
- X /* Source pixels were square. */
- X ixdots = slfrof.sxdots;
- X iydots = slfrof.sydots;
- X dsar = slfrof.sdsar;
- X adjust = FALSE; /* Mark no adjustment needed */
- X }
- X
- X /* If there's a uniform scale factor specified, apply it. */
- X
- X if (uscale > 0) {
- X ixdots = (ixdots * uscale) + 0.5;
- X iydots = (iydots * uscale) + 0.5;
- X }
- X
- X /* If the image is to be stretched to a given width, set the
- X output image sizes accordingly. If only a height or width is
- X given, scale the other direction proportionally to preserve the
- X aspect ratio. */
- X
- X if (sxsize > 0) {
- X if (sysize > 0) {
- X iydots = sysize - 1;
- X } else {
- X iydots = ((((long) iydots) * (sxsize - 1)) +
- X (iydots / 2)) / ixdots;
- X }
- X ixdots = sxsize - 1;
- X } else if (sysize > 0) {
- X if (sxsize > 0) {
- X ixdots = sxsize - 1;
- X } else {
- X ixdots = ((((long) ixdots) * (sysize - 1)) +
- X (ixdots / 2)) / iydots;
- X }
- X iydots = sysize - 1;
- X }
- X
- X if (adjust) {
- X pm_message(
- X "Resized from %dx%d to %dx%d to correct pixel aspect ratio.",
- X slfrof.sxdots + 1, slfrof.sydots + 1, ixdots + 1, iydots + 1);
- X }
- X
- X /* Allocate image buffer and clear it to black. */
- X
- X pixels = ppm_allocarray(pixcols = ixdots + 1, pixrows = iydots + 1);
- X PPM_ASSIGN(rgbcolour, 0, 0, 0);
- X ppmd_filledrectangle(pixels, pixcols, pixrows, pixmaxval, 0, 0,
- X pixcols, pixrows, PPMD_NULLDRAWPROC,
- X (char *) &rgbcolour);
- X
- X if ((rescale = slfrof.sxdots != ixdots ||
- X slfrof.sydots != iydots ||
- X slfrof.sdsar != dsar) != 0) {
- X
- X /* Rescale all coords. so they'll look (more or less)
- X right on this display. */
- X
- X xfac = (ixdots + 1) * 0x10000L;
- X xfac /= (long) (slfrof.sxdots + 1);
- X yfac = (iydots + 1) * 0x10000L;
- X yfac /= (long) (slfrof.sydots + 1);
- X if (dsar < slfrof.sdsar) {
- X yfac = yfac * dsar / slfrof.sdsar;
- X } else {
- X xfac = xfac * slfrof.sdsar / dsar;
- X }
- X }
- X
- X poly.npoints = 0; /* No flood in progress. */
- X
- X while ((cw = sli()) != 0xFC00) {
- X switch (cw & 0xFF00) {
- X case 0xFB00: /* Short vector compressed */
- X vec.f.x = lx + extend(cw & 0xFF);
- X vec.f.y = ly + slib();
- X vec.t.x = lx + slib();
- X vec.t.y = ly + slib();
- X lx = vec.f.x;
- X ly = vec.f.y;
- X if (rescale) {
- X vscale(&vec.f.x, &vec.f.y);
- X vscale(&vec.t.x, &vec.t.y);
- X }
- X (*slvec)(&vec, curcolour);/* Draw vector on screen */
- X slx = vec.f.x; /* Save scaled point */
- X sly = vec.f.y;
- X break;
- X
- X case 0xFC00: /* End of file */
- X break;
- X
- X case 0xFD00: /* Flood command */
- X vec.f.x = sli();
- X vec.f.y = sli();
- X if ((int) vec.f.y < 0) { /* start or end */
- X if (poly.npoints != 0) { /* end? */
- X if (poly.npoints > 2 && poly.npoints < 11) {
- X (*slflood)(&poly, curcolour);
- X } else {
- X pm_error("Bad polygon vertex count (%d)",
- X poly.npoints);
- X }
- X poly.npoints = 0;
- X } else {
- X poly.fill = -vec.f.y; /* Start */
- X }
- X } else { /* Polygon vertex */
- X if (poly.npoints < 10) {
- X if (rescale) {
- X vscale(&vec.f.x, &vec.f.y);
- X }
- X poly.pt[poly.npoints].x = vec.f.x;
- X poly.pt[poly.npoints].y = vec.f.y;
- X }
- X poly.npoints++;
- X }
- X break;
- X
- X case 0xFE00: /* Common endpoint compressed */
- X vec.f.x = lx + extend(cw & 0xFF);
- X vec.f.y = ly + slib();
- X lx = vec.f.x;
- X ly = vec.f.y;
- X vec.t.x = slx;
- X vec.t.y = sly;
- X if (rescale) {
- X vscale(&vec.f.x, &vec.f.y);
- X }
- X (*slvec)(&vec, curcolour);/* Draw vector */
- X slx = vec.f.x; /* Save scaled point */
- X sly = vec.f.y;
- X break;
- X
- X case 0xFF00: /* Change colour */
- X curcolour = cw & 0xFF;
- X break;
- X
- X default: /* Co-ordinates */
- X lx = vec.f.x = cw;
- X ly = vec.f.y = sli();
- X vec.t.x = sli();
- X vec.t.y = sli();
- X if (rescale) {
- X vscale(&vec.f.x, &vec.f.y);
- X vscale(&vec.t.x, &vec.t.y);
- X }
- X (*slvec)(&vec, curcolour);
- X slx = vec.f.x; /* Save scaled point */
- X sly = vec.f.y;
- X break;
- X }
- X }
- }
- X
- /* SLIDEFIND -- Find a slide in a library or, if DIRONLY is
- X nonzero, print a directory listing of the library.
- X If UCASEN is nonzero, the requested slide name is
- X converted to upper case. */
- X
- static void slidefind(sname, dironly, ucasen)
- X char *sname;
- X int dironly, ucasen;
- {
- X char uname[32];
- X unsigned char libent[36];
- X long pos;
- X
- X if (dironly) {
- X pm_message("Slides in library:");
- X } else {
- X int i;
- X char *ip = sname;
- X
- X for (i = 0; i < 31; i++) {
- X char ch = *ip++;
- X if (ch == EOS) {
- X break;
- X }
- X if (ucasen && islower(ch)) {
- X ch = toupper(ch);
- X }
- X uname[i] = ch;
- X }
- X uname[i] = EOS;
- X }
- X
- X /* Read slide library header and verify. */
- X
- X if ((fread(libent, 32, 1, slfile) != 1) ||
- X (strcmp(libent, "AutoCAD Slide Library 1.0\015\012\32") != 0)) {
- X pm_error("not an AutoCAD slide library file.");
- X }
- X pos = 32;
- X
- X /* Search for a slide with the requested name. */
- X
- X while (TRUE) {
- X if ((fread(libent, 36, 1, slfile) != 1) ||
- X (strlen(libent) == 0)) {
- X if (dironly) {
- X return;
- X }
- X pm_error("slide %s not in library.", sname);
- X }
- X pos += 36;
- X if (dironly) {
- X pm_message(" %s", libent);
- X } else if (strcmp(libent, uname) == 0) {
- X long dpos = (((((libent[35] << 8) | libent[34]) << 8) |
- X libent[33]) << 8) | libent[32];
- X if ((slfile == stdin) || (fseek(slfile, dpos, 0) == -1)) {
- X dpos -= pos;
- X
- X while (dpos-- > 0) {
- X (void) getc(slfile);
- X }
- X }
- X break;
- X }
- X }
- }
- X
- /* DRAW -- Draw a vector in the given AutoCAD colour. */
- X
- static void draw(vec, colour)
- X struct svector *vec;
- X int colour;
- {
- X pixel rgbcolour;
- X
- X if (blither) {
- X pm_message("Vector (%d, %d) - (%d, %d) Colour %d",
- X vec->f.x, vec->f.y, vec->t.x, vec->t.y, colour);
- X }
- X assert(vec->f.x >= 0 && vec->f.x < pixcols);
- X assert(vec->f.y >= 0 && vec->f.y < pixrows);
- X assert(vec->t.x >= 0 && vec->t.x < pixcols);
- X assert(vec->t.y >= 0 && vec->t.y < pixrows);
- X PPM_ASSIGN(rgbcolour,
- X acadcol[colour][0], acadcol[colour][1], acadcol[colour][2]);
- X ppmd_line(pixels, pixcols, pixrows, pixmaxval,
- X vec->f.x, iydots - vec->f.y, vec->t.x, iydots - vec->t.y,
- X PPMD_NULLDRAWPROC,
- X (char *) &rgbcolour);
- SHAR_EOF
- true || echo 'restore of ppm/sldtoppm.c failed'
- fi
- echo 'End of part 4'
- echo 'File ppm/sldtoppm.c is continued in part 5'
- echo 5 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-