home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / ppm / ppmtopj.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  7KB  |  256 lines

  1. /* ppmtopj.c - convert a portable pixmap to an HP PainJetXL image
  2. **
  3. ** Copyright (C) 1990 by Christos Zoulas (christos@ee.cornell.edu)
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "ppm.h"
  14.  
  15. static int compress_row ARGS((unsigned char *op, unsigned char *oe, unsigned char *cp));
  16. /*
  17.  * XXX: Only 8.5 x 11 paper
  18.  */
  19. #define WIDTH      8.5
  20. #define HEIGHT      11.0
  21. #define DPI      180
  22. #define XPIX      ((int) ((DPI * WIDTH + 7) / 8) << 3)
  23. #define YPIX      ((int) ((DPI * HEIGHT + 7) / 8) << 3)
  24.  
  25. #define C_RESET             "\033E"
  26. #define C_RENDER             "\033*t%dJ"
  27. # define C_RENDER_NONE            0
  28. # define C_RENDER_SNAP            1
  29. # define C_RENDER_BW            2
  30. # define C_RENDER_DITHER        3
  31. # define C_RENDER_DIFFUSE        4
  32. # define C_RENDER_MONODITHER        5
  33. # define C_RENDER_MONODIFFUSE        6
  34. # define C_RENDER_MONO_CL_DITHER    5
  35. # define C_RENDER_MONO_CL_DIFFUSE    6
  36. #define C_BACK_SCALE            "\033*t%dK"
  37. # define C_BACK_SCALE_LIGHT        0
  38. # define C_BACK_SCALE_DARK        1
  39. #define C_GAMMA                "\033*t%dI"
  40. #define C_IMAGE_WIDTH            "\033*r%dS"
  41. #define C_IMAGE_HEIGHT            "\033*r%dT"
  42. #define C_DATA_PLANES            "\033*r%dU"
  43. #define C_TRANS_MODE            "\033*b%dM"
  44. # define C_TRANS_MODE_STD        0
  45. # define C_TRANS_MODE_RLE        1
  46. # define C_TRANS_MODE_TIFF        2
  47. #define C_SEND_PLANE            "\033*b%dV"
  48. #define C_LAST_PLANE            "\033*b%dW"
  49. #define C_BEGIN_RASTER            "\033*r%dA"
  50. # define C_BEGIN_RASTER_MARGIN        0
  51. # define C_BEGIN_RASTER_ACTIVE        1
  52. # define C_BEGIN_RASTER_NOSCALE        0
  53. # define C_BEGIN_RASTER_SCALE        2
  54. #define C_END_RASTER            "\033*r%dC"
  55. # define C_END_RASTER_UNUSED        0
  56. #define C_RESOLUTION            "\033*t%dR"
  57. # define C_RESOLUTION_90DPI        90
  58. # define C_RESOLUTION_180DPI        180
  59. #define C_MOVE_X            "\033*p+%dX"
  60. #define C_MOVE_Y            "\033*p+%dY"
  61.  
  62. char *testimage;
  63.  
  64. static char *rmode[] = { "none", "snap", "bw", "dither", "diffuse", 
  65.              "monodither", "monodiffuse", "clusterdither", 
  66.              "monoclusterdither", NULL };
  67.  
  68. /*
  69.  * Run-length encoding for the PaintJet. We have pairs of <instances>
  70.  * <value>, where instances goes from 0 (meaning one instance) to 255
  71.  * If we are unlucky we can double the size of the image.
  72.  */
  73. static int
  74. compress_row(op, oe, cp)
  75. unsigned char *op, *oe, *cp;
  76. {
  77.     unsigned char *ce = cp;
  78.     while ( op < oe ) {    
  79.     unsigned char px = *op++;
  80.     unsigned char *pr = op;
  81.     while ( op < oe && *op == px && op - pr < 255) op++;
  82.     *ce++ = op - pr;
  83.     *ce++ = px;
  84.     }
  85.     return ce - cp;
  86. }
  87.  
  88. int main(argc, argv)
  89. int argc;
  90. char *argv[];
  91. {
  92.     pixel **pixels;
  93.     FILE *ifp;
  94.     int argn, rows, cols, colors, r, c, k, m, p;
  95.     pixval maxval;
  96.     int planes = 3;
  97.     unsigned char *obuf, *op, *cbuf;
  98.     int render_mode = C_RENDER_NONE;
  99.     int back_scale = C_BACK_SCALE_DARK;
  100.     int gamma = 0;
  101.     int mode = C_TRANS_MODE_STD;
  102.     int deciwidth = 0, deciheight = 0;
  103.     int center = 0;
  104.     int xoff = 0, yoff = 0;
  105.     /*
  106.      * XXX: Someday we could make this command line options.
  107.      */
  108.     int posscale = C_BEGIN_RASTER_MARGIN | C_BEGIN_RASTER_NOSCALE;
  109.     int resolution = C_RESOLUTION_180DPI;
  110.  
  111.     char *usage = "[-center] [-xpos <pos>] [-ypos <pos>] [-gamma <val>] [-back <dark|lite>] [-rle] [-render <none|snap|bw|dither|diffuse|monodither|monodiffuse|clusterdither|monoclusterdither>] [ppmfile]";
  112.  
  113.  
  114.     ppm_init( &argc, argv );
  115.  
  116.     argn = 1;
  117.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  118.         {
  119.         if ( pm_keymatch(argv[argn],"-render",2) && argn + 1 < argc )
  120.         {
  121.         ++argn;
  122.         for (r = 0; rmode[r] != NULL; r++)
  123.              if (strcmp(rmode[r], argv[argn]) == 0)
  124.              break;
  125.         if (rmode[r] != NULL)
  126.             render_mode = r;
  127.         else
  128.             pm_usage(usage);
  129.         }
  130.         else if ( pm_keymatch(argv[argn],"-back",2) && argn + 1 < argc )
  131.         {
  132.         ++argn;
  133.         if (strcmp(argv[argn], "dark") == 0)
  134.             back_scale = C_BACK_SCALE_DARK;
  135.         else if (strcmp(argv[argn], "lite") == 0)
  136.             back_scale = C_BACK_SCALE_LIGHT;
  137.         else
  138.             pm_usage(usage);
  139.         }
  140.         else if ( pm_keymatch(argv[argn],"-gamma",2) && argn + 1 < argc )
  141.         {
  142.         ++argn;
  143.         if ( sscanf( argv[argn], "%d",&gamma ) != 1 )
  144.             pm_usage( usage );
  145.         }
  146.         else if ( pm_keymatch(argv[argn],"-xpos",2) && argn + 1 < argc )
  147.         {
  148.         ++argn;
  149.         if ( sscanf( argv[argn], "%d",&xoff ) != 1 )
  150.             pm_usage( usage );
  151.         }
  152.         else if ( pm_keymatch(argv[argn],"-ypos",2) && argn + 1 < argc )
  153.         {
  154.         ++argn;
  155.         if ( sscanf( argv[argn], "%d",&yoff ) != 1 )
  156.             pm_usage( usage );
  157.         }
  158.         else if (pm_keymatch(argv[argn],"-rle",2))
  159.         mode = C_TRANS_MODE_RLE;
  160.         else if (pm_keymatch(argv[argn],"-center",2))
  161.         center = 1;
  162.         else
  163.         pm_usage( usage );
  164.         ++argn;
  165.         }
  166.  
  167.     if ( argn < argc )
  168.         {
  169.         ifp = pm_openr( argv[argn] );
  170.         ++argn;
  171.         }
  172.     else
  173.         ifp = stdin;
  174.  
  175.     if ( argn != argc )
  176.         pm_usage( usage );
  177.  
  178.     pixels = ppm_readppm( ifp, &cols, &rows, &maxval );
  179.  
  180.     pm_close( ifp );
  181.     obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char));
  182.     cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char));
  183.  
  184.         if (cols > XPIX || rows > YPIX)
  185.         pm_message("image too large for page");
  186.         if (center) {
  187.         if (xoff || yoff)
  188.         pm_error("cannot specify both center and position");
  189.         xoff = (XPIX - cols) / 2;
  190.         yoff = (YPIX - rows) / 2;
  191.     }
  192.  
  193.     (void) printf(C_RESET);
  194.     /*
  195.      * Set the resolution before begin raster otherwise it
  196.      * does not work.
  197.      */
  198.     (void) printf(C_RESOLUTION, resolution);
  199.     (void) printf(C_BEGIN_RASTER, posscale);
  200.     if (xoff)
  201.         (void) printf(C_MOVE_X, xoff);
  202.     if (yoff)
  203.         (void) printf(C_MOVE_Y, yoff);
  204.     (void) printf(C_TRANS_MODE, mode);
  205.     (void) printf(C_RENDER, render_mode);
  206.     (void) printf(C_BACK_SCALE, back_scale);
  207.     (void) printf(C_GAMMA,     gamma);
  208.     (void) printf(C_IMAGE_WIDTH, cols);
  209.     (void) printf(C_IMAGE_HEIGHT, rows);
  210.     (void) printf(C_DATA_PLANES, 3);
  211.  
  212.         for (r = 0; r < rows; r++)
  213.         /* for each primary */
  214.         for (p = 0; p < 3; p++) {
  215.         switch (p) {
  216.         case 0:
  217.             for (c = 0, op = &obuf[-1]; c < cols; c++) {
  218.             if ((k = (c & 7)) == 0)
  219.                 *++op = 0;
  220.             if (PPM_GETR(pixels[r][c]) > maxval / 2)
  221.                 *op |= 1 << (7 - k);
  222.             }
  223.             break;
  224.         case 1:
  225.             for (c = 0, op = &obuf[-1]; c < cols; c++) {
  226.             if ((k = (c & 7)) == 0)
  227.                 *++op = 0;
  228.             if (PPM_GETG(pixels[r][c]) > maxval / 2)
  229.                 *op |= 1 << (7 - k);
  230.             }
  231.             break;
  232.         case 2:
  233.             for (c = 0, op = &obuf[-1]; c < cols; c++) {
  234.             if ((k = (c & 7)) == 0)
  235.                 *++op = 0;
  236.             if (PPM_GETB(pixels[r][c]) > maxval / 2)
  237.                 *op |= 1 << (7 - k);
  238.             }
  239.             break;
  240.         }
  241.         ++op;
  242.         if (mode == C_TRANS_MODE_RLE) {
  243.             k = compress_row(obuf, op, cbuf);
  244.             op = cbuf;
  245.         }
  246.         else {
  247.             k = op - obuf;
  248.             op = obuf;
  249.         }
  250.         (void) printf(p == 2 ? C_LAST_PLANE : C_SEND_PLANE, k);
  251.         (void) fwrite(op, 1, k, stdout);
  252.         }
  253.     (void) printf(C_END_RASTER, C_END_RASTER_UNUSED);
  254.     exit(0);
  255. }
  256.